[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