[MUD-Dev] Re: atomic functions

Felix A. Croes felix at xs1.simplex.nl
Fri May 1 15:11:58 New Zealand Standard Time 1998


Shawn Halpenny <malachai at iname.com> wrote:

> On Thu, Apr 30, 1998 at 03:59:20AM +0200, Felix A. Croes wrote:
>[...]
> >     An atomic function is a function that succeeds or fails as a
> >     whole.  Any runtime error that is not caught within the function
> >     will lead to the entire function call, with all its effects
> >     and side-effects, being undone.
>
> For me, a function cannot be executed without having a corresponding
> event:  it is tied tightly to the lockless-ness of the DB commits. 
> Events accumulate a working set.  If those objects are committed (and
> they will be if no other event has already finished with its objects
> and has C&C'd), then the thread that was executing that event
> effectively "dies" (although it's kept around in a pool for subsequent
> quick reuse) and the event is no more.

If I understand you correctly, you use "event" to denote the unit of
execution as viewed from within the mud, and "thread" for how the
underlying implementation manages events.  I have been using "thread"
to mean both, assuming a 1-to-1 mapping, or rather giving the matter
no thought at all.  To simplify matters, I will adopt your terminology.

To transplant the idea of atomic functions to your model, in which
functions are already implicitly atomic, make the following change:
rather than

	atomic foo()
	{
	    /* code of foo */
	}

use

	foo()
	{
	    /* code fragment 1 */

	    atomic {
		/* code fragment 2, executed atomically */
	    }

	    /* code fragment 3 */
	}


> I would consider each executing
> event method an atomic function as you've described them--all of the
> effects undone on failed C&C reset the world state for that event to
> the new current state.  A runtime error in a function essentially
> amounts to a failed C&C, since the end result is the same:  no changes
> persist.  However, a failed function will cause the event method in
> which it was called to not be rescheduled and thus it will not attempt
> to C&C again.  A C&C failure without a corresponding function error is
> perfectly acceptable and, in fact, required.  

In this model, atomic code fragments would still be useless, since
an error in an atomic fragment would cancel the entire event.  To
make them meaningful, you would need a way to (optionally) catch
errors in an event.  That way, individual bits of atomic code could
fail without the entire event failing.


> > Atomic functions would be used to enforce consistency -- just like a
> > thread either fails or succeeds without leaving the mud in an
> > inconsistent, half-completed state.  Of course, every function called
> > at the beginning of a thread is effectively called atomically, so
> > code that depends on atomic functions can be replaced by code that
> > depends on (atomic) threads.  The advantage of atomic functions
> > would be to place the function call within the wider thread
> > context, which would be similar to imposing an execution order on
> > threads.  Also, calls to atomic functions could be nested.
>
> I'm not sure I understand how this alone will impose an execution
> order.  If I have threads (I could even substitute "events") executing
> in parallel, normally whichever is able to C&C first, wins.  Any order
> I impose on executing events depends on sequence numbers associated
> with the events themselves.  Design details about the sequencing are still
> muddy, since I'm re-examining my approach.

What it actually does is impose an execution order on bits of
atomically executed code:

	foo()
	{
	    atomic {
		/* code fragment 1 */
	    }
	    atomic {
		/* code fragment 2 */
	    }
	    atomic {
		/* code fragment 3 */
	    }
	}

Now, focusing on atomic code and abstracting from the rest, you can
map the sequence of code fragments to a sequence of atomic events.

Having events execute in parallel and compete for completion is done
to get the mud to run efficiently on multi-processor architectures.
But the atomic code property is also desirable from a software design
point of view, which is why I am trying to separate atomicity and
events.  It gets especially interesting when you nest atomic code,
allowing you to make code atomic on several abstraction levels.

Felix Croes

--
MUD-Dev: Advancing an unrealised future.



More information about the MUD-Dev mailing list