Changes in uspace/lib/c/generic/fibril.c [e768aea:3b1cc8d] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
re768aea r3b1cc8d 49 49 #include <async.h> 50 50 51 #include "private/fibril.h" 52 51 #ifdef FUTEX_UPGRADABLE 52 #include <rcu.h> 53 #endif 53 54 54 55 /** … … 71 72 static void fibril_main(void) 72 73 { 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(); 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 78 82 79 83 /* Call the implementing function. */ 80 84 fibril->retval = fibril->func(fibril->arg); 81 85 82 futex_ lock(&async_futex);86 futex_down(&async_futex); 83 87 fibril_switch(FIBRIL_FROM_DEAD); 84 88 /* Not reached */ … … 94 98 return NULL; 95 99 96 fibril_t *fibril = calloc(1,sizeof(fibril_t));100 fibril_t *fibril = malloc(sizeof(fibril_t)); 97 101 if (!fibril) { 98 102 tls_free(tcb); … … 102 106 tcb->fibril_data = fibril; 103 107 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; 104 117 105 118 /* … … 128 141 /** Switch from the current fibril. 129 142 * 130 * The async_futex must be held when entering this function,131 * and is still held on return.143 * If stype is FIBRIL_TO_MANAGER or FIBRIL_FROM_DEAD, the async_futex must 144 * be held. 132 145 * 133 146 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, … … 141 154 int fibril_switch(fibril_switch_type_t stype) 142 155 { 143 /* Make sure the async_futex is held. */144 futex_assert_is_locked(&async_futex);145 146 156 futex_lock(&fibril_futex); 147 157 148 fibril_t *srcf = fibril_self();158 fibril_t *srcf = __tcb_get()->fibril_data; 149 159 fibril_t *dstf = NULL; 150 160 151 161 /* Choose a new fibril to run */ 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 } 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); 159 167 160 168 /* If we are going to manager and none exists, create it */ … … 167 175 dstf = list_get_instance(list_first(&manager_list), 168 176 fibril_t, link); 169 } else { 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 170 188 dstf = list_get_instance(list_first(&ready_list), fibril_t, 171 189 link); 172 }173 190 break; 191 } 174 192 list_remove(&dstf->link); 175 if (stype == FIBRIL_FROM_DEAD)176 dstf->clean_after_me = srcf;177 193 178 194 /* Put the current fibril into the correct run list */ … … 185 201 break; 186 202 case FIBRIL_FROM_DEAD: 187 case FIBRIL_FROM_BLOCKED:188 203 // Nothing. 189 204 break; 190 } 191 192 /* Bookkeeping. */ 193 futex_give_to(&fibril_futex, dstf); 194 futex_give_to(&async_futex, dstf); 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 195 218 196 219 /* Swap to the next fibril. */ … … 322 345 } 323 346 324 fibril_t *fibril_self(void)325 {326 return __tcb_get()->fibril_data;327 }328 329 347 /** Return fibril id of the currently running fibril. 330 348 * … … 334 352 fid_t fibril_get_id(void) 335 353 { 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); 354 return (fid_t) __tcb_get()->fibril_data; 344 355 } 345 356
Note:
See TracChangeset
for help on using the changeset viewer.