[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