The new version of comlib! This version passed "make test" in charm/tests on order...
[charm.git] / src / conv-com / petable.h
1 /*****************************************************************************
2  * $Source$
3  * $Author$
4  * $Date$
5  * $Revision$
6  *****************************************************************************/
7 /**
8    @addtogroup ConvComlib
9    @{
10    @file 
11    @brief Stores lists of messages and sizes from multiple PEs
12
13    This header is meant for usage with ExtractAndVectorize and
14    ExtractAndVectorizeAll. It will contain a list of messages with its sizes.
15    The parent class will later call a CmiFree to sizes and msgs. This will
16    delete this two arrays, and also the containint ptvectorlist struct. This is
17    done (in the two functions) by allocating a single message containing both
18    the ptvectorlist struct, and the two arrays. Throught CmiReference
19    (incremented only once), when both the arrays are deleted, the struct will
20    also dirappear.
21    
22 */
23
24 #ifndef PETABLE_H
25 #define PETABLE_H
26
27 #include "router.h"
28
29 #ifndef NULL
30 #define NULL 0
31 #endif
32
33 #define CMK_COMLIB_USE_VECTORIZE 0
34
35 #define MSGQLEN 32
36
37 typedef struct ptinfo {
38   int refCount;
39   int magic;
40   int offset;
41   /*int freelistindex;*/
42   int msgsize;
43   void *msg;
44   struct ptinfo * next;
45 } PTinfo;
46
47 typedef struct ptvectorlist {
48   int count;
49   int *sizes;
50   char **msgs;
51 }* PTvectorlist;
52
53
54
55 /* Reduce the no. of mallocs by allocating from
56  * a free list. By allocating 21 at a time, it allocates
57  * 512 contiguous bytes. */
58 #define PTALLOC(ktmp) {\
59   if (PTFreeList) {\
60         ktmp=PTFreeList;\
61         PTFreeList=ktmp->next;\
62   }\
63   else {\
64         ktmp=(PTinfo *)CmiAlloc(21*sizeof(PTinfo)+sizeof(PTinfo *));\
65         for (int ii=1; ii<20; ++ii) {\
66           ktmp[ii].next = &(ktmp[ii+1]);\
67         }\
68         ktmp[20].next = NULL;\
69         PTFreeList=&(ktmp[1]);\
70         *((PTinfo**)(&ktmp[21]))=PTFreeChunks;\
71         PTFreeChunks=ktmp;\
72   }\
73 }
74
75 #define PTFREE(ktmp) {\
76   ktmp->next=PTFreeList;\
77   PTFreeList=ktmp;\
78 }
79
80 #define PTNEXTCHUNK(ktmp)  (*((PTinfo**)(&ktmp[21])));
81
82 #define REALLOC(ktmp, ksize) {\
83    PTinfo **junkptr=(PTinfo **)CmiAlloc(2*ksize*sizeof(void *));\
84    for (int ki=0; ki<ksize;ki++) junkptr[ki]=ktmp[ki];\
85    CmiFree(ktmp);\
86    ktmp=junkptr;\
87 }
88
89 class PeTable {
90   private:
91     PTinfo ***PeList;
92     CkVec<PTinfo *> ptrvec;
93
94     PTinfo *PTFreeList;
95     PTinfo *PTFreeChunks;
96     //  char * CombBuffer;
97     int *msgnum, *MaxSize;
98     int NumPes;
99     int magic;
100     //GList *FreeList;
101
102     inline int TotalMsgSize(int npe, int *pelist, int *nm, int *nd) {
103         register int totsize=0;
104         magic++;
105         *nm=0;
106         *nd=0;        
107         
108         for (int i=0;i<npe;i++) {            
109             int index = pelist[i];            
110             *nm += msgnum[index];
111             
112             ComlibPrintf("%d: NUM MSGS %d, %d\n", CkMyPe(), index, 
113                          msgnum[index]);
114             
115             for (int j=0;j<msgnum[index];j++) {
116                 if (PeList[index][j]->magic != magic) {                    
117                     int tmp_size = PeList[index][j]->msgsize;
118                     tmp_size = ALIGN8(tmp_size);                
119                     totsize += tmp_size;                
120                     totsize += sizeof(int)+sizeof(int);                    
121                     PeList[index][j]->magic=magic;
122                     (*nd)++;
123                 }
124             }
125         }
126         return(totsize);
127     }
128
129  public:
130     
131     PeTable(int n);
132     ~PeTable();
133     
134     inline void InsertMsgs(int npe, int *pelist, int size, void *msg) {
135         PTinfo *tmp;
136         PTALLOC(tmp);
137         tmp->refCount=0;
138         tmp->magic=0;
139         tmp->offset=0;
140         /*tmp->freelistindex=-1;*/
141         tmp->msgsize=size;
142         tmp->msg=msg;
143         
144         for (int j=0;j<npe;j++) {
145             tmp->refCount++;
146             int index=pelist[j];
147             
148             ComlibPrintf("[%d] Inserting %d %d %d\n", CkMyPe(), 
149                          msgnum[index], index, size);
150             
151             if (msgnum[index] >= MaxSize[index]) {
152                 REALLOC(PeList[index], MaxSize[index]);
153                 MaxSize[index] *= 2;
154             }
155             PeList[index][msgnum[index]]=tmp;
156             msgnum[index]++;
157         }
158     }
159
160     inline void InsertMsgs(int npe, int *pelist, int nmsgs, void **msglist){
161         msgstruct **m=(msgstruct **)msglist;
162         for (int i=0;i<nmsgs;i++)
163             InsertMsgs(npe, pelist, m[i]->msgsize, m[i]->msg);
164     }
165         
166     void ExtractAndDeliverLocalMsgs(int pe, Strategy *myStrat);
167     
168     int UnpackAndInsert(void *in);
169     int UnpackAndInsertAll(void *in, int npes, int *pelist);
170     
171     char * ExtractAndPack(comID, int, int, int *pelist, int *length); 
172     char * ExtractAndPackAll(comID id, int ufield, int *length);
173     
174     struct ptvectorlist * ExtractAndVectorize(comID, int, int, int *pelist); 
175     struct ptvectorlist * ExtractAndVectorizeAll(comID id, int ufield);
176     
177     void GarbageCollect();
178     void Purge();
179 };
180
181 #endif
182
183 /*@}*/