PERFORCE change 68249 for review
David Xu
davidxu at FreeBSD.org
Tue Jan 4 12:44:55 GMT 2005
http://perforce.freebsd.org/chv.cgi?CH=68249
Change 68249 by davidxu at davidxu_tiger on 2005/01/04 12:44:47
merge thread list operations into thr_list.c
Affected files ...
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/Makefile.inc#4 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_find_thread.c#4 delete
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_fork.c#6 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_init.c#6 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_kern.c#9 edit
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_list.c#1 add
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_private.h#12 edit
Differences ...
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/Makefile.inc#4 (text+ko) ====
@@ -23,6 +23,7 @@
thr_getschedparam.c \
thr_init.c \
thr_join.c \
+ thr_list.c \
thr_kern.c \
thr_kill.c \
thr_main_np.c \
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_fork.c#6 (text+ko) ====
@@ -87,13 +87,24 @@
/* Child process */
errsave = errno;
+ curthread->cancelflags &= ~THR_CANCEL_NEEDED;
curthread->critical_count = 0;
curthread->locklevel = 0;
+ /* clear other threads locked us. */
+ umtx_init(&curthread->lock);
+ thr_self(&curthread->tid);
+ _thr_setthreaded(0);
+
_mutex_reinit(&_thr_atfork_mutex);
- /* Reinitialize lib kernel. */
- _thr_single_thread(curthread);
+ /* reinitialize libc spinlocks, this includes __malloc_lock. */
+ _thr_spinlock_init();
+ TAILQ_INIT(&curthread->mutexq);
+ curthread->priority_mutex_count = 0;
+
+ /* reinit library. */
+ _libpthread_init(curthread);
/* Restore signal mask. */
__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_init.c#6 (text+ko) ====
@@ -260,7 +260,6 @@
/* Initialize pthread private data. */
init_private();
- _thr_kern_init();
/* Set the initial thread. */
if (curthread == NULL) {
@@ -367,8 +366,7 @@
size_t len;
int mib[2];
- TAILQ_INIT(&_thread_list);
- TAILQ_INIT(&_thread_gc_list);
+ _thr_list_init();
/*
* Avoid reinitializing some things if they don't need to be,
@@ -392,7 +390,6 @@
umtx_init(&_cond_static_lock);
umtx_init(&_rwlock_static_lock);
umtx_init(&_keytable_lock);
- umtx_init(&_thread_list_lock);
_thr_spinlock_init();
_pthread_mutex_init(&_thr_atfork_mutex, NULL);
} else {
@@ -401,7 +398,6 @@
umtx_init(&_cond_static_lock);
umtx_init(&_rwlock_static_lock);
umtx_init(&_keytable_lock);
- umtx_init(&_thread_list_lock);
/* reinitialized in thr_fork.c */
#if 0
_thr_spinlock_init();
@@ -409,8 +405,6 @@
#endif
}
-
- /* Are we in M:N mode (default) or 1:1 mode? */
#ifdef SYSTEM_SCOPE_ONLY
_thread_scope_system = 1;
#else
@@ -419,9 +413,5 @@
else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL)
_thread_scope_system = -1;
#endif
- /*
- * _thread_list_lock is initialized
- * by _thr_init()
- */
init_once = 1;
}
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_kern.c#9 (text+ko) ====
@@ -30,16 +30,6 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
-#include <sys/signalvar.h>
-#include <sys/queue.h>
-
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
#include "thr_private.h"
#include "libc_private.h"
@@ -51,103 +41,21 @@
#endif
/*
- * Define a high water mark for the maximum number of threads that
- * will be cached. Once this level is reached, any extra threads
- * will be free()'d.
- */
-#define MAX_CACHED_THREADS 100
-
-/*
- * We've got to keep track of everything that is allocated, not only
- * to have a speedy free list, but also so they can be deallocated
- * after a fork().
- */
-static TAILQ_HEAD(, pthread) free_threadq;
-static struct umtx free_thread_lock;
-static int free_thread_count = 0;
-static int inited = 0;
-static u_int64_t next_uniqueid = 1;
-
-LIST_HEAD(thread_hash_head, pthread);
-#define HASH_QUEUES 128
-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);
-static void thread_gc(struct pthread *thread);
-
-/*
- * This is called after a fork().
- * No locks need to be taken here since we are guaranteed to be
- * single threaded.
- *
- * XXX
- * POSIX says for threaded process, fork() function is used
- * only to run new programs, and the effects of calling functions
- * that require certain resources between the call to fork() and
- * the call to an exec function are undefined.
- *
- * It is not safe to free memory after fork(), because these data
- * structures may be in inconsistent state.
- */
-void
-_thr_single_thread(struct pthread *curthread)
-{
- curthread->cancelflags &= ~THR_CANCEL_NEEDED;
- /* clear other threads locked us. */
- umtx_init(&curthread->lock);
- thr_self(&curthread->tid);
- /* reinitialize libc spinlocks, this includes __malloc_lock. */
- _thr_spinlock_init();
- TAILQ_INIT(&curthread->mutexq);
- curthread->priority_mutex_count = 0;
- _libpthread_init(curthread);
-#if 0
- if (__isthreaded) {
- _thr_rtld_fini();
- }
-#endif
- __isthreaded = 0;
-}
-
-/*
- * This is used to initialize housekeeping and to initialize the
- * KSD for the KSE.
- */
-void
-_thr_kern_init(void)
-{
- TAILQ_INIT(&free_threadq);
- _gc_count = 0;
- if (inited == 0) {
- umtx_init(&free_thread_lock);
- umtx_init(&tcb_lock);
- inited = 1;
- } else {
- umtx_init(&free_thread_lock);
- umtx_init(&tcb_lock);
- }
-}
-
-/*
* This is called when the first thread (other than the initial
* thread) is created.
*/
int
_thr_setthreaded(int threaded)
{
- if ((threaded != 0) && (__isthreaded == 0)) {
-#if 0
- /*
- * Locking functions in libc are required when there are
- * threads other than the initial thread.
- */
- _thr_rtld_init();
-#endif
+ if (((threaded == 0) ^ (__isthreaded == 0)) == 0)
+ return (0);
+
+ if (threaded != 0) {
+/* _thr_rtld_init(); */
__isthreaded = 1;
+ } else {
+ __isthreaded = 0;
+/* _thr_rtld_fini(); */
}
return (0);
}
@@ -166,275 +74,7 @@
}
void
-_thr_gc(struct pthread *curthread)
-{
- thread_gc(curthread);
-}
-
-static void
-thread_gc(struct pthread *curthread)
-{
- struct pthread *td, *td_next;
- TAILQ_HEAD(, pthread) worklist;
-
- TAILQ_INIT(&worklist);
- THREAD_LIST_LOCK(curthread);
-
- /* 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) {
- /* 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)) {
- /*
- * The thread has detached and is no longer
- * referenced. It is safe to remove all
- * remnants of the thread.
- */
- THR_LIST_REMOVE(td);
- TAILQ_INSERT_HEAD(&worklist, td, gcle);
- }
- }
- THREAD_LIST_UNLOCK(curthread);
-
- while ((td = TAILQ_FIRST(&worklist)) != NULL) {
- TAILQ_REMOVE(&worklist, td, gcle);
- /*
- * XXX we don't free initial thread and its kse
- * (if thread is a bound thread), because there might
- * have some code referencing initial thread and kse.
- */
- if (td == _thr_initial) {
- DBG_MSG("Initial thread won't be freed\n");
- continue;
- }
-
- DBG_MSG("Freeing thread %p\n", td);
- _thr_free(curthread, td);
- }
-}
-
-struct pthread *
-_thr_alloc(struct pthread *curthread)
-{
- struct pthread *thread = NULL;
-
- if (curthread != NULL) {
- if (GC_NEEDED())
- _thr_gc(curthread);
- if (free_thread_count > 0) {
- THR_LOCK_ACQUIRE(curthread, &free_thread_lock);
- if ((thread = TAILQ_FIRST(&free_threadq)) != NULL) {
- TAILQ_REMOVE(&free_threadq, thread, tle);
- free_thread_count--;
- }
- THR_LOCK_RELEASE(curthread, &free_thread_lock);
- }
- }
- 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 */);
- THR_LOCK_RELEASE(curthread, &tcb_lock);
- } else {
- thread->tcb = _tcb_ctor(thread, 1 /* initial tls */);
- }
- if (thread->tcb == NULL) {
- free(thread);
- thread = NULL;
- } else {
- /*
- * Initialize thread locking.
- */
- umtx_init(&thread->lock);
- }
- } else if (thread != NULL) {
- umtx_init(&thread->lock);
- }
- return (thread);
-}
-
-void
-_thr_free(struct pthread *curthread, struct pthread *thread)
-{
- DBG_MSG("Freeing thread %p\n", thread);
- if (thread->name) {
- free(thread->name);
- thread->name = NULL;
- }
- if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) {
- thr_destroy(curthread, thread);
- } else {
- /* Add the thread to the free thread list. */
- THR_LOCK_ACQUIRE(curthread, &free_thread_lock);
- TAILQ_INSERT_TAIL(&free_threadq, thread, tle);
- free_thread_count++;
- THR_LOCK_RELEASE(curthread, &free_thread_lock);
- }
-}
-
-static void
-thr_destroy(struct pthread *curthread, struct pthread *thread)
-{
- if (curthread) {
- THR_LOCK_ACQUIRE(curthread, &tcb_lock);
- _tcb_dtor(thread->tcb);
- THR_LOCK_RELEASE(curthread, &tcb_lock);
- } else {
- _tcb_dtor(thread->tcb);
- }
- free(thread);
-}
-
-/*
- * Add an active thread:
- *
- * o Assign the thread a unique id (which GDB uses to track
- * threads.
- * o Add the thread to the list of all threads and increment
- * number of active threads.
- */
-void
-_thr_link(struct pthread *curthread, struct pthread *thread)
-{
- THREAD_LIST_LOCK(curthread);
- /*
- * Initialize the unique id (which GDB uses to track
- * threads), add the thread to the list of all threads,
- * and
- */
- thread->uniqueid = next_uniqueid++;
- THR_LIST_ADD(thread);
- if (thread->attr.flags & PTHREAD_DETACHED)
- thread->tlflags |= TLFLAGS_DETACHED;
- _thread_active_threads++;
- THREAD_LIST_UNLOCK(curthread);
-}
-
-/*
- * Remove an active thread.
- */
-void
-_thr_unlink(struct pthread *curthread, struct pthread *thread)
-{
- THREAD_LIST_LOCK(curthread);
- THR_LIST_REMOVE(thread);
- _thread_active_threads--;
- THREAD_LIST_UNLOCK(curthread);
-}
-
-void
-_thr_hash_add(struct pthread *thread)
-{
- struct thread_hash_head *head;
-
- head = &thr_hashtable[THREAD_HASH(thread)];
- LIST_INSERT_HEAD(head, thread, hle);
-}
-
-void
-_thr_hash_remove(struct pthread *thread)
-{
- LIST_REMOVE(thread, hle);
-}
-
-struct pthread *
-_thr_hash_find(struct pthread *thread)
-{
- struct pthread *td;
- struct thread_hash_head *head;
-
- head = &thr_hashtable[THREAD_HASH(thread)];
- LIST_FOREACH(td, head, hle) {
- if (td == thread)
- return (thread);
- }
- return (NULL);
-}
-
-/*
- * Find a thread in the linked list of active threads and add a reference
- * to it. Threads with positive reference counts will not be deallocated
- * until all references are released.
- */
-int
-_thr_ref_add(struct pthread *curthread, struct pthread *thread,
- int include_dead)
-{
- int ret;
-
- if (thread == NULL)
- /* Invalid thread: */
- return (EINVAL);
-
- 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);
-
- /* Return zero if the thread exists: */
- return (ret);
-}
-
-void
-_thr_ref_delete(struct pthread *curthread, struct pthread *thread)
-{
- 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);
- THREAD_LIST_UNLOCK(curthread);
- }
-}
-
-int
-_thr_find_thread(struct pthread *curthread, struct pthread *thread,
- int include_dead)
-{
- struct pthread *pthread;
-
- if (thread == NULL)
- /* Invalid thread: */
- return (EINVAL);
-
- pthread = _thr_hash_find(thread);
- if (pthread) {
- if (include_dead == 0 && pthread->state == PS_DEAD)
- pthread = NULL;
- }
-
- /* Return zero if the thread exists: */
- return ((pthread != NULL) ? 0 : ESRCH);
-}
-
-void
_thr_assert_lock_level()
{
- PANIC("lockleve <=0");
+ PANIC("lockleve <= 0");
}
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_private.h#12 (text+ko) ====
@@ -686,7 +686,7 @@
* Function prototype definitions.
*/
__BEGIN_DECLS
-void _thr_kern_init();
+void _thr_list_init();
void _thr_single_thread(struct pthread *);
int _thr_setthreaded(int);
int _mutex_cv_lock(pthread_mutex_t *);
More information about the p4-projects
mailing list