Ignore:
File:
1 edited

Legend:

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

    ra55d76b1 r49a796f1  
    629629}
    630630
    631 /**
    632  * Initialize a semaphore with initial count set to the provided value.
    633  *
    634  * @param sem    Semaphore to initialize.
    635  * @param count  Initial count. Must not be negative.
    636  */
    637 void fibril_semaphore_initialize(fibril_semaphore_t *sem, long count)
    638 {
    639         /*
    640          * Negative count denotes the length of waitlist,
    641          * so it makes no sense as an initial value.
    642          */
    643         assert(count >= 0);
    644         sem->count = count;
    645         list_initialize(&sem->waiters);
    646 }
    647 
    648 /**
    649  * Produce one token.
    650  * If there are fibrils waiting for tokens, this operation satisfies
    651  * exactly one waiting `fibril_semaphore_down()`.
    652  * This operation never blocks the fibril.
    653  *
    654  * @param sem  Semaphore to use.
    655  */
    656 void fibril_semaphore_up(fibril_semaphore_t *sem)
    657 {
    658         futex_down(&async_futex);
    659         sem->count++;
    660 
    661         if (sem->count > 0) {
    662                 futex_up(&async_futex);
    663                 return;
    664         }
    665 
    666         link_t *tmp = list_first(&sem->waiters);
    667         assert(tmp);
    668         list_remove(tmp);
    669 
    670         futex_up(&async_futex);
    671 
    672         awaiter_t *wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    673         fibril_add_ready(wdp->fid);
    674         optimize_execution_power();
    675 }
    676 
    677 /**
    678  * Consume one token.
    679  * If there are no available tokens (count <= 0), this operation blocks until
    680  * another fibril produces a token using `fibril_semaphore_up()`.
    681  *
    682  * @param sem  Semaphore to use.
    683  */
    684 void fibril_semaphore_down(fibril_semaphore_t *sem)
    685 {
    686         futex_down(&async_futex);
    687         sem->count--;
    688 
    689         if (sem->count >= 0) {
    690                 futex_up(&async_futex);
    691                 return;
    692         }
    693 
    694         awaiter_t wdata;
    695         awaiter_initialize(&wdata);
    696 
    697         wdata.fid = fibril_get_id();
    698         list_append(&wdata.wu_event.link, &sem->waiters);
    699         fibril_switch(FIBRIL_TO_MANAGER);
    700 
    701         /* async_futex not held after fibril_switch() */
    702 }
    703 
    704631/** @}
    705632 */
Note: See TracChangeset for help on using the changeset viewer.