Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/fibril.c

    r596d65c r63f8966  
    4848
    4949#ifndef FIBRIL_INITIAL_STACK_PAGES_NO
    50         #define FIBRIL_INITIAL_STACK_PAGES_NO  1
     50#define FIBRIL_INITIAL_STACK_PAGES_NO   1
    5151#endif
    5252
    5353/**
    54  * This futex serializes access to ready_list,
    55  * serialized_list and manager_list.
    56  */
     54 * This futex serializes access to ready_list, serialized_list and manager_list.
     55 */
    5756static atomic_t fibril_futex = FUTEX_INITIALIZER;
    5857
     
    6160static LIST_INITIALIZE(manager_list);
    6261
     62static void fibril_main(void);
     63
    6364/** Number of threads that are executing a manager fibril. */
    6465static int threads_in_manager;
    65 
    66 /**
    67  * Number of threads that are executing a manager fibril
    68  * and are serialized. Protected by async_futex.
    69  */
    70 static int serialized_threads;
    71 
     66/** Number of threads that are executing a manager fibril and are serialized. */
     67static int serialized_threads;  /* Protected by async_futex */
    7268/** Fibril-local count of serialization. If > 0, we must not preempt */
    7369static fibril_local int serialization_count;
     70
     71/** Setup fibril information into TCB structure */
     72fibril_t *fibril_setup(void)
     73{
     74        fibril_t *f;
     75        tcb_t *tcb;
     76
     77        tcb = __make_tls();
     78        if (!tcb)
     79                return NULL;
     80
     81        f = malloc(sizeof(fibril_t));
     82        if (!f) {
     83                __free_tls(tcb);
     84                return NULL;
     85        }
     86
     87        tcb->fibril_data = f;
     88        f->tcb = tcb;
     89
     90        f->func = NULL;
     91        f->arg = NULL;
     92        f->stack = NULL;
     93        f->clean_after_me = NULL;
     94        f->retval = 0;
     95        f->flags = 0;
     96
     97        return f;
     98}
     99
     100void fibril_teardown(fibril_t *f)
     101{
     102        __free_tls(f->tcb);
     103        free(f);
     104}
    74105
    75106/** Function that spans the whole life-cycle of a fibril.
     
    78109 * the fibril logic is called.  After its return, the return value is saved.
    79110 * The fibril then switches to another fibril, which cleans up after it.
    80  *
    81  */
    82 static void fibril_main(void)
    83 {
    84         fibril_t *fibril = __tcb_get()->fibril_data;
    85        
     111 */
     112void fibril_main(void)
     113{
     114        fibril_t *f = __tcb_get()->fibril_data;
     115
    86116        /* Call the implementing function. */
    87         fibril->retval = fibril->func(fibril->arg);
    88        
     117        f->retval = f->func(f->arg);
     118
    89119        fibril_switch(FIBRIL_FROM_DEAD);
    90         /* Not reached */
    91 }
    92 
    93 /** Setup fibril information into TCB structure
    94  *
    95  */
    96 fibril_t *fibril_setup(void)
    97 {
    98         tcb_t *tcb = __make_tls();
    99         if (!tcb)
    100                 return NULL;
    101        
    102         fibril_t *fibril = malloc(sizeof(fibril_t));
    103         if (!fibril) {
    104                 __free_tls(tcb);
    105                 return NULL;
    106         }
    107        
    108         tcb->fibril_data = fibril;
    109         fibril->tcb = tcb;
    110        
    111         fibril->func = NULL;
    112         fibril->arg = NULL;
    113         fibril->stack = NULL;
    114         fibril->clean_after_me = NULL;
    115         fibril->retval = 0;
    116         fibril->flags = 0;
    117        
    118         return fibril;
    119 }
    120 
    121 void fibril_teardown(fibril_t *fibril)
    122 {
    123         __free_tls(fibril->tcb);
    124         free(fibril);
     120        /* not reached */
    125121}
    126122
     
    130126 * held.
    131127 *
    132  * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
    133  *              FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter
    134  *              describes the circumstances of the switch.
    135  *
    136  * @return 0 if there is no ready fibril,
    137  * @return 1 otherwise.
    138  *
     128 * @param stype         Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER,
     129 *                      FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter
     130 *                      describes the circumstances of the switch.
     131 * @return              Return 0 if there is no ready fibril,
     132 *                      return 1 otherwise.
    139133 */
    140134int fibril_switch(fibril_switch_type_t stype)
     
    252246/** Create a new fibril.
    253247 *
    254  * @param func Implementing function of the new fibril.
    255  * @param arg Argument to pass to func.
    256  *
    257  * @return 0 on failure or TLS of the new fibril.
    258  *
     248 * @param func          Implementing function of the new fibril.
     249 * @param arg           Argument to pass to func.
     250 *
     251 * @return              Return 0 on failure or TLS of the new fibril.
    259252 */
    260253fid_t fibril_create(int (*func)(void *), void *arg)
    261254{
    262         fibril_t *fibril;
    263        
    264         fibril = fibril_setup();
    265         if (fibril == NULL)
     255        fibril_t *f;
     256
     257        f = fibril_setup();
     258        if (!f)
    266259                return 0;
    267        
    268         fibril->stack =
    269             (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize());
    270         if (!fibril->stack) {
    271                 fibril_teardown(fibril);
     260        f->stack = (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO *
     261            getpagesize());
     262        if (!f->stack) {
     263                fibril_teardown(f);
    272264                return 0;
    273265        }
    274266       
    275         fibril->func = func;
    276         fibril->arg = arg;
    277        
    278         context_save(&fibril->ctx);
    279         context_set(&fibril->ctx, FADDR(fibril_main), fibril->stack,
    280             FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), fibril->tcb);
    281 
    282         return (fid_t) fibril;
     267        f->func = func;
     268        f->arg = arg;
     269
     270        context_save(&f->ctx);
     271        context_set(&f->ctx, FADDR(fibril_main), f->stack,
     272            FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), f->tcb);
     273
     274        return (fid_t) f;
    283275}
    284276
    285277/** Add a fibril to the ready list.
    286278 *
    287  * @param fid Pointer to the fibril structure of the fibril to be
    288  *            added.
    289  *
     279 * @param fid           Pointer to the fibril structure of the fibril to be
     280 *                      added.
    290281 */
    291282void fibril_add_ready(fid_t fid)
    292283{
    293         fibril_t *fibril = (fibril_t *) fid;
    294        
     284        fibril_t *f;
     285
     286        f = (fibril_t *) fid;
    295287        futex_down(&fibril_futex);
    296        
    297         if ((fibril->flags & FIBRIL_SERIALIZED))
    298                 list_append(&fibril->link, &serialized_list);
     288        if ((f->flags & FIBRIL_SERIALIZED))
     289                list_append(&f->link, &serialized_list);
    299290        else
    300                 list_append(&fibril->link, &ready_list);
    301        
     291                list_append(&f->link, &ready_list);
    302292        futex_up(&fibril_futex);
    303293}
     
    305295/** Add a fibril to the manager list.
    306296 *
    307  * @param fid Pointer to the fibril structure of the fibril to be
    308  *            added.
    309  *
     297 * @param fid           Pointer to the fibril structure of the fibril to be
     298 *                      added.
    310299 */
    311300void fibril_add_manager(fid_t fid)
    312301{
    313         fibril_t *fibril = (fibril_t *) fid;
    314        
     302        fibril_t *f;
     303
     304        f = (fibril_t *) fid;
     305
    315306        futex_down(&fibril_futex);
    316         list_append(&fibril->link, &manager_list);
     307        list_append(&f->link, &manager_list);
    317308        futex_up(&fibril_futex);
    318309}
     
    322313{
    323314        futex_down(&fibril_futex);
    324        
    325         if (!list_empty(&manager_list))
    326                 list_remove(manager_list.next);
    327        
     315        if (list_empty(&manager_list)) {
     316                futex_up(&fibril_futex);
     317                return;
     318        }
     319        list_remove(manager_list.next);
    328320        futex_up(&fibril_futex);
    329321}
Note: See TracChangeset for help on using the changeset viewer.