2e0a8fc1264c8a13383fe508b0df7217175c5e7e
[IRC.git] / Robust / src / Runtime / bamboo / pmc_garbage.c
1 #include "multicoregc.h"
2 #include "multicoreruntime.h"
3 #include "pmc_garbage.h"
4 #include "runtime_arch.h"
5
6 struct pmc_heap * pmc_heapptr;
7 struct pmc_queue * pmc_localqueue;
8 volatile bool gcflag;
9
10 void incrementthreads() {
11   tmc_spin_mutex_lock(&pmc_heapptr->lock);
12   pmc_heapptr->numthreads++;
13   tmc_spin_mutex_unlock(&pmc_heapptr->lock);
14 }
15
16 void decrementthreads() {
17   tmc_spin_mutex_lock(&pmc_heapptr->lock);
18   pmc_heapptr->numthreads--;
19   tmc_spin_mutex_unlock(&pmc_heapptr->lock);
20 }
21
22 void * pmc_unitend(unsigned int index) {
23   return gcbaseva+(index+1)*UNITSIZE;
24 }
25
26 void pmc_onceInit() {
27   pmc_localqueue=&pmc_heapptr->regions[BAMBOO_NUM_OF_CORE].markqueue;
28   pmc_queueinit(pmc_localqueue);
29   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
30     tmc_spin_barrier_init(&pmc_heapptr->barrier, NUMCORES4GC);
31     for(int i=0;i<NUMPMCUNITS;i++) {
32       pmc_heapptr->units[i].endptr=pmc_unitend(i);
33       //tprintf("%u endptr=%x\n", i, pmc_heapptr->units[i].endptr);
34     }
35     
36     for(int i=0;i<NUMCORES4GC;i+=2) {
37       if (i==0) {
38         pmc_heapptr->regions[i].lastptr=gcbaseva;
39       } else
40         pmc_heapptr->regions[i].lastptr=pmc_heapptr->units[i*4-1].endptr;
41       pmc_heapptr->regions[i].lowunit=4*i;
42       pmc_heapptr->regions[i].highunit=4*(i+1);
43       pmc_heapptr->regions[i+1].lastptr=pmc_heapptr->units[(i+1)*4+3].endptr;
44       pmc_heapptr->regions[i+1].lowunit=4*(i+1);
45       pmc_heapptr->regions[i+1].highunit=4*(i+2);
46     }
47     //    for(int i=0;i<NUMCORES4GC;i++) {
48     //      tprintf("%u lastptr=%x\n", i, pmc_heapptr->regions[i].lastptr);
49     //    }
50   }
51 }
52
53 void pmc_init() {
54   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
55     pmc_heapptr->numthreads=NUMCORES4GC;
56     for(int i=0;i<NUMCORES4GC;i+=2) {
57       void *startptr=pmc_heapptr->regions[i].lastptr;
58       void *finishptr=pmc_heapptr->regions[i+1].lastptr;
59       struct pmc_region *region=&pmc_heapptr->regions[i];
60       unsigned int startindex=region->lowunit;
61       unsigned int endindex=pmc_heapptr->regions[i+1].highunit;
62       //      tprintf("Free space in partition %u from %x to %x\n", i, startptr, finishptr);
63       for(unsigned int index=startindex;index<endindex;index++) {
64         void *ptr=pmc_heapptr->units[index].endptr;
65         if ((ptr>startptr)&&(ptr<=finishptr)) {
66           padspace(startptr, (unsigned int)(ptr-startptr));
67           startptr=ptr;
68         }
69         if (ptr>finishptr) {
70           void *prevunitptr=pmc_heapptr->units[index-1].endptr;
71           padspace(startptr, finishptr-startptr);
72           break;
73         }
74       }
75     }
76   }
77   if (bamboo_smem_size) {
78     //    tprintf("Left over alloc space from %x to %x\n", bamboo_cur_msp, bamboo_cur_msp+bamboo_smem_size);
79     padspace(bamboo_cur_msp, bamboo_smem_size);  
80   }
81   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
82 }
83
84 void gc(struct garbagelist *gl) {
85   if (BAMBOO_NUM_OF_CORE==STARTUPCORE)
86     tprintf("start GC\n");
87   pmc_init();
88   //mark live objects
89   //  tprintf("mark\n");
90   pmc_mark(gl);
91   //count live objects per unit
92   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
93   //  tprintf("count\n");
94   pmc_count();
95   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
96   //divide up work
97   //  tprintf("divide\n");
98   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
99     pmc_processunits();
100   }
101   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
102   //set up forwarding pointers
103   //  tprintf("forward\n");
104   pmc_doforward();
105   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
106   //update pointers
107   //  tprintf("updaterefs\n");
108   pmc_doreferenceupdate(gl);
109   tmc_spin_barrier_wait(&pmc_heapptr->barrier);
110   //compact data
111   //  tprintf("compact\n");
112   pmc_docompact();
113   //reset memory allocation
114   bamboo_cur_msp=NULL;
115   bamboo_smem_size=0;
116   //  tprintf("done\n");
117
118   if (BAMBOO_NUM_OF_CORE==STARTUPCORE) {
119     tmc_spin_barrier_wait(&pmc_heapptr->barrier);
120     //people will resend...no need to get gcflag so quickly
121     gcflag=false;
122     //    for(int i=0;i<NUMCORES4GC;i+=2) {
123     //      tprintf("%u %x %x\n",i, pmc_heapptr->regions[i].lastptr, pmc_heapptr->regions[i+1].lastptr);
124     //      tprintf("%x %x %x %x\n", pmc_heapptr->regions[i].startptr, pmc_heapptr->regions[i].endptr, pmc_heapptr->regions[i+1].startptr, pmc_heapptr->regions[i+1].endptr);
125     //      tprintf("%u %u %u %u\n", pmc_heapptr->regions[i].lowunit, pmc_heapptr->regions[i].highunit, pmc_heapptr->regions[i+1].lowunit, pmc_heapptr->regions[i+1].highunit);
126     //    }
127     //    for(int i=0;i<NUMPMCUNITS;i++) {
128     //      tprintf("%u %x %u\n",i, pmc_heapptr->units[i].endptr, pmc_heapptr->units[i].regionnum);
129     //    }
130   } else {
131     //start to listen for gcflags before we exit
132     gcflag=false;
133     tmc_spin_barrier_wait(&pmc_heapptr->barrier);
134   }
135 }
136
137 void padspace(void *ptr, unsigned int length) {
138   //zero small blocks
139   //  tprintf("Padspace from %x to %x\n", ptr, ptr+length);
140   if (length<sizeof(struct ArrayObject)) {
141     BAMBOO_MEMSET_WH(ptr,0,length);
142   } else {
143     //generate fake arrays for big blocks
144     struct ArrayObject *ao=(struct ArrayObject *)ptr;
145     ao->type=BYTEARRAYTYPE;
146     unsigned arraylength=length-sizeof(struct ArrayObject);
147     ao->___length___=arraylength;
148     ao->marked=0;
149   }
150 }
151
152 void gettype_size(void * ptr, int * ttype, unsigned int * tsize) {
153   int type = ((int *)ptr)[0];
154   if(type < NUMCLASSES) {
155     // a normal object
156     *tsize = classsize[type];
157     *ttype = type;
158   } else {
159     // an array
160     struct ArrayObject *ao=(struct ArrayObject *)ptr;
161     unsigned int elementsize=classsize[type];
162     unsigned int length=ao->___length___;
163     *tsize = sizeof(struct ArrayObject)+length*elementsize;
164     *ttype = type;
165   } 
166 }