PERFORCE change 69097 for review
David Xu
davidxu at FreeBSD.org
Sat Jan 15 17:05:03 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=69097
Change 69097 by davidxu at 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: */
More information about the p4-projects
mailing list