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