我正在尝试使用系统调用的setcontext / getcontext / ect ...库来实现user = level线程库。对于我的生活,当我尝试在下面的waitall和yield函数中交换上下文时,我无法弄清楚为什么我会遇到段错误。我已经尝试过广泛地使用print语句,valgrind和gdb进行调试,但我还是没有理解它。谢谢!
static struct node* ready;
static ucontext_t main;
void ta_libinit(void) {
ready = malloc(sizeof(struct node));
getcontext(&main);
ready -> thread = main;
ready -> isMain = 0;
ready -> next = NULL;
return;
}
void ta_create(void (*func)(void *), void *arg) {
ucontext_t thread; // fix ptrs
unsigned char *stack = (unsigned char *)malloc(STACKSIZE);
assert(stack);
/* Set up thread*/
getcontext(&thread);
thread.uc_stack.ss_sp = stack;
thread.uc_stack.ss_size = STACKSIZE;
thread.uc_link = &main;
makecontext(&thread, (void (*)(void))func, 1, arg);
fifo_append(thread, &ready);
return;
}
void ta_yield(void) {
// Switches to the next thread on the ready queue, pushing the current
// thread to the back.
struct node* current = fifo_pop(&ready);
fifo_push(current, ready);
swapcontext(&(current -> thread), &(ready -> thread));
return;
}
int ta_waitall(void) {
// Only called from calling program - wait for all threads to finish.
while (ready -> next != NULL) {
struct node *current = fifo_pop(&ready);
swapcontext(¤t -> thread, &ready -> thread);
// Took this out for testing purposes.
//free((¤t -> thread.uc_stack));
//free(current);
}
return -1;
}