[DGD] Melville under the Kernel Lib

Felix A. Croes felix at dworkin.nl
Sun Feb 8 17:42:50 CET 2004


"Steve Foley" <zeppo1 at mindspring.com> wrote:

> >     - It must be possible to start a callout without making
> >       a change to data in any object (this is why callouts
> >       are no longer a resource in the kernel library, since
> >       resources are tracked by a central object).
>
> I don't understand the nature of this requirement.  I wish I could more
> specifically articulate what I don't understand about this, but I'm afraid
> I can't.  I have a vague feeling it has to do with the compare, commit or
> reschedule process that occurs in making a multi-threaded environment
> appear to be single-threaded, but I'm not really even all that sure of
> that.  Would someone be so kind as to shine some light on this?  Thanks in
> advance.

Let's start with what this requirement means.  What you should not do
is anything like the following, in the auto object:

    private int pending_callouts;

    int call_out(string function, mixed delay, mixed args...)
    {
	int handle;

	handle = ::call_out("call_out_gate", delay, string function, args);
	pending_callouts++;
	return handle;
    }

    void call_out_gate(string function, mixed *args)
    {
	--pending_callouts;
	call_other(this_object(), function, args...);
    }

This is no good because each started callout modifies the object's data
(i.e. pending_callouts).  Therefore the thread will compete with any
other thread that also tries to modify this object.  If the above
method of starting callouts is the only way, then in fact <any> callout
addition will also modify the object, and no two threads will be able
to simultaneously add callouts to the same object.

Worse still, if you were to keep track of callouts in a central object
somewhere, any callout started in any object will compete with any other
callout started somewhere else, since both threads will be trying to
modify the same central object.

Removing all references to pending_callouts in the above example code,
adding a callout to the object will not count as an object modification.
1000 simultaneous threads could each add a callout to the object, and
none would be considered to be in competition with the others.  In
theory, all would be able to complete.

Why is this important?  Suppose that you want to broadcast a message
to all players online.  Actually calling a function in all player
objects that modifies data in each of them is likely to conflict with
anything else that also modifies player objects (and there is a lot of
that going on). So, instead of sending the message directly, you call
a relay function in the player object, which starts a zero-delay callout
to process the message later on.  No data is modified, and the
broadcasting thread will not be in competition with any other.

Regards,
Dworkin
_________________________________________________________________
List config page:  http://list.imaginary.com/mailman/listinfo/dgd



More information about the DGD mailing list