Hi,
I'm trying to implement a simple user thread library. all threads are stored in a 'ready' state queue, and when the timer runs out of time a signal causes a signal handler to switch to the next ready thread.
now i'm having a segmentation fault, and couldn't find the reason. it happens during the longjmp call (setting registers back to previous state...), and seems to be like the jmp_buf isn't set correctly.
valgrind tells me:
'conditional jump or move depends on uninitialised values...
at.... sigprocmask
at... lonjmp
at... dispatch' <-- my signal handler
this error occurs in the first call to dispatch, so i guess i'm not setting right something in the thread's initializer. the functions i use are thread_spawn(void (*f)(void)) which is the .h function, and thread_init(** thread) which is called by thread_spawn.
the struct:
the functions:Code:typedef struct{ struct thread_status status; int state; jmp_buf *env; char *stack; } thread;
the signal_handlerCode:int thread_init(thread **new_thread) { if ((*new_thread =(thread *)malloc(sizeof(thread))) == NULL) return FAILED; if (((*new_thread)->env =(jmp_buf *)malloc(sizeof(jmp_buf))) == NULL) { FREE(*new_thread); return FAILED; } (*new_thread)->stack = (char*)malloc(STACKSIZE); if (!(*new_thread)->stack) { FREE(*new_thread); FREE(*new_thread); return FAILED; } (*new_thread)->state = READY; ((*new_thread)->status).bursts = 0; return SUCCESS; } int thread_spawn(void (*f)(void)){ sigset_t set; // starting termination process, mask_all_signals(&set); // masking all signals. if (running_thread == -1) process_init(); // if first call, init process and MAIN thread if (tids.empty()) return FAILED; // if no more thread ids to allocate, fail thread *newthread; if(!thread_init(&newthread)) return FAILED; // if could not initialize the thread, fail //setjmp(*(newthread->env)); ((*(newthread->env))->__jmpbuf)[JB_SP] = (unsigned) newthread->stack + STACKSIZE - sizeof(int); ((*(newthread->env))->__jmpbuf)[JB_PC] = (unsigned) f; (*(newthread->env))->__mask_was_saved = 1; int new_id = tids.top(); tids.pop(); threads[new_id] = newthread; ready.push_back(new_id); set_mask(&set); // switching to previous mask return new_id; }
I know it's a lot of code, but i'm desperate!!!Code:void dispatch(int sig){ set_timer(QUANTUM); //resetting the timer if (sig == CALL){ //specific call to dispatch if (ready.empty()) error_handler(FATAL_THREAD_ERROR); } else { //dispatch called by signal if (ready.empty()) return; // no ready threads, current keeps running } int ready_tid = ready.front(); ready.pop_front(); if(setjmp(*(threads[running_thread]->env)) == 0){ // Save the running thread if (sig != CALL) { threads[running_thread]->state = READY; ready.push_back(running_thread); } running_thread = ready_tid; threads[running_thread]->state = RUN; threads[running_thread]->status.bursts++; longjmp(*(threads[running_thread]->env), 1); } }
thanks!



LinkBack URL
About LinkBacks


