summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authormtm <mtm@FreeBSD.org>2003-05-25 07:58:22 +0000
committermtm <mtm@FreeBSD.org>2003-05-25 07:58:22 +0000
commit33c8b02fd8ae4e20728d11cbf06a9e18d546af6b (patch)
treea918630c18944b3bcffd684ebd3891e041ea368c /lib/libthr
parent9a47cfedaa161760fa17eca1844ce525389199b2 (diff)
downloadFreeBSD-src-33c8b02fd8ae4e20728d11cbf06a9e18d546af6b.zip
FreeBSD-src-33c8b02fd8ae4e20728d11cbf06a9e18d546af6b.tar.gz
The libthr code makes use of higher-level primitives (pthread_mutex_t and
pthread_cond_t) internaly in addition to the low-level spinlock_t. The garbage collector mutex and condition variable are two such examples. This might lead to critical sections nested within critical sections. Implement a reference counting mechanism so that signals are masked only on the first entry and unmasked on the last exit. I'm not sure I like the idea of nested critical sections, but if the library is going to use the pthread primitives it might be necessary. Approved by: re/blanket libthr
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_kern.c13
-rw-r--r--lib/libthr/thread/thr_private.h1
2 files changed, 14 insertions, 0 deletions
diff --git a/lib/libthr/thread/thr_kern.c b/lib/libthr/thread/thr_kern.c
index 77b0094..1c9a8ce 100644
--- a/lib/libthr/thread/thr_kern.c
+++ b/lib/libthr/thread/thr_kern.c
@@ -68,6 +68,13 @@ _thread_critical_enter(pthread_t pthread)
* acquired the giant lock.
*/
_SPINLOCK(&pthread->lock);
+
+ /* If we are already in a critical section, just up the refcount */
+ if (++curthread->crit_ref > 1)
+ return;
+ PTHREAD_ASSERT(curthread->crit_ref == 1,
+ ("Critical section reference count must be 1!"));
+
if (__sys_sigprocmask(SIG_SETMASK, &set, &sav)) {
_thread_printf(STDERR_FILENO, "Critical Enter: sig err %d\n",
errno);
@@ -81,6 +88,12 @@ _thread_critical_exit(pthread_t pthread)
{
sigset_t set;
+ /* We might be in a nested critical section */
+ if (--curthread->crit_ref > 0)
+ return;
+ PTHREAD_ASSERT(curthread->crit_ref == 0,
+ ("Non-Zero critical section reference count."));
+
/*
* Restore signals.
*/
diff --git a/lib/libthr/thread/thr_private.h b/lib/libthr/thread/thr_private.h
index b02df32..6048bd0 100644
--- a/lib/libthr/thread/thr_private.h
+++ b/lib/libthr/thread/thr_private.h
@@ -426,6 +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 */
/*
* Lock for accesses to this thread structure.
OpenPOWER on IntegriCloud