Code clean
[IRC.git] / Robust / src / Runtime / bamboo / multicoremem.c
1 #ifdef MULTICORE
2 #include "runtime_arch.h"
3 #include "multicoreruntime.h"
4
5 #ifdef MULTICORE_GC
6 #include "multicorehelper.h"
7 #include "multicoremem_helper.h"
8
9 INLINE void setupsmemmode(void) {
10 #ifdef SMEML
11   // Only allocate local mem chunks to each core.
12   // If a core has used up its local shared memory, start gc.
13   bamboo_smem_mode = SMEMLOCAL;
14 #elif defined SMEMF
15   // Allocate the local shared memory to each core with the highest priority,
16   // if a core has used up its local shared memory, try to allocate the 
17   // shared memory that belong to its neighbours, if also failed, start gc.
18   bamboo_smem_mode = SMEMFIXED;
19 #elif defined SMEMM
20   // Allocate the local shared memory to each core with the highest priority,
21   // if a core has used up its local shared memory, try to allocate the 
22   // shared memory that belong to its neighbours first, if failed, check 
23   // current memory allocation rate, if it has already reached the threshold,
24   // start gc, otherwise, allocate the shared memory globally.  If all the 
25   // shared memory has been used up, start gc.
26   bamboo_smem_mode = SMEMMIXED;
27 #elif defined SMEMG
28   // Allocate all the memory chunks globally, do not consider the host cores
29   // When all the shared memory are used up, start gc.
30   bamboo_smem_mode = SMEMGLOBAL;
31 #else
32   // defaultly using local mode
33   bamboo_smem_mode = SMEMLOCAL;
34 #endif 
35
36
37 INLINE void * mallocmem(int tofindb,
38                         int totest,
39                         int size,
40                         int * allocsize) {
41   void * mem = NULL;
42   // find suitable block
43   mem=gcbaseva+bamboo_smemtbl[tofindb]+OFFSET2BASEVA(tofindb);
44   *allocsize = size;
45   // set bamboo_smemtbl
46   for(int i = tofindb; i <= totest; i++) {
47     bamboo_smemtbl[i]=BLOCKSIZE(i<NUMCORES4GC);
48   }
49   if(tofindb == bamboo_free_block) {
50     bamboo_free_block = totest+1;
51   }
52   return mem;
53 }
54
55 INLINE void * searchBlock4Mem(int* tofindb, 
56                               int* totest,
57                               int gccorenum,
58                               int isize,
59                               int * allocsize) {
60   int i=0;
61   int j=0;
62   int size = 0;
63   int bound = BAMBOO_SMEM_SIZE_L;
64   while(*totest<(gcnumblock-bamboo_reserved_smem)) {
65     bound = BLOCKSIZE(*totest<NUMCORES4GC);
66     int nsize = bamboo_smemtbl[*totest];
67     if((nsize==bound)||((nsize != 0)&&(*totest != *tofindb))) {
68       // a fully/partially occupied partition, can not be appended 
69       //the last continuous block is not big enough,check the next local block
70       i++;
71       if(2==i) {
72         i = 0;
73         j++;
74       }
75       *tofindb=*totest=gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
76     } else {
77       // an empty block or a partially occupied block that can be set as the 
78       // first block
79       if(*totest == *tofindb) {
80         // the first partition
81         size = bound - nsize;
82       } else if(nsize == 0) {
83         // an empty partition, can be appended
84         size += bound;
85       } 
86       if(size >= isize) {
87         // have enough space in the block, malloc
88         return mallocmem(*tofindb, *totest, size, allocsize);
89         break;
90       } else {
91         // no enough space yet, try to append next continuous block
92         *totest = *totest + 1;
93       }  
94     }
95   }
96   return NULL;
97 }
98
99 INLINE void * searchBlock4Mem_global(int* tofindb, 
100                                      int* totest,
101                                      int isize,
102                                      int * allocsize) {
103   int i=0;
104   int j=0;
105   int size = 0;
106   int bound = BAMBOO_SMEM_SIZE_L;
107   while(*totest<(gcnumblock-bamboo_reserved_smem)) {
108     bound = BLOCKSIZE(*totest<NUMCORES4GC);
109     int nsize = bamboo_smemtbl[*totest];
110     if((nsize==bound)||((nsize != 0)&&(*totest != *tofindb))) {
111       // a fully/partially occupied partition, can not be appended 
112       // set the next block as a new start
113       *totest = *totest+1;
114       *tofindb = *totest;
115     } else {
116       // an empty block or a partially occupied block that can be set as the 
117       // first block
118       if(*totest == *tofindb) {
119         // the first partition
120         size = bound - nsize;
121       } else if(nsize == 0) {
122         // an empty partition, can be appended
123         size += bound;
124       } 
125       if(size >= isize) {
126         // have enough space in the block, malloc
127         return mallocmem(*tofindb, *totest, size, allocsize);
128         break;
129       } else {
130         // no enough space yet, try to append next continuous block
131         *totest = *totest + 1;
132       }  
133     }
134   }
135   return NULL;
136 }
137
138 // Only allocate local mem chunks to each core.
139 // If a core has used up its local shared memory, start gc.
140 void * localmalloc_I(int coren,
141                      int isize,
142                      int * allocsize) {
143   void * mem = NULL;
144   int gccorenum = (coren<NUMCORES4GC)?(coren):(coren%NUMCORES4GC);
145   int tofindb = gc_core2block[2*gccorenum];
146   int totest = tofindb;
147   mem = searchBlock4Mem(&tofindb, &totest, gccorenum, isize, allocsize);
148   if(mem == NULL) {
149     // no more local mem, do not find suitable block
150     *allocsize = 0;
151   }
152   return mem;
153
154
155 #ifdef SMEMF
156 // Allocate the local shared memory to each core with the highest priority,
157 // if a core has used up its local shared memory, try to allocate the 
158 // shared memory that belong to its neighbours, if also failed, start gc.
159 void * fixedmalloc_I(int coren,
160                      int isize,
161                      int * allocsize) {
162   void * mem;
163   int k;
164   int gccorenum = (coren<NUMCORES4GC)?(coren):(coren%NUMCORES4GC);
165   int totest, tofindb;
166   int bound = BAMBOO_SMEM_SIZE_L;
167   int foundsmem = 0;
168   int size = 0;
169   for(k=0; k<NUM_CORES2TEST; k++) {
170     if(core2test[gccorenum][k] == -1) {
171       // try next neighbour
172       continue;
173     }
174     tofindb=totest=gc_core2block[2*core2test[gccorenum][k]];
175     mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],
176         isize,allocsize);
177     if(mem != NULL) {
178       return mem;
179     }
180   }
181   // no more memory available on either coren or its neighbour cores
182   *allocsize = 0;
183   return NULL;
184
185 #endif 
186
187 #ifdef SMEMM
188 // Allocate the local shared memory to each core with the highest priority,
189 // if a core has used up its local shared memory, try to allocate the 
190 // shared memory that belong to its neighbours first, if failed, check 
191 // current memory allocation rate, if it has already reached the threshold,
192 // start gc, otherwise, allocate the shared memory globally.  If all the 
193 // shared memory has been used up, start gc.
194 void * mixedmalloc_I(int coren,
195                      int isize,
196                      int * allocsize) {
197   void * mem;
198   int k;
199   int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
200   int totest,tofindb;
201   int bound = BAMBOO_SMEM_SIZE_L;
202   int foundsmem = 0;
203   int size = 0;
204   for(k=0; k<NUM_CORES2TEST; k++) {
205     if(core2test[gccorenum][k] == -1) {
206       // try next neighbour
207       continue;
208     }
209     tofindb=totest=gc_core2block[2*core2test[gccorenum][k]];
210     mem=searchBlock4Mem(&tofindb,&totest,core2test[gccorenum][k],
211         isize,allocsize);
212     if(mem != NULL) {
213       gcmem_mixed_usedmem += size;
214       return mem;
215     }
216   }
217   if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
218     // no more memory available on either coren or its neighbour cores
219     *allocsize = 0;
220     return NULL; 
221   } else {
222     // try allocate globally
223     mem = globalmalloc_I(coren, isize, allocsize);
224     if(mem != NULL) {
225       gcmem_mixed_usedmem += size;
226     }
227     return mem;
228   }
229
230 #endif 
231
232 // Allocate all the memory chunks globally, do not consider the host cores
233 // When all the shared memory are used up, start gc.
234 void * globalmalloc_I(int coren,
235                       int isize,
236                       int * allocsize) {
237   void * mem = NULL;
238   int tofindb = bamboo_free_block;
239   int totest = tofindb;
240   int bound = BAMBOO_SMEM_SIZE_L;
241   int foundsmem = 0;
242   int size = 0;
243   if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
244     // Out of shared memory
245     *allocsize = 0;
246     return NULL;
247   }
248   mem=searchBlock4Mem_global(&tofindb, &totest, isize, allocsize);
249   if(mem == NULL) {
250     *allocsize = 0;
251   }
252   return mem;
253
254
255 // malloc from the shared memory
256 void * smemalloc_I(int coren,
257                    int size,
258                    int * allocsize) {
259   void * mem = NULL;
260   int isize = size+(BAMBOO_CACHE_LINE_SIZE);
261
262   // go through the bamboo_smemtbl for suitable partitions
263   switch(bamboo_smem_mode) {
264   case SMEMLOCAL: {
265     mem = localmalloc_I(coren, isize, allocsize);
266     break;
267   }
268
269   case SMEMFIXED: {
270 #ifdef SMEMF
271     mem = fixedmalloc_I(coren, isize, allocsize);
272 #else
273     // not supported yet
274     BAMBOO_EXIT();
275 #endif
276     break;
277   }
278
279   case SMEMMIXED: {
280 #ifdef SMEMM
281     mem = mixedmalloc_I(coren, isize, allocsize);
282 #else
283     // not supported yet
284     BAMBOO_EXIT();
285 #endif
286     break;
287   }
288
289   case SMEMGLOBAL: {
290     mem = globalmalloc_I(coren, isize, allocsize);
291     break;
292   }
293
294   default:
295     break;
296   }
297
298   if(mem == NULL) {
299     // no enough shared global memory
300     *allocsize = 0;
301     if(!gcflag) {
302       gcflag = true;
303       if(!gcprocessing) {
304         // inform other cores to stop and wait for gc
305         gcprecheck = true;
306         for(int i = 0; i < NUMCORESACTIVE; i++) {
307           // reuse the gcnumsendobjs & gcnumreceiveobjs
308           gcnumsendobjs[0][i] = 0;
309           gcnumreceiveobjs[0][i] = 0;
310         }
311         GC_SEND_MSG_1_TO_CLIENT(GCSTARTPRE);
312       }
313     }
314     return NULL;
315   }
316   return mem;
317 }
318 #else
319 // malloc from the shared memory
320 void * smemalloc_I(int coren,
321                    int size,
322                    int * allocsize) {
323   void * mem = NULL;
324   int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
325   if(toallocate > bamboo_free_smem_size) {
326     // no enough mem
327     mem = NULL;
328   } else {
329     mem = (void *)bamboo_free_smemp;
330     bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
331     bamboo_free_smem_size -= toallocate;
332   }
333   *allocsize = toallocate;
334   if(mem == NULL) {
335     // no enough shared global memory
336     *allocsize = 0;
337     BAMBOO_EXIT();
338   }
339   return mem;
340
341 #endif // MULTICORE_GC
342
343 #endif // MULTICORE