[M3devel] further reducing cloned headers wrt pthread?
Jay
jay.krell at cornell.edu
Mon Feb 2 00:10:17 CET 2009
I meant translate Modula-3 to C -- C because it knows size and alignment.
I didn't presume I could just call malloc.
Even if untraced, I thought calling "the allocator" might
have some positive interaction with the garbage collector.
Maybe not?
(I should look at the code....could be untraced really
does just call malloc and no gc interaction. Oops.)
> array := NEW(UNTRACED REF ARRAY OF CHAR, sizeof_pthread_mutex_t)
That is good. I must have had some hangup about it.
NEW is guaranteed to be "very aligned" so there is no alignment issue here?
> Sure, except that now you smear code across the C and Modula-3
> universes. Lack of clarity...
I agree. I'm conflicted here.
Look at for example at the dealings with "ackSem".
It is a "simple transform" but "transform" is the suspicious
word there, not wholly exonerated by "simple".
The static variables may also have an issue on Darwin -- can't have
non-static variables in a shared object or somesuch. So I'll hold off.
(no access to Darwin past few days)
Solution could be wrapping the variables up in functions, or every
operation on them, like for ackSem. Both kind of not ideal though.
On the other hand, the RTThread / RTThreadStk / ThreadPosix
split is also a bit smearing/unclear -- you know, FreeStack vs. DisposeStack.
But two wrongs don't make a right, I understand.
I do consider the user thread code to be a second class citizen.
>> Why not embed it "by value"?
>
> Because it is difficult to embed by value when the type is opaque.
Why?
I understand issues of "binary compatibility + dynamic linking".
"Pointers are good because they never change size."
"Pointers are good for opaque types because they never change size.
Better than an int because int often can't store a pointer."
But I think we ignore these issues in Modula-3. I know I have been.
> hack
Seemed a good way to generalize what I'm thinking about for pthread/mutex/etc.
- Jay
----------------------------------------
> From: hosking at cs.purdue.edu
> To: jay.krell at cornell.edu
> Date: Mon, 2 Feb 2009 09:54:27 +1100
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] further reducing cloned headers wrt pthread?
>
> 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