[M3devel] fewer wrappers/more C? (or a wash?)
Jay
jay.krell at cornell.edu
Fri Apr 17 23:48:44 CEST 2009
Ok. And the rest/overall?
Usually I'm very certain my "more C code" changes are for the better.
In this case it might be a wash.
REFANY might have some tag bits set?
ADDRESS really is/must-be a direct pointer that us C programmers are familiar with?
UNTRACED REF T would have to be a plain old pointer too right?
- Jay
________________________________
> CC: m3devel at elegosoft.com
> From: hosking at cs.purdue.edu
> To: jay.krell at cornell.edu
> Subject: Re: fewer wrappers/more C? (or a wash?)
> Date: Fri, 17 Apr 2009 22:57:10 +1000
>
> I am a little concerned about passing REFANY directly to C code as there is no guarantee that REFANY and C pointers will always be compatible. ADDRESS can more safely be assumed compatible.
>
> On 16 Apr 2009, at 00:12, Jay wrote:
>
>
> 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
>
>
More information about the M3devel
mailing list