Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 4 Jan 2005 12:44:53 GMT
From:      David Xu <davidxu@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 68249 for review
Message-ID:  <200501041244.j04CirwN008554@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=68249

Change 68249 by davidxu@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 *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200501041244.j04CirwN008554>