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