[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