<html>
<head>
<style>
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 10pt;
font-family:Verdana
}
</style>
</head>
<body class='hmmessage'>
Hm, nevermind that. More later.<BR>
 <BR>
I think either wrapping it up more in C would be cleaner or even Modula-3 ("Upthread.m3"), than this sort of "split", or at least changing it to ADDRESS and if size <= BYTESIZE(ADDRESS), just use that space and save the heap alloc.<BR>
 <BR>
 <BR>
On systems that already have either a small object or an indirection, save the heap alloc.<BR>
 <BR>
 <BR>
Later,<BR>
 - Jay<BR><BR><BR>

<HR id=stopSpelling>
<BR>
From: jay.krell@cornell.edu<BR>To: m3devel@elegosoft.com<BR>Subject: reducing system-dependence in Upthread.i3?<BR>Date: Thu, 5 Feb 2009 18:11:37 +0000<BR><BR>
<STYLE>
.ExternalClass .EC_hmmessage P
{padding:0px;}
.ExternalClass body.EC_hmmessage
{font-size:10pt;font-family:Verdana;}
</STYLE>
Does this make sense?<BR>It is pushing my Modula-3 knowledge.<BR>I didn't yet check the number of bytes requested by malloc/calloc.<BR>All platforms would have to be changed, not just what is shown here.<BR> <BR> <BR>UNTRACED REF ARRAY OF CHAR is "adequately hard to instantiate", right?<BR> Don't need to resort to ADDRESS?<BR> <BR> <BR>OR should we go the other way and remove the heap allocs?<BR> <BR> <BR>(attached and inline)<BR><BR>Index: src/thread/PTHREAD/ThreadPThread.m3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/thread/PTHREAD/ThreadPThread.m3,v<BR>retrieving revision 1.90<BR>diff -u -r1.90 ThreadPThread.m3<BR>--- src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 09:47:09 -0000 1.90<BR>+++ src/thread/PTHREAD/ThreadPThread.m3 5 Feb 2009 18:04:01 -0000<BR>@@ -24,20 +24,20 @@<BR> <BR>   nextId: CARDINAL := 1;<BR> <BR>-  activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of active threads *)<BR>-  slotMu   := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread slot table *)<BR>-  initMu   := PTHREAD_MUTEX_INITIALIZER; (* global lock for initializers *)<BR>+  activeMu := NewMutex(); (* global lock for list of active threads *)<BR>+  slotMu   := NewMutex(); (* global lock for thread slot table *)<BR>+  initMu   := NewMutex(); (* global lock for initializers *)<BR> <BR> REVEAL<BR>   Mutex = MutexRep.Public BRANDED "Mutex Pthread-1.0" OBJECT<BR>-    mutex: UNTRACED REF pthread_mutex_t := NIL;<BR>+    mutex: pthread_mutex_t := NIL;<BR>   OVERRIDES<BR>     acquire := Acquire;<BR>     release := Release;<BR>   END;<BR> <BR>   Condition = BRANDED "Thread.Condition Pthread-1.0" OBJECT<BR>-    mutex: UNTRACED REF pthread_mutex_t := NIL;<BR>+    mutex: pthread_mutex_t := NIL;<BR>     waiters: T := NIL;    (* LL = mutex *)<BR>   END;<BR> <BR>@@ -58,7 +58,7 @@<BR>     nextWaiter: T := NIL;   (* LL = waitingOn.mutex *)<BR> <BR>     (* condition for blocking during "Wait" *)<BR>-    waitCond: UNTRACED REF pthread_cond_t;<BR>+    waitCond: pthread_cond_t;<BR> <BR>     (* the alert flag *)<BR>     alerted : BOOLEAN := FALSE;   (* LL = mutex *)<BR>@@ -94,6 +94,8 @@<BR>     heapState : RTHeapRep.ThreadState;<BR>   END;<BR> <BR>+(*---------------------------------------------------------------------------*)<BR>+<BR> PROCEDURE SetState (act: Activation;  state: ActState) =<BR>   CONST text = ARRAY ActState OF TEXT<BR>     { "Starting", "Started", "Stopping", "Stopped" };<BR>@@ -108,24 +110,41 @@<BR>     END;<BR>   END SetState;    <BR> <BR>+(*---------------------------------------------------------------------------*)<BR>+<BR>+(* probably move this to Upthread.m3 *)<BR>+PROCEDURE NewMutex(): pthread_mutex_t =<BR>+VAR m := NEW(pthread_mutex_t, Upthread.pthread_mutex_t_size);<BR>+    r := Upthread.mutex_init(m);<BR>+BEGIN<BR>+  <*ASSERT r=0*><BR>+  RETURN m;<BR>+END NewMutex;<BR>+<BR>+(* probably move this to Upthread.m3 *)<BR>+PROCEDURE NewCond(): pthread_cond_t =<BR>+VAR c := NEW(pthread_cond_t, Upthread.pthread_cond_t_size);<BR>+    r := Upthread.cond_init(c);<BR>+BEGIN<BR>+  <*ASSERT r=0*><BR>+  RETURN c;<BR>+END NewCond;<BR>+<BR> (*----------------------------------------------------------------- Mutex ---*)<BR> <BR> PROCEDURE CleanMutex (r: REFANY) =<BR>   VAR m := NARROW(r, Mutex);<BR>   BEGIN<BR>-    WITH r = Upthread.mutex_destroy (m.mutex^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.mutex_destroy (m.mutex) DO <*ASSERT r=0*> END;<BR>     DISPOSE(m.mutex);<BR>   END CleanMutex;<BR> <BR> PROCEDURE InitMutex (m: Mutex) =<BR>-  VAR mutex: UNTRACED REF pthread_mutex_t;<BR>   BEGIN<BR>     TRY<BR>       WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END;<BR>       IF m.mutex # NIL THEN RETURN END;<BR>-      mutex := NEW(UNTRACED REF pthread_mutex_t);<BR>-      WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;<BR>-      m.mutex := mutex;<BR>+      m.mutex := NewMutex();<BR>     FINALLY<BR>       WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END;<BR>     END;<BR>@@ -140,7 +159,7 @@<BR>     END;<BR>     IF m.mutex = NIL THEN InitMutex(m) END;<BR>     IF perfOn THEN PerfChanged(self.id, State.locking) END;<BR>-    WITH r = Upthread.mutex_lock(m.mutex^) DO<BR>+    WITH r = Upthread.mutex_lock(m.mutex) DO<BR>       IF r # 0 THEN<BR>         RTError.MsgI(ThisFile(), ThisLine(),<BR>                      "Thread client error: pthread_mutex_lock error: ", r);<BR>@@ -156,7 +175,7 @@<BR>     IF self = NIL THEN<BR>       Die(ThisLine(), "Release called from a non-Modula-3 thread");<BR>     END;<BR>-    WITH r = Upthread.mutex_unlock(m.mutex^) DO<BR>+    WITH r = Upthread.mutex_unlock(m.mutex) DO<BR>       IF r # 0 THEN<BR>         RTError.MsgI(ThisFile(), ThisLine(),<BR>                      "Thread client error: pthread_mutex_unlock error: ", r);<BR>@@ -169,19 +188,16 @@<BR> PROCEDURE CleanCondition (r: REFANY) =<BR>   VAR c := NARROW(r, Condition);<BR>   BEGIN<BR>-    WITH r = Upthread.mutex_destroy (c.mutex^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.mutex_destroy (c.mutex) DO <*ASSERT r=0*> END;<BR>     DISPOSE(c.mutex);<BR>   END CleanCondition;<BR> <BR> PROCEDURE InitCondition (c: Condition) =<BR>-  VAR mutex: UNTRACED REF pthread_mutex_t;<BR>   BEGIN<BR>     TRY<BR>       WITH r = Upthread.mutex_lock(initMu) DO <*ASSERT r=0*> END;<BR>       IF c.mutex # NIL THEN RETURN END;<BR>-      mutex := NEW(UNTRACED REF pthread_mutex_t);<BR>-      WITH r = Upthread.mutex_init(mutex^, NIL) DO <*ASSERT r=0*> END;<BR>-      c.mutex := mutex;<BR>+      c.mutex := NewMutex();<BR>     FINALLY<BR>       WITH r = Upthread.mutex_unlock(initMu) DO <*ASSERT r=0*> END;<BR>     END;<BR>@@ -198,7 +214,7 @@<BR>       <*ASSERT self.waitingOn = NIL*><BR>       <*ASSERT self.nextWaiter = NIL*><BR>       IF perfOn THEN PerfChanged(self.id, State.waiting) END;<BR>-      WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+      WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END;<BR>       BEGIN<BR>         self.waitingOn := c;<BR>         next := c.waiters;<BR>@@ -211,10 +227,10 @@<BR>           prev.nextWaiter := self;<BR>         END;<BR>       END;<BR>-      WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+      WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END;<BR>       IF alertable AND XTestAlert(self) THEN RAISE Alerted; END;<BR>       LOOP<BR>-        WITH r = Upthread.cond_wait(self.waitCond^, m.mutex^) DO<BR>+        WITH r = Upthread.cond_wait(self.waitCond, m.mutex) DO<BR>           IF r # 0 THEN<BR>             RTError.MsgI(ThisFile(), ThisLine(),<BR>                          "Thread client error: pthread_cond_wait error ", r);<BR>@@ -224,7 +240,7 @@<BR>         IF self.waitingOn = NIL THEN RETURN END;<BR>       END;<BR>     FINALLY<BR>-      WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+      WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END;<BR>       IF self.waitingOn # NIL THEN<BR>         <*ASSERT self.waitingOn = c*><BR>         (* alerted: dequeue from condition *)<BR>@@ -240,7 +256,7 @@<BR>         self.nextWaiter := NIL;<BR>         self.waitingOn := NIL;<BR>       END;<BR>-      WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+      WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END;<BR>       IF perfOn THEN PerfRunning(self.id) END;<BR>       <*ASSERT self.waitingOn = NIL*><BR>       <*ASSERT self.nextWaiter = NIL*><BR>@@ -275,23 +291,23 @@<BR>     t := c.waiters; c.waiters := t.nextWaiter;<BR>     t.nextWaiter := NIL;<BR>     t.waitingOn := NIL;<BR>-    WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END;<BR>   END DequeueHead;<BR> <BR> PROCEDURE Signal (c: Condition) =<BR>   BEGIN<BR>     IF c.mutex = NIL THEN InitCondition(c) END;<BR>-    WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END;<BR>     IF c.waiters # NIL THEN DequeueHead(c) END;<BR>-    WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END;<BR>   END Signal;<BR> <BR> PROCEDURE Broadcast (c: Condition) =<BR>   BEGIN<BR>     IF c.mutex = NIL THEN InitCondition(c) END;<BR>-    WITH r = Upthread.mutex_lock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.mutex_lock(c.mutex) DO <*ASSERT r=0*> END;<BR>     WHILE c.waiters # NIL DO DequeueHead(c) END;<BR>-    WITH r = Upthread.mutex_unlock(c.mutex^) DO <*ASSERT r=0*> END;<BR>+    WITH r = Upthread.mutex_unlock(c.mutex) DO <*ASSERT r=0*> END;<BR>   END Broadcast;<BR> <BR> PROCEDURE Alert (t: T) =<BR>@@ -299,7 +315,7 @@<BR>     LOCK t DO<BR>       t.alerted := TRUE;<BR>       IF t.waitCond # NIL THEN<BR>-        WITH r = Upthread.cond_signal(t.waitCond^) DO <*ASSERT r=0*> END;<BR>+        WITH r = Upthread.cond_signal(t.waitCond) DO <*ASSERT r=0*> END;<BR>       END;<BR>     END;<BR>   END Alert;<BR>@@ -480,8 +496,7 @@<BR>      which will try to acquire "activeMu". *)<BR>   VAR t := NEW(T, act := act);<BR>   BEGIN<BR>-    t.waitCond := NEW(UNTRACED REF pthread_cond_t);<BR>-    WITH r = Upthread.cond_init (t.waitCond^, NIL) DO <*ASSERT r=0*> END;<BR>+    t.waitCond := NewCond();<BR>     t.cond     := NEW(Condition);<BR>     FloatMode.InitThread (act.floatState);<BR>     AssignSlot (t);<BR>@@ -533,7 +548,7 @@<BR>       (* mark "self" done and clean it up a bit *)<BR>       self.completed := TRUE;<BR>       Broadcast(self.cond); (* let everybody know that "self" is done *)<BR>-      WITH r = Upthread.cond_destroy(self.waitCond^) DO <*ASSERT r=0*> END;<BR>+      WITH r = Upthread.cond_destroy(self.waitCond) DO <*ASSERT r=0*> END;<BR>       DISPOSE(self.waitCond);<BR>     END;<BR> <BR>Index: src/unix/Common/Uconstants.c<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Uconstants.c,v<BR>retrieving revision 1.15<BR>diff -u -r1.15 Uconstants.c<BR>--- src/unix/Common/Uconstants.c 3 Feb 2009 23:06:42 -0000 1.15<BR>+++ src/unix/Common/Uconstants.c 5 Feb 2009 18:04:01 -0000<BR>@@ -105,10 +105,14 @@<BR> <BR> #undef X<BR> #define X(type, x) const type Upthread_##x = x;<BR>+#undef Y<BR>+#define Y(x, y) const size_t Upthread_##x = y;<BR> <BR> X(pthread_mutex_t, PTHREAD_MUTEX_INITIALIZER)<BR> X(pthread_cond_t, PTHREAD_COND_INITIALIZER)<BR>-<BR>+<BR>+Y(pthread_mutex_t_size, sizeof(pthread_mutex_t))<BR>+Y(pthread_cond_t_size, sizeof(pthread_cond_t))<BR> <BR> #undef X<BR> #define X(x) const int Usocket_##x = x;<BR>Index: src/unix/Common/Upthread.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/Common/Upthread.i3,v<BR>retrieving revision 1.4<BR>diff -u -r1.4 Upthread.i3<BR>--- src/unix/Common/Upthread.i3 5 Feb 2009 09:47:09 -0000 1.4<BR>+++ src/unix/Common/Upthread.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -7,11 +7,15 @@<BR> FROM Ctypes IMPORT int;<BR> FROM Utypes IMPORT size_t;<BR> IMPORT Usysdep;<BR>+<BR>+(*CONST*)<BR>+<*EXTERNAL "Upthread_pthread_mutex_t_size"*> VAR pthread_mutex_t_size: size_t;<BR>+<*EXTERNAL "Upthread_pthread_cond_t_size"*> VAR pthread_cond_t_size: size_t;<BR> <BR> TYPE<BR>   pthread_t = Usysdep.pthread_t;<BR>-  pthread_mutex_t = Usysdep.pthread_mutex_t;<BR>-  pthread_cond_t = Usysdep.pthread_cond_t;<BR>+  pthread_mutex_t = UNTRACED REF ARRAY OF CHAR;<BR>+  pthread_cond_t = UNTRACED REF ARRAY OF CHAR;<BR>   pthread_key_t = Usysdep.pthread_key_t;<BR> <BR>   destructor_t = PROCEDURE(arg: ADDRESS);<BR>Index: src/unix/cygwin/Usysdep.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/cygwin/Usysdep.i3,v<BR>retrieving revision 1.13<BR>diff -u -r1.13 Usysdep.i3<BR>--- src/unix/cygwin/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.13<BR>+++ src/unix/cygwin/Usysdep.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -28,8 +28,6 @@<BR> (* INTERFACE Upthread; *)<BR> <BR>   pthread_t = ADDRESS; (* opaque *)<BR>-  pthread_mutex_t = ADDRESS; (* opaque *)<BR>-  pthread_cond_t = ADDRESS; (* opaque *)<BR>   pthread_key_t = ADDRESS; (* opaque *)<BR> <BR> (* INTERFACE Usocket; *)<BR>Index: src/unix/darwin-common/Usysdep.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/darwin-common/Usysdep.i3,v<BR>retrieving revision 1.3<BR>diff -u -r1.3 Usysdep.i3<BR>--- src/unix/darwin-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.3<BR>+++ src/unix/darwin-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -20,8 +20,6 @@<BR> (* INTERFACE Upthread; *)<BR> <BR>   pthread_t = INTEGER; (* opaque *)<BR>-  pthread_mutex_t = RECORD opaque: ARRAY [1..11] OF INTEGER; END;<BR>-  pthread_cond_t = RECORD opaque: ARRAY [1..7] OF INTEGER; END;<BR>   pthread_key_t = INTEGER; (* opaque *)<BR> <BR> (* INTERFACE Usocket; *)<BR>Index: src/unix/freebsd-common/Usysdep.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/freebsd-common/Usysdep.i3,v<BR>retrieving revision 1.6<BR>diff -u -r1.6 Usysdep.i3<BR>--- src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.6<BR>+++ src/unix/freebsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -22,8 +22,6 @@<BR> (* INTERFACE Upthread; *)<BR> <BR>   pthread_t = ADDRESS;<BR>-  pthread_mutex_t = ADDRESS;<BR>-  pthread_cond_t = ADDRESS;<BR>   pthread_key_t = int;<BR> <BR> (* INTERFACE Usocket; *)<BR>Index: src/unix/linux-common/Usysdep.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/linux-common/Usysdep.i3,v<BR>retrieving revision 1.11<BR>diff -u -r1.11 Usysdep.i3<BR>--- src/unix/linux-common/Usysdep.i3 5 Feb 2009 09:47:10 -0000 1.11<BR>+++ src/unix/linux-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -21,8 +21,6 @@<BR> (* INTERFACE Upthread; *)<BR> <BR>   pthread_t = ADDRESS;<BR>-  pthread_mutex_t = Upthreadtypes.pthread_mutex_t;<BR>-  pthread_cond_t = RECORD data: ARRAY[1..6] OF LONGINT; END;<BR>   pthread_key_t = uint32_t;<BR> <BR> (* INTERFACE Usocket; *)<BR>Index: src/unix/openbsd-common/Usysdep.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/openbsd-common/Usysdep.i3,v<BR>retrieving revision 1.12<BR>diff -u -r1.12 Usysdep.i3<BR>--- src/unix/openbsd-common/Usysdep.i3 21 Jan 2009 15:25:13 -0000 1.12<BR>+++ src/unix/openbsd-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -21,8 +21,6 @@<BR> <BR>   pthread_t = ADDRESS;<BR>   pthread_attr_t = ADDRESS;<BR>-  pthread_mutex_t = ADDRESS;<BR>-  pthread_cond_t = ADDRESS;<BR>   pthread_key_t = int;<BR> <BR> (* INTERFACE Usocket; *)<BR>Index: src/unix/solaris-common/Usysdep.i3<BR>===================================================================<BR>RCS file: /usr/cvs/cm3/m3-libs/m3core/src/unix/solaris-common/Usysdep.i3,v<BR>retrieving revision 1.4<BR>diff -u -r1.4 Usysdep.i3<BR>--- src/unix/solaris-common/Usysdep.i3 5 Feb 2009 09:47:11 -0000 1.4<BR>+++ src/unix/solaris-common/Usysdep.i3 5 Feb 2009 18:04:01 -0000<BR>@@ -24,8 +24,6 @@<BR> (* INTERFACE Upthread; *)<BR> <BR>     pthread_t = int32_t; (* opaque *)<BR>-    pthread_mutex_t = RECORD opaque: ARRAY [1..4] OF LONGINT; END; (* 32 bytes with 64 bit alignment *)<BR>-    pthread_cond_t = RECORD opaque: ARRAY [1..2] OF LONGINT; END; (* 16 bytes with 64 bit alignment *)<BR>     pthread_key_t = int32_t; (* opaque *)<BR> <BR> (* INTERFACE Usocket; *)<BR><BR><BR><BR></body>
</html>