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