在用户级线程库中使用swapcontext()时的Segfault?

时间:2014-11-13 18:03:33

标签: c linux multithreading fiber

我正在尝试使用系统调用的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(&current -> thread, &ready -> thread);

    // Took this out for testing purposes.
    //free((&current -> thread.uc_stack));
    //free(current); 
  }
  return -1;
}

0 个答案:

没有答案