Changes in / [80f345c:be2a20ac] in mainline
- Location:
- uspace/lib/c
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
r80f345c rbe2a20ac 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 74 77 fibril_t *fibril = __tcb_get()->fibril_data; 75 78 … … 211 214 } 212 215 213 futex_unlock(&fibril_futex);214 215 216 #ifdef FUTEX_UPGRADABLE 216 217 if (stype == FIBRIL_FROM_DEAD) { … … 223 224 224 225 /* Restored by another fibril! */ 226 227 /* Must be after context_swap()! */ 228 futex_unlock(&fibril_futex); 225 229 226 230 if (srcf->clean_after_me) { -
uspace/lib/c/generic/fibril_synch.c
r80f345c rbe2a20ac 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 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 631 704 /** @} 632 705 */ -
uspace/lib/c/include/fibril_synch.h
r80f345c rbe2a20ac 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 145 165 extern void fibril_mutex_initialize(fibril_mutex_t *); 146 166 extern void fibril_mutex_lock(fibril_mutex_t *); … … 174 194 extern fibril_timer_state_t fibril_timer_clear_locked(fibril_timer_t *); 175 195 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 176 200 #endif 177 201
Note:
See TracChangeset
for help on using the changeset viewer.