www.digitalmars.com         C & C++   DMDScript  

D - implementation of fiber in D

reply yaneurao sun-inet.or.jp writes:
It is very important for the modern langauge
to have mechanism such as co-routine (like fiber in Win32).

I want to introduce my implementation of fiber, what is called ,
'micro-thread' in D.  micro-thread is too easy to implement.
(If you have more interest, see Game Programming Gems 2)

A brief idea is to switch the stack frame like this :

asm {
naked;
push	EBX;
push	EBP;
push	ESI;
push	EDI;

//		push	dword ptr FS:[0];	//	for SEH

xchg	ESP,[EAX+8];

//		pop		dword ptr FS:[0];	//	for SEH

pop		EDI;
pop		ESI;
pop		EBP;
pop		EBX;
ret;
}

FS:[0] means the pointer to SEH(Win32 structure exception handling) table.

If you want to use exception in micro-thread ,
you need to use SEH and provide the virtual stack buffer
from the real stack frame managed by Operating System.

Here is my implementation :

class MicroThread {
public:
void	start(void delegate() start_func,int nStackSize/*=0x1000*/)
{
if (nStackSize) nStackSize_ = nStackSize;
if (!nStackSize_) nStackSize_ = 0x1000;

if (abyStack_.length < nStackSize_) 
{
abyStack_ = new byte[nStackSize_];
}
register_esp_ = &abyStack_[0] + nStackSize_;

bEnd_ = false; bSuspended_ = false;

register_esp_start_ = register_esp_;
start_func_ = start_func;

ms_push(cast(uint)(&start_));
ms_push(0); // ebx
ms_push(0); // ebp
ms_push(0); // esi
ms_push(0); // edi

switchThread();
}

void	start(void delegate () start_func)
{ start(start_func,0); }

void	suspend()
{
bSuspended_ = true;
switchThread();
}

void	sleep(int n)
{	while(--n >= 0) suspend(); }

void	resume()
{
if (!isSuspended()) return ;
bSuspended_ = false;
switchThread();
}

bool	isSuspended() { return bSuspended_;}
bool	isEnd() { return bEnd_; }

void	onMove() {
if (!isEnd()){
if (!isSuspended()) {
start(start_func_);
} else {
resume();
}
}
}

this() {}

this(void delegate () start_func)
{ start_func_ = start_func; }

this(void delegate () start_func,int nStackSize)
{ start_func_ = start_func; nStackSize_ = nStackSize; }

private:
byte*			register_esp_;		//	ESP
byte*			register_esp_start_;//	ESP when start
bool			bSuspended_;		//	suspend flag
bool			bEnd_;				//	termination flag
byte[]			abyStack_;			//	virtual stack
int				nStackSize_;		//	virtual stack size

void	delegate() start_func_;		//	function to call

static void start_(MicroThread mt) {
mt.start_func_();
mt.bEnd_ = true;
mt.switchThread();
}

void	ms_push(uint u)
{
register_esp_ -= 4;
*cast(uint*)(register_esp_) = u;
}

void	switchThread(){
asm {
naked;

push	EBX;
push	EBP;
push	ESI;
push	EDI;

//			push	dword ptr FS:[0];	//	for SEH

xchg	ESP,[EAX+8];

//			pop		dword ptr FS:[0];	//	for SEH

pop		EDI;
pop		ESI;
pop		EBP;
pop		EBX;
ret;
}
}
};
Jan 05 2004
parent reply "Matthew" <matthew.hat stlsoft.dot.org> writes:
 It is very important for the modern langauge
 to have mechanism such as co-routine (like fiber in Win32).

Quite true.
 I want to introduce my implementation of fiber, what is called ,
 'micro-thread' in D.  micro-thread is too easy to implement.
 (If you have more interest, see Game Programming Gems 2)

I have that book. Maybe it's time I read it ... :)
 A brief idea is to switch the stack frame like this :

<snip> Do you have this in a form that you could contribute? I think it would be fantastic if we could get this in the language itself, but if it was a servicable library that would be fine. Matthew
Jan 05 2004
parent reply yaneurao sun-inet.or.jp writes:
In article <btd95o$1o1a$2 digitaldaemon.com>, Matthew says...
Do you have this in a form that you could contribute?
I think it would be fantastic if we could get this in the language itself,
but if it was a servicable library that would be fine.

my micro-thread source code is included in my game library : http://www.sun-inet.or.jp/~yaneurao/dlang/english.html please use freely if you need. but obviously it is better to be supported in the language itself. Fortunately , GC in D is so conservative that virtual stack frame used by micro-thread is going well. GC in D would be scanning into virtual stack frame because it is allocated by GC's heap. But unfortunately my micro-thread is exception unsafe.
Jan 06 2004
parent Ant <Ant_member pathlink.com> writes:
In article <btdqmo$2k29$1 digitaldaemon.com>, yaneurao sun-inet.or.jp says...
my micro-thread source code is included in my game library :

http://www.sun-inet.or.jp/~yaneurao/dlang/english.html

please use freely if you need.

Nice set of features. I now feel stupid for being waiting for a directory listing thing for over a month. That does it, from now on I will do windows ;) Ant
Jan 06 2004