diff options
author | davidxu <davidxu@FreeBSD.org> | 2004-08-19 23:49:04 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2004-08-19 23:49:04 +0000 |
commit | 1d227ebfe244c308f779bc951b98515f9271c2dd (patch) | |
tree | c2cbf5cdc79daabfc870a497148f30881083b1aa /lib/libthr/thread/thr_create.c | |
parent | be1d6f4eb1c9af043ddd260b2c562df680609aad (diff) | |
download | FreeBSD-src-1d227ebfe244c308f779bc951b98515f9271c2dd.zip FreeBSD-src-1d227ebfe244c308f779bc951b98515f9271c2dd.tar.gz |
Adjust code to support AMD64, on AMD64, thread needs to set fsbase by
itself before it can execute any other code, so new thread should be
created with all signals are masked until after fsbase is set.
Diffstat (limited to 'lib/libthr/thread/thr_create.c')
-rw-r--r-- | lib/libthr/thread/thr_create.c | 23 |
1 files changed, 20 insertions, 3 deletions
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c index 38e483f..c5ad8c9 100644 --- a/lib/libthr/thread/thr_create.c +++ b/lib/libthr/thread/thr_create.c @@ -99,9 +99,10 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, /* Initialise the machine context: */ getcontext(&new_thread->ctx); + new_thread->savedsig = new_thread->ctx.uc_sigmask; new_thread->ctx.uc_stack.ss_sp = new_thread->stack; new_thread->ctx.uc_stack.ss_size = pattr->stacksize_attr; - makecontext(&new_thread->ctx, _thread_start, 0); + makecontext(&new_thread->ctx, (void (*)(void))_thread_start, 1, new_thread); new_thread->arch_id = _set_curthread(&new_thread->ctx, new_thread, &ret); if (ret != 0) { if (pattr->stackaddr_attr == NULL) { @@ -145,7 +146,11 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, */ if (pattr->suspend == PTHREAD_CREATE_SUSPENDED) new_thread->flags |= PTHREAD_FLAGS_SUSPENDED; + /* new thread inherits signal mask in kernel */ + _thread_sigblock(); ret = thr_create(&new_thread->ctx, &new_thread->thr_id, flags); + /* restore my signal mask */ + _thread_sigunblock(); if (ret != 0) { _thread_printf(STDERR_FILENO, "thr_create() == %d\n", ret); PANIC("thr_create"); @@ -160,12 +165,24 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr, } void -_thread_start(void) +_thread_start(pthread_t td) { + int ret; + + /* + * for AMD64, we need to set fsbase by thread itself, before + * fsbase is set, we can not run any other code, for example + * signal code. + */ + _set_curthread(NULL, td, &ret); + + /* restore signal mask inherited before */ + __sys_sigprocmask(SIG_SETMASK, &td->savedsig, NULL); + if ((curthread->flags & PTHREAD_FLAGS_SUSPENDED) != 0) _thread_suspend(curthread, NULL); - pthread_exit(curthread->start_routine(curthread->arg)); + pthread_exit(curthread->start_routine(curthread->arg)); /* This point should never be reached. */ PANIC("Thread has resumed after exit"); } |