changes committed
[IRC.git] / Robust / src / Runtime / bamboo / multicoregcflush.c
1 #ifdef MULTICORE_GC
2 #include "multicoregcflush.h"
3 #include "multicoreruntime.h"
4 #include "ObjectHash.h"
5 #include "GenericHashtable.h"
6
7 /* Task specific includes */
8
9 #ifdef TASK
10 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
11 extern int numqueues[][NUMCLASSES];
12 extern struct genhashtable * activetasks;
13 extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
14 extern struct taskparamdescriptor *currtpd;
15 extern struct LockValue runtime_locks[MAXTASKPARAMS];
16 extern int runtime_locklen;
17 #endif
18
19 extern struct global_defs_t * global_defs_p;
20
21 #ifdef MGC
22 extern struct lockvector bamboo_threadlocks;
23 #endif
24
25 // NOTE: the objptr should not be NULL and should not be non shared ptr
26 #define FLUSHOBJ(obj, tt) {void *flushtmpptr=obj; if (flushtmpptr!=NULL) obj=flushObj(flushtmpptr);}
27 #define FLUSHOBJNONNULL(obj, tt) {void *flushtmpptr=obj; obj=flushObj(flushtmpptr);}
28
29 INLINE void * flushObj(void * objptr) {
30   return gcmappingtbl[OBJMAPPINGINDEX((unsigned int)objptr)];
31 }
32
33 INLINE void updategarbagelist(struct garbagelist *listptr) {
34   for(;listptr!=NULL; listptr=listptr->next) {
35     for(int i=0; i<listptr->size; i++) {
36       FLUSHOBJ(listptr->array[i], i);
37     }
38   }
39 }
40
41 INLINE void flushRuntimeObj(struct garbagelist * stackptr) {
42   // flush current stack
43   updategarbagelist(stackptr);
44
45   // flush static pointers global_defs_p
46   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
47     updategarbagelist((struct garbagelist *)global_defs_p);
48   }
49
50 #ifdef TASK
51   // flush objectsets
52   if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
53     for(int i=0; i<NUMCLASSES; i++) {
54       struct parameterwrapper ** queues = objectqueues[BAMBOO_NUM_OF_CORE][i];
55       int length = numqueues[BAMBOO_NUM_OF_CORE][i];
56       for(int j = 0; j < length; ++j) {
57         struct parameterwrapper * parameter = queues[j];
58         struct ObjectHash * set=parameter->objectset;
59         for(struct ObjectNode * ptr=set->listhead;ptr!=NULL;ptr=ptr->lnext) {
60           FLUSHOBJNONNULL(ptr->key, 0);
61         }
62         ObjectHashrehash(set);
63       }
64     }
65   }
66
67   // flush current task descriptor
68   if(currtpd != NULL) {
69     for(int i=0; i<currtpd->numParameters; i++) {
70       // the parameter can not be NULL
71       FLUSHOBJNONNULL(currtpd->parameterArray[i], i);
72     }
73   }
74
75   // flush active tasks
76   if(activetasks != NULL) {
77     for(struct genpointerlist * ptr=activetasks->list;ptr!=NULL;ptr=ptr->inext) {
78       struct taskparamdescriptor *tpd=ptr->src;
79       for(int i=0; i<tpd->numParameters; i++) {
80         // the parameter can not be NULL
81         FLUSHOBJNONNULL(tpd->parameterArray[i], i);
82       }
83     }
84     genrehash(activetasks);
85   }
86
87   // flush cached transferred obj
88   for(struct QueueItem * tmpobjptr =  getHead(&objqueue);tmpobjptr != NULL;tmpobjptr = getNextQueueItem(tmpobjptr)) {
89     struct transObjInfo * objInfo=(struct transObjInfo *)(tmpobjptr->objectptr);
90     // the obj can not be NULL
91     FLUSHOBJNONNULL(objInfo->objptr, 0);
92   }
93
94   // flush cached objs to be transferred
95   for(struct QueueItem * item = getHead(totransobjqueue);item != NULL;item = getNextQueueItem(item);) {
96     struct transObjInfo * totransobj = (struct transObjInfo *)(item->objectptr);
97     // the obj can not be NULL
98     FLUSHOBJNONNULL(totransobj->objptr, 0);
99   }  
100
101   // enqueue lock related info
102   for(int i = 0; i < runtime_locklen; ++i) {
103     FLUSHOBJ(runtime_locks[i].redirectlock, i);
104     FLUSHOBJ(runtime_locks[i].value, i);
105   }
106 #endif
107
108 #ifdef MGC
109   // flush the bamboo_threadlocks
110   for(int i = 0; i < bamboo_threadlocks.index; i++) {
111     // the locked obj can not be NULL
112     FLUSHOBJNONNULL(bamboo_threadlocks.locks[i].object, i);
113   }
114
115   // flush the bamboo_current_thread
116   FLUSHOBJ(bamboo_current_thread, 0);
117
118   // flush global thread queue
119   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
120     unsigned int thread_counter = *((unsigned int*)(bamboo_thread_queue+1));
121     if(thread_counter > 0) {
122       unsigned int start = *((unsigned int*)(bamboo_thread_queue+2));
123       for(int i = thread_counter; i > 0; i--) {
124         // the thread obj can not be NULL
125         FLUSHOBJNONNULL(bamboo_thread_queue[4+start], 0);
126         start = (start+1)&bamboo_max_thread_num_mask;
127       }
128     }
129     unlockthreadqueue();
130   }
131 #endif
132 }
133
134 INLINE void flushPtrsInObj(void * ptr) {
135   int type = ((int *)(ptr))[0];
136   // scan all pointers in ptr
137   unsigned int * pointer=pointerarray[type];
138   if (pointer==0) {
139     /* Array of primitives */
140 #ifdef OBJECTHASPOINTERS
141     //handle object class
142     pointer=pointerarray[OBJECTTYPE];
143     unsigned int size=pointer[0];
144     for(int i=1; i<=size; i++) {
145       unsigned int offset=pointer[i];
146       FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
147     }
148 #endif
149   } else if (((unsigned int)pointer)==1) {
150     /* Array of pointers */
151     struct ArrayObject *ao=(struct ArrayObject *) ptr;
152     int length=ao->___length___;
153     for(int j=0; j<length; j++) {
154       FLUSHOBJ(((void **)(((char *)&ao->___length___)+sizeof(int)))[j], j);
155     }
156 #ifdef OBJECTHASPOINTERS
157     pointer=pointerarray[OBJECTTYPE];
158     //handle object class
159     unsigned int size=pointer[0];
160     
161     for(int i=1; i<=size; i++) {
162       unsigned int offset=pointer[i];     
163       FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
164     }
165 #endif
166   } else {
167     unsigned int size=pointer[0];
168     
169     for(int i=1; i<=size; i++) {
170       unsigned int offset=pointer[i];
171       FLUSHOBJ(*((void **)(((char *)ptr)+offset)), i);
172     }
173   }  
174 }
175
176 void flush(struct garbagelist * stackptr) {
177   BAMBOO_CACHE_MF();
178
179   flushRuntimeObj(stackptr);
180   while(true) {
181     BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
182     if(!gc_moreItems_I()) {
183       BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
184       break;
185     }
186
187     unsigned int ptr = gc_dequeue_I();
188     BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
189     // should be a local shared obj and should have mapping info
190     FLUSHOBJNONNULL(ptr, 0);
191     BAMBOO_ASSERT(ptr != NULL, 0xb02a);
192
193     if(((struct ___Object___ *)ptr)->marked == COMPACTED) {
194       flushPtrsInObj((void *)ptr);
195       // restore the mark field, indicating that this obj has been flushed
196       ((struct ___Object___ *)ptr)->marked = INIT;
197     }
198   } 
199
200   // TODO bug here: the startup core contains all lobjs' info, thus all the
201   // lobjs are flushed in sequence.
202   // flush lobjs
203   while(gc_lobjmoreItems_I()) {
204     unsigned int ptr = gc_lobjdequeue_I(NULL, NULL);
205     FLUSHOBJ(ptr, 0);
206     BAMBOO_ASSERT(ptr!=NULL, 0xb02d);
207
208     if(((struct ___Object___ *)ptr)->marked == COMPACTED) {
209       flushPtrsInObj((void *)ptr);
210       // restore the mark field, indicating that this obj has been flushed
211       ((struct ___Object___ *)ptr)->marked = INIT;
212     }     
213   } 
214
215   // send flush finish message to core coordinator
216   if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
217     gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
218   } else {
219     send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
220   }
221
222
223 #endif // MULTICORE_GC