errval_t domain_thread_create_on_varstack(coreid_t core_id, thread_func_t start_func, void *arg, size_t stacksize, struct thread **newthread) { if (disp_get_core_id() == core_id) { struct thread *th = NULL; if (stacksize == 0) { th = thread_create(start_func, arg); } else { th = thread_create_varstack(start_func, arg, stacksize); } if (th != NULL) { if (newthread) { *newthread = th; } return SYS_ERR_OK; } else { return LIB_ERR_THREAD_CREATE; } } else { struct domain_state *domain_state = get_domain_state(); errval_t err; if (domain_state->b[core_id] == NULL) { return LIB_ERR_NO_SPANNED_DISP; } struct interdisp_binding *b = domain_state->b[core_id]; struct create_thread_req *req = malloc(sizeof(*req)); req->reply_received = false; // use special waitset to make sure loop exits properly. struct waitset ws, *old_ws = b->waitset; waitset_init(&ws); b->change_waitset(b, &ws); err = b->tx_vtbl.create_thread_request(b, NOP_CONT, (genvaddr_t)(uintptr_t)start_func, (genvaddr_t)(uintptr_t)arg, stacksize, (genvaddr_t)(lvaddr_t)req); if (err_is_fail(err)) { return err; } while (!req->reply_received) { event_dispatch(&ws); } if (newthread) { *newthread = req->thread; } free(req); b->change_waitset(b, old_ws); return SYS_ERR_OK; } }
static void create_thread_request(struct interdisp_binding *b, genvaddr_t funcaddr, genvaddr_t argaddr, uint64_t stacksize) { thread_func_t start_func = (thread_func_t)(uintptr_t)funcaddr; void *arg = (void *)(uintptr_t)argaddr; struct thread *newthread; // XXX: Probably want to return pointer to thread struct to caller if(stacksize > 0) { newthread = thread_create_varstack(start_func, arg, stacksize); } else { newthread = thread_create(start_func, arg); } assert(newthread != NULL); }
static void create_thread_request(struct interdisp_binding *b, genvaddr_t funcaddr, genvaddr_t argaddr, uint64_t stacksize, genvaddr_t req) { thread_func_t start_func = (thread_func_t)(uintptr_t)funcaddr; void *arg = (void *)(uintptr_t)argaddr; struct thread *newthread; // XXX: Probably want to return pointer to thread struct to caller if(stacksize > 0) { newthread = thread_create_varstack(start_func, arg, stacksize); } else { newthread = thread_create(start_func, arg); } assert(newthread != NULL); errval_t err = b->tx_vtbl.create_thread_reply(b, NOP_CONT, SYS_ERR_OK, (genvaddr_t)(lvaddr_t)newthread, req); assert(err_is_ok(err)); }
errval_t domain_thread_create_on_varstack(coreid_t core_id, thread_func_t start_func, void *arg, size_t stacksize) { if (disp_get_core_id() == core_id) { struct thread *th = NULL; if (stacksize == 0) { th = thread_create(start_func, arg); } else { th = thread_create_varstack(start_func, arg, stacksize); } if (th != NULL) { return SYS_ERR_OK; } else { return LIB_ERR_THREAD_CREATE; } } else { struct domain_state *domain_state = get_domain_state(); errval_t err; if (domain_state->b[core_id] == NULL) { return LIB_ERR_NO_SPANNED_DISP; } struct interdisp_binding *b = domain_state->b[core_id]; err = b->tx_vtbl.create_thread(b, NOP_CONT, (genvaddr_t)(uintptr_t)start_func, (genvaddr_t)(uintptr_t)arg, stacksize); if (err_is_fail(err)) { return err; } return SYS_ERR_OK; } }