Benjamin --

The trick is to find the cheapest possible way to get conditional
processing to occur if and only if there are events in the event
queue.

I'll only be considering the fast core here for simplicity. But,
if you look at include/parrot/interp_guts.h, the only thing of
interest there is the definition of the DO_OP() macro, which
looks like this:

  #define DO_OP(PC,INTERP) \
  (PC = ((INTERP->op_func_table)[*PC])(PC,INTERP))

The easiest way to intercept this flow with minimal cost is to
have the mechanism that wants to take over replace the interpreter's
op_func_table with a block of pointers to some Parrot_hijack()
function that conforms to the opfunc prototype. Enqueueing an
event would set the appropriate interpreter's op_func_table to
hijack_op_func_table. Of course, if threads are involved there
are going to be locking issues, and I don't know how cheap the
locking can be made... I'm aware that there are some very cheap
locking approaches available, but I don't have a good feel for
when you can and cannot use them, and how cheap they really are.

The hijack op_func can do whatever it needs to do and then reset
the interpreter's op_func_table to the saved pointer and return
the same PC, so the interpreter will pick up where it left off.

There might be some use for continuations in here, too. Perhaps
the hijack function could save the current state as a continuation
(presumably with the old opfunc table as part of the saved
context), and then it could invoke the event handler with that
continuation as the place to return to...

If something like what I've described is workable, it would mean
we wouldn't have to have an explicit event queue checking policy.
Events would get delivered on the next op dispatch after they
were enqueued. As we handle the last event, we notice the queue
is empty and make sure the normal op_func_table is installed and
normal execution is resumed.

This approach does mean that events arriving quickly could DoS
the main line of execution, which could require us to add a bit
more logic to make sure that "thread" is not starved (if that
is important).


Regards,

-- Gregor

On Fri, 2003-07-11 at 16:07, Benjamin Goldberg wrote:
> Leopold Toetsch wrote:
> [snip]
> > - When will we check, it there are events in the event queue?
> 
> If we check too often (between each two ops), it will slow things down.
> 
> If we don't check often enough, the code might manage to avoid checking
> for events entirely.
> 
> I would suggest that every flow control op check for events.  Or maybe
> just every control flow op that goes to earlier instructions.
> 
> And of course ops which might block for IO.
-- 
Gregor Purdy                            [EMAIL PROTECTED]
Focus Research, Inc.               http://www.focusresearch.com/

Reply via email to