#include <hpcxx_rts.h>
#include <iostream.h>
#include <unistd.h>
#include <stdlib.h>

/***********************************************************************
tjs - 98.09.22

This example creates running threads by using a runnable object instead
of redefining run() in the thread object.

Note: mutexes are used to protect critical sections

***********************************************************************/
HPCxx_Mutex outLock;  // note that scope is this file

class RunnableObject : public HPCxx_Runnable {
  int myID;

public:

  RunnableObject(int _myID) : myID(_myID), HPCxx_Runnable() {}

  void run() {

    outLock.lock();
    cout << "thread " << myID 
	 << " ...sleeping" << endl << flush;
    outLock.unlock();

    sleep(10-myID);

    outLock.lock();
    cout << "thread " << myID << " awake, slept " << 10-myID << endl << flush;
    outLock.unlock();

  }
};

int main(int argc, char **argv)
{
  // These two must come first
  HPCxx_Group *g;
  hpcxx_init(argc, argv, g);

  int
    i,
    n_threads;

  cout << "how many threads do you want? " << flush;
  cin >> n_threads;

  //Array of threads
  HPCxx_Thread *t[n_threads];

  // spawn the threads
  for(i=0;i<n_threads;i++) {
    HPCxx_Runnable *r = new RunnableObject(i);
    t[i] = new HPCxx_Thread(r);
    t[i]->start();
  }

  
  // join threads into single thread of execution
  for(i=0;i<n_threads;i++) {
    t[i]->join();
  }

  outLock.lock();
  cout << "from main(): DONE" << endl << flush;
  outLock.unlock();

  // clean up hpcxx.  This should be the last thing you do.
  return hpcxx_exit(g);
}
