summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2003-06-29 21:21:52 +0000
committermtm <mtm@FreeBSD.org>2003-06-29 21:21:52 +0000
commita810bddc153bedad5167855ef52ee1f9bc9f57cc (patch)
treebe0db3a8ab1b26666404e965e5bd32a14afe8dd1 /lib/libthr
parent44509f207ffb90a4c042b0c0dc5a3e9d028286e1 (diff)
downloadFreeBSD-src-a810bddc153bedad5167855ef52ee1f9bc9f57cc.zip
FreeBSD-src-a810bddc153bedad5167855ef52ee1f9bc9f57cc.tar.gz
In a critical section, separate the aquisition of the thread lock
and the disabling of signals. What we are really interested in is keeping track of recursive disabling of signals. We should not be recursively acquiring thread locks. Any such situations should be reorganized to not require a recursive lock. Separating the two out also allows us to block signals independent of acquiring thread locks. This will be needed in libthr in the near future when we put the pieces together to protect libc functions that use pthread mutexes and low level locks.
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_kern.c40
-rw-r--r--lib/libthr/thread/thr_private.h4
2 files changed, 27 insertions, 17 deletions
diff --git a/lib/libthr/thread/thr_kern.c b/lib/libthr/thread/thr_kern.c
index f45cae5..4a60bfe 100644
--- a/lib/libthr/thread/thr_kern.c
+++ b/lib/libthr/thread/thr_kern.c
@@ -55,6 +55,20 @@ static sigset_t restore;
void
_thread_critical_enter(pthread_t pthread)
{
+ _thread_sigblock();
+ _SPINLOCK(&pthread->lock);
+}
+
+void
+_thread_critical_exit(pthread_t pthread)
+{
+ _SPINUNLOCK(&pthread->lock);
+ _thread_sigunblock();
+}
+
+void
+_thread_sigblock()
+{
sigset_t set;
sigset_t sav;
@@ -62,18 +76,13 @@ _thread_critical_enter(pthread_t pthread)
* Block all signals.
*/
SIGFILLSET(set);
+ SIGADDSET(set, SIGTHR);
- /*
- * We can not use the global 'restore' set until after we have
- * acquired the giant lock.
- */
- _SPINLOCK(&pthread->lock);
-
- /* If we are already in a critical section, just up the refcount */
- if (++curthread->crit_ref > 1)
+ /* If we have already blocked signals, just up the refcount */
+ if (++curthread->signest > 1)
return;
- PTHREAD_ASSERT(curthread->crit_ref == 1,
- ("Critical section reference count must be 1!"));
+ PTHREAD_ASSERT(curthread->signest == 1,
+ ("Blocked signal nesting level must be 1!"));
if (__sys_sigprocmask(SIG_SETMASK, &set, &sav)) {
_thread_printf(STDERR_FILENO, "Critical Enter: sig err %d\n",
@@ -84,15 +93,15 @@ _thread_critical_enter(pthread_t pthread)
}
void
-_thread_critical_exit(pthread_t pthread)
+_thread_sigunblock()
{
sigset_t set;
- /* We might be in a nested critical section */
- if (--curthread->crit_ref > 0)
+ /* We might be in a nested 'blocked signal' section */
+ if (--curthread->signest > 0)
return;
- PTHREAD_ASSERT(curthread->crit_ref == 0,
- ("Non-Zero critical section reference count."));
+ PTHREAD_ASSERT(curthread->signest == 0,
+ ("Non-Zero blocked signal nesting level."));
/*
* Restore signals.
@@ -103,7 +112,6 @@ _thread_critical_exit(pthread_t pthread)
errno);
abort();
}
- _SPINUNLOCK(&pthread->lock);
}
void
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index b273890..5e8da18 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -426,7 +426,7 @@ struct pthread {
u_int64_t uniqueid; /* for gdb */
thr_id_t thr_id;
sigset_t savedsig;
- int crit_ref; /* crit. section netsting level */
+ int signest; /* blocked signal netsting level */
/*
* Lock for accesses to this thread structure.
@@ -766,6 +766,8 @@ void _thread_cancellation_point(void);
int _thread_suspend(pthread_t thread, struct timespec *abstime);
void _thread_critical_enter(pthread_t);
void _thread_critical_exit(pthread_t);
+void _thread_sigblock();
+void _thread_sigunblock();
/* #include <sys/aio.h> */
#ifdef _SYS_AIO_H_
OpenPOWER on IntegriCloud