Changes in / [be2a20ac:80f345c] in mainline
- Location:
- uspace/lib/c
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
rbe2a20ac r80f345c 72 72 static void fibril_main(void) 73 73 { 74 /* fibril_futex is locked when a fibril is first started. */75 futex_unlock(&fibril_futex);76 77 74 fibril_t *fibril = __tcb_get()->fibril_data; 78 75 … … 214 211 } 215 212 213 futex_unlock(&fibril_futex); 214 216 215 #ifdef FUTEX_UPGRADABLE 217 216 if (stype == FIBRIL_FROM_DEAD) { … … 224 223 225 224 /* Restored by another fibril! */ 226 227 /* Must be after context_swap()! */228 futex_unlock(&fibril_futex);229 225 230 226 if (srcf->clean_after_me) { -
uspace/lib/c/generic/fibril_synch.c
rbe2a20ac r80f345c 629 629 } 630 630 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 satisfies651 * 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 until680 * 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 704 631 /** @} 705 632 */ -
uspace/lib/c/include/fibril_synch.h
rbe2a20ac r80f345c 143 143 } fibril_timer_t; 144 144 145 /** A counting semaphore for fibrils. */146 typedef struct {147 long count;148 list_t waiters;149 } fibril_semaphore_t;150 151 #define FIBRIL_SEMAPHORE_INITIALIZER(name, cnt) \152 { \153 .count = (cnt), \154 .waiters = { \155 .head = { \156 .next = &(name).waiters.head, \157 .prev = &(name).waiters.head, \158 } \159 } \160 }161 162 #define FIBRIL_SEMAPHORE_INITIALIZE(name, cnt) \163 fibril_semaphore_t name = FIBRIL_SEMAPHORE_INITIALIZER(name, cnt)164 165 145 extern void fibril_mutex_initialize(fibril_mutex_t *); 166 146 extern void fibril_mutex_lock(fibril_mutex_t *); … … 194 174 extern fibril_timer_state_t fibril_timer_clear_locked(fibril_timer_t *); 195 175 196 extern void fibril_semaphore_initialize(fibril_semaphore_t *, long);197 extern void fibril_semaphore_up(fibril_semaphore_t *);198 extern void fibril_semaphore_down(fibril_semaphore_t *);199 200 176 #endif 201 177
Note:
See TracChangeset
for help on using the changeset viewer.