<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>