[M3devel] thread calls on non-modula3 threads, win32 vs. posix

Jay K jay.krell at cornell.edu
Mon Sep 27 05:26:22 CEST 2010


Tony, I don't know, but sometimes I think you are too unforgiving of unsafe code.
I guess in this case though it will null deref soon enough, and that is highly similar to anything else we might do.
 
 
I have another take on things, not easy to achieve currently.
 
 
That is, I should be able to write "some" program, any program, in C or C++, with an "extensibility model" -- where it can load .dlls discovered through some mechanism, not know that initial authoring/compile/link-time, and those .dlls should work whether they use C and/or C++ and/or Modula-3.
 
 
I should be able to create threads using the native Win32 CreateThread or pthread_create.
I shouldn't have to call Modula-3's Thread.Fork.
 
 
This reality already exists for C and C++.
But it isn't easy to achieve for Modula-3.
Currently we basically divide the world between Modula-3 code and other code.
They don't interact as well as they should.
At least not in both directions.
I can call C from Modula-3 just fine and use C/C++ on Modula-3 threads.
But not the other way around.
 
 
(There is an indication of a counterpoint, the existance of _beginthread/_beginthreadex suggests that C has the same problem, that native CreateThread won't do there either, but this is almost entirely false. _beginthread has no advantage over CreateThread if the caller is a .dll or if it uses the C runtime in a .dll, as the C runtime manages its thread locals in DllMain and on-demand. It makes some difference if you use the static C runtime (which is discouraged) and are in an .exe.)
 
 
Partly I'm alluding to two different design principles:
 sort of more static, monolithic, where more stuff is known at build-time
  Every initialization function called from a central place that knows to coordinate and knows what call to call.
 
  vs. a more distributed dynamic construction where anyone can declare they have initialization and it discovered and called as needed
 
 
 In reality these are kind of the same. It's just that on both Windows and all/most Posix systems there already exists a central dynamic mechanism available to C and Modula-3, but Modula-3 doesn't use it.
 
  Specifically on Windows this is DllMain. C++ has these things, globals with constructors/destructors. You can have them in a .dll. They tie into DllMain.
 
 
  C++ has these everywhere and the problem is solved some way everywhere.
  I believe typical ELF systems use .init/.fini ELF sections, similar to how C++ constructors/destructors work -- section is an array of pointers that some special code knows to call at the right time.
 
 
Very possible Modula-3 should use these mechanisms.
However it is somewhat of a portability nightmare.
By doing things itsself, Modula-3 gets *almost* as good functionality, with one portable implementation.
Kind of like the $ORIGIN stuff.
 
 
 - Jay


----------------------------------------
> From: hosking at cs.purdue.edu
> Date: Sun, 26 Sep 2010 10:20:27 -0400
> To: jay.krell at cornell.edu
> CC: m3devel at elegosoft.com
> Subject: Re: [M3devel] thread calls on non-modula3 threads, win32 vs. posix
>
> We don't need the checks. If someone calls from native threads to M3 threads they are programming "UNSAFE"ly anyway, and will have to pay the piper. We could consider an UNSAFE interface that allows native threads to register themselves for GC, etc. But this would only be for super-hackers.
>
> On 26 Sep 2010, at 09:59, Jay K wrote:
>
> >
> > Understood -- that is seemingly the point of the Win32 checks. Should they be present on Posix then too?
> >
> > Merely hitting "TRY" I expect would access violate.
> >
> > - Jay
> >
> > ----------------------------------------
> >> From: hosking at cs.purdue.edu
> >> Date: Sun, 26 Sep 2010 09:56:29 -0400
> >> To: jay.krell at cornell.edu
> >> CC: m3devel at elegosoft.com
> >> Subject: Re: [M3devel] thread calls on non-modula3 threads, win32 vs. posix
> >>
> >> In general that would be dangerous. If it is a thread not created by Modula-3 Thread.Fork then how will we have the machinery to stop it for GC so its roots can be scanned. In principle, native threads are untraced, whereas M3 threads are traced. Untraced things are not allowed to refer to traced things.
> >>
> >> On 26 Sep 2010, at 09:51, Jay K wrote:
> >>
> >>>
> >>> What is supposed to happen if you call into Modula-3 code on a non-Modula-3 thread?
> >>>
> >>> - Jay
> >>>
> >>> ----------------------------------------
> >>>> From: hosking at cs.purdue.edu
> >>>> Date: Sun, 26 Sep 2010 09:13:09 -0400
> >>>> To: jay.krell at cornell.edu
> >>>> CC: m3devel at elegosoft.com
> >>>> Subject: Re: [M3devel] thread calls on non-modula3 threads, win32 vs. posix
> >>>>
> >>>> Why does a native thread need M3-supported thread locals? The idea is to keep native and M3 threads separate, right?
> >>>>
> >>>> On 26 Sep 2010, at 08:21, Jay K wrote:
> >>>>
> >>>>>
> >>>>> I think it is problematic in both.
> >>>>> If I understand you.
> >>>>>
> >>>>>
> >>>>> The thread locals could be allocated on-demand which might
> >>>>> address some situations. Though that can also fail.
> >>>>>
> >>>>>
> >>>>> A reasonable seeming place to allocate thread locals is m3core.DllMain(thread attach).
> >>>>> That even allows you to fail (due to low memory).
> >>>>> However that doesn't work as well as one might hope.
> >>>>> In particular, any number of threads can be created before a particular .dll is loaded.
> >>>>> And a .dll can be unloaded while the threads still exist -- making also thread detach
> >>>>> not so ideal for freeing. What you have to do is:
> >>>>> - be willing to allocate on demand
> >>>>> - have some story for failure
> >>>>> - track all the thread locals through a global (!) and free them in thread/process detach
> >>>>> (but note that there are two .dll unload scenarios: FreeLibrary and ExitProcess;
> >>>>> there is a parameter that distinguishes them; best to do nothing, quickly in
> >>>>> the ExitProcess).
> >>>>>
> >>>>>
> >>>>> Best really really really really best to avoid thread locals.
> >>>>> But that is probably impossible.
> >>>>>
> >>>>>
> >>>>> Cygwin does wacky stuff where it puts its thread locals at the top of the stack.
> >>>>> Which doesn't solve the problems.
> >>>>>
> >>>>>
> >>>>> - Jay
> >>>>>
> >>>>> ----------------------------------------
> >>>>>> From: hosking at cs.purdue.edu
> >>>>>> Date: Sat, 25 Sep 2010 10:32:21 -0400
> >>>>>> To: jay.krell at cornell.edu
> >>>>>> CC: m3devel at elegosoft.com
> >>>>>> Subject: Re: [M3devel] thread calls on non-modula3 threads, win32 vs. posix
> >>>>>>
> >>>>>> Is it ok in the WIn32 implementation for the thread to be native.
> >>>>>> I think it is ok for pthread.
> >>>>>>
> >>>>>> On 25 Sep 2010, at 05:35, Jay K wrote:
> >>>>>>
> >>>>>>>
> >>>>>>> PROCEDURE AlertWait (m: Mutex; c: Condition) RAISES {Alerted} =
> >>>>>>> (* LL = m *)
> >>>>>>> VAR self := GetActivation();
> >>>>>>> BEGIN
> >>>>>>> IF DEBUG THEN ThreadDebug.AlertWait(m, c); END;
> >>>>>>> IF self = NIL THEN Die(ThisLine(), "AlertWait called from non-Modula-3 thread") END;
> >>>>>>> XWait(m, c, self, alertable := TRUE);
> >>>>>>> END AlertWait;
> >>>>>>>
> >>>>>>>
> >>>>>>> The pthread code doesn't have the check for NIL and call to Die.
> >>>>>>> Nor for that matter, the uses of ThreadDebug -- which I added.
> >>>>>>>
> >>>>>>> I think these should be more similar.
> >>>>>>>
> >>>>>>> What I was really wondering about, again, is more common code between Win32 and Posix
> >>>>>>> in the thread code...
> >>>>>>>
> >>>>>>> - Jay
> >>>>>>>
> >>>>>>
> >>>>>
> >>>>
> >>>
> >>
> >
> 		 	   		  


More information about the M3devel mailing list