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

Tony Hosking hosking at cs.purdue.edu
Fri Apr 17 14:57:10 CEST 2009


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
> <ThreadPThreadC.c><ThreadPThread.m3><diff.txt>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20090417/a349c889/attachment-0002.html>


More information about the M3devel mailing list