Ignore:
File:
1 edited

Legend:

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

    rc1b979a r4d11204  
    4949#include <assert.h>
    5050#include <async.h>
     51#include <futex.h>
     52
     53#ifdef FUTEX_UPGRADABLE
     54#include <rcu.h>
     55#endif
    5156
    5257/**
    5358 * This futex serializes access to ready_list,
    54  * serialized_list and manager_list.
    55  */
    56 static atomic_t fibril_futex = FUTEX_INITIALIZER;
     59 * serialized_list, manager_list and fibril_list.
     60 */
     61static futex_t fibril_futex = FUTEX_INITIALIZER;
    5762
    5863static LIST_INITIALIZE(ready_list);
     
    8388{
    8489        fibril_t *fibril = __tcb_get()->fibril_data;
     90
     91#ifdef FUTEX_UPGRADABLE
     92        rcu_register_fibril();
     93#endif
    8594       
    8695        /* Call the implementing function. */
     
    117126       
    118127        fibril->waits_for = NULL;
     128
     129        futex_lock(&fibril_futex);
    119130        list_append(&fibril->all_link, &fibril_list);
     131        futex_unlock(&fibril_futex);
    120132       
    121133        return fibril;
    122134}
    123135
    124 void fibril_teardown(fibril_t *fibril)
    125 {
     136void fibril_teardown(fibril_t *fibril, bool locked)
     137{       
     138        if (!locked)
     139                futex_lock(&fibril_futex);
    126140        list_remove(&fibril->all_link);
     141        if (!locked)
     142                futex_unlock(&fibril_futex);
    127143        tls_free(fibril->tcb);
    128144        free(fibril);
     
    146162        int retval = 0;
    147163       
    148         futex_down(&fibril_futex);
     164        futex_lock(&fibril_futex);
    149165       
    150166        if (stype == FIBRIL_PREEMPT && list_empty(&ready_list))
     
    168184        if ((stype == FIBRIL_TO_MANAGER) || (stype == FIBRIL_FROM_DEAD)) {
    169185                while (list_empty(&manager_list)) {
    170                         futex_up(&fibril_futex);
     186                        futex_unlock(&fibril_futex);
    171187                        async_create_manager();
    172                         futex_down(&fibril_futex);
     188                        futex_lock(&fibril_futex);
    173189                }
    174190        }
     
    199215                                        as_area_destroy(stack);
    200216                                }
    201                                 fibril_teardown(srcf->clean_after_me);
     217                                fibril_teardown(srcf->clean_after_me, true);
    202218                                srcf->clean_after_me = NULL;
    203219                        }
    204220                       
    205                         return 1;       /* futex_up already done here */
     221                        return 1;       /* futex_unlock already done here */
    206222                }
    207223               
     
    246262        list_remove(&dstf->link);
    247263       
    248         futex_up(&fibril_futex);
     264        futex_unlock(&fibril_futex);
     265       
     266#ifdef FUTEX_UPGRADABLE
     267        if (stype == FIBRIL_FROM_DEAD) {
     268                rcu_deregister_fibril();
     269        }
     270#endif
     271       
    249272        context_restore(&dstf->ctx);
    250273        /* not reached */
    251274       
    252275ret_0:
    253         futex_up(&fibril_futex);
     276        futex_unlock(&fibril_futex);
    254277        return retval;
    255278}
     
    278301            AS_AREA_LATE_RESERVE);
    279302        if (fibril->stack == (void *) -1) {
    280                 fibril_teardown(fibril);
     303                fibril_teardown(fibril, false);
    281304                return 0;
    282305        }
     
    305328       
    306329        as_area_destroy(fibril->stack);
    307         fibril_teardown(fibril);
     330        fibril_teardown(fibril, false);
    308331}
    309332
     
    318341        fibril_t *fibril = (fibril_t *) fid;
    319342       
    320         futex_down(&fibril_futex);
     343        futex_lock(&fibril_futex);
    321344       
    322345        if ((fibril->flags & FIBRIL_SERIALIZED))
     
    325348                list_append(&fibril->link, &ready_list);
    326349       
    327         futex_up(&fibril_futex);
     350        futex_unlock(&fibril_futex);
    328351}
    329352
     
    338361        fibril_t *fibril = (fibril_t *) fid;
    339362       
    340         futex_down(&fibril_futex);
     363        futex_lock(&fibril_futex);
    341364        list_append(&fibril->link, &manager_list);
    342         futex_up(&fibril_futex);
     365        futex_unlock(&fibril_futex);
    343366}
    344367
     
    346369void fibril_remove_manager(void)
    347370{
    348         futex_down(&fibril_futex);
     371        futex_lock(&fibril_futex);
    349372       
    350373        if (!list_empty(&manager_list))
    351374                list_remove(list_first(&manager_list));
    352375       
    353         futex_up(&fibril_futex);
     376        futex_unlock(&fibril_futex);
    354377}
    355378
Note: See TracChangeset for help on using the changeset viewer.