/** Work-stealing loop for workers */ static int worker_run (void * data) { struct worker_args * args = (struct worker_args*) data; int id = args->id; errval_t err = thread_detach(thread_self()); assert(err_is_ok(err)); free(args); workers[id].worker_thr = thread_self(); workers[id].id = id; workers[id].core_id = disp_get_core_id(); struct generic_task_desc * _tweed_top_ = NULL; thread_set_tls( &(workers[id])); trace_init_disp(); num_dispatchers += 1; // start trying to steal work int steal_id = (id+1) % num_workers; while(!do_quit) { int success = steal(_tweed_top_, &workers[steal_id]); if (!success) { // try next worker steal_id = (steal_id+1) % num_workers; } } exit(0); return 0; }
/** Start the main task */ static int main_worker (int id, int(*main_func)(struct generic_task_desc *,void*), void * main_args) { workers[id].worker_thr = thread_self(); workers[id].id = id; workers[id].core_id = disp_get_core_id(); struct generic_task_desc * _tweed_top_ = NULL; thread_set_tls(&(workers[id])); int ret = main_func(_tweed_top_, main_args); // signal exit to other workers do_quit = 1; return ret; }
/** * \brief * * \param arg * * \return */ static int bomp_thread_msg_handler(void *arg) { errval_t err; struct bomp_tls *tls = calloc(1, sizeof(struct bomp_tls)); if (tls == NULL) { BOMP_ERROR("Could not allocate memory for TLS. %p\n", arg); return -1; } BOMP_DEBUG_THREAD("thread message handler started %p\n", tls); tls->role = BOMP_THREAD_ROLE_WORKER; tls->self = thread_self(); tls->r.thread.coreid = disp_get_core_id(); tls->r.thread.msgbuf = arg; tls->r.thread.tls = tls; struct waitset local_waitset; //struct waitset *ws = get_default_waitset(); struct waitset *ws = &local_waitset; waitset_init(ws); struct bomp_frameinfo fi = { .sendbase = (lpaddr_t)arg, .inbuf = ((uint8_t *) arg) + BOMP_CHANNEL_SIZE, .inbufsize = BOMP_CHANNEL_SIZE, .outbuf = ((uint8_t *) arg), .outbufsize = BOMP_CHANNEL_SIZE }; err = bomp_connect(&fi, bomp_thread_connect_cb, &tls->r.thread, ws, IDC_EXPORT_FLAGS_DEFAULT); if (err_is_fail(err)) { /* TODO: Clean up */ return err_push(err, XOMP_ERR_WORKER_INIT_FAILED); } thread_set_tls(tls); while(1) { err = event_dispatch_non_block(ws); switch(err_no(err)) { case LIB_ERR_NO_EVENT : thread_yield(); continue; break; case SYS_ERR_OK: continue; break; default: USER_PANIC_ERR(err, "event dispatch"); break; } } BOMP_NOTICE("thread %" PRIuCOREID " terminated", disp_get_core_id()); return 0; }