// Code that times thread and process create-delete times.
// CS 537, Client-Server Interfaces, Spring 2002.

#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
#include <cassert>
#include <cstdio>
#include <pthread.h>
#include "stopwatch.h"


static unsigned loop_maximum = 2000;


static void * f(void *) {
  return NULL;
  }


#define timeit(_et, stmts) \
  do { \
    stopwatch sw(loop_maximum); \
    sw.start(); \
    for (unsigned _i = 0; _i < loop_maximum; _i++) { stmts ; } \
    sw.stop(); \
    _et = static_cast<time_t>(sw.avg()); \
    } while (false)


static void
do_fork(unsigned loop_maximum) {

  pid_t pid;
  time_t s;

  timeit(s, 
    switch (pid = fork()) {
      case 0: 
	exit(EXIT_SUCCESS);
      case -1:
	perror("fork() error:");
	exit(EXIT_FAILURE);
      default:
	assert(wait(NULL) == pid);
      }
    );

  printf("Time per fork() call for %d calls: %g usec.\n", loop_maximum,
	 ((double) s)/((double) loop_maximum));

  }

static void 
do_thread(unsigned loop_maximum) {

  pthread_t tid;
  int e;
  time_t s;

  timeit(s, 
    if ((e = pthread_create(&tid, NULL, f, NULL))) {
      printf("pthread_create() failed with error %d.\n", e);
      exit(EXIT_FAILURE);
      }
    if ((e = pthread_join(tid, NULL))) {
      printf("pthread_join() failed with error %d.\n", e);
      exit(EXIT_FAILURE);
      }
    );

  printf("Time per pthread_create() call for %d calls: %g usec.\n", 
	 loop_maximum, ((double) s)/((double) loop_maximum));
  }

int 
main(int argc, char * argv[]) {

  time_t oh;

  timeit(oh,);
  printf("Loop overhead is %lu usec for %d iterations, %g usec/iteration.\n",
	 oh, loop_maximum, ((double) oh)/((double) loop_maximum));

  do_fork(loop_maximum);
  do_thread(loop_maximum);

  return EXIT_SUCCESS;
  }


syntax highlighted by Code2HTML, v. 0.9