
00001 00002 #ifndef PUP_CMIALLOC_H__ 00003 #define PUP_CMIALLOC_H__ 00004 00005 #include "pup.h" 00006 #include "converse.h" 00007 00008 #include <stdio.h> 00009 #include <stdlib.h> 00010 #include <string.h> 00011 #include <ctype.h> 00012 00013 /******** CMIALLOC buffer management functions ******/ 00014 00015 /* Given a user chunk m, extract the enclosing chunk header fields: */ 00016 #define SIZEFIELD(m) (((CmiChunkHeader *)(m))[-1].size) 00017 #define REFFIELD(m) (((CmiChunkHeader *)(m))[-1].ref) 00018 #define BLKSTART(m) (((CmiChunkHeader *)(m))-1) 00019 00020 //Align data sizes to 8 bytes 00021 #define ALIGN8_LONG(x) (long)((~7)&((x)+7)) 00022 00023 //Assuming Size of CmiChunkHeader is a multiple of 8 bytes!! 00024 00025 /*For CMI alloc'ed memory 00026 CmiAlloc currently has the following memory footprint 00027 00028 |int size|int ref|user allocated buffer| 00029 00030 The ref count can be set so that a sub buffers can be individually 00031 freed. When all sub buffers have been individually freed the 00032 super buffer is freed. This is very use ful for message combining. 00033 00034 For example, the memory foot print of a combined message could 00035 look like this 00036 00037 |size_bigbuf|ref_bigbuf|begin_bigbuf 00038 ..... |size_subbuf1|ref_subbuf1|subbuf1| 00039 .... |size_subbuf2|ref_subbuf2|subbuf2| 00040 ..... |size_subbufk|ref_subbufk|subbufk| 00041 00042 The usr program can then get use each of the sub_bufs 00043 sub_buf1, ... , sub_bufk 00044 00045 These sub_bufs could be converse messages or just data pointers 00046 00047 To create such a combined message, the pup framwork can be used 00048 00049 PUP_cmiAllocSizer psizer; 00050 for(count = 0; count < k; count++) 00051 psizer.pupCmiAllocBuf(&sub_buf[k]); 00052 00053 void *bigbuf = CmiAlloc(psizer.size()); 00054 PUP_toCmiAllocMem pmem(bigbuf); 00055 00056 for(count = 0; count < k; count++) 00057 pmem.pupCmiAllocBuf(&sub_buf[k]); 00058 00059 //NOW big buf has all the subbuffers 00060 //If you also add a converse header to it it can become a 00061 //converse message 00062 00063 //To extract sub buffers from bigbuf 00064 PUP_fromCmiAllocMem pfmem(bigbuf); 00065 00066 //Notice not memory allocation or copying needed on the 00067 //destination 00068 for(count = 0; count < k; count++) 00069 pfmem.pupCmiAllocBuf(&sub_buf[k]); 00070 00071 00072 To free these buffers the user program on the destination after 00073 receiving the messages MUST CALL!! 00074 00075 CmiFree(sub_buf[1]); 00076 .... 00077 CmiFree(sub_buf[k]); 00078 */ 00079 00085 class PUP_cmiAllocSizer : public PUP::sizer { 00086 protected: 00087 //Generic bottleneck: n items of size itemSize 00088 virtual void bytes(void *p,int n,size_t itemSize,PUP::dataType t); 00089 public: 00090 //Write data to the given buffer 00091 PUP_cmiAllocSizer(void): PUP::sizer() {} 00092 00093 //Must be a CmiAlloced buf while packing 00094 void pupCmiAllocBuf(void **msg); 00095 00096 //In case source is not CmiAlloced the size can be passed and any 00097 //user buf can be converted into a cmialloc'ed buf 00098 void pupCmiAllocBuf(void **msg, int msg_size); 00099 }; 00100 00101 00102 //For packing into a preallocated, presized memory cmialloc'ed buffer 00103 //Can use reference counting to reduce one level of copying on the 00104 //receiver 00105 class PUP_toCmiAllocMem : public PUP::toMem { 00106 protected: 00107 //Generic bottleneck: pack n items of size itemSize from p. 00108 virtual void bytes(void *p,int n,size_t itemSize, PUP::dataType t); 00109 00110 public: 00111 //Write data to the given buffer 00112 PUP_toCmiAllocMem(int size): PUP::toMem(CmiAlloc(size)) {} 00113 PUP_toCmiAllocMem(void *buf): PUP::toMem(buf) {} 00114 00115 //Copy the size of the buffer and the reference count while packing 00116 //Get the buffer directly from the message while unpacking 00117 //Saves on a copy 00118 void pupCmiAllocBuf(void **msg); 00119 00120 //Non cmialloc'ed buffers can also be passed and pupped as a 00121 //cmialloc'ed buffers 00122 void pupCmiAllocBuf(void **msg, int size); 00123 }; 00124 00125 00126 //For unpacking from a memory buffer 00127 class PUP_fromCmiAllocMem : public PUP::fromMem { 00128 protected: 00129 //Generic bottleneck: unpack n items of size itemSize from p. 00130 virtual void bytes(void *p,int n,size_t itemSize, PUP::dataType t); 00131 public: 00132 //Read data from the given buffer 00133 //The buffer SHOULD have been CMIALLOC'ed 00134 PUP_fromCmiAllocMem(const void *Nbuf): PUP::fromMem(Nbuf) {} 00135 00136 //Copy the size of the buffer and the reference count while packing 00137 //Get the buffer directly from the message while unpacking 00138 //Saves on a copy 00139 void pupCmiAllocBuf(void **msg); 00140 00141 //size is irrelevant and for consistency with toCmiAllocMem 00142 void pupCmiAllocBuf(void **msg, int size) { 00143 pupCmiAllocBuf(msg); 00144 } 00145 }; 00146 00147 #endif
1.5.5