bug fixes to get dtlb miss handler working
[IRC.git] / Robust / src / Runtime / bamboo / multicorecache.c
1 #ifdef GC_CACHE_ADAPT
2 #include "multicorecache.h"
3 #include "multicoremsg.h"
4 #include "multicoregcprofile.h"
5
6 gc_cache_revise_info_t gc_cache_revise_information;
7
8 /* This function initialize the gc_cache_revise_information. It should be 
9  * invoked before we start compaction.
10  */
11 void samplingDataReviseInit(struct moveHelper * orig,struct moveHelper * to) {
12   // initialize the destination page info
13   gc_cache_revise_information.to_page_start_va=to->ptr;
14   unsigned int toindex=(unsigned INTPTR)(to->base-gcbaseva)>>BAMBOO_PAGE_SIZE_BITS;
15   gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(toindex+1);
16   gc_cache_revise_information.to_page_index=toindex;
17   // initilaize the original page info
18   unsigned int origindex=((unsigned INTPTR)(orig->base-gcbaseva))>>BAMBOO_PAGE_SIZE_BITS;
19   gc_cache_revise_information.orig_page_start_va=orig->ptr;
20   gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(origindex+1);
21   gc_cache_revise_information.orig_page_index=origindex;
22 }
23
24 /* This function computes the revised profiling data of the first closed destination 
25  * page of an object that acrosses multiple pages
26  */
27 void firstPageConvert(bool origclosefirst, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) {
28   unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
29   unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
30   int * newtable=&gccachesamplingtbl_r[topage];
31   int * oldtable=&gccachesamplingtbl[oldpage];
32   // compute the revised profiling info for the start destination page
33   if(origclosefirst) {
34     // the start original page closes first, now compute the revised profiling
35     // info for the start destination page.
36     // The start destination page = the rest of the start original page + 
37     //                              delta_fator from the next original page
38     int * oldtable_next=&gccachesamplingtbl[oldpage+NUMCORESACTIVE];
39     for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
40       (*newtable)=(*newtable)+((*oldtable)*main_factor+(*oldtable_next)*delta_factor)>>BAMBOO_PAGE_SIZE_BITS;
41       newtable++;
42       oldtable++;
43       oldtable_next++;
44     }
45     // close the start original page 
46     gc_cache_revise_information.orig_page_start_va+=main_factor+delta_factor;
47     gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE;
48     gc_cache_revise_information.orig_page_index++;
49   } else {
50     // the start destination page closes first, now compute the revised 
51     // profiling info for it.
52     for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
53       (*newtable)=(*newtable)+((*oldtable)*main_factor)>>BAMBOO_PAGE_SIZE_BITS;
54       newtable++;
55       oldtable++;
56     }
57     // record the new start of the original page
58     gc_cache_revise_information.orig_page_start_va+=main_factor;
59   }
60   // close the start original page and destination page
61   gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va;
62   gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE;
63   gc_cache_revise_information.to_page_index++;
64 }
65
66 /* This function computes the revised profiling info for closed destination 
67  * pages that are occupied by one object that acrosses multiple pages.
68  * the destination page = main_factor from the first unclosed original page 
69  *                       + delta_factor from the next unclosed original page
70  */
71 void restClosedPageConvert(void * current_ptr, unsigned INTPTR main_factor, unsigned INTPTR delta_factor) {
72   while(gc_cache_revise_information.to_page_end_va<=current_ptr) {
73     unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
74     unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
75     int *newtable=&gccachesamplingtbl_r[topage];
76     int *oldtable=&gccachesamplingtbl[oldpage];
77     int *oldtable_next=&gccachesamplingtbl[oldpage+NUMCORESACTIVE];
78
79     for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
80       (*newtable)=(*newtable)+((*oldtable)*main_factor+(*oldtable_next)*delta_factor)>>BAMBOO_PAGE_SIZE_BITS;
81       newtable++;
82       oldtable++;
83       oldtable_next++;
84     }
85
86     // close the original page and the destination page
87     gc_cache_revise_information.orig_page_start_va+=BAMBOO_PAGE_SIZE;
88     gc_cache_revise_information.orig_page_end_va+=BAMBOO_PAGE_SIZE;
89     gc_cache_revise_information.orig_page_index++;
90     gc_cache_revise_information.to_page_start_va=gc_cache_revise_information.to_page_end_va;
91     gc_cache_revise_information.to_page_end_va+=BAMBOO_PAGE_SIZE;
92     gc_cache_revise_information.to_page_index++;
93   }
94 }
95
96 /* This function computes the revised profiling info for the last
97  * destination page of an object that acrosses multiple pages.
98  */
99 void lastPageConvert(void * current_ptr) {
100   unsigned INTPTR to_factor=current_ptr-gc_cache_revise_information.to_page_start_va;
101   unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
102   unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
103   int *newtable=&gccachesamplingtbl_r[topage];
104   int *oldtable=&gccachesamplingtbl[oldpage];
105
106   for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
107     (*newtable)=(*newtable)+((*oldtable)*to_factor)>>BAMBOO_PAGE_SIZE_BITS;
108     newtable++;
109     oldtable++;
110   }
111   // do not need to set gc_cache_revise_information here for the last 
112   // original/destination page as it will be set in completePageConvert()
113 }
114
115 /* This function converts multiple original pages profiling data to multiple 
116  * destination pages' profiling data
117  */
118 void samplingDataConvertMultiple(void * current_ptr) {
119   // first decide which page close first: original or destination?
120   unsigned INTPTR to_factor=(unsigned INTPTR)(gc_cache_revise_information.to_page_end_va-gc_cache_revise_information.to_page_start_va);
121   unsigned INTPTR orig_factor=(unsigned INTPTR)(gc_cache_revise_information.orig_page_end_va-gc_cache_revise_information.orig_page_start_va);
122   bool origclosefirst=to_factor>orig_factor;
123   unsigned INTPTR delta_factor=(origclosefirst)?(to_factor-orig_factor):(orig_factor-to_factor);
124   unsigned INTPTR main_factor=(origclosefirst)?orig_factor:to_factor;
125
126   // compute the revised profiling info for the start destination page
127   firstPageConvert(origclosefirst, main_factor, delta_factor);
128   // update main_factor/delta_factor
129   if(origclosefirst) {
130     // for the following destination pages that are fully used:
131     // the destination page = (page_size-delta_factor) from the 
132     //                        first unclosed original page + delta_factor 
133     //                        from the next unclosed original page
134     // we always use main_factor to represent the factor from the first 
135     // unclosed original page
136     main_factor=BAMBOO_PAGE_SIZE-delta_factor;
137   } else {
138     // for the following destination pages that are fully used:
139     // the destination page = delta_factor from the first unclosed original    
140     //                        page + (page_size-delta_factor) from the next 
141     //                        unclosed original page
142     // we always use main_factor to represent the factor from the first
143     // unclosed original page
144     main_factor=delta_factor;
145     delta_factor=BAMBOO_PAGE_SIZE-delta_factor;
146   }
147
148   // compute the revised profiling info for the following closed destination
149   // pages
150   restClosedPageConvert(current_ptr, main_factor, delta_factor);
151
152   // compute the revised profiling info for the last destination page if needed
153   lastPageConvert(current_ptr);
154 }
155
156 /* This function converts originial pages' profiling data to destination pages'
157  * profiling data.
158  * The parameter current_ptr indicates the current position in the destination 
159  * pages.
160  * Note that there could be objects that across pages. In such cases, there are 
161  * multiple orig/to pages are closed and all these to pages' profiling data 
162  * should be properly updated.
163  */
164 void samplingDataConvert(void * current_ptr) {
165   if(gc_cache_revise_information.to_page_end_va<current_ptr) {
166     // multiple pages are closed
167     samplingDataConvertMultiple(current_ptr);
168   } else {
169     unsigned INTPTR tmp_factor=(unsigned INTPTR)(current_ptr-gc_cache_revise_information.to_page_start_va);
170     if(tmp_factor) {
171       unsigned INTPTR topage=gc_cache_revise_information.to_page_index*NUMCORESACTIVE;
172       unsigned INTPTR oldpage=gc_cache_revise_information.orig_page_index*NUMCORESACTIVE;
173       int * newtable=&gccachesamplingtbl_r[topage];
174       int * oldtable=&gccachesamplingtbl[oldpage];
175   
176       for(int tt = 0; tt < NUMCORESACTIVE; tt++) {
177         (*newtable)=(*newtable)+((*oldtable)*tmp_factor)>>BAMBOO_PAGE_SIZE_BITS;
178         newtable++;
179         oldtable++;
180       }
181     }
182   }
183
184
185 /* This function computes the impact of an original page on a destination page
186  * in terms of profiling data. It can only be invoked when there is an original 
187  * page that is closed or a destination page that is closed. When finished 
188  * computing the revised profiling info of the current destination page, it 
189  * sets up the gc_cache_revise_information to the latest position in the 
190  * original page and the destination page.
191  */
192 void completePageConvert(void * origptr, void * toptr, void * current_ptr) {
193   bool closeToPage=(unsigned int)(toptr)>=(unsigned int)(gc_cache_revise_information.to_page_end_va);
194   bool closeOrigPage=(unsigned int)(origptr)>=(unsigned int)(gc_cache_revise_information.orig_page_end_va);
195   if(closeToPage||closeOrigPage) {
196     // end of one or more orig/to page
197     // compute the impact of the original page(s) for the desitination page(s)
198     samplingDataConvert(current_ptr);
199     // prepare for an new orig page
200     unsigned INTPTR tmp_index=((unsigned INTPTR)(origptr-gcbaseva))>>BAMBOO_PAGE_SIZE_BITS;
201     gc_cache_revise_information.orig_page_start_va=origptr;
202     gc_cache_revise_information.orig_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(tmp_index+1);
203     gc_cache_revise_information.orig_page_index=tmp_index;
204     gc_cache_revise_information.to_page_start_va=toptr;
205     if(closeToPage) {
206       unsigned INTPTR to_index=((unsigned INTPTR)(toptr-gcbaseva))>>BAMBOO_PAGE_SIZE_BITS;
207       gc_cache_revise_information.to_page_end_va=gcbaseva+BAMBOO_PAGE_SIZE*(to_index+1);
208       gc_cache_revise_information.to_page_index=to_index;
209     }
210   }
211 }
212
213 // prepare for cache adaption:
214 //   -- flush the shared heap
215 //   -- clean dtlb entries
216 //   -- change cache strategy
217 void cacheAdapt_gc(bool isgccachestage) {
218   // flush the shared heap
219   BAMBOO_CACHE_FLUSH_L2();
220
221   // clean the dtlb entries
222   BAMBOO_CLEAN_DTLB();
223
224   if(isgccachestage) {
225     bamboo_install_dtlb_handler_for_gc();
226   } else {
227     bamboo_install_dtlb_handler_for_mutator();
228   }
229
230
231 // the master core decides how to adapt cache strategy for the mutator 
232 // according to collected statistic data
233
234 // find the core that accesses the page #page_index most
235 #define CACHEADAPT_FIND_HOTTEST_CORE(page_index,hottestcore,hotfreq) \
236   { \
237     int *local_tbl=&gccachesamplingtbl_r[page_index*NUMCORESACTIVE]; \
238     for(int i = 0; i < NUMCORESACTIVE; i++) { \
239       int freq = *local_tbl; \
240       local_tbl++; \
241       if(hotfreq < freq) { \
242         hotfreq = freq; \
243         hottestcore = i; \
244       } \
245     } \
246   }
247 // find the core that accesses the page #page_index most and comput the total
248 // access time of the page at the same time
249 #define CACHEADAPT_FIND_HOTTEST_CORE_W_TOTALFREQ(page_index,hottestcore,hotfreq,totalfreq) \
250   { \
251     int *local_tbl=&gccachesamplingtbl_r[page_index*NUMCORESACTIVE]; \
252     for(int i = 0; i < NUMCORESACTIVE; i++) { \
253       int freq = *local_tbl; \
254       local_tbl++; \
255       totalfreq += freq; \
256       if(hotfreq < freq) { \
257         hotfreq = freq; \
258         hottestcore = i; \
259       } \
260     } \
261   }
262 // Set the policy as hosted by coren
263 // NOTE: (x,y) should be changed to (x+1, y+1)!!!
264 #define CACHEADAPT_POLICY_SET_HOST_CORE(policy, coren) \
265   { \
266     (policy).cache_mode = BAMBOO_CACHE_MODE_COORDS; \    
267     (policy).lotar_x = bamboo_cpu2coords[2*(coren)]+1; \
268     (policy).lotar_y = bamboo_cpu2coords[2*(coren)+1]+1; \
269   }
270 // store the new policy information at tmp_p in gccachepolicytbl
271 #define CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy) \
272   { \
273     ((int*)(tmp_p))[page_index] = (policy).word; \
274   }
275
276 // make all pages hfh
277 void cacheAdapt_policy_h4h(int coren){
278   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)>>(BAMBOO_PAGE_SIZE_BITS);
279   unsigned int page_gap=page_num/NUMCORESACTIVE;
280   unsigned int page_index=page_gap*coren;
281   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
282   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
283   int * tmp_p = gccachepolicytbl;
284   for(; page_index < page_index_end; page_index++) {
285     bamboo_cache_policy_t policy = {0};
286     policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
287     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
288     page_sva += BAMBOO_PAGE_SIZE;
289   }
290
291
292 // make all pages local as non-cache-adaptable gc local mode
293 void cacheAdapt_policy_local(int coren){
294   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)>>(BAMBOO_PAGE_SIZE_BITS);
295   unsigned int page_gap=page_num/NUMCORESACTIVE;
296   unsigned int page_index=page_gap*coren;
297   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
298   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
299   int * tmp_p = gccachepolicytbl;
300   for(; page_index < page_index_end; page_index++) {
301     bamboo_cache_policy_t policy = {0};
302     unsigned int block = 0;
303     BLOCKINDEX(block, (void *) page_sva);
304     unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
305     CACHEADAPT_POLICY_SET_HOST_CORE(policy, coren);
306     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
307     page_sva += BAMBOO_PAGE_SIZE;
308   }
309
310
311 void cacheAdapt_policy_hottest(int coren){
312   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)>>(BAMBOO_PAGE_SIZE_BITS);
313   unsigned int page_gap=page_num/NUMCORESACTIVE;
314   unsigned int page_index=page_gap*coren;
315   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
316   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
317   int * tmp_p = gccachepolicytbl;
318   for(; page_index < page_index_end; page_index++) {
319     bamboo_cache_policy_t policy = {0};
320     unsigned int hottestcore = 0;
321     unsigned int hotfreq = 0;
322     CACHEADAPT_FIND_HOTTEST_CORE(page_index,hottestcore,hotfreq);
323     // TODO
324     // Decide the cache strategy for this page
325     // If decide to adapt a new cache strategy, write into the shared block of
326     // the gcsharedsamplingtbl. The mem recording information that has been 
327     // written is enough to hold the information.
328     // Format: page start va + cache strategy(hfh/(host core+[x,y]))
329     if(hotfreq != 0) {
330       // locally cache the page in the hottest core
331       CACHEADAPT_POLICY_SET_HOST_CORE(policy, hottestcore);
332     }
333     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
334     page_sva += BAMBOO_PAGE_SIZE;
335   }
336
337
338 #define GC_CACHE_ADAPT_DOMINATE_THRESHOLD  1
339 // cache the page on the core that accesses it the most if that core accesses 
340 // it more than (GC_CACHE_ADAPT_DOMINATE_THRESHOLD)% of the total.  Otherwise,
341 // h4h the page.
342 void cacheAdapt_policy_dominate(int coren){
343   unsigned int page_num=(BAMBOO_SHARED_MEM_SIZE)>>(BAMBOO_PAGE_SIZE_BITS);
344   unsigned int page_gap=page_num/NUMCORESACTIVE;
345   unsigned int page_index=page_gap*coren;
346   unsigned int page_index_end=(coren==NUMCORESACTIVE-1)?page_num:(page_index+page_gap);
347   VA page_sva = gcbaseva+(BAMBOO_PAGE_SIZE)*page_index;
348   int * tmp_p = gccachepolicytbl;
349   for(; page_index < page_index_end; page_index++) {
350     bamboo_cache_policy_t policy = {0};
351     unsigned int hottestcore = 0;
352     unsigned int totalfreq = 0;
353     unsigned int hotfreq = 0;
354     CACHEADAPT_FIND_HOTTEST_CORE_W_TOTALFREQ(page_index,hottestcore,hotfreq,totalfreq);
355     // Decide the cache strategy for this page
356     // If decide to adapt a new cache strategy, write into the shared block of
357     // the gcpolicytbl 
358     // Format: page start va + cache policy
359     if(hotfreq != 0) {
360       totalfreq=totalfreq>>GC_CACHE_ADAPT_DOMINATE_THRESHOLD;
361       if((unsigned int)hotfreq < (unsigned int)totalfreq) {
362         // use hfh
363         policy.cache_mode = BAMBOO_CACHE_MODE_HASH;
364         /*unsigned int block = 0;
365         BLOCKINDEX(block, (void *) page_sva);
366         unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
367         CACHEADAPT_POLICY_SET_HOST_CORE(policy, coren);*/
368       } else {
369         // locally cache the page in the hottest core
370         CACHEADAPT_POLICY_SET_HOST_CORE(policy, hottestcore);
371       }     
372     }
373     CACHEADAPT_CHANGE_POLICY_4_PAGE(tmp_p,page_index,policy);
374     page_sva += BAMBOO_PAGE_SIZE;
375   }
376 }
377
378 unsigned int cacheAdapt_decision(int coren) {
379   BAMBOO_CACHE_MF();
380   // check the statistic data
381   // for each page, decide the new cache strategy
382 #ifdef GC_CACHE_ADAPT_POLICY1
383   cacheAdapt_policy_h4h(coren);
384 #elif defined GC_CACHE_ADAPT_POLICY2
385   cacheAdapt_policy_local(coren);
386 #elif defined GC_CACHE_ADAPT_POLICY3
387   cacheAdapt_policy_hottest(coren);
388 #elif defined GC_CACHE_ADAPT_POLICY4
389   cacheAdapt_policy_dominate(coren);
390 #endif
391 }
392
393 // adapt the cache strategy for the mutator
394 void cacheAdapt_mutator() {
395   BAMBOO_CACHE_MF();
396   // check the changes and adapt them
397   int * tmp_p = gccachepolicytbl;
398   unsigned int page_sva = gcbaseva;
399   for(; page_sva<gctopva; page_sva+=BAMBOO_PAGE_SIZE) {
400     // read out the policy
401     bamboo_cache_policy_t policy = (bamboo_cache_policy_t)(*(tmp_p));
402     // adapt the policy
403     if(policy.word != 0) {
404       bamboo_adapt_cache_policy(page_sva,policy,BAMBOO_PAGE_SIZE);
405     }
406     tmp_p += 1;
407   }
408 }
409
410 // Cache adapt phase process for clients
411 void cacheAdapt_phase_client() {
412   WAITFORGCPHASE(CACHEPOLICYPHASE);
413   GC_PRINTF("Start cachepolicy phase\n");
414   cacheAdapt_decision(BAMBOO_NUM_OF_CORE);
415   //send init finish msg to core coordinator
416   send_msg_2(STARTUPCORE, GCFINISHCACHEPOLICY, BAMBOO_NUM_OF_CORE);
417   GC_PRINTF("Finish cachepolicy phase\n");
418
419   WAITFORGCPHASE(PREFINISHPHASE);
420   GC_PRINTF("Start prefinish phase\n");
421   // cache adapt phase
422   cacheAdapt_mutator();
423   cacheAdapt_gc(false);
424   //send init finish msg to core coordinator
425   send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE);
426   GC_PRINTF("Finish prefinish phase\n");
427   CACHEADAPT_SAMPLING_RESET();
428   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
429     // zero out the gccachesamplingtbl
430     BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);  
431     BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,size_cachesamplingtbl_local_r);
432   }
433 }
434
435 extern unsigned long long gc_output_cache_policy_time;
436
437 // Cache adpat phase process for the master
438 void cacheAdapt_phase_master() {
439   GCPROFILE_ITEM();
440   unsigned long long tmpt = BAMBOO_GET_EXE_TIME();
441   CACHEADAPT_OUTPUT_CACHE_SAMPLING_R();
442   gc_output_cache_policy_time += (BAMBOO_GET_EXE_TIME()-tmpt);
443   // let all cores to parallelly process the revised profile data and decide 
444   // the cache policy for each page
445   gc_status_info.gcphase = CACHEPOLICYPHASE;
446   GC_SEND_MSG_1_TO_CLIENT(GCSTARTCACHEPOLICY);
447   GC_PRINTF("Start cachepolicy phase \n");
448   // cache adapt phase
449   cacheAdapt_decision(BAMBOO_NUM_OF_CORE);
450   GC_CHECK_ALL_CORE_STATUS();
451   BAMBOO_CACHE_MF();
452
453   // let all cores to adopt new policies
454   gc_status_info.gcphase = PREFINISHPHASE;
455   // Note: all cores should flush their runtime data including non-gc cores
456   GC_SEND_MSG_1_TO_CLIENT(GCSTARTPREF);
457   GC_PRINTF("Start prefinish phase \n");
458   // cache adapt phase
459   cacheAdapt_mutator();
460   cacheAdapt_gc(false);
461   GC_CHECK_ALL_CORE_STATUS();
462   
463   CACHEADAPT_SAMPLING_RESET();
464   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
465     // zero out the gccachesamplingtbl
466     BAMBOO_MEMSET_WH(gccachesamplingtbl_local,0,size_cachesamplingtbl_local);
467     BAMBOO_MEMSET_WH(gccachesamplingtbl_local_r,0,size_cachesamplingtbl_local_r);
468     BAMBOO_MEMSET_WH(gccachepolicytbl,0,size_cachepolicytbl);
469   }
470 }
471
472 // output original cache sampling data for each page
473 void gc_output_cache_sampling() {
474   extern volatile bool gc_profile_flag;
475   if(!gc_profile_flag) return;
476   unsigned int page_index = 0;
477   VA page_sva = 0;
478   unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) >> (BAMBOO_PAGE_SIZE_BITS);
479   for(page_index = 0; page_index < page_num; page_index++) {
480     page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
481     unsigned int block = 0;
482     BLOCKINDEX(block, (void *) page_sva);
483     unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
484     printf("%x,  %d,  %d,  ",(int)page_sva,page_index,coren);
485     int * local_tbl = &gccachesamplingtbl[page_index*NUMCORESACTIVE];
486     for(int i = 0; i < NUMCORESACTIVE; i++) {
487       int freq = *local_tbl;
488       local_tbl++;
489       //if(freq != 0) {
490         printf("%d,  ", freq);
491       //}
492     }
493     printf("\n");
494   }
495   printf("=================\n");
496
497
498 // output revised cache sampling data for each page after compaction
499 void gc_output_cache_sampling_r() {
500   extern volatile bool gc_profile_flag;
501   if(!gc_profile_flag) return;
502   // TODO summary data
503   unsigned int sumdata[NUMCORESACTIVE][NUMCORESACTIVE];
504   for(int i = 0; i < NUMCORESACTIVE; i++) {
505     for(int j = 0; j < NUMCORESACTIVE; j++) {
506       sumdata[i][j] = 0;
507     }
508   }
509   tprintf("cache sampling_r \n");
510   unsigned int page_index = 0;
511   VA page_sva = 0;
512   unsigned int page_num = (BAMBOO_SHARED_MEM_SIZE) >> (BAMBOO_PAGE_SIZE_BITS);
513   for(page_index = 0; page_index < page_num; page_index++) {
514     page_sva = gcbaseva + (BAMBOO_PAGE_SIZE) * page_index;
515     unsigned int block = 0;
516     BLOCKINDEX(block, (void *)page_sva);
517     unsigned int coren = gc_block2core[block%(NUMCORES4GC*2)];
518     printf(" %x,  %d,  %d,  ",(int)page_sva,page_index,coren);
519     int accesscore = 0; // TODO
520     int * local_tbl = &gccachesamplingtbl_r[page_index*NUMCORESACTIVE];
521     for(int i = 0; i < NUMCORESACTIVE; i++) {
522       int freq = *local_tbl; 
523       printf("%d,  ", freq);
524       if(freq != 0) {
525         accesscore++;// TODO
526       }
527       local_tbl++;
528     }
529     if(accesscore!=0) {
530       int * local_tbl = &gccachesamplingtbl_r[page_index*NUMCORESACTIVE];
531       for(int i = 0; i < NUMCORESACTIVE; i++) {
532         int freq = *local_tbl;
533         sumdata[accesscore-1][i]+=freq;
534         local_tbl++;
535       }
536     }
537   
538     printf("\n");
539   }
540   printf("+++++\n");
541   // TODO printout the summary data
542   for(int i = 0; i < NUMCORESACTIVE; i++) {
543     printf("%d  ", i);
544     for(int j = 0; j < NUMCORESACTIVE; j++) {
545       printf(" %d  ", sumdata[j][i]);
546     }
547     printf("\n");
548   }
549   printf("=================\n");
550
551 #endif // GC_CACHE_ADAPT