NAMD
packmsg.h
Go to the documentation of this file.
1 
7 #ifndef PACKMSG_H
8 #define PACKMSG_H
9 
10 /* Macros for automatically packing and unpacking messages.
11 
12 Usage:
13 
14 PACK_MSG(MyMsg,
15  PACK_THIS; // for the lazy, bit-copies the whole object, may be unsafe
16  PACK(myint);
17  PACK(myfloat);
18  PACK_RESIZE(myvector); // needs size(), resize(), and begin()
19  PACK_ARRAY(myarray,n); // n must be a message field and is also sent
20  PACK_AND_NEW_ARRAY(myarray2,n); // also calls new [] but not delete []
21 )
22 
23 */
24 
25 #define ALIGN_8(x) (((unsigned long)x + 7) & (~7))
26 
27 #define PACKMSG_CHECKSUM(X)
28 
29 template<class T> class ResizeArray;
30 
31 template<class T> inline size_t sizeof_element(ResizeArray<T> &) { return sizeof(T); }
32 
33 template<class T> inline T* new_array(T*, int n) { return new T[n]; }
34 
35 #define PACK_MSG(MSGTYPE,MSGDATA) \
36 void *MSGTYPE::pack(MSGTYPE *packmsg_msg) { \
37  PACKMSG_CHECKSUM(unsigned int packmsg_checksum = 0;) \
38  int packmsg_size = 0; \
39  char *packmsg_cur = 0; \
40  { \
41  const int packmsg_pass = 0; \
42  PACKMSG_CHECKSUM( \
43  packmsg_size += sizeof(packmsg_checksum); \
44  PACK_MEMORY(&packmsg_size,sizeof(packmsg_size)); \
45  ) \
46  MSGDATA \
47  } \
48  void *packmsg_buf = CkAllocBuffer(packmsg_msg,packmsg_size); \
49  packmsg_cur = (char *)packmsg_buf; \
50  { \
51  const int packmsg_pass = 1; \
52  PACKMSG_CHECKSUM( \
53  packmsg_cur += sizeof(packmsg_checksum); \
54  PACK_MEMORY(&packmsg_size,sizeof(packmsg_size)); \
55  ) \
56  MSGDATA \
57  } \
58  PACKMSG_CHECKSUM( \
59  packmsg_cur = (char *)packmsg_buf; \
60  for ( int i=sizeof(packmsg_checksum); i < packmsg_size; i++ ) { \
61  packmsg_checksum += (unsigned char) packmsg_cur[i]; \
62  } \
63  CmiMemcpy(packmsg_buf,(void *)&packmsg_checksum,sizeof(packmsg_checksum)); \
64  ) \
65  delete packmsg_msg; \
66  return packmsg_buf; \
67 } \
68  \
69 MSGTYPE *MSGTYPE::unpack(void *packmsg_buf) { \
70  PACKMSG_CHECKSUM( \
71  unsigned int packmsg_checksum = 0; \
72  unsigned int packmsg_checksum_orig = 0; \
73  ) \
74  int packmsg_size = 0; \
75  void *packmsg_msg_ = CkAllocBuffer(packmsg_buf,sizeof(MSGTYPE)); \
76  MSGTYPE *packmsg_msg = new (packmsg_msg_) MSGTYPE; \
77  char *packmsg_cur = (char *)packmsg_buf; \
78  { \
79  const int packmsg_pass = 2; \
80  PACKMSG_CHECKSUM( \
81  CmiMemcpy((void *)&packmsg_checksum_orig,(void *)packmsg_cur, \
82  sizeof(packmsg_checksum)); \
83  packmsg_cur += sizeof(packmsg_checksum); \
84  PACK_MEMORY(&packmsg_size,sizeof(packmsg_size)); \
85  char *packmsg_cur2 = (char *)packmsg_buf; \
86  for ( int i=sizeof(packmsg_checksum); i < packmsg_size; i++ ) { \
87  packmsg_checksum += (unsigned char) packmsg_cur2[i]; \
88  } \
89  if ( packmsg_checksum != packmsg_checksum_orig ) { \
90  char errmsg[256]; \
91  sprintf(errmsg,"PACKMSG checksums do not agree! %s(%d): %d vs %d", \
92  __FILE__, __LINE__, packmsg_checksum, packmsg_checksum_orig); \
93  NAMD_bug(errmsg); \
94  } \
95  ) \
96  MSGDATA \
97  } \
98  CkFreeMsg(packmsg_buf); \
99  return packmsg_msg; \
100 }
101 
102 #define PACK_MEMORY(BUF,SIZE) { \
103  int ASIZE = ALIGN_8(SIZE); \
104  switch ( packmsg_pass ) { \
105  case 0: \
106  packmsg_size += (ASIZE); \
107  break; \
108  case 1: \
109  CmiMemcpy((void *)packmsg_cur,(void *)(BUF),(SIZE)); \
110  packmsg_cur += (ASIZE); \
111  break; \
112  case 2: \
113  CmiMemcpy((void *)(BUF),(void *)packmsg_cur,(SIZE)); \
114  packmsg_cur += (ASIZE); \
115  break; \
116  default: \
117  break; \
118  } \
119 }
120 
121 #define PACK_THIS PACK_MEMORY(packmsg_msg,sizeof(*packmsg_msg));
122 
123 #define PACK(DATA) PACK_MEMORY(&(packmsg_msg->DATA),sizeof(packmsg_msg->DATA))
124 
125 #define PACK_RESIZE(DATA) { \
126  int packmsg_array_len = packmsg_msg->DATA.size(); \
127  PACK_MEMORY(&packmsg_array_len,sizeof(packmsg_array_len)); \
128  if ( packmsg_pass == 2 ) packmsg_msg->DATA.resize(packmsg_array_len); \
129  int packmsg_array_size = \
130  packmsg_array_len * sizeof_element(packmsg_msg->DATA); \
131  PACK_MEMORY(packmsg_msg->DATA.begin(),packmsg_array_size); \
132 }
133 
134 #define PACK_ARRAY(DATA,LEN) { \
135  PACK(LEN); \
136  PACK_MEMORY(packmsg_msg->DATA,packmsg_msg->LEN*sizeof(*(packmsg_msg->DATA))); \
137 }
138 
139 #define PACK_AND_NEW_ARRAY(DATA,LEN) { \
140  PACK(LEN)\
141  if ( packmsg_pass == 2 ) { \
142  packmsg_msg->DATA = new_array(packmsg_msg->DATA,packmsg_msg->LEN); \
143  } \
144  PACK_MEMORY(packmsg_msg->DATA,packmsg_msg->LEN*sizeof(*(packmsg_msg->DATA))); \
145 }
146 
147 #endif
148 
T * new_array(T *, int n)
Definition: packmsg.h:33
size_t sizeof_element(ResizeArray< T > &)
Definition: packmsg.h:31