00001
00007 #ifndef PACKMSG_H
00008 #define PACKMSG_H
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
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