Added version number for charmdebug (to detect incompatible versions)
[charm.git] / src / ck-core / debug-charm.h
1 /*
2  Interface to Charm++ portion of parallel debugger.
3  Orion Sky Lawlor, olawlor@acm.org, 7/30/2001
4  */
5 #ifndef __CMK_DEBUG_CHARM_H
6 #define __CMK_DEBUG_CHARM_H
7
8 #ifndef __cplusplus
9 #  error "debug-charm.h is for C++; use debug-conv.h for C programs"
10 #endif
11
12 #include "converse.h"
13 #include "debug-conv.h"
14 #include "pup.h"
15 #include "cklists.h"
16
17 #define CHARMDEBUG_MAJOR   10
18 #define CHARMDEBUG_MINOR    0
19
20 void *CpdGetCurrentObject();
21 void *CpdGetCurrentMsg();
22
23 //Hooks inside the debugger before and after an entry method is invoked
24 extern void CpdBeforeEp(int, void*, void*);
25 extern void CpdAfterEp(int);
26 extern void CpdFinishInitialization();
27
28 class CpdPersistentChecker {
29 public:
30   virtual void cpdCheck(void*) {}
31 };
32
33 typedef struct DebugPersistentCheck {
34   CpdPersistentChecker *object;
35   void *msg;
36   
37   DebugPersistentCheck() : object(NULL), msg(NULL) {}
38   DebugPersistentCheck(CpdPersistentChecker *o, void *m) : object(o), msg(m) {}
39 } DebugPersistentCheck;
40
41 // This class is the parallel of EntryInfo declared in register.h and is used
42 // to extend the former with additional debug information. There is a direct
43 // correspondence between elements on the two arrays.
44 class DebugEntryInfo {
45 public:
46   // true if this entry method has a breakpoint set
47   CmiBool isBreakpoint;
48   CkVec<DebugPersistentCheck> preProcess;
49   CkVec<DebugPersistentCheck> postProcess;
50
51   DebugEntryInfo() : isBreakpoint(CmiFalse) { }
52 };
53
54 typedef CkVec<DebugEntryInfo> DebugEntryTable;
55
56 //These pup functions are useful in CpdLists, as they document the name
57 //  of the variable.  Your object must be named "c" (a stupid hack).
58 #define PCOM(field) p.comment(#field); p(c->field);
59 #define PCOMS(field) \
60   if (!p.isUnpacking()) { \
61         p.comment(#field); p((char *)c->field,strlen(c->field)); \
62   }
63
64 /**
65   A CpdListAccessor responds to CCS requests for a single CpdList.
66   To make some data available via the CpdList interface, you 
67   make a subclass of this class (possibly CpdSimpleListAccessor),
68   and pass it to CpdListRegister, below.
69 */
70 class CpdListAccessor {
71 protected:
72   /**
73     Subclasses must call this before pupping each requested item.
74     This inserts a marker to allow the client to distinguish between
75     different CpdList items. 
76   */
77   void beginItem(PUP::er &p,int itemNo);
78   /// Decides if this CpdList requires boundary checking
79   bool checkBound;
80 public:
81   CpdListAccessor() : checkBound(true) {}
82   virtual ~CpdListAccessor(); 
83   /// Return the CpdList path CCS clients should use to access this data.
84   virtual const char *getPath(void) const =0;
85   /// Return the length of this CpdList.
86   virtual size_t getLength(void) const =0;
87   /// Does this CpdList requires boundary checking?
88   virtual bool checkBoundary(void) const { return checkBound; }
89   /// Pup the items listed in this request.  Be sure to call beginItem between items!
90   virtual void pup(PUP::er &p,CpdListItemsRequest &req) =0;
91 };
92
93 /**
94   Register this CpdListAccessor with Cpd.  The accessor
95   will then be called to respond to CCS requests for its path.
96   CpdList will eventually delete this object.
97 */
98 void CpdListRegister(CpdListAccessor *acc);
99
100 class CpdListAccessor_c : public CpdListAccessor {
101   const char *path; //Path to this item
102   CpdListLengthFn_c lenFn;
103   void *lenParam;
104   CpdListItemsFn_c itemsFn;
105   void *itemsParam;
106 public:
107   CpdListAccessor_c(const char *path_,
108             CpdListLengthFn_c lenFn_,void *lenParam_,
109             CpdListItemsFn_c itemsFn_,void *itemsParam_,bool checkBoundary_=true):
110         path(path_), lenFn(lenFn_), lenParam(lenParam_), 
111         itemsFn(itemsFn_), itemsParam(itemsParam_) {checkBound = checkBoundary_;}
112   CpdListAccessor_c(const CpdListAccessor_c &p);//You don't want to copy
113   void operator=(const CpdListAccessor_c &p);   // You don't want to copy
114   
115   virtual const char *getPath(void) const {return path;}
116   virtual size_t getLength(void) const {return (*lenFn)(lenParam);}
117   virtual void pup(PUP::er &p,CpdListItemsRequest &req) {
118     (itemsFn)(itemsParam,(pup_er *)&p,&req);
119   }
120 };
121
122 /**
123   A typical CpdList accessor: length is stored at some fixed 
124    location in memory, path is a constant string, and the 
125    pup routine is completely random-access.
126 */
127 class CpdSimpleListAccessor : public CpdListAccessor {
128 public:
129         /// This routine is called to pup each item of the list.
130         ///  beginItem has already been called before this function.
131         typedef void (*pupFn)(PUP::er &p,int itemNo);
132 private:
133         const char *path;
134         size_t &length;
135         pupFn pfn;
136 public:
137         /**
138           Create a new CpdSimpleListAccessor.
139              \param path_ CpdList path CCS clients should use.
140              \param length_ Reference to number of elements in the list.
141                             This class keeps the reference, so as the list length
142                             changes, Cpd always has the latest value.
143                             In particular, this means length must not be moved!
144              \param pfn_ Function to pup the items in the list.
145         */
146         CpdSimpleListAccessor(const char *path_,size_t &length_,pupFn pfn_)
147                 :path(path_),length(length_),pfn(pfn_) { }
148         virtual ~CpdSimpleListAccessor();
149         virtual const char *getPath(void) const;
150         virtual size_t getLength(void) const;
151         virtual void pup(PUP::er &p,CpdListItemsRequest &req);
152 };
153
154 #endif