Я работаю над домашним заданием, которое должно быть в следующем семестре. Это требует от нас реализации нашей собственной библиотеки переключения контекста / потоков с помощью API ucontext. Преподаватель предоставляет код, который делает это, но перед тем, как поток возвращается, он вручную выполняет некоторую работу и вызывает ISR, который находит другой поток для использования и обменивается с ним или, если его не осталось, завершается.
Смысл назначения состоит в том, чтобы использовать поле uc_link контекста, чтобы при достижении возврата он выполнял всю работу. Я создал функцию (типа void / void args), которая просто выполняет работу, которую выполняли функции раньше (очищает и затем вызывает ISR). Профессор сказал, что хочет этого.
Итак, все, что осталось, это сделать makecontext где-нибудь по пути в контексте в поле uc_link, чтобы он запускал мой поток, верно? Что ж, когда я делаю makecontext для, по-видимому, любой комбинации ucontext_t и функции, я получаю segfault, а gdb не помогает. Я могу пропустить makecontext, и моя программа существует «нормально», когда она достигает возврата в потоках, которые я создала, потому что ( предположительно) поле uc_link настроено неправильно (что я и пытаюсь сделать).
Я также не могу найти что-нибудь о том, почему makecontext будет сбоить. Кто-нибудь может помочь?
stack2.ss_sp = (void *)(malloc(STACKSIZE));
if(stack2.ss_sp == NULL){
printf("thread failed to get stack space\n");
exit(8);
}
stack2.ss_size = STACKSIZE;
stack2.ss_flags = 0;
if(getcontext(&main_context) == -1){
perror("getcontext in t_init, rtn_env");
exit(5);
}
//main_context.uc_stack = t_state[i].mystk;
main_context.uc_stack = stack2;
main_context.uc_link = 0;
makecontext(&main_context, (void (*)(void))thread_rtn, 0);
Я также пробовал только thread_rtn, & thread_rtn и другие вещи. thread_rtn объявляется как void thread_rtn (void).
позже, в каждой теме. run_env имеет тип ucontext_t:
...
t_state[i].run_env.uc_link = &main_context;