packmsg.h

Go to the documentation of this file.
00001 
00007 #ifndef PACKMSG_H
00008 #define PACKMSG_H
00009 
00010 /* Macros for automatically packing and unpacking messages.
00011 
00012 Usage:
00013 
00014 PACK_MSG(MyMsg,
00015   PACK_THIS;  // for the lazy, bit-copies the whole object, may be unsafe
00016   PACK(myint);
00017   PACK(myfloat);
00018   PACK_RESIZE(myvector);  // needs size(), resize(), and begin()
00019   PACK_ARRAY(myarray,n);  // n must be a message field and is also sent
00020   PACK_AND_NEW_ARRAY(myarray2,n);  // also calls new [] but not delete []
00021 )
00022 
00023 */
00024 
00025 #define ALIGN_8(x)   (((unsigned long)x + 7) & (~7))
00026 
00027 #define PACKMSG_CHECKSUM(X)
00028 
00029 template<class T> class ResizeArray;
00030 
00031 template<class T> inline size_t sizeof_element(ResizeArray<T> &) { return sizeof(T); }
00032 
00033 template<class T> inline T* new_array(T*, int n) { return new T[n]; }
00034 
00035 #define PACK_MSG(MSGTYPE,MSGDATA) \
00036 void *MSGTYPE::pack(MSGTYPE *packmsg_msg) { \
00037   PACKMSG_CHECKSUM(unsigned int packmsg_checksum = 0;) \
00038   int packmsg_size = 0; \
00039   char *packmsg_cur = 0; \
00040   { \
00041     const int packmsg_pass = 0; \
00042     PACKMSG_CHECKSUM( \
00043       packmsg_size += sizeof(packmsg_checksum); \
00044       PACK_MEMORY(&packmsg_size,sizeof(packmsg_size)); \
00045     ) \
00046     MSGDATA \
00047   } \
00048   void *packmsg_buf = CkAllocBuffer(packmsg_msg,packmsg_size); \
00049   packmsg_cur = (char *)packmsg_buf; \
00050   { \
00051     const int packmsg_pass = 1; \
00052     PACKMSG_CHECKSUM( \
00053       packmsg_cur += sizeof(packmsg_checksum); \
00054       PACK_MEMORY(&packmsg_size,sizeof(packmsg_size)); \
00055     ) \
00056     MSGDATA \
00057   } \
00058   PACKMSG_CHECKSUM( \
00059     packmsg_cur = (char *)packmsg_buf; \
00060     for ( int i=sizeof(packmsg_checksum); i < packmsg_size; i++ ) { \
00061       packmsg_checksum += (unsigned char) packmsg_cur[i]; \
00062     } \
00063     CmiMemcpy(packmsg_buf,(void *)&packmsg_checksum,sizeof(packmsg_checksum)); \
00064   ) \
00065   delete packmsg_msg; \
00066   return packmsg_buf; \
00067 } \
00068  \
00069 MSGTYPE *MSGTYPE::unpack(void *packmsg_buf) { \
00070   PACKMSG_CHECKSUM( \
00071     unsigned int packmsg_checksum = 0; \
00072     unsigned int packmsg_checksum_orig = 0; \
00073   ) \
00074   int packmsg_size = 0; \
00075   void *packmsg_msg_ = CkAllocBuffer(packmsg_buf,sizeof(MSGTYPE)); \
00076   MSGTYPE *packmsg_msg = new (packmsg_msg_) MSGTYPE; \
00077   char *packmsg_cur = (char *)packmsg_buf; \
00078   { \
00079     const int packmsg_pass = 2; \
00080     PACKMSG_CHECKSUM( \
00081       CmiMemcpy((void *)&packmsg_checksum_orig,(void *)packmsg_cur, \
00082                                 sizeof(packmsg_checksum)); \
00083       packmsg_cur += sizeof(packmsg_checksum); \
00084       PACK_MEMORY(&packmsg_size,sizeof(packmsg_size)); \
00085       char *packmsg_cur2 = (char *)packmsg_buf; \
00086       for ( int i=sizeof(packmsg_checksum); i < packmsg_size; i++ ) { \
00087         packmsg_checksum += (unsigned char) packmsg_cur2[i]; \
00088       } \
00089       if ( packmsg_checksum != packmsg_checksum_orig ) { \
00090         char errmsg[256]; \
00091         sprintf(errmsg,"PACKMSG checksums do not agree!  %s(%d): %d vs %d", \
00092         __FILE__, __LINE__, packmsg_checksum, packmsg_checksum_orig); \
00093         NAMD_bug(errmsg); \
00094       } \
00095     ) \
00096     MSGDATA \
00097   } \
00098   CkFreeMsg(packmsg_buf); \
00099   return packmsg_msg; \
00100 }
00101 
00102 #define PACK_MEMORY(BUF,SIZE) { \
00103   int ASIZE = ALIGN_8(SIZE); \
00104   switch ( packmsg_pass ) { \
00105   case 0: \
00106     packmsg_size += (ASIZE); \
00107     break; \
00108   case 1: \
00109     CmiMemcpy((void *)packmsg_cur,(void *)(BUF),(SIZE)); \
00110     packmsg_cur += (ASIZE); \
00111     break; \
00112   case 2: \
00113     CmiMemcpy((void *)(BUF),(void *)packmsg_cur,(SIZE)); \
00114     packmsg_cur += (ASIZE); \
00115     break; \
00116   default: \
00117     break; \
00118   } \
00119 }
00120 
00121 #define PACK_THIS PACK_MEMORY(packmsg_msg,sizeof(*packmsg_msg));
00122 
00123 #define PACK(DATA) PACK_MEMORY(&(packmsg_msg->DATA),sizeof(packmsg_msg->DATA))
00124 
00125 #define PACK_RESIZE(DATA) { \
00126   int packmsg_array_len = packmsg_msg->DATA.size(); \
00127   PACK_MEMORY(&packmsg_array_len,sizeof(packmsg_array_len)); \
00128   if ( packmsg_pass == 2 ) packmsg_msg->DATA.resize(packmsg_array_len); \
00129   int packmsg_array_size = \
00130     packmsg_array_len * sizeof_element(packmsg_msg->DATA); \
00131   PACK_MEMORY(packmsg_msg->DATA.begin(),packmsg_array_size); \
00132 }
00133 
00134 #define PACK_ARRAY(DATA,LEN) { \
00135   PACK(LEN); \
00136   PACK_MEMORY(packmsg_msg->DATA,packmsg_msg->LEN*sizeof(*(packmsg_msg->DATA))); \
00137 }
00138 
00139 #define PACK_AND_NEW_ARRAY(DATA,LEN) { \
00140   PACK(LEN)\
00141   if ( packmsg_pass == 2 ) { \
00142     packmsg_msg->DATA = new_array(packmsg_msg->DATA,packmsg_msg->LEN); \
00143   } \
00144   PACK_MEMORY(packmsg_msg->DATA,packmsg_msg->LEN*sizeof(*(packmsg_msg->DATA))); \
00145 }
00146 
00147 #endif
00148 

Generated on Fri Sep 22 01:17:14 2017 for NAMD by  doxygen 1.4.7