changes
[IRC.git] / Robust / src / Runtime / bamboo / multicoremem.c
1 #if defined(MULTICORE)&&defined(MULTICORE_GC)
2 #include "runtime_arch.h"
3 #include "multicoreruntime.h"
4 #include "multicoregarbage.h"
5 #include "multicorehelper.h"
6 #include "multicoremem_helper.h"
7
8 // Only allocate local mem chunks to each core.
9 // If a core has used up its local shared memory, start gc.
10 void * localmalloc_I(int coren, unsigned INTPTR memcheck, unsigned INTPTR * allocsize) {
11   for(block_t localblocknum=0;localblocknum<GCNUMLOCALBLOCK;localblocknum++) {
12     block_t searchblock=BLOCKINDEX2(coren, localblocknum);
13     if (searchblock>=GCNUMBLOCK)
14       return NULL;
15     struct blockrecord * block=&allocationinfo.blocktable[searchblock];
16     if (block->status==BS_FREE) {
17       unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
18       if (freespace>=memcheck) {
19         //we have a block
20         //mark block as used
21         block->status=BS_USED;
22         void *blockptr=OFFSET2BASEVA(searchblock)+gcbaseva;
23         unsigned INTPTR usedspace=((block->usedspace-1)&~BAMBOO_CACHE_LINE_MASK)+BAMBOO_CACHE_LINE_SIZE;
24         void *startaddr=blockptr+usedspace;
25         *allocsize=freespace;
26         return startaddr;
27       }
28     }
29   }
30   
31   return NULL;
32
33
34 // Allocate the local shared memory to each core with the highest priority,
35 // if a core has used up its local shared memory, try to allocate the 
36 // shared memory that belong to its neighbours, if also failed, start gc.
37 void * fixedmalloc_I(int coren, unsigned INTPTR memcheck, unsigned INTPTR * allocsize) {
38   //try locally first
39   void * mem=localmalloc_I(coren,memcheck,allocsize);
40   if (mem!=NULL)
41     return mem;
42
43   //failed try neighbors...in a round robin fashion
44   for(block_t lblock=0;lblock<MAXNEIGHBORALLOC;lblock++) {  
45     for(int i=0;i<NUM_CORES2TEST;i++) {
46       int neighborcore=core2test[coren][i];
47       if (neighborcore!=-1) {
48         block_t globalblockindex=BLOCKINDEX2(neighborcore, lblock);
49         if (globalblockindex>=GCNUMBLOCK||globalblockindex<0)
50           return NULL;
51         struct blockrecord * block=&allocationinfo.blocktable[globalblockindex];
52         if (block->status==BS_FREE) {
53           unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
54           if (freespace>=memcheck) {
55             //we have a block
56             //mark block as used
57             block->status=BS_USED;
58             void *blockptr=OFFSET2BASEVA(globalblockindex)+gcbaseva;
59             unsigned INTPTR usedspace=((block->usedspace-1)&~BAMBOO_CACHE_LINE_MASK)+BAMBOO_CACHE_LINE_SIZE;
60             *allocsize=freespace;
61             return blockptr+usedspace;
62           }
63         }
64       }
65     }
66   }
67   //no memory
68   return NULL;
69
70
71
72 // Allocate the local shared memory to each core with the highest priority,
73 // if a core has used up its local shared memory, try to allocate the 
74 // shared memory that belong to its neighbours first, if failed, check 
75 // current memory allocation rate, if it has already reached the threshold,
76 // start gc, otherwise, allocate the shared memory globally.  If all the 
77 // shared memory has been used up, start gc.
78 void * mixedmalloc_I(int coren, unsigned INTPTR isize, unsigned INTPTR * allocsize) {
79   void * mem=fixedmalloc_I(coren,isize,allocsize);
80   if (mem!=NULL)
81     return mem;
82
83   //try global allocator instead
84   return globalmalloc_I(coren, isize, allocsize);
85
86
87
88 // Allocate all the memory chunks globally, do not consider the host cores
89 // When all the shared memory are used up, start gc.
90 void * globalmalloc_I(int coren, unsigned INTPTR memcheck, unsigned INTPTR * allocsize) {
91   block_t firstfree=NOFREEBLOCK;
92   block_t lowestblock=allocationinfo.lowestfreeblock;
93   for(block_t searchblock=lowestblock;searchblock<GCNUMBLOCK;searchblock++) {
94     struct blockrecord * block=&allocationinfo.blocktable[searchblock];
95     if (block->status==BS_FREE) {
96       if(firstfree==NOFREEBLOCK)
97         firstfree=searchblock;
98       unsigned INTPTR freespace=block->freespace&~BAMBOO_CACHE_LINE_MASK;
99       if (freespace>=memcheck) {
100         //we have a block
101         //mark block as used
102         block->status=BS_USED;
103         void *blockptr=OFFSET2BASEVA(searchblock)+gcbaseva;
104         unsigned INTPTR usedspace=((block->usedspace-1)&~BAMBOO_CACHE_LINE_MASK)+BAMBOO_CACHE_LINE_SIZE;
105         allocationinfo.lowestfreeblock=firstfree;
106         void *startaddr=blockptr+usedspace;
107         *allocsize=freespace;
108         return startaddr;
109       }
110     }
111   }
112   return NULL;
113
114
115 void * smemalloc(int coren, unsigned INTPTR isize, unsigned INTPTR * allocsize) {
116   BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
117   void *retval=smemalloc_I(coren, isize, allocsize);
118   BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
119   return retval;
120 }
121
122 // malloc from the shared memory
123 void * smemalloc_I(int coren, unsigned INTPTR isize, unsigned INTPTR * allocsize) {
124 #ifdef SMEML
125   void *mem = localmalloc_I(coren, isize, allocsize);
126 #elif defined(SMEMF)
127   void *mem = fixedmalloc_I(coren, isize, allocsize);
128 #elif defined(SMEMM)
129   void *mem = mixedmalloc_I(coren, isize, allocsize);
130 #elif defined(SMEMG)
131   void *mem = globalmalloc_I(coren, isize, allocsize);
132 #endif
133
134   if(mem == NULL) {
135     // not enough shared global memory
136     // trigger gc
137     if(!gcflag) {
138       gcflag = true;
139       if(!gc_status_info.gcprocessing) {
140         // inform other cores to stop and wait for gc
141         gcprecheck = true;
142         for(int i = 0; i < NUMCORESACTIVE; i++) {
143           // reuse the gcnumsendobjs & gcnumreceiveobjs
144           gcnumsendobjs[0][i] = 0;
145           gcnumreceiveobjs[0][i] = 0;
146         }
147         GC_SEND_MSG_1_TO_CLIENT(GCSTARTPRE);
148       }
149     }
150   }
151   return mem;
152 }
153 #else
154 // malloc from the shared memory
155 void * smemalloc_I(int coren, unsigned INTPTR size, unsigned INTPTR * allocsize) {
156   void * mem = NULL;
157   int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
158   if(toallocate > bamboo_free_smem_size) {
159     // no enough mem
160     mem = NULL;
161   } else {
162     mem = (void *)bamboo_free_smemp;
163     bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
164     bamboo_free_smem_size -= toallocate;
165   }
166   *allocsize = toallocate;
167   if(mem == NULL) {
168     // no enough shared global memory
169     *allocsize = 0;
170     BAMBOO_EXIT();
171   }
172   return mem;
173
174 #endif