Changeset ab6edb6 in mainline
- 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)
- Location:
- uspace/lib/c/generic
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/async/client.c
rb59318e rab6edb6 372 372 373 373 /* Leave the async_futex locked when entering this function */ 374 fibril_switch(FIBRIL_TO_MANAGER); 375 376 /* Futex is up automatically after fibril_switch */ 374 fibril_switch(FIBRIL_FROM_BLOCKED); 375 futex_unlock(&async_futex); 377 376 378 377 done: … … 445 444 446 445 /* Leave the async_futex locked when entering this function */ 447 fibril_switch(FIBRIL_TO_MANAGER); 448 449 /* Futex is up automatically after fibril_switch */ 446 fibril_switch(FIBRIL_FROM_BLOCKED); 447 futex_unlock(&async_futex); 450 448 451 449 if (!msg->done) … … 511 509 512 510 /* Leave the async_futex locked when entering this function */ 513 fibril_switch(FIBRIL_TO_MANAGER); 514 515 /* Futex is up automatically after fibril_switch() */ 511 fibril_switch(FIBRIL_FROM_BLOCKED); 512 futex_unlock(&async_futex); 516 513 } 517 514 -
uspace/lib/c/generic/async/server.c
rb59318e rab6edb6 997 997 * case, route_call() will perform the wakeup. 998 998 */ 999 fibril_switch(FIBRIL_TO_MANAGER); 1000 1001 /* 1002 * Futex is up after getting back from async_manager. 1003 * Get it again. 1004 */ 1005 futex_lock(&async_futex); 999 fibril_switch(FIBRIL_FROM_BLOCKED); 1000 1006 1001 if ((usecs) && (conn->wdata.to_event.occurred) && 1007 1002 (list_empty(&conn->msg_queue))) { … … 1143 1138 { 1144 1139 while (true) { 1145 if (fibril_switch(FIBRIL_FROM_MANAGER)) {1146 futex_unlock(&async_futex);1147 /*1148 * async_futex is always held when entering a manager1149 * fibril.1150 */1151 continue;1152 }1153 1154 1140 futex_lock(&async_futex); 1141 fibril_switch(FIBRIL_FROM_MANAGER); 1142 1143 /* 1144 * The switch only returns when there is no non-manager fibril 1145 * it can run. 1146 */ 1155 1147 1156 1148 suseconds_t timeout; … … 1226 1218 static errno_t async_manager_fibril(void *arg) 1227 1219 { 1228 futex_unlock(&async_futex);1229 1230 /*1231 * async_futex is always locked when entering manager1232 */1233 1220 async_manager_worker(); 1234 1235 1221 return 0; 1236 1222 } -
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 -
uspace/lib/c/generic/fibril_synch.c
rb59318e rab6edb6 116 116 check_for_deadlock(&fm->oi); 117 117 f->waits_for = &fm->oi; 118 fibril_switch(FIBRIL_ TO_MANAGER);118 fibril_switch(FIBRIL_FROM_BLOCKED); 119 119 } else { 120 120 fm->oi.owned_by = f; 121 futex_unlock(&async_futex);122 }121 } 122 futex_unlock(&async_futex); 123 123 } 124 124 … … 206 206 check_for_deadlock(&frw->oi); 207 207 f->waits_for = &frw->oi; 208 fibril_switch(FIBRIL_ TO_MANAGER);208 fibril_switch(FIBRIL_FROM_BLOCKED); 209 209 } else { 210 210 /* Consider the first reader the owner. */ 211 211 if (frw->readers++ == 0) 212 212 frw->oi.owned_by = f; 213 futex_unlock(&async_futex);214 }213 } 214 futex_unlock(&async_futex); 215 215 } 216 216 … … 230 230 check_for_deadlock(&frw->oi); 231 231 f->waits_for = &frw->oi; 232 fibril_switch(FIBRIL_ TO_MANAGER);232 fibril_switch(FIBRIL_FROM_BLOCKED); 233 233 } else { 234 234 frw->oi.owned_by = f; 235 235 frw->writers++; 236 futex_unlock(&async_futex);237 }236 } 237 futex_unlock(&async_futex); 238 238 } 239 239 … … 377 377 list_append(&wdata.wu_event.link, &fcv->waiters); 378 378 _fibril_mutex_unlock_unsafe(fm); 379 fibril_switch(FIBRIL_TO_MANAGER); 379 fibril_switch(FIBRIL_FROM_BLOCKED); 380 futex_unlock(&async_futex); 381 382 // XXX: This could be replaced with an unlocked version to get rid 383 // of the unlock-lock pair. I deliberately don't do that because 384 // further changes would most likely need to revert that optimization. 380 385 fibril_mutex_lock(fm); 381 386 382 /* async_futex not held after fibril_switch() */383 387 futex_lock(&async_futex); 384 388 if (wdata.to_event.inlist) … … 698 702 wdata.fid = fibril_get_id(); 699 703 list_append(&wdata.wu_event.link, &sem->waiters); 700 fibril_switch(FIBRIL_TO_MANAGER); 701 702 /* async_futex not held after fibril_switch() */704 705 fibril_switch(FIBRIL_FROM_BLOCKED); 706 futex_unlock(&async_futex); 703 707 } 704 708 -
uspace/lib/c/generic/private/fibril.h
rb59318e rab6edb6 59 59 typedef enum { 60 60 FIBRIL_PREEMPT, 61 FIBRIL_ TO_MANAGER,61 FIBRIL_FROM_BLOCKED, 62 62 FIBRIL_FROM_MANAGER, 63 63 FIBRIL_FROM_DEAD -
uspace/lib/c/generic/rcu.c
rb59318e rab6edb6 373 373 blocked_fib.is_ready = false; 374 374 futex_unlock(&rcu.sync_lock.futex); 375 fibril_switch(FIBRIL_TO_MANAGER); 375 futex_lock(&async_futex); 376 fibril_switch(FIBRIL_FROM_BLOCKED); 377 futex_unlock(&async_futex); 376 378 futex_lock(&rcu.sync_lock.futex); 377 379 } while (rcu.sync_lock.locked);
Note:
See TracChangeset
for help on using the changeset viewer.