Changeset a55d76b1 in mainline
- Timestamp:
- 2018-06-13T17:07:58Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- be2a20ac, c407b98
- Parents:
- 899342e
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-13 17:04:01)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-13 17:07:58)
- Location:
- uspace/lib/c
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril_synch.c
r899342e ra55d76b1 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
r899342e ra55d76b1 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.