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