summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_find_thread.c
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>2003-04-18 05:04:16 +0000
committerdeischen <deischen@FreeBSD.org>2003-04-18 05:04:16 +0000
commit5d56aa9cb2bdbe0a18bafbdbb6eb8cf6a46beb79 (patch)
tree46bc1e113ddc7c1ed88e4fa724039df8664c963a /lib/libpthread/thread/thr_find_thread.c
parente68f624d876da04bfb6860b450593c77d80368bd (diff)
downloadFreeBSD-src-5d56aa9cb2bdbe0a18bafbdbb6eb8cf6a46beb79.zip
FreeBSD-src-5d56aa9cb2bdbe0a18bafbdbb6eb8cf6a46beb79.tar.gz
Revamp libpthread so that it has a chance of working in an SMP
environment. This includes support for multiple KSEs and KSEGs. The ability to create more than 1 KSE via pthread_setconcurrency() is in the works as well as support for PTHREAD_SCOPE_SYSTEM threads. Those should come shortly. There are still some known issues which davidxu and I are working on, but it'll make it easier for us by committing what we have. This library now passes all of the ACE tests that libc_r passes with the exception of one. It also seems to work OK with KDE including konqueror, kwrite, etc. I haven't been able to get mozilla to run due to lack of java plugin, so I'd be interested to see how it works with that. Reviewed by: davidxu
Diffstat (limited to 'lib/libpthread/thread/thr_find_thread.c')
-rw-r--r--lib/libpthread/thread/thr_find_thread.c72
1 files changed, 53 insertions, 19 deletions
diff --git a/lib/libpthread/thread/thr_find_thread.c b/lib/libpthread/thread/thr_find_thread.c
index 032fcfb..9b291b1 100644
--- a/lib/libpthread/thread/thr_find_thread.c
+++ b/lib/libpthread/thread/thr_find_thread.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (c) 2003 Daniel Eischen <deischen@freebsd.org>
* Copyright (c) 1998 John Birrell <jb@cimlogic.com.au>.
* All rights reserved.
*
@@ -35,32 +36,65 @@
#include <pthread.h>
#include "thr_private.h"
-/* Find a thread in the linked list of active threads: */
+/*
+ * 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
-_find_thread(pthread_t pthread)
+_thr_ref_add(struct pthread *curthread, struct pthread *thread,
+ int include_dead)
{
- pthread_t pthread1;
+ kse_critical_t crit;
+ struct pthread *pthread;
- /* Check if the caller has specified an invalid thread: */
- if (pthread == NULL || pthread->magic != PTHREAD_MAGIC)
+ if (thread == NULL)
/* Invalid thread: */
- return(EINVAL);
-
- /*
- * Defer signals to protect the thread list from access
- * by the signal handler:
- */
- _thread_kern_sig_defer();
+ return (EINVAL);
- /* Search for the specified thread: */
- TAILQ_FOREACH(pthread1, &_thread_list, tle) {
- if (pthread == pthread1)
+ crit = _kse_critical_enter();
+ KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock);
+ TAILQ_FOREACH(pthread, &_thread_list, tle) {
+ if (pthread == thread) {
+ if ((include_dead == 0) &&
+ ((pthread->state == PS_DEAD) ||
+ ((pthread->state == PS_DEADLOCK) ||
+ ((pthread->flags & THR_FLAGS_EXITING) != 0))))
+ pthread = NULL;
+ else {
+ thread->refcount++;
+ curthread->critical_count++;
+ }
break;
+ }
}
-
- /* Undefer and handle pending signals, yielding if necessary: */
- _thread_kern_sig_undefer();
+ KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock);
+ _kse_critical_leave(crit);
/* Return zero if the thread exists: */
- return ((pthread1 != NULL) ? 0:ESRCH);
+ return ((pthread != NULL) ? 0 : ESRCH);
+}
+
+void
+_thr_ref_delete(struct pthread *curthread, struct pthread *thread)
+{
+ kse_critical_t crit;
+
+ if (thread != NULL) {
+ crit = _kse_critical_enter();
+ KSE_LOCK_ACQUIRE(curthread->kse, &_thread_list_lock);
+ thread->refcount--;
+ curthread->critical_count--;
+ if (((thread->flags & THR_FLAGS_GC_SAFE) != 0) &&
+ (thread->refcount == 0) &&
+ ((thread->attr.flags & PTHREAD_DETACHED) != 0)) {
+ THR_LIST_REMOVE(thread);
+ THR_GCLIST_ADD(thread);
+ _gc_check = 1;
+ if (KSE_WAITING(_kse_initial))
+ KSE_WAKEUP(_kse_initial);
+ }
+ KSE_LOCK_RELEASE(curthread->kse, &_thread_list_lock);
+ _kse_critical_leave(crit);
+ }
}
OpenPOWER on IntegriCloud