[M3devel] cooperative suspend?

Tony Hosking hosking at cs.purdue.edu
Wed Apr 28 16:22:55 CEST 2010



On 27 Apr 2010, at 23:32, Jay K wrote:

> 
> Ok. I still like calling a parameter-less function for code size.
> 
> 
> That would lead to perhaps, if any number of threads can be suspended,
> and compatible with current direction of suspending all of them:
> 
> 
> VAR anyThreadsBeingSuspended: BOOLEAN;

We could have a global array with an entry/bit per thread.  It would limit the number of total threads (because we'd want it statically allocated), but has the advantage that we never divert threads that don't need to suspend.

> PROCEDURE PollSuspend() =
> BEGIN
>  IF anyThreadsBeingSuspended = FALSE THEN RETURN END;
>  PollSuspendSlow();
> END PollSuspend;

We could easily inline the pollcheck using the compiler.

> PROCEDURE PollSuspendSlow() =
> VAR self := GetActivation();
> BEGIN
>  IF NOT self.suspend THEN RETURN END;
>  .. more stuff here ..
> END PollSuspendSlow;
> 
> 
> or if only one suspend would be requested a time:
> 
> 
> VAR threadToSuspend: ADDRESS;

Ultimately we want more than just suspend.  We really want pairwise handshakes between threads, with the possibility of many in flight simultaneously.  This gives us the ability to do biased lock revocation very efficiently.

> PROCEDURE PollSuspend() =
> BEGIN
>  IF threadToSuspend = NIL THEN RETURN END;
>  PollSuspendSlow();
> END PollSuspend;
> 
> 
> PROCEDURE PollSuspendSlow() =
> VAR self := GetActivation();
> BEGIN
>  IF self <> threadToSuspend THEN RETURN END;
>  .. more stuff here ..
> END PollSuspendSlow;
> 
> 
> I imagine what is "really" ideal is to request 1 or more threads to suspend, and then in the "more stuff here", they tell the requester they have suspended. ?

Yeah, or simply deliver an ack that they have seen the event.

> That way, if some thread takes a while to suspend, the whole process isn't backed up behind it. ?

Exactly.

> That would would favor my first exposition (with per thread self.suspend boolean).
>  Which fits current scheme in that you'd just set them all to true.

Yes, that would work.   I like it.

> 
> 
> 
> - Jay
> 
> 
> ----------------------------------------
>> From: hosking at cs.purdue.edu
>> Date: Tue, 27 Apr 2010 21:51:53 -0400
>> To: jay.krell at cornell.edu
>> CC: m3devel at elegosoft.com
>> Subject: Re: [M3devel] cooperative suspend?
>> 
>> Ultimately we don't really want stop-the-world at all. What we really need is per-thread suspension. For scalability we should be aiming to stop threads individually rather than all at once. This means some sort of per-thread (local) mechanism.
>> 
>> On 27 Apr 2010, at 05:01, Jay K wrote:
>> 
>>> 
>>> cooperative suspend
>>> 
>>> 
>>> Tony, you mind if I take a stab at "cooperative suspend"
>>> fairly soon?
>>> I can't find a good way to suspend threads on VMS.
>>> Or even get context in a signal handler.
>>> It will be a boolen in Target.i3, so no existing targets affected.
>>> Of course I'll test it on an existing target with the boolean set wrong. :)
>>> 
>>> 
>>> To optimize size instead of speed, I think the "every so often
>>> extra generated code" should be a call to a parameter-less function.
>>> Instead of checking a per-thread or global variable.
>>> 
>>> Something like:
>>> 
>>> 
>>> VAR threadRequestingSuspend: ADDRESS;
>>> 
>>> 
>>> PROCEDURE Thread.PollSuspend()
>>> BEGIN
>>> IF threadRequestingSuspend = NIL THEN RETURN END;
>>> PollSuspendSlow();
>>> END PollSuspend;
>>> 
>>> 
>>> (* This is split to avoid needing a frame in PollSuspend. *)
>>> PROCEDURE PollSuspendSlow()
>>> VAR self: ADDRESS;
>>> BEGIN
>>> IF threadRequestingSuspend = NIL THEN RETURN END;
>>> self := GetActivation();
>>> IF self = threadRequestingSuspend THEN RETURN END; (* important consideration! *)
>>> GetContext(self.context); (* roughly *)
>>> self.suspended := TRUE; (* roughly *)
>>> WaitForResume(); (* details to be determined, either the semaphore
>>> * or maybe acquire per-thread lock. *)
>>> END PollSuspendSlow;
>>> 
>>> 
>>> The poll call could also be a function pointer and usually point to a function that does nothing.
>>> But that'd require loading the address from a global, and calling it.
>>> Probably more bloat than calling direct instead of indirect.
>>> 
>>> 
>>> - Jay
>>> 
>> 		 	   		  




More information about the M3devel mailing list