summaryrefslogtreecommitdiffstats
path: root/lib/libthr/thread/thr_kern.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libthr/thread/thr_kern.c')
-rw-r--r--lib/libthr/thread/thr_kern.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/lib/libthr/thread/thr_kern.c b/lib/libthr/thread/thr_kern.c
index 2b1dcc3..2945cc3 100644
--- a/lib/libthr/thread/thr_kern.c
+++ b/lib/libthr/thread/thr_kern.c
@@ -52,6 +52,56 @@
static sigset_t restore;
void
+_thread_critical_enter(pthread_t pthread)
+{
+ sigset_t set;
+ sigset_t sav;
+
+ /*
+ * Block all signals.
+ */
+ SIGFILLSET(set);
+
+ /*
+ * We can not use the global 'restore' set until after we have
+ * acquired the giant lock.
+ */
+ _SPINLOCK(&pthread->lock);
+ if (__sys_sigprocmask(SIG_SETMASK, &set, &sav)) {
+ _thread_printf(STDERR_FILENO, "Critical Enter: sig err %d\n",
+ errno);
+ abort();
+ }
+
+ restore = sav;
+}
+
+void
+_thread_critical_exit(pthread_t pthread)
+{
+ sigset_t set;
+ int error;
+
+ /*
+ * restore is protected by giant. We could restore our signal state
+ * incorrectly if someone else set restore between unlocking giant
+ * and restoring the signal mask. To avoid this we cache a copy prior
+ * to the unlock.
+ */
+ set = restore;
+
+ /*
+ * Restore signals.
+ */
+ if (__sys_sigprocmask(SIG_SETMASK, &set, NULL)) {
+ _thread_printf(STDERR_FILENO, "Critical Exit: sig err %d\n",
+ errno);
+ abort();
+ }
+ _SPINUNLOCK(&pthread->lock);
+}
+
+void
GIANT_LOCK(pthread_t pthread)
{
sigset_t set;
OpenPOWER on IntegriCloud