guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 19/24: Separate fat mutex unlock and wait operations


From: Andy Wingo
Subject: [Guile-commits] 19/24: Separate fat mutex unlock and wait operations
Date: Sun, 6 Nov 2016 18:00:46 +0000 (UTC)

wingo pushed a commit to branch master
in repository guile.

commit fc4df456a15a20bf3f8d381f8db9a37ab3b07d8c
Author: Andy Wingo <address@hidden>
Date:   Sat Nov 5 11:51:02 2016 +0100

    Separate fat mutex unlock and wait operations
    
    * libguile/threads.c (fat_mutex_unlock, fat_mutex_wait): Separate wait
      from unlock.
      (scm_unlock_mutex, scm_timed_wait_condition_variable): Adapt.
---
 libguile/threads.c |  130 ++++++++++++++++++++++++++++------------------------
 1 file changed, 71 insertions(+), 59 deletions(-)

diff --git a/libguile/threads.c b/libguile/threads.c
index 5497eb0..d7295bc 100644
--- a/libguile/threads.c
+++ b/libguile/threads.c
@@ -1277,21 +1277,14 @@ typedef struct {
 #define SCM_CONDVARP(x)       SCM_SMOB_PREDICATE (scm_tc16_condvar, x)
 #define SCM_CONDVAR_DATA(x)   ((fat_cond *) SCM_SMOB_DATA (x))
 
-static int
-fat_mutex_unlock (SCM mutex, SCM cond,
-                 const scm_t_timespec *waittime, int relock)
+static void
+fat_mutex_unlock (SCM mutex)
 {
-  SCM owner;
   fat_mutex *m = SCM_MUTEX_DATA (mutex);
-  fat_cond *c = NULL;
-  scm_i_thread *t = SCM_I_CURRENT_THREAD;
-  int err = 0, ret = 0;
 
   scm_i_scm_pthread_mutex_lock (&m->lock);
 
-  owner = m->owner;
-
-  if (!scm_is_eq (owner, t->handle))
+  if (!scm_is_eq (m->owner, SCM_I_CURRENT_THREAD->handle))
     {
       if (m->level == 0)
        {
@@ -1305,66 +1298,83 @@ fat_mutex_unlock (SCM mutex, SCM cond,
        }
     }
 
-  if (! (SCM_UNBNDP (cond)))
-    {
-      c = SCM_CONDVAR_DATA (cond);
-      while (1)
-       {
-         int brk = 0;
-
-         if (m->level > 0)
-           m->level--;
-         if (m->level == 0)
-            /* Change the owner of MUTEX.  */
-            m->owner = unblock_from_queue (m->waiting);
-
-         t->block_asyncs++;
-
-         err = block_self (c->waiting, cond, &m->lock, waittime);
-         scm_i_pthread_mutex_unlock (&m->lock);
-
-         if (err == 0)
-           {
-             ret = 1;
-             brk = 1;
-           }
-         else if (err == ETIMEDOUT)
-           {
-             ret = 0;
-             brk = 1;
-           }
-         else if (err != EINTR)
-           {
-             errno = err;
-             scm_syserror (NULL);
-           }
+  if (m->level > 0)
+    m->level--;
+  if (m->level == 0)
+    /* Change the owner of MUTEX.  */
+    m->owner = unblock_from_queue (m->waiting);
 
-         if (brk)
-           {
-             if (relock)
-               scm_lock_mutex_timed (mutex, SCM_UNDEFINED, SCM_UNDEFINED);
-             t->block_asyncs--;
-             break;
-           }
+  scm_i_pthread_mutex_unlock (&m->lock);
+}
 
-         t->block_asyncs--;
-         scm_async_tick ();
+static int
+fat_mutex_wait (SCM cond, SCM mutex, const scm_t_timespec *waittime)
+{
+  fat_cond *c = SCM_CONDVAR_DATA (cond);
+  fat_mutex *m = SCM_MUTEX_DATA (mutex);
+  scm_i_thread *t = SCM_I_CURRENT_THREAD;
+  int err = 0, ret = 0;
 
-         scm_remember_upto_here_2 (cond, mutex);
+  scm_i_scm_pthread_mutex_lock (&m->lock);
 
-         scm_i_scm_pthread_mutex_lock (&m->lock);
+  if (!scm_is_eq (m->owner, t->handle))
+    {
+      if (m->level == 0)
+       {
+          scm_i_pthread_mutex_unlock (&m->lock);
+          scm_misc_error (NULL, "mutex not locked", SCM_EOL);
+       }
+      else if (m->kind != FAT_MUTEX_UNOWNED)
+       {
+         scm_i_pthread_mutex_unlock (&m->lock);
+         scm_misc_error (NULL, "mutex not locked by current thread", SCM_EOL);
        }
     }
-  else
+
+  while (1)
     {
+      int brk = 0;
+
       if (m->level > 0)
-       m->level--;
+        m->level--;
       if (m->level == 0)
         /* Change the owner of MUTEX.  */
         m->owner = unblock_from_queue (m->waiting);
 
+      t->block_asyncs++;
+
+      err = block_self (c->waiting, cond, &m->lock, waittime);
       scm_i_pthread_mutex_unlock (&m->lock);
-      ret = 1;
+
+      if (err == 0)
+        {
+          ret = 1;
+          brk = 1;
+        }
+      else if (err == ETIMEDOUT)
+        {
+          ret = 0;
+          brk = 1;
+        }
+      else if (err != EINTR)
+        {
+          errno = err;
+          scm_syserror (NULL);
+        }
+
+      if (brk)
+        {
+          scm_lock_mutex (mutex);
+          t->block_asyncs--;
+          break;
+        }
+
+      t->block_asyncs--;
+      scm_async_tick ();
+
+      scm_remember_upto_here_2 (cond, mutex);
+
+      scm_i_scm_pthread_mutex_lock (&m->lock);
     }
 
   return ret;
@@ -1379,7 +1389,9 @@ SCM_DEFINE (scm_unlock_mutex, "unlock-mutex", 1, 0, 0, 
(SCM mx),
 {
   SCM_VALIDATE_MUTEX (1, mx);
 
-  return scm_from_bool (fat_mutex_unlock (mx, SCM_UNDEFINED, NULL, 0));
+  fat_mutex_unlock (mx);
+
+  return SCM_BOOL_T;
 }
 #undef FUNC_NAME
 
@@ -1480,7 +1492,7 @@ SCM_DEFINE (scm_timed_wait_condition_variable, 
"wait-condition-variable", 2, 1,
       waitptr = &waittime;
     }
 
-  return fat_mutex_unlock (mx, cv, waitptr, 1) ? SCM_BOOL_T : SCM_BOOL_F;
+  return scm_from_bool (fat_mutex_wait (cv, mx, waitptr));
 }
 #undef FUNC_NAME
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]