Date: Sun, 16 Jan 2005 01:05:02 GMT From: David Xu <davidxu@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 69097 for review Message-ID: <200501160105.j0G1525o014890@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=69097 Change 69097 by davidxu@davidxu_tiger on 2005/01/16 01:04:45 simplify code for creating new thread. Affected files ... .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_create.c#6 edit .. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_list.c#3 edit Differences ... ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_create.c#6 (text+ko) ==== @@ -58,167 +58,118 @@ void *(*start_routine) (void *), void *arg) { ucontext_t uc; - sigset_t sigmask; + sigset_t sigmask, oldsigmask; struct pthread *curthread, *new_thread; int ret = 0; _thr_check_init(); /* - * Turn on threaded mode, if failed, it is unnecessary to - * do further work. + * Tell libc and others now they need lock to protect their data. */ - if (_thr_isthreaded() == 0 && _thr_setthreaded(1)) { + if (_thr_isthreaded() == 0 && _thr_setthreaded(1)) return (EAGAIN); - } + curthread = _get_curthread(); + if ((new_thread = _thr_alloc(curthread)) == NULL) + return (EAGAIN); - /* - * Allocate memory for the thread structure. - * Some functions use malloc, so don't put it - * in a critical region. - */ - if ((new_thread = _thr_alloc(curthread)) == NULL) { - /* Insufficient memory to create a thread: */ - ret = EAGAIN; - } else { - /* Check if default thread attributes are required: */ - if (attr == NULL || *attr == NULL) - /* Use the default thread attributes: */ - new_thread->attr = _pthread_attr_default; - else { - new_thread->attr = *(*attr); - if ((*attr)->sched_inherit == PTHREAD_INHERIT_SCHED) { - /* inherit scheduling contention scop */ - if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) - new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else - new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - /* - * scheduling policy and scheduling parameters will be - * inherited in following code. - */ - } - } - - if (_thread_scope_system > 0) + if (attr == NULL || *attr == NULL) + /* Use the default thread attributes: */ + new_thread->attr = _pthread_attr_default; + else + new_thread->attr = *(*attr); + if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { + /* inherit scheduling contention scope */ + if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM) new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; - else if (_thread_scope_system < 0) + else new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; + /* + * scheduling policy and scheduling parameters will be + * inherited in following code. + */ + } - if (create_stack(&new_thread->attr) != 0) { - /* Insufficient memory to create a stack: */ - ret = EAGAIN; - new_thread->isdead = 1; - _thr_free(curthread, new_thread); - } else { - new_thread->tid = 0; - new_thread->cycle = 0; - new_thread->isdead = 0; - new_thread->rtld_bits = 0; - /* - * Write a magic value to the thread structure - * to help identify valid ones: - */ - new_thread->magic = THR_MAGIC; + if (_thread_scope_system > 0) + new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM; + else if (_thread_scope_system < 0) + new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM; - new_thread->start_routine = start_routine; - new_thread->arg = arg; - new_thread->cancelflags = PTHREAD_CANCEL_ENABLE | - PTHREAD_CANCEL_DEFERRED; + if (create_stack(&new_thread->attr) != 0) { + /* Insufficient memory to create a stack: */ + new_thread->terminated = 1; + _thr_free(curthread, new_thread); + return (EAGAIN); + } + /* + * Write a magic value to the thread structure + * to help identify valid ones: + */ + new_thread->magic = THR_MAGIC; + new_thread->start_routine = start_routine; + new_thread->arg = arg; + new_thread->cancelflags = PTHREAD_CANCEL_ENABLE | + PTHREAD_CANCEL_DEFERRED; + getcontext(&uc); + SIGFILLSET(uc.uc_sigmask); + uc.uc_stack.ss_sp = new_thread->attr.stackaddr_attr; + uc.uc_stack.ss_size = new_thread->attr.stacksize_attr; + makecontext(&uc, (void (*)(void))thread_start, 1, new_thread); - /* No thread is wanting to join to this one: */ - new_thread->joiner = NULL; - new_thread->join_status.thread = NULL; - new_thread->critical_count = 0; - new_thread->sflags = 0; - getcontext(&uc); - SIGFILLSET(uc.uc_sigmask); - uc.uc_stack.ss_sp = new_thread->attr.stackaddr_attr; - uc.uc_stack.ss_size = new_thread->attr.stacksize_attr; - makecontext(&uc, (void (*)(void))thread_start, 1, - new_thread); + /* + * Check if this thread is to inherit the scheduling + * attributes from its parent: + */ + if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { + /* + * Copy the scheduling attributes. Lock the scheduling + * lock to get consistent scheduling parameters. + */ + THR_LOCK(curthread); + new_thread->base_priority = curthread->base_priority; + new_thread->attr.prio = curthread->base_priority; + new_thread->attr.sched_policy = curthread->attr.sched_policy; + THR_UNLOCK(curthread); + } else { + /* + * Use just the thread priority, leaving the + * other scheduling attributes as their + * default values: + */ + new_thread->base_priority = new_thread->attr.prio; + } + new_thread->active_priority = new_thread->base_priority; - /* - * Check if this thread is to inherit the scheduling - * attributes from its parent: - */ - if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) { - /* - * Copy the scheduling attributes. - * Lock the scheduling lock to get consistent - * scheduling parameters. - */ - THR_LOCK(curthread); - new_thread->base_priority = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.prio = - curthread->base_priority & - ~THR_SIGNAL_PRIORITY; - new_thread->attr.sched_policy = - curthread->attr.sched_policy; - THR_UNLOCK(curthread); - } else { - /* - * Use just the thread priority, leaving the - * other scheduling attributes as their - * default values: - */ - new_thread->base_priority = - new_thread->attr.prio; - } - new_thread->active_priority = new_thread->base_priority; - new_thread->inherited_priority = 0; + /* Initialize the mutex queue: */ + TAILQ_INIT(&new_thread->mutexq); + TAILQ_INIT(&new_thread->pri_mutexq); - /* Initialize the mutex queue: */ - TAILQ_INIT(&new_thread->mutexq); - TAILQ_INIT(&new_thread->pri_mutexq); - - /* Initialise hooks in the thread structure: */ - new_thread->specific = NULL; - new_thread->specific_data_count = 0; - new_thread->cleanup = NULL; - new_thread->flags = 0; - new_thread->tlflags = 0; - new_thread->sigbackout = NULL; - new_thread->error = 0; - SIGEMPTYSET(new_thread->sigpend); - new_thread->check_pending = 0; - new_thread->refcount = 0; - new_thread->locklevel = 0; - new_thread->rdlock_count = 0; - new_thread->data.mutex = 0; - new_thread->priority_mutex_count = 0; - new_thread->rtld_bits = 0; - if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) - new_thread->flags = THR_FLAGS_SUSPENDED; - new_thread->state = PS_RUNNING; - /* - * Schedule the new thread. - */ - SIGFILLSET(sigmask); - /* - * Thread created by thr_create() inherits currrent thread - * sigmask, however, before new thread setup itself correctly, - * it can not handle signal, so we should masks all signals here. - */ - __sys_sigprocmask(SIG_SETMASK, &sigmask, &curthread->sigmask); - new_thread->sigmask = curthread->sigmask; - /* Add the new thread. */ - _thr_link(curthread, new_thread); - /* Return a pointer to the thread structure: */ - (*thread) = new_thread; - ret = thr_create(&uc, &new_thread->tid, 0); - __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL); - if (ret != 0) { - _thr_unlink(curthread, new_thread); - free_thread(curthread, new_thread); - (*thread) = 0; - } - } + /* Initialise hooks in the thread structure: */ + if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) + new_thread->flags = THR_FLAGS_SUSPENDED; + new_thread->state = PS_RUNNING; + /* + * Thread created by thr_create() inherits currrent thread + * sigmask, however, before new thread setup itself correctly, + * it can not handle signal, so we should masks all signals here. + */ + SIGFILLSET(sigmask); + __sys_sigprocmask(SIG_SETMASK, &sigmask, &oldsigmask); + new_thread->sigmask = oldsigmask; + /* Add the new thread. */ + _thr_link(curthread, new_thread); + /* Return thread pointer eariler so that new thread can use it. */ + (*thread) = new_thread; + /* Schedule the new thread. */ + ret = thr_create(&uc, &new_thread->tid, 0); + __sys_sigprocmask(SIG_SETMASK, &oldsigmask, NULL); + if (ret != 0) { + _thr_unlink(curthread, new_thread); + free_thread(curthread, new_thread); + (*thread) = 0; + ret = EAGAIN; } - /* Return the status: */ return (ret); } @@ -226,7 +177,7 @@ free_thread(struct pthread *curthread, struct pthread *thread) { free_stack(curthread, &thread->attr); - curthread->isdead = 1; + curthread->terminated = 1; _thr_free(curthread, thread); } ==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_list.c#3 (text+ko) ==== @@ -28,8 +28,6 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - #include <sys/types.h> #include <sys/queue.h> @@ -61,6 +59,7 @@ */ static TAILQ_HEAD(, pthread) free_threadq; static struct umtx free_thread_lock; +static struct umtx tcb_lock; static int free_thread_count = 0; static int inited = 0; static u_int64_t next_uniqueid = 1; @@ -70,9 +69,6 @@ static struct thread_hash_head thr_hashtable[HASH_QUEUES]; #define THREAD_HASH(thrd) (((unsigned long)thrd >> 12) % HASH_QUEUES) -/* Lock for thread tcb constructor/destructor */ -static struct umtx tcb_lock; - static void thr_destroy(struct pthread *curthread, struct pthread *thread); void @@ -81,7 +77,7 @@ int i; _gc_count = 0; - umtx_init(&_thread_list_lock); + umtx_init(&_thr_list_lock); TAILQ_INIT(&_thread_list); TAILQ_INIT(&free_threadq); umtx_init(&free_thread_lock); @@ -96,6 +92,7 @@ void _thr_gc(struct pthread *curthread) { + return; struct pthread *td, *td_next; TAILQ_HEAD(, pthread) worklist; @@ -105,26 +102,14 @@ /* Check the threads waiting for GC. */ for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) { td_next = TAILQ_NEXT(td, gcle); - if ((td->tlflags & TLFLAGS_GC_SAFE) == 0) - continue; - else if (td->isdead == 0) { + if (td->terminated == 0) { /* make sure we are not still in userland */ continue; } - /* - * Remove the thread from the GC list. If the thread - * isn't yet detached, it will get added back to the - * GC list at a later time. - */ - THR_GCLIST_REMOVE(td); - DBG_MSG("Freeing thread %p stack\n", td); - /* - * We can free the thread stack since it's no longer - * in use. - */ _thr_stack_free(&td->attr); if (((td->tlflags & TLFLAGS_DETACHED) != 0) && (td->refcount == 0)) { + THR_GCLIST_REMOVE(td); /* * The thread has detached and is no longer * referenced. It is safe to remove all @@ -156,6 +141,7 @@ _thr_alloc(struct pthread *curthread) { struct pthread *thread = NULL; + struct tcb *tcb = NULL; if (curthread != NULL) { if (GC_NEEDED()) @@ -164,6 +150,7 @@ THR_LOCK_ACQUIRE(curthread, &free_thread_lock); if ((thread = TAILQ_FIRST(&free_threadq)) != NULL) { TAILQ_REMOVE(&free_threadq, thread, tle); + tcb = thread->tcb; free_thread_count--; } THR_LOCK_RELEASE(curthread, &free_thread_lock); @@ -171,25 +158,21 @@ } if ((thread == NULL) && ((thread = malloc(sizeof(struct pthread))) != NULL)) { - bzero(thread, sizeof(struct pthread)); if (curthread) { THR_LOCK_ACQUIRE(curthread, &tcb_lock); - thread->tcb = _tcb_ctor(thread, 0 /* not initial tls */); + tcb = _tcb_ctor(thread, 0 /* not initial tls */); THR_LOCK_RELEASE(curthread, &tcb_lock); } else { - thread->tcb = _tcb_ctor(thread, 1 /* initial tls */); + tcb = _tcb_ctor(thread, 1 /* initial tls */); } - if (thread->tcb == NULL) { + if (tcb == NULL) { free(thread); thread = NULL; - } else { - /* - * Initialize thread locking. - */ - umtx_init(&thread->lock); } - } else if (thread != NULL) { - umtx_init(&thread->lock); + } + if (thread) { + memset(thread, 0, sizeof(*thread)); + thread->tcb = tcb; } return (thread); } @@ -310,8 +293,6 @@ THREAD_LIST_LOCK(curthread); if ((ret = _thr_find_thread(curthread, thread, include_dead)) == 0) { thread->refcount++; - if (curthread != NULL) - curthread->critical_count++; } THREAD_LIST_UNLOCK(curthread); @@ -325,8 +306,6 @@ if (thread != NULL) { THREAD_LIST_LOCK(curthread); thread->refcount--; - if (curthread != NULL) - curthread->critical_count--; if ((thread->refcount == 0) && (thread->tlflags & TLFLAGS_GC_SAFE) != 0) THR_GCLIST_ADD(thread); @@ -346,8 +325,9 @@ pthread = _thr_hash_find(thread); if (pthread) { - if (include_dead == 0 && pthread->state == PS_DEAD) + if (include_dead == 0 && pthread->state == PS_DEAD) { pthread = NULL; + } } /* Return zero if the thread exists: */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501160105.j0G1525o014890>