Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Created May 28, 2020 19:52
Show Gist options
  • Save alphaKAI/0107e5f529bc6ca747f7758bb98a228d to your computer and use it in GitHub Desktop.
Save alphaKAI/0107e5f529bc6ca747f7758bb98a228d to your computer and use it in GitHub Desktop.
setjmp/longtest behavior test in D
import core.sys.posix.setjmp;
import std.stdio;
import std.format;
string yield(alias callee_env, alias caller_env, alias val)() {
return q{
if (setjmp(%s) == 0) {
longjmp(%s, %s);
}
}.format(callee_env.stringof, caller_env.stringof, val);
}
string yield_ptr(alias callee_env_ptr, alias caller_env_ptr, alias val)() {
return q{
if (setjmp(*%s) == 0) {
longjmp(*%s, %s);
}
}.format(callee_env_ptr.stringof, caller_env_ptr.stringof, val);
}
void func1(alias callee_env, alias caller_env)() {
enum FNAME = __FUNCTION__;
writefln("<%s> addr of callee_env: %s, addr of callee_env: %s", FNAME, &callee_env, &caller_env);
writefln("<%s> A", FNAME);
mixin (yield!(callee_env, caller_env, 1));
writefln("<%s> B", FNAME);
mixin (yield!(callee_env, caller_env, 1));
writefln("<%s> C", FNAME);
mixin (yield!(callee_env, caller_env, -1));
}
void func2(jmp_buf callee_env, jmp_buf caller_env) {
enum FNAME = __FUNCTION__;
writefln("<%s> addr of callee_env: %s, addr of callee_env: %s", FNAME, &callee_env, &caller_env);
writefln("<%s> A", FNAME);
mixin (yield!(callee_env, caller_env, 1));
writefln("<%s> B", FNAME);
mixin (yield!(callee_env, caller_env, 1));
writefln("<%s> C", FNAME);
mixin (yield!(callee_env, caller_env, -1));
}
void func3(ref jmp_buf callee_env, ref jmp_buf caller_env) {
enum FNAME = __FUNCTION__;
writefln("<%s> addr of callee_env: %s, addr of callee_env: %s", FNAME, &callee_env, &caller_env);
writefln("<%s> A", FNAME);
mixin (yield!(callee_env, caller_env, 1));
writefln("<%s> B", FNAME);
mixin (yield!(callee_env, caller_env, 1));
writefln("<%s> C", FNAME);
mixin (yield!(callee_env, caller_env, -1));
}
void func4(jmp_buf* callee_env, jmp_buf* caller_env) {
enum FNAME = __FUNCTION__;
writefln("<%s> addr of callee_env: %s, addr of callee_env: %s", FNAME, callee_env, caller_env);
writefln("<%s> A", FNAME);
mixin (yield_ptr!(callee_env, caller_env, 1));
writefln("<%s> B", FNAME);
mixin (yield_ptr!(callee_env, caller_env, 1));
writefln("<%s> C", FNAME);
mixin (yield_ptr!(callee_env, caller_env, -1));
}
void test_func1(alias callee_env, alias caller_env)() {
const status = setjmp(caller_env);
if (status == 0) {
func1!(callee_env, caller_env);
} else if (status != -1) {
writefln("RESUME!");
longjmp(callee_env, 1);
} else if (status == -1) {
writefln("Fiber finished");
}
}
void test_func2(alias callee_env, alias caller_env)() {
const status = setjmp(caller_env);
if (status == 0) {
func2(callee_env, caller_env);
} else if (status != -1) {
writefln("resume!");
longjmp(callee_env, 1);
} else if (status == -1) {
writefln("fiber finished");
}
}
void test_func3(alias callee_env, alias caller_env)() {
const status = setjmp(caller_env);
if (status == 0) {
func3(callee_env, caller_env);
} else if (status != -1) {
writefln("resume!");
longjmp(callee_env, 1);
} else if (status == -1) {
writefln("fiber finished");
}
}
void test_func4(alias callee_env, alias caller_env)() {
const status = setjmp(caller_env);
if (status == 0) {
func4(&callee_env, &caller_env);
} else if (status != -1) {
writefln("resume!");
longjmp(callee_env, 1);
} else if (status == -1) {
writefln("fiber finished");
}
}
void main(string[] args) {
__gshared jmp_buf callee_env;
__gshared jmp_buf caller_env;
writefln("TEST <%s>-------------------------------------", "func1");
test_func1!(callee_env, caller_env);
writefln("TEST <%s>-------------------------------------", "func2");
test_func2!(callee_env, caller_env);
writefln("TEST <%s>-------------------------------------", "func3");
test_func3!(callee_env, caller_env);
writefln("TEST <%s>-------------------------------------", "func4");
test_func4!(callee_env, caller_env);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment