threads/119920: fork broken in libpthread
Julian Elischer
julian at elischer.org
Thu Jan 31 00:58:55 PST 2008
Landon Fuller wrote:
> Thanks -- pulling in relevant change from sys/lock.c -- plus your
> previous patch -- solves my reproduction case:
> http://landonf.bikemonkey.org/static/code/freebsd/patch-libpthread63-fork
is this the patch you used? It's huge..
I cut it down to a smaller size by removing most of the cosmetic stuff
(included) but if your change is smaller can you post it back?
(sounds like you cherry picked smaller psrts)
>
>
> -landonf
>
-------------- next part --------------
Index: sys/lock.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/sys/Attic/lock.c,v
retrieving revision 1.9.2.1
diff -u -r1.9.2.1 lock.c
--- sys/lock.c 5 Aug 2005 19:43:56 -0000 1.9.2.1
+++ sys/lock.c 30 Jan 2008 21:56:05 -0000
@@ -54,11 +54,12 @@
int
_lock_init(struct lock *lck, enum lock_type ltype,
- lock_handler_t *waitfunc, lock_handler_t *wakeupfunc)
+ lock_handler_t *waitfunc, lock_handler_t *wakeupfunc,
+ void *(calloc_cb)(size_t, size_t))
{
if (lck == NULL)
return (-1);
- else if ((lck->l_head = malloc(sizeof(struct lockreq))) == NULL)
+ else if ((lck->l_head = calloc_cb(1, sizeof(struct lockreq))) == NULL)
return (-1);
else {
lck->l_type = ltype;
@@ -80,7 +81,7 @@
if (lck == NULL)
return (-1);
else if (lck->l_head == NULL)
- return (_lock_init(lck, ltype, waitfunc, wakeupfunc));
+ return (_lock_init(lck, ltype, waitfunc, wakeupfunc, calloc));
else {
lck->l_head->lr_locked = 0;
lck->l_head->lr_watcher = NULL;
@@ -117,14 +118,22 @@
{
if (lu == NULL)
return (-1);
- /*
- * All lockusers keep their watch request and drop their
- * own (lu_myreq) request. Their own request is either
- * some other lockuser's watch request or is the head of
- * the lock.
- */
- lu->lu_myreq = lu->lu_watchreq;
+ if (lu->lu_watchreq != NULL) {
+ /*
+ * In this case the lock is active. All lockusers
+ * keep their watch request and drop their own
+ * (lu_myreq) request. Their own request is either
+ * some other lockuser's watch request or is the
+ * head of the lock.
+ */
+ lu->lu_myreq = lu->lu_watchreq;
+ lu->lu_watchreq = NULL;
+ }
if (lu->lu_myreq == NULL)
+ /*
+ * Oops, something isn't quite right. Try to
+ * allocate one.
+ */
return (_lockuser_init(lu, priv));
else {
lu->lu_myreq->lr_locked = 1;
Index: sys/lock.h
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/sys/Attic/lock.h,v
retrieving revision 1.7
diff -u -r1.7 lock.h
--- sys/lock.h 4 Nov 2003 20:01:38 -0000 1.7
+++ sys/lock.h 30 Jan 2008 21:14:31 -0000
@@ -83,7 +83,7 @@
void _lock_destroy(struct lock *);
void _lock_grant(struct lock *, struct lockuser *);
int _lock_init(struct lock *, enum lock_type,
- lock_handler_t *, lock_handler_t *);
+ lock_handler_t *, lock_handler_t *, void *(size_t, size_t));
int _lock_reinit(struct lock *, enum lock_type,
lock_handler_t *, lock_handler_t *);
void _lock_release(struct lock *, struct lockuser *);
Index: thread/thr_exit.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_exit.c,v
retrieving revision 1.39
diff -u -r1.39 thr_exit.c
--- thread/thr_exit.c 23 Oct 2004 23:37:54 -0000 1.39
+++ thread/thr_exit.c 30 Jan 2008 21:14:31 -0000
@@ -10,10 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
@@ -31,6 +28,8 @@
*
* $FreeBSD: src/lib/libpthread/thread/thr_exit.c,v 1.39 2004/10/23 23:37:54 davidxu Exp $
*/
+
+#include "namespace.h"
#include <errno.h>
#include <unistd.h>
#include <fcntl.h>
@@ -38,6 +37,7 @@
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
+#include "un-namespace.h"
#include "thr_private.h"
void _pthread_exit(void *status);
@@ -45,7 +45,7 @@
__weak_reference(_pthread_exit, pthread_exit);
void
-_thr_exit(char *fname, int lineno, char *msg)
+_thr_exit(const char *fname, int lineno, const char *msg)
{
/* Write an error message to the standard error file descriptor: */
@@ -122,7 +122,7 @@
/* Save the return value: */
curthread->ret = status;
while (curthread->cleanup != NULL) {
- pthread_cleanup_pop(1);
+ _pthread_cleanup_pop(1);
}
if (curthread->attr.cleanup_attr != NULL) {
curthread->attr.cleanup_attr(curthread->attr.arg_attr);
Index: thread/thr_init.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_init.c,v
retrieving revision 1.70.2.1
diff -u -r1.70.2.1 thr_init.c
--- thread/thr_init.c 16 Mar 2006 23:29:07 -0000 1.70.2.1
+++ thread/thr_init.c 30 Jan 2008 21:14:31 -0000
@@ -462,16 +460,16 @@
* process signal mask and pending signal sets.
*/
if (_lock_init(&_thread_signal_lock, LCK_ADAPTIVE,
- _kse_lock_wait, _kse_lock_wakeup) != 0)
+ _kse_lock_wait, _kse_lock_wakeup, calloc) != 0)
PANIC("Cannot initialize _thread_signal_lock");
if (_lock_init(&_mutex_static_lock, LCK_ADAPTIVE,
- _thr_lock_wait, _thr_lock_wakeup) != 0)
+ _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
PANIC("Cannot initialize mutex static init lock");
if (_lock_init(&_rwlock_static_lock, LCK_ADAPTIVE,
- _thr_lock_wait, _thr_lock_wakeup) != 0)
+ _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
PANIC("Cannot initialize rwlock static init lock");
if (_lock_init(&_keytable_lock, LCK_ADAPTIVE,
- _thr_lock_wait, _thr_lock_wakeup) != 0)
+ _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
PANIC("Cannot initialize thread specific keytable lock");
_thr_spinlock_init();
Index: thread/thr_kern.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_kern.c,v
retrieving revision 1.116.2.1
diff -u -r1.116.2.1 thr_kern.c
--- thread/thr_kern.c 16 Mar 2006 23:29:07 -0000 1.116.2.1
+++ thread/thr_kern.c 30 Jan 2008 21:14:31 -0000
@@ -176,7 +176,7 @@
static void kse_gc(struct pthread *thread);
static void kseg_gc(struct pthread *thread);
-static void __inline
+static __inline void
thr_accounting(struct pthread *thread)
{
if ((thread->slice_usec != -1) &&
@@ -228,6 +228,10 @@
__sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL);
_thread_active_threads = 1;
+ curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL;
+ curthread->attr.flags &= ~PTHREAD_SCOPE_PROCESS;
+ curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
+
/*
* Enter a loop to remove and free all threads other than
* the running thread from the active thread list:
@@ -310,13 +314,6 @@
inited = 0;
}
- /*
- * After a fork(), the leftover thread goes back to being
- * scope process.
- */
- curthread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM;
- curthread->attr.flags |= PTHREAD_SCOPE_PROCESS;
-
/* We're no longer part of any lists */
curthread->tlflags = 0;
@@ -345,6 +342,16 @@
_LCK_SET_PRIVATE2(&curthread->kse->k_lockusers[i], NULL);
}
curthread->kse->k_locklevel = 0;
+
+ /*
+ * Reinitialize the thread and signal locks so that
+ * sigaction() will work after a fork().
+ */
+ _lock_reinit(&curthread->lock, LCK_ADAPTIVE, _thr_lock_wait,
+ _thr_lock_wakeup);
+ _lock_reinit(&_thread_signal_lock, LCK_ADAPTIVE, _kse_lock_wait,
+ _kse_lock_wakeup);
+
_thr_spinlock_init();
if (__isthreaded) {
_thr_rtld_fini();
@@ -354,6 +361,19 @@
curthread->kse->k_kcb->kcb_kmbx.km_curthread = NULL;
curthread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
+ /*
+ * After a fork, it is possible that an upcall occurs in
+ * the parent KSE that fork()'d before the child process
+ * is fully created and before its vm space is copied.
+ * During the upcall, the tcb is set to null or to another
+ * thread, and this is what gets copied in the child process
+ * when the vm space is cloned sometime after the upcall
+ * occurs. Note that we shouldn't have to set the kcb, but
+ * we do it for completeness.
+ */
+ _kcb_set(curthread->kse->k_kcb);
+ _tcb_set(curthread->kse->k_kcb, curthread->tcb);
+
/* After a fork(), there child should have no pending signals. */
sigemptyset(&curthread->sigpend);
@@ -381,13 +401,13 @@
TAILQ_INIT(&free_threadq);
TAILQ_INIT(&gc_ksegq);
if (_lock_init(&kse_lock, LCK_ADAPTIVE,
- _kse_lock_wait, _kse_lock_wakeup) != 0)
+ _kse_lock_wait, _kse_lock_wakeup, calloc) != 0)
PANIC("Unable to initialize free KSE queue lock");
if (_lock_init(&thread_lock, LCK_ADAPTIVE,
- _kse_lock_wait, _kse_lock_wakeup) != 0)
+ _kse_lock_wait, _kse_lock_wakeup, calloc) != 0)
PANIC("Unable to initialize free thread queue lock");
if (_lock_init(&_thread_list_lock, LCK_ADAPTIVE,
- _kse_lock_wait, _kse_lock_wakeup) != 0)
+ _kse_lock_wait, _kse_lock_wakeup, calloc) != 0)
PANIC("Unable to initialize thread list lock");
_pthread_mutex_init(&_tcb_mutex, NULL);
active_kse_count = 0;
@@ -764,7 +784,6 @@
break;
case PS_DEAD:
- curthread->check_pending = 0;
/* Unlock the scheduling queue and exit the KSE and thread. */
thr_cleanup(curkse, curthread);
KSE_SCHED_UNLOCK(curkse, curkse->k_kseg);
@@ -1150,6 +1170,11 @@
struct kse_mailbox *kmbx = NULL;
int sys_scope;
+ thread->active = 0;
+ thread->need_switchout = 0;
+ thread->lock_switch = 0;
+ thread->check_pending = 0;
+
if ((joiner = thread->joiner) != NULL) {
/* Joinee scheduler lock held; joiner won't leave. */
if (joiner->kseg == curkse->k_kseg) {
@@ -1717,9 +1742,6 @@
* stack. It is safe to do garbage collecting
* here.
*/
- thread->active = 0;
- thread->need_switchout = 0;
- thread->lock_switch = 0;
thr_cleanup(kse, thread);
return;
break;
@@ -2122,7 +2144,7 @@
{
kseg_reinit(kseg);
_lock_init(&kseg->kg_lock, LCK_ADAPTIVE, _kse_lock_wait,
- _kse_lock_wakeup);
+ _kse_lock_wakeup, calloc);
}
static void
@@ -2392,7 +2414,7 @@
* enter critical region before doing this!
*/
if (_lock_init(&thread->lock, LCK_ADAPTIVE,
- _thr_lock_wait, _thr_lock_wakeup) != 0)
+ _thr_lock_wait, _thr_lock_wakeup, calloc) != 0)
PANIC("Cannot initialize thread lock");
for (i = 0; i < MAX_THR_LOCKLEVEL; i++) {
_lockuser_init(&thread->lockusers[i], (void *)thread);
Index: thread/thr_mutex.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_mutex.c,v
retrieving revision 1.47.2.1
diff -u -r1.47.2.1 thr_mutex.c
--- thread/thr_mutex.c 16 Mar 2006 23:29:07 -0000 1.47.2.1
+++ thread/thr_mutex.c 30 Jan 2008 21:28:13 -0000
@@ -76,7 +76,7 @@
*/
static struct kse_mailbox *mutex_handoff(struct pthread *,
struct pthread_mutex *);
-static inline int mutex_self_trylock(struct pthread *, pthread_mutex_t);
+static inline int mutex_self_trylock(pthread_mutex_t);
static inline int mutex_self_lock(struct pthread *, pthread_mutex_t);
static int mutex_unlock_common(pthread_mutex_t *, int);
static void mutex_priority_adjust(struct pthread *, pthread_mutex_t);
@@ -87,6 +87,16 @@
static inline void mutex_queue_enq(pthread_mutex_t, pthread_t);
static void mutex_lock_backout(void *arg);
+int __pthread_mutex_init(pthread_mutex_t *mutex,
+ const pthread_mutexattr_t *mutex_attr);
+int __pthread_mutex_trylock(pthread_mutex_t *mutex);
+int __pthread_mutex_lock(pthread_mutex_t *m);
+int __pthread_mutex_timedlock(pthread_mutex_t *m,
+ const struct timespec *abs_timeout);
+int _pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
+ void *(calloc_cb)(size_t, size_t));
+
+
static struct pthread_mutex_attr static_mutex_attr =
PTHREAD_MUTEXATTR_STATIC_INITIALIZER;
static pthread_mutexattr_t static_mattr = &static_mutex_attr;
@@ -101,11 +111,9 @@
__weak_reference(_pthread_mutex_destroy, pthread_mutex_destroy);
__weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock);
-
-
-int
-__pthread_mutex_init(pthread_mutex_t *mutex,
- const pthread_mutexattr_t *mutex_attr)
+static int
+thr_mutex_init(pthread_mutex_t *mutex,
+ const pthread_mutexattr_t *mutex_attr, void *(calloc_cb)(size_t, size_t))
{
struct pthread_mutex *pmutex;
enum pthread_mutextype type;
@@ -149,10 +157,10 @@
/* Check no errors so far: */
if (ret == 0) {
if ((pmutex = (pthread_mutex_t)
- malloc(sizeof(struct pthread_mutex))) == NULL)
+ calloc_cb(1, sizeof(struct pthread_mutex))) == NULL)
ret = ENOMEM;
else if (_lock_init(&pmutex->m_lock, LCK_ADAPTIVE,
- _thr_lock_wait, _thr_lock_wakeup) != 0) {
+ _thr_lock_wait, _thr_lock_wakeup, calloc_cb) != 0) {
free(pmutex);
*mutex = NULL;
ret = ENOMEM;
@@ -207,6 +215,14 @@
}
int
+__pthread_mutex_init(pthread_mutex_t *mutex,
+ const pthread_mutexattr_t *mutex_attr)
+{
+
+ return (thr_mutex_init(mutex, mutex_attr, calloc));
+}
+
+int
_pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *mutex_attr)
{
@@ -222,6 +238,23 @@
}
}
+/* This function is used internally by malloc. */
+int
+_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
+ void *(calloc_cb)(size_t, size_t))
+{
+ static const struct pthread_mutex_attr attr = {
+ .m_type = PTHREAD_MUTEX_NORMAL,
+ .m_protocol = PTHREAD_PRIO_NONE,
+ .m_ceiling = 0,
+ .m_flags = 0
+ };
+ static const struct pthread_mutex_attr *pattr = &attr;
+
+ return (thr_mutex_init(mutex, (pthread_mutexattr_t *)&pattr,
+ calloc_cb));
+}
+
void
_thr_mutex_reinit(pthread_mutex_t *mutex)
{
@@ -252,7 +285,7 @@
* Check to see if this mutex is in use:
*/
if (((*mutex)->m_owner != NULL) ||
- (TAILQ_FIRST(&(*mutex)->m_queue) != NULL) ||
+ (!TAILQ_EMPTY(&(*mutex)->m_queue)) ||
((*mutex)->m_refcount != 0)) {
ret = EBUSY;
@@ -290,7 +323,7 @@
THR_LOCK_ACQUIRE(thread, &_mutex_static_lock);
if (*mutex == NULL)
- ret = pthread_mutex_init(mutex, NULL);
+ ret = _pthread_mutex_init(mutex, NULL);
else
ret = 0;
@@ -307,7 +340,7 @@
THR_LOCK_ACQUIRE(thread, &_mutex_static_lock);
if (*mutex == NULL)
- ret = pthread_mutex_init(mutex, &static_mattr);
+ ret = _pthread_mutex_init(mutex, &static_mattr);
else
ret = 0;
@@ -353,7 +386,7 @@
TAILQ_INSERT_TAIL(&curthread->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == curthread)
- ret = mutex_self_trylock(curthread, *mutex);
+ ret = mutex_self_trylock(*mutex);
else
/* Return a busy error: */
ret = EBUSY;
@@ -385,7 +418,7 @@
TAILQ_INSERT_TAIL(&curthread->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == curthread)
- ret = mutex_self_trylock(curthread, *mutex);
+ ret = mutex_self_trylock(*mutex);
else
/* Return a busy error: */
ret = EBUSY;
@@ -422,7 +455,7 @@
TAILQ_INSERT_TAIL(&curthread->mutexq,
(*mutex), m_qe);
} else if ((*mutex)->m_owner == curthread)
- ret = mutex_self_trylock(curthread, *mutex);
+ ret = mutex_self_trylock(*mutex);
else
/* Return a busy error: */
ret = EBUSY;
@@ -949,7 +982,7 @@
}
static inline int
-mutex_self_trylock(struct pthread *curthread, pthread_mutex_t m)
+mutex_self_trylock(pthread_mutex_t m)
{
int ret = 0;
@@ -1561,7 +1594,7 @@
for (m = TAILQ_FIRST(&pthread->mutexq); m != NULL; m = m_next) {
m_next = TAILQ_NEXT(m, m_qe);
if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0)
- pthread_mutex_unlock(&m);
+ _pthread_mutex_unlock(&m);
}
}
Index: thread/thr_mutex_prioceiling.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_mutex_prioceiling.c,v
retrieving revision 1.8
diff -u -r1.8 thr_mutex_prioceiling.c
--- thread/thr_mutex_prioceiling.c 7 Jul 2003 04:28:23 -0000 1.8
+++ thread/thr_mutex_prioceiling.c 30 Jan 2008 21:14:31 -0000
@@ -31,10 +31,13 @@
*
* $FreeBSD: src/lib/libpthread/thread/thr_mutex_prioceiling.c,v 1.8 2003/07/07 04:28:23 davidxu Exp $
*/
+
+#include "namespace.h"
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>
+#include "un-namespace.h"
#include "thr_private.h"
__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling);
@@ -82,10 +85,11 @@
ret = EINVAL;
else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
ret = EINVAL;
- else
- ret = (*mutex)->m_prio;
-
- return(ret);
+ else {
+ *prioceiling = (*mutex)->m_prio;
+ ret = 0;
+ }
+ return (ret);
}
int
@@ -100,13 +104,13 @@
else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
ret = EINVAL;
/* Lock the mutex: */
- else if ((ret = pthread_mutex_lock(mutex)) == 0) {
+ else if ((ret = _pthread_mutex_lock(mutex)) == 0) {
tmp = (*mutex)->m_prio;
/* Set the new ceiling: */
(*mutex)->m_prio = prioceiling;
/* Unlock the mutex: */
- ret = pthread_mutex_unlock(mutex);
+ ret = _pthread_mutex_unlock(mutex);
/* Return the old ceiling: */
Index: thread/thr_rtld.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_rtld.c,v
retrieving revision 1.5.10.1
diff -u -r1.5.10.1 thr_rtld.c
--- thread/thr_rtld.c 16 Mar 2006 23:29:08 -0000 1.5.10.1
+++ thread/thr_rtld.c 30 Jan 2008 21:14:31 -0000
@@ -162,7 +162,7 @@
if ((l = malloc(sizeof(struct rtld_kse_lock))) != NULL) {
_lock_init(&l->lck, LCK_ADAPTIVE, _kse_lock_wait,
- _kse_lock_wakeup);
+ _kse_lock_wakeup, calloc);
l->owner = NULL;
l->count = 0;
l->write = 0;
Index: thread/thr_sig.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_sig.c,v
retrieving revision 1.83.2.2
diff -u -r1.83.2.2 thr_sig.c
--- thread/thr_sig.c 23 Jun 2006 10:51:35 -0000 1.83.2.2
+++ thread/thr_sig.c 30 Jan 2008 21:14:31 -0000
@@ -299,16 +299,18 @@
struct sigcontext *scp, char *addr, __sighandler_t *catcher);
void
-_thr_sig_handler(int sig, siginfo_t *info, ucontext_t *ucp)
+_thr_sig_handler(int sig, siginfo_t *info, void *ucp_arg)
{
struct pthread_sigframe psf;
__siginfohandler_t *sigfunc;
struct pthread *curthread;
struct kse *curkse;
+ ucontext_t *ucp;
struct sigaction act;
int sa_flags, err_save;
err_save = errno;
+ ucp = (ucontext_t *)ucp_arg;
DBG_MSG(">>> _thr_sig_handler(%d)\n", sig);
Index: thread/thr_sigaction.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_sigaction.c,v
retrieving revision 1.22.10.1
diff -u -r1.22.10.1 thr_sigaction.c
--- thread/thr_sigaction.c 23 Jun 2006 10:51:36 -0000 1.22.10.1
+++ thread/thr_sigaction.c 30 Jan 2008 21:14:31 -0000
@@ -86,7 +86,7 @@
* Specify the thread kernel signal
* handler:
*/
- newact.sa_handler = (void (*) ())_thr_sig_handler;
+ newact.sa_sigaction = _thr_sig_handler;
}
/*
* Install libpthread signal handler wrapper
@@ -95,8 +95,7 @@
* SIG_DFL or SIG_IGN.
*/
if (sig == SIGINFO && _thr_dump_enabled()) {
- newact.sa_handler =
- (void (*) ())_thr_sig_handler;
+ newact.sa_sigaction = _thr_sig_handler;
}
/* Change the signal action in the kernel: */
if (__sys_sigaction(sig, &newact, NULL) != 0) {
Index: thread/thr_spinlock.c
===================================================================
RCS file: /opt/FreeBSD/cvs/src/lib/libpthread/thread/Attic/thr_spinlock.c,v
retrieving revision 1.22
diff -u -r1.22 thr_spinlock.c
--- thread/thr_spinlock.c 18 Dec 2004 18:07:37 -0000 1.22
+++ thread/thr_spinlock.c 30 Jan 2008 21:14:31 -0000
@@ -33,20 +30,30 @@
*
*/
+#include "namespace.h"
#include <sys/types.h>
#include <machine/atomic.h>
-
+#include <pthread.h>
#include <libc_private.h>
+#include "un-namespace.h"
#include "spinlock.h"
#include "thr_private.h"
-#define MAX_SPINLOCKS 5
+#define MAX_SPINLOCKS 72
struct spinlock_extra {
spinlock_t *owner;
pthread_mutex_t lock;
};
+struct nv_spinlock {
+ long access_lock;
+ long lock_owner;
+ struct spinlock_extra *extra; /* overlays fname in spinlock_t */
+ int lineno;
+};
+typedef struct nv_spinlock nv_spinlock_t;
+
static void init_spinlock(spinlock_t *lck);
static struct pthread_mutex_attr static_mutex_attr =
@@ -66,10 +73,10 @@
void
_spinunlock(spinlock_t *lck)
{
- struct spinlock_extra *extra;
+ struct spinlock_extra *sl_extra;
- extra = (struct spinlock_extra *)lck->fname;
- _pthread_mutex_unlock(&extra->lock);
+ sl_extra = ((nv_spinlock_t *)lck)->extra;
+ _pthread_mutex_unlock(&sl_extra->lock);
}
/*
@@ -81,7 +88,7 @@
void
_spinlock(spinlock_t *lck)
{
- struct spinlock_extra *extra;
+ struct spinlock_extra *sl_extra;
if (!__isthreaded)
PANIC("Spinlock called when not threaded.");
@@ -93,8 +100,8 @@
*/
if (lck->fname == NULL)
init_spinlock(lck);
- extra = (struct spinlock_extra *)lck->fname;
- _pthread_mutex_lock(&extra->lock);
+ sl_extra = ((nv_spinlock_t *)lck)->extra;
+ _pthread_mutex_lock(&sl_extra->lock);
}
/*
@@ -108,7 +115,7 @@
* returning.
*/
void
-_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
+_spinlock_debug(spinlock_t *lck, char *fname __unused, int lineno __unused)
{
_spinlock(lck);
}
More information about the freebsd-threads
mailing list