int thread_run(void (*func)(void *), void *arg) { struct thread *current; struct thread *t; current = current_thread(); if (!thread_can_yield(current)) { printk(BIOS_ERR, "thread_run() called from non-yielding context!\n"); return -1; } t = get_free_thread(); if (t == NULL) { printk(BIOS_ERR, "thread_run() No more threads!\n"); return -1; } prepare_thread(t, func, arg, call_wrapper_block_current, NULL); schedule(t); return 0; }
int thread_run_until(void (*func)(void *), void *arg, boot_state_t state, boot_state_sequence_t seq) { struct thread *current; struct thread *t; struct block_boot_state *bbs; current = current_thread(); if (!thread_can_yield(current)) { printk(BIOS_ERR, "thread_run() called from non-yielding context!\n"); return -1; } t = get_free_thread(); if (t == NULL) { printk(BIOS_ERR, "thread_run() No more threads!\n"); return -1; } bbs = thread_alloc_space(t, sizeof(*bbs)); bbs->state = state; bbs->seq = seq; prepare_thread(t, func, arg, call_wrapper_block_state, bbs); schedule(t); return 0; }
static void idle_thread_init(void) { struct thread *t; t = get_free_thread(); if (t == NULL) die("No threads available for idle thread!\n"); /* Queue idle thread to run once all other threads have yielded. */ prepare_thread(t, idle_thread, NULL, call_wrapper, NULL); push_runnable(t); /* Mark the currently executing thread to cooperate. */ thread_cooperate(); }