[Mono-devel-list] Embedding Mono in a Virtual World

Paolo Molaro lupus at ximian.com
Thu Feb 10 13:59:18 EST 2005

On 02/09/05 Jim Purbrick wrote:
> I've started trying this approach out using yields and
> think it might well work, although with yields strange
> things happen mixing them with recursion. I'm not sure
> how generally a call graph can be mapped to a state
> machine, especially in the presence of recursion.
> The easiest way to represent the information would be
> to build a stack for each script, but could I mess
> with the stack pointer to switch stacks or would I
> have to emulate a stack using heaps and would that be
> horribly inefficient?

Not orrible but not very nice either.

> I keep coming back to the idea that what I really want
> is a light weight user threads library. I've seen some
> stuff about people using Win32 fibers to run managed
> code. Would it be possible to use a Linux light weight
> threads library in a similar way?

I have no idea what fibers are and how this would interact
with the GC and other info the runtime keeps per-thread.
It would likely require quite a bit of work and debugging.

> > *) use the threadpool as initially suggested: you
> > will queue all the scripts for execution.
> I looked at this approach and implemented a simple
> test app which used Abort and ResetAbort to cancel
> processing after some timeout. While this would stop
> DOS attacks it would also cancel arbitrarily long
> valid processing, which is not the current model and
> so not acceptable.

Another option you might want to investigate is to use
Thread.Suspend (). You'd have a control thread and you'd
hand out the scripts to execute to a single worker
thread and wait for a timeout. If the script didn't finish, the
thread is suspended and put on a fifo to be resumed later
when you decide it's time to do it. Otherwise the timeout is
reset and you make the thread execute another script.
This is likely an implementation similar to your current code.
The tricky issue here is the exact time you suspend and long
running script. This is likely to cause deadlocks if not
handled carefully. It should be pretty safe if you inject
in the user code checks for a global var that signals the event:

	// user code
	while (true) {
		// do expensive calc
		// code injected by the compiler
		if (suspend_flag)
			CurrentThread.Suspend ();

A volatile read is needed so the jit won't optimize it out of the loop.
The Suspend method is marked obsolete in 2.0, because of the potential
for deadlocks, but using it this way should be safe.
Since most of the scripts should terminate within the timeout, if I
understood correctly, you should just have a number of threads
created as many as the slow scripts and I guess in your current system
you already don't call again a script if it didn't finish it's work
in the previous run.
Hope this helps.


lupus at debian.org                                     debian/rules
lupus at ximian.com                             Monkeys do it better

More information about the Mono-devel-list mailing list