2 #ifndef PUP_CMIALLOC_H__
3 #define PUP_CMIALLOC_H__
13 /******** CMIALLOC buffer management functions ******/
15 /* Given a user chunk m, extract the enclosing chunk header fields: */
16 #define SIZEFIELD(m) (((CmiChunkHeader *)(m))[-1].size)
17 #define REFFIELD(m) (((CmiChunkHeader *)(m))[-1].ref)
18 #define BLKSTART(m) (((CmiChunkHeader *)(m))-1)
20 //Align data sizes to 8 bytes
21 #define ALIGN8_LONG(x) (long)((~7)&((x)+7))
23 //Assuming Size of CmiChunkHeader is a multiple of 8 bytes!!
25 /*For CMI alloc'ed memory
26 CmiAlloc currently has the following memory footprint
28 |int size|int ref|user allocated buffer|
30 The ref count can be set so that a sub buffers can be individually
31 freed. When all sub buffers have been individually freed the
32 super buffer is freed. This is very use ful for message combining.
34 For example, the memory foot print of a combined message could
37 |size_bigbuf|ref_bigbuf|begin_bigbuf
38 ..... |size_subbuf1|ref_subbuf1|subbuf1|
39 .... |size_subbuf2|ref_subbuf2|subbuf2|
40 ..... |size_subbufk|ref_subbufk|subbufk|
42 The usr program can then get use each of the sub_bufs
43 sub_buf1, ... , sub_bufk
45 These sub_bufs could be converse messages or just data pointers
47 To create such a combined message, the pup framwork can be used
49 PUP_cmiAllocSizer psizer;
50 for(count = 0; count < k; count++)
51 psizer.pupCmiAllocBuf(&sub_buf[k]);
53 void *bigbuf = CmiAlloc(psizer.size());
54 PUP_toCmiAllocMem pmem(bigbuf);
56 for(count = 0; count < k; count++)
57 pmem.pupCmiAllocBuf(&sub_buf[k]);
59 //NOW big buf has all the subbuffers
60 //If you also add a converse header to it it can become a
63 //To extract sub buffers from bigbuf
64 PUP_fromCmiAllocMem pfmem(bigbuf);
66 //Notice not memory allocation or copying needed on the
68 for(count = 0; count < k; count++)
69 pfmem.pupCmiAllocBuf(&sub_buf[k]);
72 To free these buffers the user program on the destination after
73 receiving the messages MUST CALL!!
81 The current test for this code is in src/ck-com/MsgPacker.C
82 I will later port CmiMultipleSend
85 class PUP_cmiAllocSizer
: public PUP::sizer
{
87 //Generic bottleneck: n items of size itemSize
88 virtual void bytes(void *p
,int n
,size_t itemSize
,PUP::dataType t
);
90 //Write data to the given buffer
91 PUP_cmiAllocSizer(void): PUP::sizer() {}
93 //Must be a CmiAlloced buf while packing
94 void pupCmiAllocBuf(void **msg
);
96 //In case source is not CmiAlloced the size can be passed and any
97 //user buf can be converted into a cmialloc'ed buf
98 void pupCmiAllocBuf(void **msg
, int msg_size
);
102 //For packing into a preallocated, presized memory cmialloc'ed buffer
103 //Can use reference counting to reduce one level of copying on the
105 class PUP_toCmiAllocMem
: public PUP::toMem
{
107 //Generic bottleneck: pack n items of size itemSize from p.
108 virtual void bytes(void *p
,int n
,size_t itemSize
, PUP::dataType t
);
111 //Write data to the given buffer
112 PUP_toCmiAllocMem(int size
): PUP::toMem(CmiAlloc(size
)) {}
113 PUP_toCmiAllocMem(void *buf
): PUP::toMem(buf
) {}
115 //Copy the size of the buffer and the reference count while packing
116 //Get the buffer directly from the message while unpacking
118 void pupCmiAllocBuf(void **msg
);
120 //Non cmialloc'ed buffers can also be passed and pupped as a
121 //cmialloc'ed buffers
122 void pupCmiAllocBuf(void **msg
, int size
);
126 //For unpacking from a memory buffer
127 class PUP_fromCmiAllocMem
: public PUP::fromMem
{
129 //Generic bottleneck: unpack n items of size itemSize from p.
130 virtual void bytes(void *p
,int n
,size_t itemSize
, PUP::dataType t
);
132 //Read data from the given buffer
133 //The buffer SHOULD have been CMIALLOC'ed
134 PUP_fromCmiAllocMem(const void *Nbuf
): PUP::fromMem(Nbuf
) {}
136 //Copy the size of the buffer and the reference count while packing
137 //Get the buffer directly from the message while unpacking
139 void pupCmiAllocBuf(void **msg
);
141 //size is irrelevant and for consistency with toCmiAllocMem
142 void pupCmiAllocBuf(void **msg
, int size
) {