Changes in uspace/lib/c/generic/fibril.c [3b1cc8d:e768aea] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
r3b1cc8d re768aea 49 49 #include <async.h> 50 50 51 #ifdef FUTEX_UPGRADABLE 52 #include <rcu.h> 53 #endif 51 #include "private/fibril.h" 52 54 53 55 54 /** … … 72 71 static void fibril_main(void) 73 72 { 74 /* fibril_futex is locked when a fibril is first started. */ 75 futex_unlock(&fibril_futex); 76 77 fibril_t *fibril = __tcb_get()->fibril_data; 78 79 #ifdef FUTEX_UPGRADABLE 80 rcu_register_fibril(); 81 #endif 73 /* fibril_futex and async_futex are locked when a fibril is started. */ 74 futex_unlock(&fibril_futex); 75 futex_unlock(&async_futex); 76 77 fibril_t *fibril = fibril_self(); 82 78 83 79 /* Call the implementing function. */ 84 80 fibril->retval = fibril->func(fibril->arg); 85 81 86 futex_ down(&async_futex);82 futex_lock(&async_futex); 87 83 fibril_switch(FIBRIL_FROM_DEAD); 88 84 /* Not reached */ … … 98 94 return NULL; 99 95 100 fibril_t *fibril = malloc(sizeof(fibril_t));96 fibril_t *fibril = calloc(1, sizeof(fibril_t)); 101 97 if (!fibril) { 102 98 tls_free(tcb); … … 106 102 tcb->fibril_data = fibril; 107 103 fibril->tcb = tcb; 108 109 fibril->func = NULL;110 fibril->arg = NULL;111 fibril->stack = NULL;112 fibril->clean_after_me = NULL;113 fibril->retval = 0;114 fibril->flags = 0;115 116 fibril->waits_for = NULL;117 104 118 105 /* … … 141 128 /** Switch from the current fibril. 142 129 * 143 * If stype is FIBRIL_TO_MANAGER or FIBRIL_FROM_DEAD, the async_futex must144 * be held.130 * The async_futex must be held when entering this function, 131 * and is still held on return. 145 132 * 146 133 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, … … 154 141 int fibril_switch(fibril_switch_type_t stype) 155 142 { 143 /* Make sure the async_futex is held. */ 144 futex_assert_is_locked(&async_futex); 145 156 146 futex_lock(&fibril_futex); 157 147 158 fibril_t *srcf = __tcb_get()->fibril_data;148 fibril_t *srcf = fibril_self(); 159 149 fibril_t *dstf = NULL; 160 150 161 151 /* Choose a new fibril to run */ 162 switch (stype) { 163 case FIBRIL_TO_MANAGER: 164 case FIBRIL_FROM_DEAD: 165 /* Make sure the async_futex is held. */ 166 assert((atomic_signed_t) async_futex.val.count <= 0); 152 if (list_empty(&ready_list)) { 153 if (stype == FIBRIL_PREEMPT || stype == FIBRIL_FROM_MANAGER) { 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 } 167 159 168 160 /* If we are going to manager and none exists, create it */ … … 175 167 dstf = list_get_instance(list_first(&manager_list), 176 168 fibril_t, link); 177 178 if (stype == FIBRIL_FROM_DEAD) 179 dstf->clean_after_me = srcf; 180 break; 181 case FIBRIL_PREEMPT: 182 case FIBRIL_FROM_MANAGER: 183 if (list_empty(&ready_list)) { 184 futex_unlock(&fibril_futex); 185 return 0; 186 } 187 169 } else { 188 170 dstf = list_get_instance(list_first(&ready_list), fibril_t, 189 171 link); 190 break;191 } 172 } 173 192 174 list_remove(&dstf->link); 175 if (stype == FIBRIL_FROM_DEAD) 176 dstf->clean_after_me = srcf; 193 177 194 178 /* Put the current fibril into the correct run list */ … … 201 185 break; 202 186 case FIBRIL_FROM_DEAD: 187 case FIBRIL_FROM_BLOCKED: 203 188 // Nothing. 204 189 break; 205 case FIBRIL_TO_MANAGER: 206 /* 207 * Don't put the current fibril into any list, it should 208 * already be somewhere, or it will be lost. 209 */ 210 break; 211 } 212 213 #ifdef FUTEX_UPGRADABLE 214 if (stype == FIBRIL_FROM_DEAD) { 215 rcu_deregister_fibril(); 216 } 217 #endif 190 } 191 192 /* Bookkeeping. */ 193 futex_give_to(&fibril_futex, dstf); 194 futex_give_to(&async_futex, dstf); 218 195 219 196 /* Swap to the next fibril. */ … … 345 322 } 346 323 324 fibril_t *fibril_self(void) 325 { 326 return __tcb_get()->fibril_data; 327 } 328 347 329 /** Return fibril id of the currently running fibril. 348 330 * … … 352 334 fid_t fibril_get_id(void) 353 335 { 354 return (fid_t) __tcb_get()->fibril_data; 336 return (fid_t) fibril_self(); 337 } 338 339 void fibril_yield(void) 340 { 341 futex_lock(&async_futex); 342 (void) fibril_switch(FIBRIL_PREEMPT); 343 futex_unlock(&async_futex); 355 344 } 356 345
Note:
See TracChangeset
for help on using the changeset viewer.