#include <utility>
#include <cstdio>
#include <thread>

#include "barrier.h"

#include "context_switcher/context_switcher.h"

using namespace context_switcher;
using namespace std;

// Memory for custom stack and continuation semantics
const size_t STACK_SIZE = 512 * 32;
const size_t NUM_STACKS = 4;
char custom_stacks[NUM_STACKS][STACK_SIZE];

int main() {
  context_switcher::continuation cont_t1, cont_main;
  barrier bar{2};
  int error = 0;

  auto t1 = std::thread([&]() {
    while (true) {
      bar.wait();
      auto cont = enter_context(custom_stacks[0], STACK_SIZE, [&](continuation &&cont) {
        error++;
        cont_t1 = std::move(cont);
        bar.wait();
        error++;
        return std::move(cont_main);
      });
    }
  });

  int count = 0;

  while (true) {
    count++;
    if (count % 100 == 0) {
      printf("%d\n", count);
    }
    bar.wait();
    auto cont = enter_context(custom_stacks[1], STACK_SIZE, [&](continuation &&cont) {
      error++;
      cont_main = std::move(cont);
      bar.wait();
      error++;
      return std::move(cont_t1);
    });
  }

  return 0;
}
