diff options
Diffstat (limited to 'lib/libc_r/uthread/uthread_exit.c')
-rw-r--r-- | lib/libc_r/uthread/uthread_exit.c | 15 |
1 files changed, 14 insertions, 1 deletions
diff --git a/lib/libc_r/uthread/uthread_exit.c b/lib/libc_r/uthread/uthread_exit.c index a5fc400..93b8b83 100644 --- a/lib/libc_r/uthread/uthread_exit.c +++ b/lib/libc_r/uthread/uthread_exit.c @@ -49,7 +49,7 @@ void _exit(int status) itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = 0; - setitimer(ITIMER_VIRTUAL, &itimer, NULL); + setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL); /* Close the pthread kernel pipe: */ _thread_sys_close(_thread_kern_pipe[0]); @@ -127,6 +127,13 @@ pthread_exit(void *status) /* Run the thread-specific data destructors: */ _thread_cleanupspecific(); } + + /* + * Guard against preemption by a scheduling signal. A change of + * thread state modifies the waiting and priority queues. + */ + _thread_kern_sched_defer(); + /* Check if there are any threads joined to this one: */ while ((pthread = _thread_queue_deq(&(_thread_run->join_queue))) != NULL) { /* Wake the joined thread and let it detach this thread: */ @@ -134,6 +141,12 @@ pthread_exit(void *status) } /* + * Reenable preemption and yield if a scheduling signal + * occurred while in the critical region. + */ + _thread_kern_sched_undefer(); + + /* * Lock the garbage collector mutex to ensure that the garbage * collector is not using the dead thread list. */ |