#include <pthread.h>
#include <unistd.h>
#include <iostream>
#include <memory>

using std::cerr;
using std::cout;
using std::endl;
using std::unique_ptr;

void sleep_spin(int delay) {
  for (int i = 0; i < 4; i++) {
    cout << "  sleep_spin(" << delay << ") sleeping..." << endl;
    sleep(delay);
    cout << "  sleep_spin(" << delay << ") done sleeping." << endl;
  }
}

void *thread_start(void *arg) {
  unique_ptr<int> delay(reinterpret_cast<int *>(arg));
  cout << "[child thread] I'm alive!" << endl;
  cout << "[child thread] calling sleep_spin(" << *delay
            << ")" << endl;
  sleep_spin(*delay);
  cout << "[child thread] done." << endl;
  return nullptr;
}

int main(int argc, char **argv) {
  // Create a child thread, passing it an (int *) as its argument.
  cout << "[parent thread] about to pthread_create().." << endl;
  pthread_t thr;
  int *argument = new int(1);
  if (pthread_create(&thr, nullptr, &thread_start,
                     reinterpret_cast<void *>(argument)) != 0) {
    cerr << "pthread_create() failed." << endl;
    return EXIT_FAILURE;
  }

  // Could either (a) use pthread_join() to wait for the child to
  // terminate, or (b) call pthread_detach() to "detach" the child and
  // then we no longer care about or need to pthread_join() with it.
  // We'll do pthread_detach().
  if (pthread_detach(thr) != 0) {
    cerr << "pthread_detach() failed." << endl;
  }

  cout << "[parent thread] calling sleep_spin(2).." << endl;
  sleep_spin(2);
  cout << "[parent thread] done." << endl;

  return EXIT_SUCCESS;
}