[fpc-pascal] Coroutines and VirtualAlloc

Ryan Joseph ryan at thealchemistguild.com
Wed Apr 19 06:04:15 CEST 2017


> On Apr 19, 2017, at 2:34 AM, Daniel Gaspary <dgaspary at gmail.com> wrote:
> 
> Using  SetJmp and LongJmp?
> 
> I believe some months ago it was a discussion on the list on why this
> was not really the way to implement coroutines.
> 
> Searching for longjmp/setjmp you can find the thread, I guess.

I never heard of those functions and I did find a thread about them but it seemed inconslusive. 

Here’s a little test I made not knowing exactly how those functions work. I expected the stack to be restored and “i” incremented but that’s not what happens. The program jumps in and out of the loop but “i” remains the same each time. Is this not how to use those functions?

type
	TCoroutine = class (TObject)
		public
			procedure Start;
			procedure Yield;
			procedure Resume;
		private
			entry: jmp_buf;
			env: jmp_buf;
			passes: longint;
			yieldNext: boolean;
	end;
	
procedure TCoroutine.Start;
var
	i: integer = 0;
begin
	Setjmp(entry);
	if passes > 0 then
		exit;
	writeln('start');
	while i < 10 do
		begin
			writeln('loop ', i);
			i += 1;
			Setjmp(env);
			if not yieldNext then
				Yield;
			yieldNext := false;
		end;
end;

procedure TCoroutine.Yield;
begin
	writeln('yield');
	passes += 1;
	yieldNext := false;
	Longjmp(entry, 1);
end;

procedure TCoroutine.Resume;
begin
	writeln('resume');
	yieldNext := true;
	Longjmp(env, 1);
end;
	
procedure CoroutineTest; 
var
	co: TCoroutine;
	i: integer;
begin
	co := TCoroutine.Create;
	co.Start;
	writeln('stepped out');
	for i := 0 to 4 do
		co.Resume;
	writeln('finished');
end;


========

start
loop 0
yield
stepped out
resume
loop 1
yield
resume
loop 1
yield
resume
loop 1
yield
resume
loop 1
yield
resume
loop 1
yield
finished


Regards,
	Ryan Joseph




More information about the fpc-pascal mailing list