[M3devel] Re: [M3commit] CVS Update: cm3
Tony Hosking
hosking at cs.purdue.edu
Sun Jan 7 16:18:18 CET 2007
On Jan 7, 2007, at 12:36 AM, j k wrote:
>
> > Why would you expect the system-native thread creator to be able to
> > create a Modula-3 thread, given that the Modula-3 run-time system
> needs to
> > know about the threads to be GC'd. I think it is entirely fair
> that
> > the M3 run-time system know about the threads that are running
> M3 code.
>
> It would be a nice interoperability feature, for "native" code to
> call Modula-3 code and have it "just work".
> I understand that it might not be easy/doable.
>
> DllMain(thread attach) in Win32 makes it a little more doable but
> still not /always/ trivial.
>
> Given that the .exe staticaly directly or indirectly depends on
> Modula-3 code,
> and not using build_standalone(), then m3core.dll will get notified
> of all thread creations
> and no special thread creater needs to be called.
>
> I have in mind a relatively loosely coupled world, where, say,
> Modula-3 might be little used
> in a process, but say some sort of "plugin" might use it.
>
> In such a loosely coupled world, no special thread creation
> function can be agreed up except
> most likely CreateThread (there are others below it --
> NtCreateThread, and there are fibers,
> both bring back this problem)
>
> Such a loosely coupled system doesn't work today because m3core.dll
> might not be loaded until "late".
>
> However, at some cost, what could happen is Modula-3 code could
> "often" check if it has ever
> run on this thread and if not do the initialization on demand.
> "Often" could be limited to every time
> a garbage collected allocation gets done. That may or may not be a
> significant cost.
Yes, I imagine we could come up with something like this for all
targets (win32 and posix).
>
> Most libraries do not foist their custom thread creator on you.
>
> > Possible a "double check" is ok:
> > This is probably not safe either, since double-check will fail
> for relaxed memory orderings on some SMPs
>
> Oh, I forgot:
>
> Isn't enter/leave critical section considered a full memory barrier/
> fence/whatever?
Yes, it is.
> Therefore the second read initActivation is guaranteed to not be
> cached by the compiler/linker?
Yes, so one would need a second check as you propose below.
> On Win32 I am pretty darn sure and it makes writing such code a
> fair amount easier.
> If you want, you can
>
> >> full memory barrie
>
> if initActivations
> enter critical section
> >> MemoryBarrier
> if initActivations
> ...
> initActivations = true;
> >> MemoryBarrier
> end
> leave critical section
>
> Win32 has a relatively recent addition -- "MemoryBarrier".
> It is always inlined and varies per-processor. On x86 it is just an
> arbitrary interlocked operation I think.
> On other processors it is a special instruction.
> Does Modula-3 have an equivalent?
I would hate to expose a memory barrier operation to the programmer
in that way. Ideally, we would come up with a memory model for
Modula-3 along the lines of that for Java, where use of the thread
synchronization primitives of Modula-3 produces well-defined memory
orderings among threads. We have behavior like that currently simply
by virtue of use of the pthread and win32 thread primitives in the
implementation of Modula-3 thread primitives, which impose memory
barriers, so everything should work "as expected" for now on most SMPs.
>
> - Jay
>
>
>> From: Tony Hosking <hosking at cs.purdue.edu>
>> To: j k <jayk123 at hotmail.com>
>> CC: wagner at elegosoft.com, jkrell at birch.elego.de,
>> m3devel at elegosoft.com
>> Subject: Re: [M3devel] Re: [M3commit] CVS Update: cm3
>> Date: Sat, 6 Jan 2007 15:47:05 -0500
>>
>>
>> On Jan 3, 2007, at 8:57 PM, j k wrote:
>>
>>> I didn't look at the history for how the recursion got there.
>>> I didn't put it in.
>>> It was definitely there and as it was, ANY attempt to run ANY
>>> Modula-3 code would crash in startup due to infinite recursion,
>>> stack overflow.
>>>
>>> For the critical sections I just did a local analysis within the
>>> file which
>>> proved adequate to me. You can see fairly readily what are local
>>> variables and what are gobals.
>>>
>>> There is a global linked list and the critical sections are used
>>> to protect it. But you can set up a local before putting it on
>>> the list without the critical section.
>>>
>>> The shorter time you are in a critical section, the better.
>>>
>>> The critical sections are still overused or underused, in the
>>> pthread code too.
>>>
>>> Consider this pthread code:
>>>
>>> PROCEDURE GetActivation (): Activation =
>>> (* If not the initial thread and not created by Fork, returns
>>> NIL *)
>>> (* LL = 0 *)
>>> BEGIN
>>> IF initActivations THEN InitActivations() END;
>>> RETURN LOOPHOLE(Upthread.getspecific(activations), Activation);
>>> END GetActivation;
>>>
>>>
>>> PROCEDURE InitActivations () =
>>> VAR me := NEW(Activation);
>>> BEGIN
>>> WITH r = Upthread.key_create(activations, NIL) DO <*ASSERT
>>> r=0*> END;
>>> WITH r = Upthread.setspecific(activations, me) DO <*ASSERT
>>> r=0*> END;
>>> WITH r = Upthread.mutex_lock(activeMu) DO <*ASSERT r=0*> END;
>>> <* ASSERT allThreads = NIL *>
>>> me.handle := Upthread.self();
>>> me.next := me;
>>> me.prev := me;
>>> allThreads := me;
>>> initActivations := FALSE;
>>> WITH r = Upthread.mutex_unlock(activeMu) DO <*ASSERT r=0*> END;
>>> END InitActivations;
>>>
>>> The critical section might need to be expanded to encompass the
>>> "initActivations" variable.
>>>
>>> Possible a "double check" is ok:
>>> if initActivations
>>> enter critical section
>>> if initActivations
>> This is probably not safe either, since double-check will fail
>> for relaxed memory orderings on some SMPs.
>>> In Win32 you can probably get by with a simple spin lock using
>>> InterlockedIncrement.
>>> Does pthreads have that?
>> Need to look into this even for ThreadPosix.m3.
>>> In Vista a "once" would be appropriate. I believe pthreads has
>>> those too.
>> Yes, pthreads has "once".
>>> Use of simple booleans to implement "onces" is often done
>>> incorrectly.
>>>
>>> The critical section does not need to cover the lines:
>>> me.next = me;
>>> me.prev = me;
>>> me.handle = Upthread.self();
>>
>> Indeed.
>>> If this all is in some "startup" code that provides its own
>>> serialization, then more of this is unnecessary.
>>> For example on Windows this should be in m3core.dll's DllMain
>>> (process startup). It probably already is. I'd have to check.
>>>
>>> Putting it in main is just about adequate, except that
>>> someone's .dll's DllMain(process startup) could create a thread
>>> that ends up in Modula-3 code. (There is the assertion about
>>> being created by Fork, which is unfortunate -- I should be able
>>> to use Modula-3 .dlls from non-Modula-3 code and I should be
>>> able to create threads with the system-native thread creater,
>>> CreateThread on Windows. Having to go through custom functions
>>> to create threads is not good. It requires more control of the
>>> system than you often have -- imagine for example providing a
>>> COM object implemented in Modula-3...)
>> Why would you expect the system-native thread creator to be able
>> to create a Modula-3 thread, given that the Modula-3 run-time
>> system needs to know about the threads to be GC'd. I think it is
>> entirely fair that the M3 run-time system know about the threads
>> that are running M3 code.
>>> It'd be nice to not roll custom linked lists btw, and then for
>>> there to be a generic ThreadSafeList or such.
>>>
>>> - Jay
>>>
>>>
>>>
>>> From: "Olaf Wagner" <wagner at elegosoft.com>
>>> To: jkrell at birch.elego.de
>>> CC: m3devel at elegosoft.com
>>> Subject: [M3devel] Re: [M3commit] CVS Update: cm3
>>> Date: Wed, 3 Jan 2007 16:38:05 +0100 (CET)
>>> >
>>> >On Sat, December 30, 2006 3:18 am, Jay Krell wrote:
>>> > > CVSROOT: /usr/cvs
>>> > > Changes by: jkrell at birch. 06/12/30 02:18:06
>>> > >
>>> > > Modified files:
>>> > > cm3/m3-libs/m3core/src/thread/WIN32/: ThreadWin32.m3
>>> > >
>>> > > Log message:
>>> > > important: fix infinite recursion in Win32 startup
>>> > > correct check for TlsAlloc failure (TLS_OUT_OF_INDEXES
>>> instead of < 0)
>>> > > reduce critical sections slightly (esp. to avoid calling out
>>> while in a
>>> > > critical section, including to DuplicateHandle,
>>> CreateThread, VirtualQuery)
>>> >
>>> >I would like to understand this change better (especially the
>>> first item),
>>> >or at least how/why and endless recursion got into the source
>>> (as older
>>> >versions have run, haven't they?).
>>> >
>>> >As for critical sections, you seem to have remove one completely
>>> and
>>> >reduced another. Are you sure that is correct? (I've only had a
>>> short
>>> >look at the diff, and haven't got a comprehensive understanding
>>> of the
>>> >CM3 WIN32 runtime currently.)
>>> >
>>> >Olaf
>>> >--
>>> >Olaf Wagner
>>> >elego Software Solutions GmbH, Berlin, Germany
>>> >_______________________________________________
>>> >M3devel mailing list
>>> >M3devel at elegosoft.com
>>> >https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>>>
>>> Fixing up the home? Live Search can help
>>> _______________________________________________
>>> M3devel mailing list
>>> M3devel at elegosoft.com
>>> https://mail.elegosoft.com/cgi-bin/mailman/listinfo/m3devel
>>
>> Antony Hosking | Associate Professor
>> Dept of Computer Science | Office: +1 765 494-6001
>> Purdue University | Mobile: +1 765 427-5484
>> 250 N. University Street | Email: hosking at cs.purdue.edu
>> West Lafayette, IN 47907-2066 | http://www.cs.purdue.edu/~hosking
>> _--_|\
>> / \
>> \_.--._/ )
>> v /
>>
>>
>>
>
> _________________________________________________________________
> Get live scores and news about your team: Add the Live.com Football
> Page www.live.com/?addtemplate=football&icid=T001MSN30A0701
Antony Hosking | Associate Professor
Dept of Computer Science | Office: +1 765 494-6001
Purdue University | Mobile: +1 765 427-5484
250 N. University Street | Email: hosking at cs.purdue.edu
West Lafayette, IN 47907-2066 | http://www.cs.purdue.edu/~hosking
_--_|\
/ \
\_.--._/ )
v /
More information about the M3devel
mailing list