#include "zthread.h"

#include <iostream>

#include <stdlib.h>
#include <stdio.h>


#include <time.h>
#include <unistd.h>

#include "timing.h"


void fun2(void * arg)
{
time_t t0, t1;
int i;
char *strg;
strg = (char *)arg;

t0 = time(NULL);
printf("**** Entry to fun2 (arg= %s) ***** \n", strg);
int imax = atoi(strg);
for(i=0; i<imax; i++)
  {
  sleep(4);
  t1 = time(NULL)-t0;
  printf("######## Fun2 [%d]  Dt= %d \n", i, (int)t1);
  }

return;
}

void fun1(void *arg)
{
time_t t0, t1;
int i;

char * strg = (char *)arg;

t0 = time(NULL);
printf("++++ Entry to fun1 (arg= %s) +++++ \n", strg);
int imax = atoi(strg);
for(i=0; i<imax; i++)
  {
  sleep(3);
  t1 = time(NULL)-t0;
  printf("%%%% Fun1 [%d]  Dt= %d \n", i, (int)t1);
  }

return;
}

class CountLock : public ZMutex {
  int count;
public:
  CountLock() { count = 0; }
  inline int Count() { lock(); int rc = ++count; unlock(); return(rc); 
  }
};


int main(int narg, char *arg[])

{

  if (narg < 4) {
    cout << " Usage: zthr N1 N2 NLock" << endl;
    exit(1);
  }

  cout << " zthr-main() arg[1] = " << arg[1] << " arg[2]= " << arg[2] << endl;
  InitTim();

  CountLock clk;
  int kk;
  for(kk=0; kk<atoi(arg[3]); kk++) {
    clk.Count();
  }
  cout << " End Count= " << clk.Count() << endl;
  PrtTim("EndOfCount1 ");

  cout << ">>> Creating Thread Z1 and Z2 " << endl;
  ZThread zt1;
  zt1.setAction(fun1, arg[1]);
  ZThread zt2;
  zt2.setAction(fun2, arg[2]);
  cout << ">>> Starting Thread Z1 and Z2 " << endl;
  zt1.start();
  zt2.start();

  PrtTim("BeginOfCount2 ");
  for(kk=0; kk<atoi(arg[3]); kk++) {
    clk.Count();
  }
  cout << " End Count= " << clk.Count() << endl;
  PrtTim("EndOfCount2 ");

  //  sleep(5);
  cout << ">>> Joining Thread Z1 and Z2 " << endl;

  zt1.join();
  zt2.join();
  cout << ">>> Thread Z1 and Z2 Finished " << endl;
 
  return(0);
  
}
