#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ucontext.h>
enum { STATE_ONE, STATE_TWO, STATE_DONE };
struct execution_state {
int state_;
ucontext_t main_ctx_;
ucontext_t alt_ctx_;
char alt_stack_[32*1024];
} es;
void deferred_print (const char *fmt, ...) {
va_list ap;
while (es.state_ == STATE_ONE) {
es.state_ = STATE_TWO;
swapcontext(&es.main_ctx_, &es.alt_ctx_);
}
}
void state_one () {
deferred_print("this is a deferred print from %s\n", __func__);
es.state_ = STATE_DONE;
}
void state_two () {
if (rand() > RAND_MAX
/4) es.
state_ = STATE_ONE
; setcontext(&es.main_ctx_);
}
void state_machine () {
while (es.state_ != STATE_DONE) {
(void (*[])()){ state_one, state_two }[es.state_]();
}
}
void es_init () {
es.state_ = STATE_ONE;
getcontext(&es.alt_ctx_);
es.alt_ctx_.uc_stack.ss_sp = es.alt_stack_;
es.alt_ctx_.uc_stack.ss_size = sizeof(es.alt_stack_);
es.alt_ctx_.uc_link = &es.main_ctx_;
makecontext(&es.alt_ctx_, state_machine, 0);
}
int main () {
es_init();
state_machine();
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDx1Y29udGV4dC5oPgoKZW51bSB7IFNUQVRFX09ORSwgU1RBVEVfVFdPLCBTVEFURV9ET05FIH07CgpzdHJ1Y3QgZXhlY3V0aW9uX3N0YXRlIHsKICAgIGludCBzdGF0ZV87CiAgICB1Y29udGV4dF90IG1haW5fY3R4XzsKICAgIHVjb250ZXh0X3QgYWx0X2N0eF87CiAgICBjaGFyIGFsdF9zdGFja19bMzIqMTAyNF07Cn0gZXM7Cgp2b2lkIGRlZmVycmVkX3ByaW50IChjb25zdCBjaGFyICpmbXQsIC4uLikgewogICAgdmFfbGlzdCBhcDsKICAgIHdoaWxlIChlcy5zdGF0ZV8gPT0gU1RBVEVfT05FKSB7CiAgICAgICAgZXMuc3RhdGVfID0gU1RBVEVfVFdPOwogICAgICAgIHN3YXBjb250ZXh0KCZlcy5tYWluX2N0eF8sICZlcy5hbHRfY3R4Xyk7CiAgICB9CiAgICB2YV9zdGFydChhcCwgZm10KTsKICAgIHZwcmludGYoZm10LCBhcCk7CiAgICB2YV9lbmQoYXApOwp9Cgp2b2lkIHN0YXRlX29uZSAoKSB7CiAgICBwdXRzKF9fZnVuY19fKTsKICAgIGRlZmVycmVkX3ByaW50KCJ0aGlzIGlzIGEgZGVmZXJyZWQgcHJpbnQgZnJvbSAlc1xuIiwgX19mdW5jX18pOwogICAgZXMuc3RhdGVfID0gU1RBVEVfRE9ORTsKfQoKdm9pZCBzdGF0ZV90d28gKCkgewogICAgcHV0cyhfX2Z1bmNfXyk7CiAgICBpZiAocmFuZCgpID4gUkFORF9NQVgvNCkgZXMuc3RhdGVfID0gU1RBVEVfT05FOwogICAgc2V0Y29udGV4dCgmZXMubWFpbl9jdHhfKTsKfQoKdm9pZCBzdGF0ZV9tYWNoaW5lICgpIHsKICAgIHdoaWxlIChlcy5zdGF0ZV8gIT0gU1RBVEVfRE9ORSkgewogICAgICAgICh2b2lkICgqW10pKCkpeyBzdGF0ZV9vbmUsIHN0YXRlX3R3byB9W2VzLnN0YXRlX10oKTsKICAgIH0KfQoKdm9pZCBlc19pbml0ICgpIHsKICAgIGVzLnN0YXRlXyA9IFNUQVRFX09ORTsKICAgIGdldGNvbnRleHQoJmVzLmFsdF9jdHhfKTsKICAgIGVzLmFsdF9jdHhfLnVjX3N0YWNrLnNzX3NwID0gZXMuYWx0X3N0YWNrXzsKICAgIGVzLmFsdF9jdHhfLnVjX3N0YWNrLnNzX3NpemUgPSBzaXplb2YoZXMuYWx0X3N0YWNrXyk7CiAgICBlcy5hbHRfY3R4Xy51Y19saW5rID0gJmVzLm1haW5fY3R4XzsKICAgIG1ha2Vjb250ZXh0KCZlcy5hbHRfY3R4Xywgc3RhdGVfbWFjaGluZSwgMCk7CiAgICBzcmFuZCgodW5zaWduZWQpdGltZSgwKSk7Cn0KCmludCBtYWluICgpIHsKICAgIGVzX2luaXQoKTsKICAgIHB1dHMoInN0YXJ0Iik7CiAgICBzdGF0ZV9tYWNoaW5lKCk7CiAgICBwdXRzKCJmaW5pc2giKTsKICAgIHJldHVybiAwOwp9Cg==