Changeset ab6edb6 in mainline for uspace/lib/c/generic/fibril.c
- Timestamp:
- 2018-06-26T17:34:48Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e768aea
- Parents:
- b59318e
- git-author:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-25 19:28:19)
- git-committer:
- Jiří Zárevúcky <jiri.zarevucky@…> (2018-06-26 17:34:48)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
rb59318e rab6edb6 71 71 static void fibril_main(void) 72 72 { 73 /* fibril_futex is locked when a fibril is first started. */ 74 futex_unlock(&fibril_futex); 73 /* fibril_futex and async_futex are locked when a fibril is started. */ 74 futex_unlock(&fibril_futex); 75 futex_unlock(&async_futex); 75 76 76 77 fibril_t *fibril = fibril_self(); … … 127 128 /** Switch from the current fibril. 128 129 * 129 * If stype is FIBRIL_TO_MANAGER or FIBRIL_FROM_DEAD, the async_futex must130 * be held.130 * The async_futex must be held when entering this function, 131 * and is still held on return. 131 132 * 132 133 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, … … 140 141 int fibril_switch(fibril_switch_type_t stype) 141 142 { 143 /* Make sure the async_futex is held. */ 144 futex_assert_is_locked(&async_futex); 145 142 146 futex_lock(&fibril_futex); 143 147 … … 146 150 147 151 /* Choose a new fibril to run */ 148 switch (stype) { 149 case FIBRIL_TO_MANAGER: 150 case FIBRIL_FROM_DEAD: 151 /* Make sure the async_futex is held. */ 152 futex_assert_is_locked(&async_futex); 152 if (list_empty(&ready_list)) { 153 if (stype == FIBRIL_PREEMPT) { 154 // FIXME: This means that as long as there is a fibril 155 // that only yields, IPC messages are never retrieved. 156 futex_unlock(&fibril_futex); 157 return 0; 158 } 153 159 154 160 /* If we are going to manager and none exists, create it */ … … 161 167 dstf = list_get_instance(list_first(&manager_list), 162 168 fibril_t, link); 163 164 /* Bookkeeping. */ 165 futex_give_to(&async_futex, dstf); 166 167 if (stype == FIBRIL_FROM_DEAD) 168 dstf->clean_after_me = srcf; 169 break; 170 case FIBRIL_PREEMPT: 171 case FIBRIL_FROM_MANAGER: 172 futex_assert_is_not_locked(&async_futex); 173 174 if (list_empty(&ready_list)) { 175 futex_unlock(&fibril_futex); 176 return 0; 177 } 178 169 } else { 179 170 dstf = list_get_instance(list_first(&ready_list), fibril_t, 180 171 link); 181 break;182 } 172 } 173 183 174 list_remove(&dstf->link); 175 if (stype == FIBRIL_FROM_DEAD) 176 dstf->clean_after_me = srcf; 184 177 185 178 /* Put the current fibril into the correct run list */ … … 192 185 break; 193 186 case FIBRIL_FROM_DEAD: 187 case FIBRIL_FROM_BLOCKED: 194 188 // Nothing. 195 189 break; 196 case FIBRIL_TO_MANAGER:197 /*198 * Don't put the current fibril into any list, it should199 * already be somewhere, or it will be lost.200 */201 break;202 190 } 203 191 204 192 /* Bookkeeping. */ 205 193 futex_give_to(&fibril_futex, dstf); 194 futex_give_to(&async_futex, dstf); 206 195 207 196 /* Swap to the next fibril. */ … … 350 339 void fibril_yield(void) 351 340 { 352 fibril_switch(FIBRIL_PREEMPT); 341 futex_lock(&async_futex); 342 (void) fibril_switch(FIBRIL_PREEMPT); 343 futex_unlock(&async_futex); 353 344 } 354 345
Note:
See TracChangeset
for help on using the changeset viewer.