上下文使用交换上下文()和自定义yield函数进行切换

时间:2014-04-15 23:32:12

标签: c multithreading

我正在编写自己的用户级线程库,并遇到了一些问题。下面是我们在你们提供的编辑之后到目前为止所写的库的代码,以及我最终的一些反省:

struct tcb {
    int thread_id;
    int thread_pri;
    ucontext_t thread_context;
    struct tcb *next;
} *ready_head;

typedef struct tcb tcb;

tcb *running_head;
tcb *tmp,*tmp1,*tmp2,*temp;
// ucontext_t *ready;

// head = NULL;
// running_head = head;

void t_shutdown()
{
    free(temp);
    free(tmp);
    free(tmp1);
    free(ready_head);
    free(running_head);
}

void t_yield()
{
   // tmp2 = ready_head; 
    tmp1 = running_head;

/*  tmp = running_head;
  running_head = ready_head;
    while(tmp1->next != NULL)
       tmp1 = tmp1->next;

    tmp1->next = tmp;
*/
    insert(tmp1);
    running_head = ready_head;
    ready_head = ready_head->next;
    printf("yield1\n");
    swapcontext(&running_head->thread_context, &tmp1->thread_context);
    printf("yield2\n");   
   //   setcontext(&ready_head->thread_context);    
}

void insert(tcb *a)
{
    tcb *b;

    if (ready_head == NULL)
    {
        ready_head = a;
    }
    else
    {
        b = ready_head;
        while(b->next)
            b = b->next;

        b->next = a;

    }
   printf("insert\n");
}

void t_init()
{
    tmp = (tcb *)malloc(sizeof(tcb));

  getcontext(&tmp->thread_context);    /* let tmp be the context of main() */

    tmp->next = NULL;
    running_head = tmp;
    ready_head = NULL;
}

int t_create(void (*fct)(int), int id, int pri)
{
  size_t sz = 0x10000;

  temp = (tcb *)malloc(sizeof(tcb));

  getcontext(&temp->thread_context);

  temp->thread_id = id;
  temp->thread_pri = pri;

  temp->thread_context.uc_stack.ss_sp = malloc(sz);  /* new statement */
  temp->thread_context.uc_stack.ss_size = sz;
  temp->thread_context.uc_stack.ss_flags = 0;
  temp->thread_context.uc_link = &tmp->thread_context;
  makecontext(&temp->thread_context, fct, 1, id);
    insert(temp);
  printf("1\n"); 
}

我正在以下测试程序中测试此库:

void assign(void)
{
  int i;

  for (i = 0; i < 3; i++)
    printf("in assign(1): %d\n", i);

  t_yield();

  for (i = 10; i < 13; i++)
    printf("in assign(2): %d\n", i);

  t_yield();

  for (i = 20; i < 23; i++)
    printf("in assign(3): %d\n", i);
}

int main(int argc, char **argv) 
{
  t_init();
  t_create(assign, 1, 1);

  printf("in main(): 0\n");

  t_yield();

  printf("in main(): 1\n");
  t_yield();

  printf("in main(): 2\n");
  t_yield();

  printf("done...\n");

  return (0);
}

预期输出为:

in main(): 0
in assign(1): 0
in assign(1): 1
in assign(1): 2
in main(): 1
in assign(2): 10
in assign(2): 11
in assign(2): 12
in main(): 2
in assign(3): 20
in assign(3): 21
in assign(3): 22
done...

然而,我得到了:

in main(): 0
in main(): 1
in main(): 2
done...

我现在知道swapcontext()存在问题,因为它似乎根本不起作用。我试图使用printf语句来调试我的程序,但我仍然无法让它工作!请帮帮....

1 个答案:

答案 0 :(得分:1)

在我看来,在t_yield()函数中,您实际上正在使用ready_head上下文交换ready_head上下文。您可能想尝试

swapcontext(&tmp->thread_context, &running_head->thread_context);

代替。