[M3devel] pthread/Interix

Jay K jay.krell at cornell.edu
Wed Dec 16 17:49:52 CET 2009


Signals are handled by a separate thread suspending the target thread and setting the context to run the signal handler. Therefore the state is on that thread's stack, not discoverable.

 

There is only single parameter signal handlers.

 

Normally we could suspend/resume the thread "directly" but the thread is I think created by an outside process and we don't have sufficient access. There is a handle with sufficient access, used by that signal handling thread, but it isn't accessible either.

That is what is particularly unfortunate.

 

I think putting the two files in unconditionally and passing to the various functions, plus one other #ifdefed function "OpenInterixFiles" is a reasonable compromise. I've coded it up, haven't compiled/tested yet.

 

An improvement would be to use the (normally) zero sized record and pass that to the C code instead, not wasting the storage on othe platforms.

 

(A direct suspend/resume/getcontext solution will be good for Cygwin I'm sure.)

 

 - Jay

 


Subject: Re: pthread/Interix
From: hosking at cs.purdue.edu
Date: Wed, 16 Dec 2009 11:40:56 -0500
CC: m3devel at elegosoft.com
To: jay.krell at cornell.edu

I really dislike this... just for a broken platform...






Is there really no way to know that the context on is not on the stack somewhere?


On 16 Dec 2009, at 10:36, Jay K wrote:


[again, expect a bounce, but the mail does get through]
 
 
Tony, for Interix, suspend/resume thread can be achieved writing to a file.
Getting a suspended thread's registers can be gotten reading from a file.
(I believe the same thing works on Solaris.)
It appears to be intended for debuggers.
I can see that it works well.
I doubt that a thread's context is on a signal handler's stack.
I propose:
 
 
  ActState = { Starting, Started, Stopping, Stopped };
  REVEAL Activation = UNTRACED BRANDED REF RECORD
    frame: ADDRESS := NIL;              (* exception handling support *)
    handle: pthread_t := NIL;           (* LL = activeMu; thread handle *)
    statusFile: int := -1;              (* for Interix *)
    controlFile: int := -1;             (* for Interix *)
    (* C code knows the structure above this point *)
...
  END;

 
ThreadPThread.h:
 
 
typedef struct _Activation_t {
    void* frame;
    void* pthread;
    int statusFile;  /* for Interix */
    int controlFile; /* for Interix */
} Activation_t;

 
and then whereever we pass act.handle off to C code, pass act instead.
 
 
frame is kept first so that it is offset 0 in case that gives codegen efficiencies
on the often used push/popframe.
The other three are moved up to the top to reduce maintainence of ThreadPThread.h.
 
 
I assume "branding" doesn't introduce data in the record.
I'd have to check the codegen to verify frame is at offset 0.
 
 
#ifdef code will open the files.
Modula-3 code can check if the files are >= 0 and close them,
or it can be a call out to #ifdefed C.
 
 
An alternative is that wherever we pass act.handle, also pass act.statusFile and act.controlFile.
(as VAR for initialization).
That is less fragile and less extensible.
I'm fine with that approach too.
 
 
As well though, I was wondering, maybe we should have:
 
 
common/InterixThreadState.i3
 T = RECORD END; (* zero size? *)
 
 
interix/InterixThreadState.i3
  T = RECORD statusFile, controlFile := -1; END;
 
 
and then put InterixThreadState.T in Activation.
That way saving the other platforms from spending the space.
 Just two integers, not much, but in principle..
 (We also sometimes use up 8 bytes for the pthread_t when 4 would suffice,
  on 64bit platforms with pthread_t == int, I think HP-UX is like that at least.)
 
 
I could also open/close the files for every suspend/resume/processStopped,
though that seems too lame.
 
 
Another idea, that I don't really like, is to never optimize and
ignore the registers and just use the stack.
I rarely optimize, but depending on that seems bad.
 
 
Your "safe points" proposal would also make this work, though
I'd rather not wait for that.
 
 
?
 
Ok to add the two integers all the time?
Ok to either depend on the record layout in C, or to always pass the integers around?
 
 
Thanks,
 - Jay

 		 	   		  
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://m3lists.elegosoft.com/pipermail/m3devel/attachments/20091216/325cd2dc/attachment-0002.html>


More information about the M3devel mailing list