[M3devel] further reducing cloned headers wrt pthread?

Tony Hosking hosking at cs.purdue.edu
Sun Feb 1 23:54:27 CET 2009


On 2 Feb 2009, at 01:44, Jay wrote:

> I'd like to consider further reducing "system dependent cloned  
> headers".
> Upthread.i3 in particular.
>
>
> We have for example:
>
>
>  pthread_mutex_t = ARRAY[1..6] OF INTEGER;
>
>
> Now, pthread_mutex_t is used in two ways.
>
>
> Some statically allocated variables:
>
>
> VAR
>  activeMu := PTHREAD_MUTEX_INITIALIZER; (* global lock for list of  
> active threads *)
>  slotMu   := PTHREAD_MUTEX_INITIALIZER; (* global lock for thread  
> slot table *)
>  initMu   := PTHREAD_MUTEX_INITIALIZER; (* global lock for  
> initializers *)
>
>
> Some untraced heap allocated variables:
>
>
> PROCEDURE InitMutex (m: Mutex) =
>  VAR mutex: UNTRACED REF pthread_mutex_t;
>  BEGIN
>    TRY
>      WITH r = Upthread.mutex_lock(initMu) DO  END;
>      IF m.mutex # NIL THEN RETURN END;
>      mutex := NEW(UNTRACED REF pthread_mutex_t);
>      WITH r = Upthread.mutex_init(mutex^, NIL) DO  END;
>      m.mutex := mutex;
>    FINALLY
>      WITH r = Upthread.mutex_unlock(initMu) DO  END;
>    END;
>    RTHeapRep.RegisterFinalCleanup (m, CleanMutex);
>  END InitMutex;
>
>
> The statically allocated variables can just be moved to C, trivial.
> And their initialization then kept efficient.

Sure, except that now you smear code across the C and Modula-3  
universes.  Lack of clarity...

> What is the right way to translate the untraced allocation?

Not sure what you mean by "translate".  We are writing Modula-3 in  
Modula-3 here, so why translate it?  I suppose you could invoke some C  
code to allocate the mutex and return it, but then you have a call to  
malloc that might not play nice with the Modula-3 code.  In the old  
days this was certainly the case (on user-level thread systems we need  
malloc to be atomic with respect to thread transfer).  Thus,  
NEW(UNTRACED REF ...) does bottom out at malloc, but  
RTAllocator.GetUntracedRef invokes DisableSwitching/EnableSwitching  
around the call to malloc (these disable switching on user-thread  
platforms, but are no-ops on system threading platforms where malloc  
should already be thread-safe).  How about simply having some C  
variable that records sizeof(pthread_mutex_t) and use that in a call  
to new:

array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t)
mutex := ADR(array[0])

> OR, here is kind of the opposite question:
>
>
> Why is the mutex heap allocated anyway?
>
> Why not embed it "by value"?

Because it is difficult to embed by value when the type is opaque.

> Granted, that makes it more difficult to smush out platform- 
> specificity.

Indeed.

And the rest of what you say here is a pretty disgusting hack.   
Modula-3 has pretty clean type semantics and you are compromising that  
in a rather gross way.

>
> And then to address that:
>
>
> I would kind of like the idea of an "extern type".
> An extern type is a type whose instances may only be embedded within  
> heap allocated objects,
> possibly only at the end, possibly with an implied  
> alignment=maximum, their size
> would be exposed via constant C variable, probably they would have a  
> designated initialization
> function, or be zeroed. They could also be "standalone" heap  
> allocated objects.
>
>
> Specifically, something like this:
>
>
> TYPE pthread_t;
>
>
> TYPE Thread.T = RECORD
>  (* Modula-3 stuff *)
>  pthread: pthread_t;
> END;
> Thread := NEW(Thread.T);
>
>
> roughly equiv to
> Thread = malloc(offsetof(Thread.T, pthread_t) + sizeof(pthread_t));
>
>
> pthread.c:
>
>
> extern const size_t pthread_t_size = sizeof(pthread_t);
>
>
> You know -- so that they can be implemented "portably".
> Given that they are already opaque and all the Modula-3 code knows
> is their size, alignment, and what functions they can be passed to.
>
>
> - Jay




More information about the M3devel mailing list