summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_kern.c
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/thread/thr_kern.c
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/thread/thr_kern.c')
-rw-r--r--lib/libthr/thread/thr_kern.c40
1 files changed, 24 insertions, 16 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
OpenPOWER on IntegriCloud