[M3devel] fewer wrappers/more C? (or a wash?)

Jay jay.krell at cornell.edu
Wed Apr 15 16:12:34 CEST 2009


This "rewrites" ThreadPThread.InitMutex and ThreadPThread.InitCondition in C.
 They are only a few lines either way.
Thereby removing all uses of initMu from Modula-3 and enabling removing
  the "bridging" of it between Modula-3 and C.
 

Better? I'm not sure.
No real difference? Maybe.
 

Likewise can be done for CreateT's allocation/initialization of cond_t.
 And then MemAlloc/MemFree would be moved.
 

Ultimately this is the route toward
  - writing most/all of ThreadPThread.c in C
  - removing most/all bridging
 

I'm aware it should handle out of memory.
 

 - Jay


Index: ThreadPThread.i3
===================================================================
RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.i3,v
retrieving revision 1.14
diff -u -r1.14 ThreadPThread.i3
--- ThreadPThread.i3 30 Mar 2009 21:52:15 -0000 1.14
+++ ThreadPThread.i3 15 Apr 2009 14:03:58 -0000
@@ -137,20 +137,10 @@
     pthread_mutex_t = ADDRESS;
     pthread_cond_t = ADDRESS;
 
-
-(*CONST*) VAR sizeof_pthread_mutex_t:int;
-
 
 (*CONST*) VAR sizeof_pthread_cond_t:int;
 
 
-PROCEDURE pthread_mutex_init(mutex: pthread_mutex_t; attr:ADDRESS:=NIL):int;
-
-(* This wrapper has some OS-specific bug workarounds. *)
-
-PROCEDURE pthread_mutex_destroy(mutex: pthread_mutex_t):int;
-
-
 PROCEDURE pthread_mutex_lock(mutex: pthread_mutex_t):int;
 
 
@@ -170,4 +160,12 @@
 
 (*---------------------------------------------------------------------------*)
 
+
+PROCEDURE InitMutex (MutexRoot: REFANY; VAR pthread_mutex: pthread_mutex_t);
+
+
+PROCEDURE InitCondition (ConditionRoot: REFANY; VAR pthread_mutex: pthread_mutex_t);
+
+(*---------------------------------------------------------------------------*)
+
 END ThreadPThread.
Index: ThreadPThread.m3
===================================================================
RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v
retrieving revision 1.101
diff -u -r1.101 ThreadPThread.m3
--- ThreadPThread.m3 30 Mar 2009 21:59:31 -0000 1.101
+++ ThreadPThread.m3 15 Apr 2009 14:03:58 -0000
@@ -155,35 +155,13 @@
     m.release ();
   END Release;
 
-PROCEDURE CleanMutex (r: REFANY) =
-  VAR m := NARROW(r, Mutex);
-  BEGIN
-    WITH r = pthread_mutex_destroy (m.mutex) DO  END;
-    MemFree(m.mutex);
-  END CleanMutex;
-
-PROCEDURE InitMutex (m: Mutex) =
-  VAR mutex: pthread_mutex_t;
-  BEGIN
-    TRY
-      WITH r = pthread_mutex_lock_init() DO  END;
-      IF m.mutex # NIL THEN RETURN END;
-      mutex := MemAlloc(sizeof_pthread_mutex_t);
-      WITH r = pthread_mutex_init(mutex) DO  END;
-      m.mutex := mutex;
-    FINALLY
-      WITH r = pthread_mutex_unlock_init() DO  END;
-    END;
-    RTHeapRep.RegisterFinalCleanup (m, CleanMutex);
-  END InitMutex;
-
 PROCEDURE LockMutex (m: Mutex) =
   VAR self := Self();
   BEGIN
     IF self = NIL THEN
       Die(ThisLine(), "LockMutex called from a non-Modula-3 thread");
     END;
-    IF m.mutex = NIL THEN InitMutex(m) END;
+    IF m.mutex = NIL THEN InitMutex(m, m.mutex) END;
     IF perfOn THEN PerfChanged(self.id, State.locking) END;
     WITH r = pthread_mutex_lock(m.mutex) DO
       IF r # 0 THEN
@@ -211,34 +189,12 @@
 
 (*---------------------------------------- Condition variables and Alerts ---*)
 
-PROCEDURE CleanCondition (r: REFANY) =
-  VAR c := NARROW(r, Condition);
-  BEGIN
-    WITH r = pthread_mutex_destroy (c.mutex) DO  END;
-    MemFree(c.mutex);
-  END CleanCondition;
-
-PROCEDURE InitCondition (c: Condition) =
-  VAR mutex: pthread_mutex_t;
-  BEGIN
-    TRY
-      WITH r = pthread_mutex_lock_init() DO  END;
-      IF c.mutex # NIL THEN RETURN END;
-      mutex := MemAlloc(sizeof_pthread_mutex_t);
-      WITH r = pthread_mutex_init(mutex) DO  END;
-      c.mutex := mutex;
-    FINALLY
-      WITH r = pthread_mutex_unlock_init() DO  END;
-    END;
-    RTHeapRep.RegisterFinalCleanup (c, CleanCondition);
-  END InitCondition;
-
 PROCEDURE XWait (self: T; m: Mutex; c: Condition; alertable: BOOLEAN)
   RAISES {Alerted} =
   (* LL = m *)
   VAR next, prev: T;
   BEGIN
-    IF c.mutex = NIL THEN InitCondition(c) END;
+    IF c.mutex = NIL THEN InitCondition(c, c.mutex) END;
     TRY
       
       
@@ -325,7 +281,7 @@
 
 PROCEDURE Signal (c: Condition) =
   BEGIN
-    IF c.mutex = NIL THEN InitCondition(c) END;
+    IF c.mutex = NIL THEN InitCondition(c, c.mutex) END;
     WITH r = pthread_mutex_lock(c.mutex) DO  END;
     IF c.waiters # NIL THEN DequeueHead(c) END;
     WITH r = pthread_mutex_unlock(c.mutex) DO  END;
@@ -333,7 +289,7 @@
 
 PROCEDURE Broadcast (c: Condition) =
   BEGIN
-    IF c.mutex = NIL THEN InitCondition(c) END;
+    IF c.mutex = NIL THEN InitCondition(c, c.mutex) END;
     WITH r = pthread_mutex_lock(c.mutex) DO  END;
     WHILE c.waiters # NIL DO DequeueHead(c) END;
     WITH r = pthread_mutex_unlock(c.mutex) DO  END;
Index: ThreadPThreadC.c
===================================================================
RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThreadC.c,v
retrieving revision 1.19
diff -u -r1.19 ThreadPThreadC.c
--- ThreadPThreadC.c 30 Mar 2009 21:52:15 -0000 1.19
+++ ThreadPThreadC.c 15 Apr 2009 14:03:58 -0000
@@ -250,16 +250,12 @@
 
 MUTEX(active) /* global lock for list of active threads */
 MUTEX(slot)   /* global lock for thread slot table */
-MUTEX(init)   /* global lock for initializers */
 MUTEX(perf)
 MUTEX(heap)
 CONDITION_VARIABLE(heap)
 THREAD_LOCAL(activations)
 
 EXTERN_CONST
-int ThreadPThread__sizeof_pthread_mutex_t = sizeof(pthread_mutex_t);
-
-EXTERN_CONST
 int ThreadPThread__sizeof_pthread_cond_t = sizeof(pthread_cond_t);
 
 int
@@ -271,17 +267,83 @@
     pthread_mutex_destroy() intermittently returns
     EBUSY even when there are no threads accessing the mutex. */
     int e;
-    do
-    {
-        e = pthread_mutex_destroy(mutex);
-    }
-    while (e == EBUSY);
+    while ((e = pthread_mutex_destroy(mutex)) == EBUSY) { }
     return e;
 #else
     return pthread_mutex_destroy(mutex);
 #endif
 }
 
+void RTHeapRep__RegisterFinalCleanup (char* Root, void (*clean)(char*));
+
+/* This should be known at compile-time, but I don't know the Modula-3 object model. */
+size_t M3MutexToPthreadMutex;
+size_t M3ConditionToPthreadMutex;
+
+#define MemAlloc ThreadPThread__MemAlloc
+#define MemFree ThreadPThread__MemFree
+
+void* MemAlloc (size_t size);
+void MemFree (void* a);
+
+static void Common_CleanMutex(char* Root, size_t Offset)
+{
+    pthread_mutex_t** inout_Mutex = (pthread_mutex_t**)(Root + Offset);
+    pthread_mutex_t* Mutex = *inout_Mutex;
+    *inout_Mutex = NULL;
+    if (Mutex != NULL)
+    {
+        ThreadPThread__pthread_mutex_destroy(Mutex);
+        MemFree(Mutex);
+    }
+}
+
+static void CleanCondition(char* Root)
+{
+    Common_CleanMutex(Root, M3ConditionToPthreadMutex);
+}
+
+static void CleanMutex(char* Root)
+{
+    Common_CleanMutex(Root, M3MutexToPthreadMutex);
+}
+
+static void Common_InitMutex(char* Root, pthread_mutex_t** inout_Mutex, size_t* inout_Offset, void (*Clean)(char*))
+{
+    static pthread_mutex_t initMu = PTHREAD_MUTEX_INITIALIZER; /* global lock for initializers */
+    size_t Offset = *inout_Offset;
+
+    if (Offset == 0)
+        *inout_Offset = (((char*)inout_Mutex) - Root);
+    else
+        assert(Offset == (((char*)inout_Mutex) - Root));
+    assert((char*)inout_Mutex>= Root);
+
+    pthread_mutex_lock(&initMu);
+    if (*inout_Mutex == NULL)
+    {
+        pthread_mutex_t* Mutex = (pthread_mutex_t*)calloc(1, sizeof(*Mutex));
+        if (Mutex)
+        {
+            pthread_mutex_init(Mutex, NULL);
+            *inout_Mutex = Mutex;
+        }
+    }
+    pthread_mutex_unlock(&initMu);
+
+    RTHeapRep__RegisterFinalCleanup (Root, Clean);
+}
+
+void ThreadPThread__InitMutex(char* Root, pthread_mutex_t** Mutex)
+{
+    Common_InitMutex(Root, Mutex, &M3MutexToPthreadMutex, CleanMutex);
+}
+
+void ThreadPThread__InitCondition (char* Root, pthread_mutex_t** Mutex)
+{
+    Common_InitMutex(Root, Mutex, &M3ConditionToPthreadMutex, CleanCondition);
+}
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
 
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ThreadPThreadC.c
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090415/294ae4db/attachment-0001.c>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: ThreadPThread.m3
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090415/294ae4db/attachment-0001.ksh>
-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: diff.txt
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090415/294ae4db/attachment-0001.txt>


More information about the M3devel mailing list