Changes in uspace/lib/c/generic/fibril.c [596d65c:63f8966] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/c/generic/fibril.c
r596d65c r63f8966 48 48 49 49 #ifndef FIBRIL_INITIAL_STACK_PAGES_NO 50 #define FIBRIL_INITIAL_STACK_PAGES_NO150 #define FIBRIL_INITIAL_STACK_PAGES_NO 1 51 51 #endif 52 52 53 53 /** 54 * This futex serializes access to ready_list, 55 * serialized_list and manager_list. 56 */ 54 * This futex serializes access to ready_list, serialized_list and manager_list. 55 */ 57 56 static atomic_t fibril_futex = FUTEX_INITIALIZER; 58 57 … … 61 60 static LIST_INITIALIZE(manager_list); 62 61 62 static void fibril_main(void); 63 63 64 /** Number of threads that are executing a manager fibril. */ 64 65 static int threads_in_manager; 65 66 /** 67 * Number of threads that are executing a manager fibril 68 * and are serialized. Protected by async_futex. 69 */ 70 static int serialized_threads; 71 66 /** Number of threads that are executing a manager fibril and are serialized. */ 67 static int serialized_threads; /* Protected by async_futex */ 72 68 /** Fibril-local count of serialization. If > 0, we must not preempt */ 73 69 static fibril_local int serialization_count; 70 71 /** Setup fibril information into TCB structure */ 72 fibril_t *fibril_setup(void) 73 { 74 fibril_t *f; 75 tcb_t *tcb; 76 77 tcb = __make_tls(); 78 if (!tcb) 79 return NULL; 80 81 f = malloc(sizeof(fibril_t)); 82 if (!f) { 83 __free_tls(tcb); 84 return NULL; 85 } 86 87 tcb->fibril_data = f; 88 f->tcb = tcb; 89 90 f->func = NULL; 91 f->arg = NULL; 92 f->stack = NULL; 93 f->clean_after_me = NULL; 94 f->retval = 0; 95 f->flags = 0; 96 97 return f; 98 } 99 100 void fibril_teardown(fibril_t *f) 101 { 102 __free_tls(f->tcb); 103 free(f); 104 } 74 105 75 106 /** Function that spans the whole life-cycle of a fibril. … … 78 109 * the fibril logic is called. After its return, the return value is saved. 79 110 * The fibril then switches to another fibril, which cleans up after it. 80 * 81 */ 82 static void fibril_main(void) 83 { 84 fibril_t *fibril = __tcb_get()->fibril_data; 85 111 */ 112 void fibril_main(void) 113 { 114 fibril_t *f = __tcb_get()->fibril_data; 115 86 116 /* Call the implementing function. */ 87 f ibril->retval = fibril->func(fibril->arg);88 117 f->retval = f->func(f->arg); 118 89 119 fibril_switch(FIBRIL_FROM_DEAD); 90 /* Not reached */ 91 } 92 93 /** Setup fibril information into TCB structure 94 * 95 */ 96 fibril_t *fibril_setup(void) 97 { 98 tcb_t *tcb = __make_tls(); 99 if (!tcb) 100 return NULL; 101 102 fibril_t *fibril = malloc(sizeof(fibril_t)); 103 if (!fibril) { 104 __free_tls(tcb); 105 return NULL; 106 } 107 108 tcb->fibril_data = fibril; 109 fibril->tcb = tcb; 110 111 fibril->func = NULL; 112 fibril->arg = NULL; 113 fibril->stack = NULL; 114 fibril->clean_after_me = NULL; 115 fibril->retval = 0; 116 fibril->flags = 0; 117 118 return fibril; 119 } 120 121 void fibril_teardown(fibril_t *fibril) 122 { 123 __free_tls(fibril->tcb); 124 free(fibril); 120 /* not reached */ 125 121 } 126 122 … … 130 126 * held. 131 127 * 132 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, 133 * FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter 134 * describes the circumstances of the switch. 135 * 136 * @return 0 if there is no ready fibril, 137 * @return 1 otherwise. 138 * 128 * @param stype Switch type. One of FIBRIL_PREEMPT, FIBRIL_TO_MANAGER, 129 * FIBRIL_FROM_MANAGER, FIBRIL_FROM_DEAD. The parameter 130 * describes the circumstances of the switch. 131 * @return Return 0 if there is no ready fibril, 132 * return 1 otherwise. 139 133 */ 140 134 int fibril_switch(fibril_switch_type_t stype) … … 252 246 /** Create a new fibril. 253 247 * 254 * @param func Implementing function of the new fibril. 255 * @param arg Argument to pass to func. 256 * 257 * @return 0 on failure or TLS of the new fibril. 258 * 248 * @param func Implementing function of the new fibril. 249 * @param arg Argument to pass to func. 250 * 251 * @return Return 0 on failure or TLS of the new fibril. 259 252 */ 260 253 fid_t fibril_create(int (*func)(void *), void *arg) 261 254 { 262 fibril_t *f ibril;263 264 f ibril= fibril_setup();265 if ( fibril == NULL)255 fibril_t *f; 256 257 f = fibril_setup(); 258 if (!f) 266 259 return 0; 267 268 fibril->stack = 269 (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize()); 270 if (!fibril->stack) { 271 fibril_teardown(fibril); 260 f->stack = (char *) malloc(FIBRIL_INITIAL_STACK_PAGES_NO * 261 getpagesize()); 262 if (!f->stack) { 263 fibril_teardown(f); 272 264 return 0; 273 265 } 274 266 275 f ibril->func = func;276 f ibril->arg = arg;277 278 context_save(&f ibril->ctx);279 context_set(&f ibril->ctx, FADDR(fibril_main), fibril->stack,280 FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), f ibril->tcb);281 282 return (fid_t) f ibril;267 f->func = func; 268 f->arg = arg; 269 270 context_save(&f->ctx); 271 context_set(&f->ctx, FADDR(fibril_main), f->stack, 272 FIBRIL_INITIAL_STACK_PAGES_NO * getpagesize(), f->tcb); 273 274 return (fid_t) f; 283 275 } 284 276 285 277 /** Add a fibril to the ready list. 286 278 * 287 * @param fid Pointer to the fibril structure of the fibril to be 288 * added. 289 * 279 * @param fid Pointer to the fibril structure of the fibril to be 280 * added. 290 281 */ 291 282 void fibril_add_ready(fid_t fid) 292 283 { 293 fibril_t *fibril = (fibril_t *) fid; 294 284 fibril_t *f; 285 286 f = (fibril_t *) fid; 295 287 futex_down(&fibril_futex); 296 297 if ((fibril->flags & FIBRIL_SERIALIZED)) 298 list_append(&fibril->link, &serialized_list); 288 if ((f->flags & FIBRIL_SERIALIZED)) 289 list_append(&f->link, &serialized_list); 299 290 else 300 list_append(&fibril->link, &ready_list); 301 291 list_append(&f->link, &ready_list); 302 292 futex_up(&fibril_futex); 303 293 } … … 305 295 /** Add a fibril to the manager list. 306 296 * 307 * @param fid Pointer to the fibril structure of the fibril to be 308 * added. 309 * 297 * @param fid Pointer to the fibril structure of the fibril to be 298 * added. 310 299 */ 311 300 void fibril_add_manager(fid_t fid) 312 301 { 313 fibril_t *fibril = (fibril_t *) fid; 314 302 fibril_t *f; 303 304 f = (fibril_t *) fid; 305 315 306 futex_down(&fibril_futex); 316 list_append(&f ibril->link, &manager_list);307 list_append(&f->link, &manager_list); 317 308 futex_up(&fibril_futex); 318 309 } … … 322 313 { 323 314 futex_down(&fibril_futex); 324 325 if (!list_empty(&manager_list)) 326 list_remove(manager_list.next); 327 315 if (list_empty(&manager_list)) { 316 futex_up(&fibril_futex); 317 return; 318 } 319 list_remove(manager_list.next); 328 320 futex_up(&fibril_futex); 329 321 }
Note:
See TracChangeset
for help on using the changeset viewer.