PERFORCE change 73750 for review
David Xu
davidxu at FreeBSD.org
Thu Mar 24 04:54:06 PST 2005
http://perforce.freebsd.org/chv.cgi?CH=73750
Change 73750 by davidxu at davidxu_alona on 2005/03/24 12:53:22
tcb is now managed by rtld, caching it is not correct,
otherwise we may get stale copy of tls data from previous
dead thread, caching should be done in rtld if needed.
Affected files ...
.. //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_list.c#6 edit
Differences ...
==== //depot/projects/davidxu_thread/src/lib/libthread/thread/thr_list.c#6 (text+ko) ====
@@ -139,7 +139,7 @@
_thr_alloc(struct pthread *curthread)
{
struct pthread *thread = NULL;
- struct tcb *tcb = NULL;
+ struct tcb *tcb;
if (curthread != NULL) {
if (GC_NEEDED())
@@ -148,29 +148,29 @@
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);
}
}
- if ((thread == NULL) &&
- ((thread = malloc(sizeof(struct pthread))) != NULL)) {
- if (curthread) {
- THR_LOCK_ACQUIRE(curthread, &tcb_lock);
- tcb = _tcb_ctor(thread, 0 /* not initial tls */);
- THR_LOCK_RELEASE(curthread, &tcb_lock);
- } else {
- tcb = _tcb_ctor(thread, 1 /* initial tls */);
- }
- if (tcb == NULL) {
- free(thread);
- thread = NULL;
- }
+ if (thread == NULL) {
+ thread = malloc(sizeof(struct pthread));
+ if (thread == NULL)
+ return (NULL);
+ }
+ if (curthread != NULL) {
+ THR_LOCK_ACQUIRE(curthread, &tcb_lock);
+ tcb = _tcb_ctor(thread, 0 /* not initial tls */);
+ THR_LOCK_RELEASE(curthread, &tcb_lock);
+ } else {
+ tcb = _tcb_ctor(thread, 1 /* initial tls */);
}
- if (thread) {
+ if (tcb != NULL) {
memset(thread, 0, sizeof(*thread));
thread->tcb = tcb;
+ } else {
+ thr_destroy(curthread, thread);
+ thread = NULL;
}
return (thread);
}
@@ -183,10 +183,26 @@
free(thread->name);
thread->name = NULL;
}
+ /*
+ * Always free tcb, as we only know it is part of RTLD TLS
+ * block, but don't know its detail and can not assume how
+ * it works, so better to avoid caching it here.
+ */
+ if (curthread != NULL) {
+ THR_LOCK_ACQUIRE(curthread, &tcb_lock);
+ _tcb_dtor(thread->tcb);
+ THR_LOCK_RELEASE(curthread, &tcb_lock);
+ } else {
+ _tcb_dtor(thread->tcb);
+ }
+ thread->tcb = NULL;
if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) {
thr_destroy(curthread, thread);
} else {
- /* Add the thread to the free thread list. */
+ /*
+ * Add the thread to the free thread list, this also avoids
+ * pthread id is reused too quickly, may help some buggy apps.
+ */
THR_LOCK_ACQUIRE(curthread, &free_thread_lock);
TAILQ_INSERT_TAIL(&free_threadq, thread, tle);
free_thread_count++;
@@ -195,15 +211,8 @@
}
static void
-thr_destroy(struct pthread *curthread, struct pthread *thread)
+thr_destroy(struct pthread *curthread __unused, 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);
}
More information about the p4-projects
mailing list