////////////////////////////////////////////////////////////////////////////////
//
// tjs - 98.12.18
//
// TM_ClientServer.h - The Tau Monitor Client Server Classes
//
// See TM_ClientServer.C for documentation.
//
////////////////////////////////////////////////////////////////////////////////

#ifndef __TM_CLIENT_SERVER_H__
#define __TM_CLIENT_SERVER_H__

#define MAX_FUNC_NAME 1000
#define MAX_FUNC_TYPE 1000
#define MAX_FUNC_GROUP_NAME 100


typedef long functionID;

typedef struct funcInfoStruct { // data from one function of the function DB
  functionID
    ID;
  int
    threadID;
  char
    name[MAX_FUNC_NAME],
    type[MAX_FUNC_TYPE],
    groupName[MAX_FUNC_GROUP_NAME];
  long
    numCalls,
    numSubrs;
  double
    exclTime,
    inclTime;
  unsigned
    profileGroup;
} funcInfo;

typedef struct callStackInfoStruct {  // for one callstack datum
  double 
    ExclTimeThisCall;
  double 
    StartTime;
  functionID
    ID;
  double
    InclTime_cs,
    ExclTime_cs;
} callStackInfo;

// Structure for callstack.  This will probably have to be handled with some
// sort of memory management, but for now, the size is set at compile time.

#define MAX_CALL_STACK 100

typedef struct callStackStruct {  // for the whole callstack
  long
    Length;
  callStackInfo
    Stack[MAX_CALL_STACK];
} callStack;

class TM_Monitor {  // parent class for the client and the server

 protected:

  // data members for Tau info

  int
    funcDBSize;          // size of the function database
  funcInfo               
    crntFuncInfo;        // data for the current function
  callStack              
    crntCallStack;       // data for the current callstack

  // remote function and global pointer stuff

  int
    regVal;              // registration value for fuction registration
  int
    packCrntFuncInfo,    // to tell pack routine what to pack up
    packCrntCallStack;
  HPCxx_Sync<int>        // used to force server to wait
    serverWait;
  HPCxx_GlobalPtr<TM_Monitor>  // global pointer used by client to access server
    *TM_MonitorGP_Ptr;
  HPCxx_Group            // for HPC++ access etc.
    *hpcxxGroup;
  hpcxx_id_t           // HPC++ function identifiers one for each function
    WaitID,            // called remotely
    SignalID,
    GetFuncDBSizeID,
    GetCallStackID,
    GetFuncInfoID,
    getTM_MonitorGPID;

  void regFuncs(void);

  // functions for attaching client and server

  virtual int serverAllowAttach(const char *urlName) { return(0); }
  virtual HPCxx_ContextID *clientAttach(const char *urlName) { return(NULL); }

 public:
  
  TM_Monitor(int argc, char* argv[]);
  virtual ~TM_Monitor();   // virtual allows call when derived object deleted

  // functions remotely called on server by client

  virtual int Wait(int waitVal) { return(0); }
  virtual int Signal(int releaseVal) { return(0); }
  virtual int GetFuncDBSize(void) { return(0); }
  virtual int GetCallStack(int threadID) { return(0); }
  virtual int GetFuncInfo(functionID funcID, int threadID) { return(0); }

  // not changed in derived classes

  void PrintCrntFuncInfo(void);
  void PrintCrntCallStack(void);

  // registration ID as required by HPC++

  static int registrationID(){ return 346; }

  // external pack and unpack

  friend void hpcxx_pack(HPCxx_Buffer b, TM_Monitor *TM_Obj, int packSelect);
  friend void hpcxx_unpack(HPCxx_Buffer b, TM_Monitor *TM_Obj, int packSelect);
};

// Global functions and variables used for HPC++ global pointers.  Compile
// issues require that they go here after the declaration of the parent
// object.

HPCxx_GlobalPtr<TM_Monitor> getTM_MonitorGP(void); // get GP to TM_Monitor

static HPCxx_GlobalPtr<TM_Monitor> gTM_MonitorGP;  // GP to TM_Monitor class


class TM_Server : public TM_Monitor {

 protected:

  virtual int serverAllowAttach(const char *urlName);

 public:

  TM_Server(int argc, char *argv[], const char *urlName);
  ~TM_Server();

  // functions called remotely from client

  virtual int Wait(int waitVal);
  virtual int Signal(int releaseVal);
  virtual int GetFuncDBSize(void);
  virtual int GetFuncInfo(functionID funcID, int threadID);
  virtual int GetCallStack(int threadID);
};

class TM_Client : public TM_Monitor {

 protected:
  HPCxx_ContextID
    *serverContextID;

  virtual HPCxx_ContextID *clientAttach(const char *urlName);

 public:

  TM_Client(int argc, char* argv[], const char *urlName);
  ~TM_Client();

  // functions using remote function calls on the server

  virtual int Wait(int waitVal);
  virtual int Signal(int releaseVal);
  virtual int GetFuncDBSize();
  virtual int GetFuncInfo(functionID funcID, int threadID);
  virtual int GetCallStack(int threadID);
};

#endif

