--- /dev/null
+#include "MGCHash.h"
+#ifdef MULTICORE
+#include "runtime_arch.h"
+#else
+#include <stdio.h>
+#endif
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+
+#ifndef INTPTR
+#ifdef BIT64
+#define INTPTR long
+#define INTPTRSHIFT 3
+#else
+#define INTPTR int
+#define INTPTRSHIFT 2
+#endif
+#endif
+
+
+/* MGCHASH ********************************************************/
+mgchashlistnode_t *mgc_table;
+unsigned int mgc_size;
+//unsigned INTPTR mgc_mask;
+unsigned int mgc_numelements;
+unsigned int mgc_threshold;
+double mgc_loadfactor;
+mgcliststruct_t *mgc_structs;
+
+void mgchashCreate(unsigned int size, double loadfactor) {
+ mgchashtable_t *ctable;
+ mgchashlistnode_t *nodes;
+ int i;
+
+ // Allocate space for the hash table
+ mgc_table = RUNMALLOC(size*sizeof(mgchashlistnode_t));
+ mgc_loadfactor = loadfactor;
+ mgc_size = size;
+ mgc_threshold=size*loadfactor;
+ /*
+#ifdef BIT64
+ mgc_mask = ((size << 4)-1)&~(15UL);
+#else
+ mgc_mask = ((size << 4)-1)&~15;
+#endif
+*/
+ mgc_structs=RUNMALLOC(1*sizeof(mgcliststruct_t));
+ mgc_numelements = 0; // Initial number of elements in the hash
+}
+
+void mgchashreset() {
+ mgchashlistnode_t *ptr = mgc_table;
+ int i;
+
+ /*if (mgc_numelements<(mgc_size>>4)) {
+ mgchashlistnode_t *top=&ptr[mgc_size];
+ mgchashlistnode_t *tmpptr=mgc_list;
+ while(tmpptr!=NULL) {
+ mgchashlistnode_t *next=tmpptr->lnext;
+ if (tmpptr>=ptr&&tmpptr<top) {
+ //zero in list
+ tmpptr->key=NULL;
+ tmpptr->next=NULL;
+ }
+ tmpptr=next;
+ }
+ } else {*/
+ memset(mgc_table, '\0', sizeof(mgchashlistnode_t)*mgc_size);
+ //}
+ while(mgc_structs->next!=NULL) {
+ mgcliststruct_t *next=mgc_structs->next;
+ RUNFREE(mgc_structs);
+ mgc_structs=next;
+ }
+ mgc_structs->num = 0;
+ mgc_numelements = 0;
+}
+
+//Store objects and their pointers into hash
+void mgchashInsert(void * key, void *val) {
+ mgchashlistnode_t *ptr;
+
+ if(mgc_numelements > (mgc_threshold)) {
+ //Resize
+ unsigned int newsize = mgc_size << 1 + 1;
+ mgchashResize(newsize);
+ }
+
+ int hashkey = (unsigned int)key % mgc_size;
+ ptr=&mgc_table[hashkey];//&mgc_table[(((unsigned INTPTR)key)&mgc_mask)>>4];
+ mgc_numelements++;
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->val=val;
+ } else { // Insert in the beginning of linked list
+ mgchashlistnode_t * node;
+ if (mgc_structs->num<NUMMGCLIST) {
+ node=&mgc_structs->array[mgc_structs->num];
+ mgc_structs->num++;
+ } else {
+ //get new list
+ mgcliststruct_t *tcl=RUNMALLOC(1*sizeof(mgcliststruct_t));
+ tcl->next=mgc_structs;
+ mgc_structs=tcl;
+ node=&tcl->array[0];
+ tcl->num=1;
+ }
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next = node;
+ }
+}
+
+#ifdef MULTICORE
+void mgchashInsert_I(void * key, void *val) {
+ mgchashlistnode_t *ptr;
+
+ if(mgc_numelements > (mgc_threshold)) {
+ //Resize
+ unsigned int newsize = mgc_size << 1 + 1;
+ mgchashResize_I(newsize);
+ }
+
+ int hashkey = (unsigned int)key % mgc_size;
+ ptr=&mgc_table[hashkey];
+ //ptr = &mgc_table[(((unsigned INTPTR)key)&mgc_mask)>>4];
+ mgc_numelements++;
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->val=val;
+ } else { // Insert in the beginning of linked list
+ mgchashlistnode_t * node;
+ if (mgc_structs->num<NUMMGCLIST) {
+ node=&mgc_structs->array[mgc_structs->num];
+ mgc_structs->num++;
+ } else {
+ //get new list
+ mgcliststruct_t *tcl=RUNMALLOC_I(1*sizeof(mgcliststruct_t));
+ tcl->next=mgc_structs;
+ mgc_structs=tcl;
+ node=&tcl->array[0];
+ tcl->num=1;
+ }
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next = node;
+ }
+}
+#endif
+
+// Search for an address for a given oid
+INLINE void * mgchashSearch(void * key) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
+ int hashkey = (unsigned int)key % mgc_size;
+ mgchashlistnode_t *node = &mgc_table[hashkey];
+ //&mgc_table[(((unsigned INTPTR)key)&mgc_mask)>>4];
+
+ do {
+ if(node->key == key) {
+ return node->val;
+ }
+ node = node->next;
+ } while(node != NULL);
+
+ return NULL;
+}
+
+unsigned int mgchashResize(unsigned int newsize) {
+ mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next mgchashlistnodes in a linked list
+ unsigned int oldsize;
+ int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
+ unsigned int i,index;
+ //unsigned int mask;
+
+ ptr = mgc_table;
+ oldsize = mgc_size;
+
+ if((node = RUNMALLOC(newsize*sizeof(mgchashlistnode_t))) == NULL) {
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ mgc_table = node; //Update the global hashtable upon resize()
+ mgc_size = newsize;
+ mgc_threshold = newsize * mgc_loadfactor;
+ //mask=mgc_mask = (newsize << 4)-1;
+
+ for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
+ curr = &ptr[i];
+ isfirst = 1;
+ do { //Inner loop to go through linked lists
+ void * key;
+ mgchashlistnode_t *tmp,*next;
+
+ if ((key=curr->key) == 0) { //Exit inner loop if there the first element is 0
+ break; //key = val =0 for element if not present within the hash table
+ }
+ index = (unsigned int)key % mgc_size;
+ //index = (((unsigned INTPTR)key) & mask) >>4;
+ tmp=&node[index];
+ next = curr->next;
+ // Insert into the new table
+ if(tmp->key == 0) {
+ tmp->key = key;
+ tmp->val = curr->val;
+ } /*
+ NOTE: Add this case if you change this...
+ This case currently never happens because of the way things rehash....
+ else if (isfirst) {
+ chashlistnode_t *newnode= calloc(1, sizeof(chashlistnode_t));
+ newnode->key = curr->key;
+ newnode->val = curr->val;
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ } */
+ else {
+ curr->next=tmp->next;
+ tmp->next=curr;
+ }
+
+ isfirst = 0;
+ curr = next;
+ } while(curr!=NULL);
+ }
+
+ RUNFREE(ptr); //Free the memory of the old hash table
+ return 0;
+}
+
+#ifdef MULTICORE_GC
+unsigned int mgchashResize_I(unsigned int newsize) {
+ mgchashlistnode_t *node, *ptr, *curr; // curr and next keep track of the current and the next mgchashlistnodes in a linked list
+ unsigned int oldsize;
+ int isfirst; // Keeps track of the first element in the chashlistnode_t for each bin in hashtable
+ unsigned int i,index;
+ //unsigned int mask;
+
+ ptr = mgc_table;
+ oldsize = mgc_size;
+
+ if((node = RUNMALLOC_I(newsize*sizeof(mgchashlistnode_t))) == NULL) {
+ BAMBOO_EXIT(0xe001);
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ mgc_table = node; //Update the global hashtable upon resize()
+ mgc_size = newsize;
+ mgc_threshold = newsize * mgc_loadfactor;
+ //mask=mgc_mask = (newsize << 4)-1;
+
+ for(i = 0; i < oldsize; i++) { //Outer loop for each bin in hash table
+ curr = &ptr[i];
+ isfirst = 1;
+ do { //Inner loop to go through linked lists
+ void * key;
+ mgchashlistnode_t *tmp,*next;
+
+ if ((key=curr->key) == 0) {
+ //Exit inner loop if there the first element is 0
+ break;
+ //key = val =0 for element if not present within the hash table
+ }
+ index = (unsigned int)key % mgc_size;
+ //index = (((unsigned INTPTR)key) & mask) >>4;
+ tmp=&node[index];
+ next = curr->next;
+ // Insert into the new table
+ if(tmp->key == 0) {
+ tmp->key = key;
+ tmp->val = curr->val;
+ } /*
+ NOTE: Add this case if you change this...
+ This case currently never happens because of the way things rehash....*/
+ else if (isfirst) {
+ mgchashlistnode_t *newnode=RUNMALLOC_I(1*sizeof(mgchashlistnode_t));
+ newnode->key = curr->key;
+ newnode->val = curr->val;
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ }
+ else {
+ curr->next=tmp->next;
+ tmp->next=curr;
+ }
+
+ isfirst = 0;
+ curr = next;
+ } while(curr!=NULL);
+ }
+ RUNFREE(ptr); //Free the memory of the old hash table
+ return 0;
+}
+#endif
+
+//Delete the entire hash table
+void mgchashDelete() {
+ int i;
+ mgcliststruct_t *ptr=mgc_structs;
+ while(ptr!=NULL) {
+ mgcliststruct_t *next=ptr->next;
+ RUNFREE(ptr);
+ ptr=next;
+ }
+ RUNFREE(mgc_table);
+ mgc_table=NULL;
+ mgc_structs=NULL;
+}
+
+struct MGCHash * allocateMGCHash(int size,
+ int conflicts) {
+ struct MGCHash *thisvar;
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf101);
+#else
+ printf("Negative Hashtable size Exception\n");
+ exit(-1);
+#endif
+ }
+ thisvar=(struct MGCHash *)RUNMALLOC(sizeof(struct MGCHash));
+ thisvar->size = size;
+ thisvar->bucket =
+ (struct MGCNode *) RUNMALLOC(sizeof(struct MGCNode)*size);
+ // zero out all the buckets
+ memset(thisvar->bucket, '\0', sizeof(struct MGCNode)*size);
+ //Set data counts
+ thisvar->num4conflicts = conflicts;
+ return thisvar;
+}
+
+void freeMGCHash(struct MGCHash *thisvar) {
+ int i = 0;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct MGCNode *ptr;
+ for(ptr=thisvar->bucket[i].next; ptr!=NULL;) {
+ struct MGCNode * nextptr=ptr->next;
+ RUNFREE(ptr);
+ ptr=nextptr;
+ }
+ }
+ RUNFREE(thisvar->bucket);
+ RUNFREE(thisvar);
+}
+/*
+void MGCHashrehash(struct MGCHash * thisvar) {
+ int newsize=thisvar->size;
+ struct MGCNode ** newbucket = (struct MGCNode **) RUNMALLOC(sizeof(struct MGCNode *)*newsize);
+ int i;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct MGCNode *ptr;
+ for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
+ struct MGCNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ RUNFREE(thisvar->bucket);
+ thisvar->bucket=newbucket;
+}*/
+
+int MGCHashadd(struct MGCHash * thisvar, int data) {
+ // Rehash code
+ unsigned int hashkey;
+ struct MGCNode *ptr;
+
+ /*if (thisvar->numelements>=thisvar->size) {
+ int newsize=2*thisvar->size+1;
+ struct MGCNode ** newbucket = (struct MGCNode **) RUNMALLOC(sizeof(struct MGCNode *)*newsize);
+ int i;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct MGCNode *ptr;
+ for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
+ struct MGCNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ RUNFREE(thisvar->bucket);
+ thisvar->bucket=newbucket;
+ }*/
+
+ hashkey = (unsigned int)data % thisvar->size;
+ ptr = &thisvar->bucket[hashkey];
+
+ struct MGCNode * prev = NULL;
+ if(ptr->data < thisvar->num4conflicts) {
+ struct MGCNode *node=RUNMALLOC(sizeof(struct MGCNode));
+ node->data=data;
+ node->next=(ptr->next);
+ ptr->next=node;
+ ptr->data++;
+ } else {
+ while (ptr->next!=NULL) {
+ prev = ptr;
+ ptr = ptr->next;
+ }
+ ptr->data = data;
+ ptr->next = thisvar->bucket[hashkey].next;
+ thisvar->bucket[hashkey].next = ptr;
+ prev->next = NULL;
+ }
+
+ return 1;
+}
+
+#ifdef MULTICORE
+int MGCHashadd_I(struct MGCHash * thisvar, int data) {
+ // Rehash code
+ unsigned int hashkey;
+ struct MGCNode *ptr;
+
+ /*if (thisvar->numelements>=thisvar->size) {
+ int newsize=2*thisvar->size+1;
+ struct MGCNode ** newbucket = (struct MGCNode **) RUNMALLOC_I(sizeof(struct MGCNode *)*newsize);
+ int i;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct MGCNode *ptr;
+ for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
+ struct MGCNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ RUNFREE(thisvar->bucket);
+ thisvar->bucket=newbucket;
+ }*/
+
+ hashkey = (unsigned int)data % thisvar->size;
+ ptr = &thisvar->bucket[hashkey];
+
+ struct MGCNode * prev = NULL;
+ if(ptr->data < thisvar->num4conflicts) {
+ struct MGCNode *node=RUNMALLOC_I(sizeof(struct MGCNode));
+ node->data=data;
+ node->next=(ptr->next);
+ ptr->next=node;
+ ptr->data++;
+ } else {
+ while (ptr->next!=NULL) {
+ prev = ptr;
+ ptr = ptr->next;
+ }
+ ptr->data = data;
+ ptr->next = thisvar->bucket[hashkey].next;
+ thisvar->bucket[hashkey].next = ptr;
+ prev->next = NULL;
+ }
+
+ return 1;
+}
+#endif
+
+int MGCHashcontains(struct MGCHash *thisvar, int data) {
+ unsigned int hashkey = (unsigned int)data % thisvar->size;
+
+ struct MGCNode *ptr = thisvar->bucket[hashkey].next;
+ struct MGCNode *prev = NULL;
+ while (ptr!=NULL) {
+ if (ptr->data == data) {
+ if(prev != NULL) {
+ prev->next = NULL;
+ ptr->next = thisvar->bucket[hashkey].next;
+ thisvar->bucket[hashkey].next = ptr;
+ }
+
+ return 1; // success
+ }
+ prev = ptr;
+ ptr = ptr->next;
+ }
+
+ return 0; // failure
+}
+
--- /dev/null
+#ifndef MGCHASH_H
+#define MGCHASH_H
+
+#ifndef bool
+#define bool int
+#endif
+
+#ifndef true
+#define true 1
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+#ifndef INLINE
+#define INLINE inline __attribute__((always_inline))
+#endif
+
+#include "mem.h"
+
+/* MGCHash *********************************************************/
+typedef struct mgchashlistnode {
+ void * key;
+ void * val; //this can be cast to another type or used to point to a
+ //larger structure
+ struct mgchashlistnode *next;
+} mgchashlistnode_t;
+
+typedef struct mgchashtable {
+ mgchashlistnode_t *table; // points to beginning of hash table
+ unsigned int size;
+ //unsigned int mask;
+ unsigned int numelements;
+ unsigned int threshold;
+ double loadfactor;
+} mgchashtable_t;
+
+#define NUMMGCLIST 250
+typedef struct mgclist {
+ struct mgchashlistnode array[NUMMGCLIST];
+ int num;
+ struct mgclist *next;
+} mgcliststruct_t;
+
+void mgchashCreate(unsigned int size, double loadfactor);
+void mgchashInsert(void * key, void *val);
+void * mgchashSearch(void * key);
+unsigned int mgchashResize(unsigned int newsize);
+#ifdef MULTICORE_GC
+void mgchashInsert_I(void * key, void *val);
+unsigned int mgchashResize_I(unsigned int newsize);
+#endif
+void mgchashDelete();
+void mgchashreset();
+
+
+struct MGCHash * allocateMGCHash(int size, int conflicts);
+void freeMGCHash(struct MGCHash *);
+
+//void MGCHashrehash(struct MGCHash * thisvar);
+int MGCHashadd(struct MGCHash *, int data);
+#ifdef MULTICORE
+int MGCHashadd_I(struct MGCHash *, int data);
+#endif
+int MGCHashcontains(struct MGCHash *,int data);
+
+struct MGCHash {
+ int num4conflicts;
+ int size;
+ struct MGCNode *bucket;
+};
+
+/* MGCHashException *************************************************/
+
+struct MGCNode {
+ struct MGCNode * next;
+ int data;
+};
+
+#endif
gclobjtailindex2=0;
} // if (gclobjtailindex==NUMLOBJPTRS)
if(length != NULL) {
- *length = gclobjtail2->lengths[gclobjtailindex];
+ *length = gclobjtail2->lengths[gclobjtailindex2];
}
if(host != NULL) {
- *host = (int)(gclobjtail2->hosts[gclobjtailindex]);
+ *host = (int)(gclobjtail2->hosts[gclobjtailindex2]);
}
- return gclobjtail2->lobjs[gclobjtailindex++];
+ return gclobjtail2->lobjs[gclobjtailindex2++];
} // void * gc_lobjdequeue()
inline int gc_lobjmoreItems4() {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xee04);
#endif
- // check if the sum of send objs and receive obj are the same
- // yes->check if the info is the latest; no->go on executing
- int sumsendobj = 0;
- for(i = 0; i < NUMCORES4GC; ++i) {
- sumsendobj += gcnumsendobjs[i];
- } // for(i = 0; i < NUMCORES4GC; ++i)
+ // ask for confirm
+ if(!waitconfirm) {
#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee05);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
+ BAMBOO_DEBUGPRINT(0xee05);
#endif
- for(i = 0; i < NUMCORES4GC; ++i) {
- sumsendobj -= gcnumreceiveobjs[i];
- } // for(i = 0; i < NUMCORES4GC; ++i)
+ // the first time found all cores stall
+ // send out status confirm msg to all other cores
+ // reset the corestatus array too
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+ waitconfirm = true;
+ numconfirm = NUMCORES4GC - 1;
+ for(i = 1; i < NUMCORES4GC; ++i) {
+ gccorestatus[i] = 1;
+ // send mark phase finish confirm request msg to core i
+ send_msg_1(i, GCMARKCONFIRM, false);
+ } // for(i = 1; i < NUMCORES4GC; ++i)
+ } else {
+ // check if the sum of send objs and receive obj are the same
+ // yes->check if the info is the latest; no->go on executing
+ int sumsendobj = 0;
+ for(i = 0; i < NUMCORES4GC; ++i) {
+ sumsendobj += gcnumsendobjs[i];
+ } // for(i = 0; i < NUMCORES4GC; ++i)
#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee06);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
+ BAMBOO_DEBUGPRINT(0xee06);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
#endif
- if(0 == sumsendobj) {
+ for(i = 0; i < NUMCORES4GC; ++i) {
+ sumsendobj -= gcnumreceiveobjs[i];
+ } // for(i = 0; i < NUMCORES4GC; ++i)
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xee07);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
#endif
- if(!waitconfirm) {
+ if(0 == sumsendobj) {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xee08);
-#endif
- // the first time found all cores stall
- // send out status confirm msg to all other cores
- // reset the corestatus array too
- gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
- waitconfirm = true;
- numconfirm = NUMCORES4GC - 1;
- for(i = 1; i < NUMCORES4GC; ++i) {
- gccorestatus[i] = 1;
- // send mark phase finish confirm request msg to core i
- send_msg_1(i, GCMARKCONFIRM);
- } // for(i = 1; i < NUMCORES4GC; ++i)
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee09);
#endif
// all the core status info are the latest
// stop mark phase
for(i = 0; i < NUMCORES4GC; ++i) {
gccorestatus[i] = 1;
} // for(i = 0; i < NUMCORES4GC; ++i)
- } // if(!gcwautconfirm) else()
- } // if(0 == sumsendobj)
+ } // if(0 == sumsendobj)
+ } // if(!gcwaitconfirm) else()
} // if(allStall)
BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
} // if((!waitconfirm)...
for(i = 1; i < NUMCORESACTIVE; ++i) {
corestatus[i] = 1;
// send status confirm msg to core i
- send_msg_1(i, STATUSCONFIRM);
+ send_msg_1(i, STATUSCONFIRM, false);
} // for(i = 1; i < NUMCORESACTIVE; ++i)
#ifdef DEBUG
//freeMGCHash(gcpointertbl);
//gcpointertbl = allocateMGCHash(20);
//mgchashreset();
+
+ freeMGCHash(gcforwardobjtbl);
+ gcforwardobjtbl = allocateMGCHash(20, 3);
memset(gcsmemtbl, '\0', sizeof(int)*gcnumblock);
} // void initGC()
// compute load balance for all cores
-inline int loadbalance() {
+inline int loadbalance(int * heaptop) {
// compute load balance
int i;
for(i = 1; i < NUMCORES4GC; i++) {
tloads += gcloads[i];
}
- int heaptop = gcbaseva + tloads;
+ *heaptop = gcbaseva + tloads;
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xdddd);
BAMBOO_DEBUGPRINT_REG(tloads);
- BAMBOO_DEBUGPRINT_REG(heaptop);
+ BAMBOO_DEBUGPRINT_REG(*heaptop);
#endif
int b = 0;
- BLOCKINDEX(heaptop, &b);
+ BLOCKINDEX(*heaptop, &b);
int numbpc = b / NUMCORES4GC; // num of blocks per core
#ifdef DEBUG
BAMBOO_DEBUGPRINT_REG(b);
BAMBOO_DEBUGPRINT_REG(gctopcore);
#endif
return numbpc;
-} // void loadbalance()
+} // void loadbalance(int * heaptop)
inline bool cacheLObjs() {
// check the total mem size need for large objs
int cpysize = 0;
remain -= BAMBOO_CACHE_LINE_SIZE;
tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
- while(gc_lobjmoreItems()) {
- ptr = (int)(gc_lobjdequeue(&size, &host));
+ gc_lobjqueueinit4();
+ while(gc_lobjmoreItems4()) {
+ ptr = (int)(gc_lobjdequeue4(&size, &host));
ALIGNSIZE(size, &isize);
if(remain < isize) {
// this object acrosses blocks
#endif
} else {
// send the original host core with the mapping info
- send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop);
+ send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xcdcb);
BAMBOO_DEBUGPRINT_REG(ptr);
#endif
} else {
// send the original host core with the mapping info
- send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop);
+ send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xcdcd);
BAMBOO_DEBUGPRINT_REG(ptr);
BAMBOO_DEBUGPRINT_REG(host);
BAMBOO_DEBUGPRINT_REG(objptr);
#endif
- // send a msg to host informing that objptr is active
- send_msg_2(host, GCMARKEDOBJ, objptr);
- gcself_numsendobjs++;
+ // check if this obj has been forwarded
+ if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
+ // send a msg to host informing that objptr is active
+ send_msg_2(host, GCMARKEDOBJ, objptr, false);
+ gcself_numsendobjs++;
+ MGCHashadd(gcforwardobjtbl, (int)objptr);
+ }
}
} else {
BAMBOO_START_CRITICAL_SECTION();
if(ptr + size > gcmarkedptrbound) {
gcmarkedptrbound = ptr + size;
} // if(ptr + size > gcmarkedptrbound)
- } // if(isLarge(ptr, &type, &size)) else ...
+ } else {
+ // ptr is not an active obj or has been marked
+ checkfield = false;
+ }// if(isLarge(ptr, &type, &size)) else ...
} else {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xbbbb);
BAMBOO_DEBUGPRINT_REG(host);
BAMBOO_DEBUGPRINT_REG(ptr);
#endif
- // send a msg to host informing that ptr is active
- send_msg_2(host, GCMARKEDOBJ, ptr);
- gcself_numsendobjs++;
+ // check if this obj has been forwarded
+ if(!MGCHashcontains(gcforwardobjtbl, (int)ptr)) {
+ // send a msg to host informing that ptr is active
+ send_msg_2(host, GCMARKEDOBJ, ptr, false);
+ gcself_numsendobjs++;
+ MGCHashadd(gcforwardobjtbl, (int)ptr);
+ }
checkfield = false;
}// if(isLocal(ptr)) else ...
} // if(ISSHAREDOBJ(ptr))
BAMBOO_DEBUGPRINT(0xed09);
#endif
send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
- gcself_numsendobjs, gcself_numreceiveobjs);
+ gcself_numsendobjs, gcself_numreceiveobjs, false);
sendStall = true;
}
} // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
gcdstcore = gctopcore;
gcblock2fill = *numblocks + 1;
} else {
- send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1);
+ send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
}
#ifdef DEBUG
BAMBOO_DEBUGPRINT_REG(coren);
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xeb04);
#endif
- send_msg_4(dstcore, GCMOVESTART, sourcecore, startaddr, tomove);
+ send_msg_4(dstcore, GCMOVESTART, sourcecore,
+ startaddr, tomove, false);
}
gcmovepending--;
nosparemem = true;
// ask for more mem
gctomove = false;
send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
- *filledblocks, *heaptopptr, gccurr_heaptop);
+ *filledblocks, *heaptopptr, gccurr_heaptop, false);
} else {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xe108);
#endif
// finish compacting
send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
- *filledblocks, *heaptopptr, 0);
+ *filledblocks, *heaptopptr, 0, false);
}
} // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
BAMBOO_DEBUGPRINT_REG(to->base);
#endif
send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
- 0, to->base, 0);
+ 0, to->base, 0, false);
RUNFREE(orig);
RUNFREE(to);
return;
gcismapped = false;
gcmappedobj = NULL;
send_msg_3(hostcore(objptr), GCMAPREQUEST, (int)objptr,
- BAMBOO_NUM_OF_CORE);
+ BAMBOO_NUM_OF_CORE, false);
while(true) {
if(gcismapped) {
break;
inline void flush(struct garbagelist * stackptr) {
flushRuntimeObj(stackptr);
-
+
while(gc_moreItems()) {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xe301);
BAMBOO_DEBUGPRINT(0xe308);
#endif
+ // TODO bug here: the startup core contains all lobjs' info, it will
+ // redundantly flush the lobjs found in the other cores.
// flush lobjs
while(gc_lobjmoreItems()) {
#ifdef DEBUG
if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
} else {
- send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE);
+ send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
}
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xe311);
}
//BAMBOO_CLOSE_CRITICAL_SECTION();
}
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Do initGC\n");
#endif
initGC();
//send init finish msg to core coordinator
- send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE);
+ send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
while(true) {
//BAMBOO_START_CRITICAL_SECTION();
if(MARKPHASE == gcphase) {
}
//BAMBOO_CLOSE_CRITICAL_SECTION();
}
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Start mark phase\n");
#endif
mark(true, stackptr);
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Finish mark phase, start compact phase\n");
#endif
compact();
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Finish compact phase\n");
#endif
while(true) {
}
//BAMBOO_CLOSE_CRITICAL_SECTION();
}
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Start flush phase\n");
#endif
flush(stackptr);
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Finish flush phase\n");
#endif
}
//BAMBOO_CLOSE_CRITICAL_SECTION();
}
-#ifdef GC_DEBUG
+#ifdef RAWPATH // TODO GC_DEBUG
tprintf("Finish gc!\n");
#endif
} // void gc_collect(struct garbagelist * stackptr)
gcphase = INITPHASE;
for(i = 1; i < NUMCORES4GC; i++) {
// send GC init messages to all cores
- send_msg_1(i, GCSTARTINIT);
+ send_msg_1(i, GCSTARTINIT, false);
}
bool isfirst = true;
bool allStall = false;
for(i = 1; i < NUMCORES4GC; ++i) {
gccorestatus[i] = 1;
// send GC start messages to all cores
- send_msg_1(i, GCSTART);
+ send_msg_1(i, GCSTART, false);
}
gcphase = MARKPHASE;
// send msgs to all cores requiring large objs info
numconfirm = NUMCORES4GC - 1;
for(i = 1; i < NUMCORES4GC; ++i) {
- send_msg_1(i, GCLOBJREQUEST);
+ send_msg_1(i, GCLOBJREQUEST, false);
}
gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
while(true) {
BAMBOO_EXIT(0xb104);
}
// predict number of blocks to fill for each core
- int numpbc = loadbalance();
+ int tmpheaptop = 0;
+ int numpbc = loadbalance(&tmpheaptop);
// TODO
numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
#ifdef RAWPATH // TODO GC_DEBUG
tprintf("mark phase finished \n");
//dumpSMem();
#endif
- int tmptopptr = 0;
- BASEPTR(gctopcore, 0, &tmptopptr);
+ //int tmptopptr = 0;
+ //BASEPTR(gctopcore, 0, &tmptopptr);
// TODO
- tmptopptr = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
+ //tmptopptr = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
+ tmpheaptop = (BAMBOO_BASE_VA) + (BAMBOO_SHARED_MEM_SIZE);
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xabab);
BAMBOO_DEBUGPRINT_REG(tmptopptr);
#endif
for(i = 0; i < NUMCORES4GC; ++i) {
int tmpcoreptr = 0;
- BASEPTR(i, 0, &tmpcoreptr);
+ BASEPTR(i, numpbc, &tmpcoreptr);
//send start compact messages to all cores
- if (tmpcoreptr < tmptopptr) {
+ //TODO bug here, do not know if the direction is positive or negtive?
+ if (tmpcoreptr < tmpheaptop/*tmptopptr*/) {
gcstopblock[i] = numpbc + 1;
if(i != STARTUPCORE) {
- send_msg_2(i, GCSTARTCOMPACT, numpbc+1);
+ send_msg_2(i, GCSTARTCOMPACT, numpbc+1, false);
} else {
gcblock2fill = numpbc+1;
} // if(i != STARTUPCORE)
} else {
gcstopblock[i] = numpbc;
if(i != STARTUPCORE) {
- send_msg_2(i, GCSTARTCOMPACT, numpbc);
+ send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
} else {
gcblock2fill = numpbc;
} // if(i != STARTUPCORE)
for(i = 1; i < NUMCORES4GC; ++i) {
// send start flush messages to all cores
gccorestatus[i] = 1;
- send_msg_1(i, GCSTARTFLUSH);
+ send_msg_1(i, GCSTARTFLUSH, false);
}
#ifdef RAWPATH // TODO GC_DEBUG
gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
for(i = 1; i < NUMCORES4GC; ++i) {
// send gc finish messages to all cores
- send_msg_1(i, GCFINISH);
+ send_msg_1(i, GCFINISH, false);
gccorestatus[i] = 1;
}
#ifdef RAWPATH // TODO GC_DEBUG
volatile GCPHASETYPE gcphase; // indicating GC phase
int gccurr_heaptop;
+struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
// for mark phase termination
int gccorestatus[NUMCORES4GC]; // records status of each core
// 1: running gc
INTPTR gcmarkedptrbound;
int gcblock2fill;
int gcstopblock[NUMCORES4GC]; // indicate when to stop compact phase
-int gcfilledblocks[NUMCORES4GC]; //indicate how many blocks have been fulfilled
+int gcfilledblocks[NUMCORES4GC];//indicate how many blocks have been fulfilled
// move instruction;
INTPTR gcmovestartaddr;
int gcdstcore;
* (size is always 3 * sizeof(int))
*/
typedef enum {
- MSGSTART = 0x0, // 0x0
- TRANSOBJ, // 0x1
- TRANSTALL, // 0x2
- LOCKREQUEST, // 0x3
- LOCKGROUNT, // 0x4
- LOCKDENY, // 0x5
- LOCKRELEASE, // 0x6
- PROFILEOUTPUT, // 0x7
- PROFILEFINISH, // 0x8
- REDIRECTLOCK, // 0x9
- REDIRECTGROUNT, // 0xa
- REDIRECTDENY, // 0xb
- REDIRECTRELEASE, // 0xc
- STATUSCONFIRM, // 0xd
- STATUSREPORT, // 0xe
- TERMINATE, // 0xf
- MEMREQUEST, // 0x10
- MEMRESPONSE, // 0x11
+ MSGSTART = 0xD0, // 0xD0
+ TRANSOBJ, // 0xD1
+ TRANSTALL, // 0xD2
+ LOCKREQUEST, // 0xD3
+ LOCKGROUNT, // 0xD4
+ LOCKDENY, // 0xD5
+ LOCKRELEASE, // 0xD6
+ PROFILEOUTPUT, // 0xD7
+ PROFILEFINISH, // 0xD8
+ REDIRECTLOCK, // 0xD9
+ REDIRECTGROUNT, // 0xDa
+ REDIRECTDENY, // 0xDb
+ REDIRECTRELEASE, // 0xDc
+ STATUSCONFIRM, // 0xDd
+ STATUSREPORT, // 0xDe
+ TERMINATE, // 0xDf
+ MEMREQUEST, // 0xE0
+ MEMRESPONSE, // 0xE1
#ifdef MULTICORE_GC
- GCSTARTINIT, // 0x12
- GCSTART, // 0x13
- GCSTARTCOMPACT, // 0x14
- GCSTARTFLUSH, // 0x15
- GCFINISHINIT, // 0x16
- GCFINISHMARK, // 0x17
- GCFINISHCOMPACT, // 0x18
- GCFINISHFLUSH, // 0x19
- GCFINISH, // 0x1a
- GCMARKCONFIRM, // 0x1b
- GCMARKREPORT, // 0x1c
- GCMARKEDOBJ, // 0x1d
- GCMOVESTART, // 0x1e
- GCMAPREQUEST, // 0x1f
- GCMAPINFO, // 0x20
- GCLOBJREQUEST, // 0x21
- GCLOBJINFO, // 0x22
- GCLOBJMAPPING, // 0x23
+ GCSTARTINIT, // 0xE2
+ GCSTART, // 0xE3
+ GCSTARTCOMPACT, // 0xE4
+ GCSTARTFLUSH, // 0xE5
+ GCFINISHINIT, // 0xE6
+ GCFINISHMARK, // 0xE7
+ GCFINISHCOMPACT, // 0xE8
+ GCFINISHFLUSH, // 0xE9
+ GCFINISH, // 0xEa
+ GCMARKCONFIRM, // 0xEb
+ GCMARKREPORT, // 0xEc
+ GCMARKEDOBJ, // 0xEd
+ GCMOVESTART, // 0xEe
+ GCMAPREQUEST, // 0xEf
+ GCMAPINFO, // 0xF0
+ GCLOBJREQUEST, // 0xF1
+ GCLOBJINFO, // 0xF2
+ GCLOBJMAPPING, // 0xF3
#endif
MSGEND
} MSGTYPE;
// msg related functions
INLINE void send_hanging_msg();
INLINE void send_msg_1(int targetcore,
- unsigned long n0);
+ unsigned long n0,
+ bool isinterrupton);
INLINE void send_msg_2(int targetcore,
unsigned long n0,
- unsigned long n1);
+ unsigned long n1,
+ bool isinterrupton);
INLINE void send_msg_3(int targetcore,
unsigned long n0,
unsigned long n1,
- unsigned long n2);
+ unsigned long n2,
+ bool isinterrupton);
INLINE void send_msg_4(int targetcore,
unsigned long n0,
unsigned long n1,
unsigned long n2,
- unsigned long n3);
+ unsigned long n3,
+ bool isinterrupton);
INLINE void send_msg_5(int targetcore,
unsigned long n0,
unsigned long n1,
unsigned long n2,
unsigned long n3,
- unsigned long n4);
+ unsigned long n4,
+ bool isinterrupton);
INLINE void send_msg_6(int targetcore,
unsigned long n0,
unsigned long n1,
unsigned long n2,
unsigned long n3,
unsigned long n4,
- unsigned long n5);
+ unsigned long n5,
+ bool isinterrupton);
INLINE void cache_msg_2(int targetcore,
unsigned long n0,
unsigned long n1);
bamboo_smem_mode = SMEMGLOBAL;
#else
// defaultly using local mode
- bamboo_smem_mode = SMEMLOCAL;
+ //bamboo_smem_mode = SMEMLOCAL;
+ bamboo_smem_mode = SMEMGLOBAL;
#endif
} // void setupsmemmode(void)
#endif
//mgchashCreate(2000, 0.75);
gcpointertbl = allocateRuntimeHash(20);
//gcpointertbl = allocateMGCHash(20);
+ gcforwardobjtbl = allocateMGCHash(20, 3);
gcobj2map = 0;
gcmappedobj = 0;
gcismapped = false;
//mgchashDelete();
freeRuntimeHash(gcpointertbl);
//freeMGCHash(gcpointertbl);
+ freeMGCHash(gcforwardobjtbl);
if(gcsmemtbl != NULL) {
RUNFREE(gcsmemtbl);
}
for(i = 1; i < NUMCORESACTIVE; ++i) {
corestatus[i] = 1;
// send status confirm msg to core i
- send_msg_1(i, STATUSCONFIRM);
+ send_msg_1(i, STATUSCONFIRM, false);
} // for(i = 1; i < NUMCORESACTIVE; ++i)
waitconfirm = true;
numconfirm = NUMCORESACTIVE - 1;
#endif
for(i = 1; i < NUMCORESACTIVE; ++i) {
// send profile request msg to core i
- send_msg_2(i, PROFILEOUTPUT, totalexetime);
+ send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
} // for(i = 1; i < NUMCORESACTIVE; ++i)
// pour profiling data on startup core
outputProfileData();
BAMBOO_DEBUGPRINT(0xee0b);
#endif
// send stall msg
- send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs);
+ send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs, false);
sendStall = true;
isfirst = true;
busystatus = false;
int * allocsize) {
void * mem = (void *)(freemem->ptr);
// check the remaining space in this block
- int remain = (int)(mem-(BAMBOO_BASE_VA));
+ int remain = (int)(mem-gcbaseva);
int bound = (BAMBOO_SMEM_SIZE);
if(remain < BAMBOO_LARGE_SMEM_BOUND) {
bound = (BAMBOO_SMEM_SIZE_L);
if(isMsgSending) {
cache_msg_4(data4, tmp, msgdata[1], data2, data3);
} else {
- send_msg_4(data4, tmp, msgdata[1], data2, data3);
+ send_msg_4(data4, tmp, msgdata[1], data2, data3, true);
}
}
break;
if(isMsgSending) {
cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
} else {
- send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
+ send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
}
break;
}
cache_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
data1, data2, data3);
} else {
- send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
- data1, data2, data3);
+ send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
+ data1, data2, data3, true);
}
}
break;
busystatus?1:0, BAMBOO_NUM_OF_CORE,
self_numsendobjs, self_numreceiveobjs);
} else {
- send_msg_5(STARTUPCORE, STATUSREPORT,
- busystatus?1:0, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs);
+ send_msg_5(STARTUPCORE, STATUSREPORT, busystatus?1:0,
+ BAMBOO_NUM_OF_CORE, self_numsendobjs,
+ self_numreceiveobjs, true);
}
}
break;
if(isMsgSending) {
cache_msg_3(msgdata[2], MEMRESPONSE, mem, allocsize);
} else {
- send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize);
+ send_msg_3( msgdata[2], MEMRESPONSE, mem, allocsize, true);
}
}
break;
if(isMsgSending) {
cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
} else {
- send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
+ send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
}
}
} else {
if(isMsgSending) {
cache_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
} else {
- send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove);
+ send_msg_4(j, GCMOVESTART, cnum, startaddr, tomove, true);
}
} // if(STARTUPCORE == j)
if(gcrequiredmems[j] == 0) {
gcbusystatus, gcself_numsendobjs,
gcself_numreceiveobjs);
} else {
- send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
- gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
+ send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
+ gcbusystatus, gcself_numsendobjs,
+ gcself_numreceiveobjs, true);
}
}
break;
/*if(isMsgSending) {
cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
} else {
- send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
+ send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1], true);
}*/
} else {
// send back the mapping info
if(isMsgSending) {
cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
} else {
- send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr);
+ send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], (int)dstptr, true);
}
}
break;
default:
break;
}
- for(; msgdataindex > 0; --msgdataindex) {
+ /*for(; msgdataindex > 0; --msgdataindex) {
msgdata[msgdataindex-1] = -1;
- }
+ }*/
+ memset(msgdata, '\0', sizeof(int) * msgdataindex);
+ msgdataindex = 0;
msglength = BAMBOO_MSG_BUF_LENGTH;
#ifdef DEBUG
#ifndef CLOSE_PRINT
} else {
// send lock release with redirect info msg
// for 32 bit machine, the size is always 4 words
- send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
+ send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock,
+ (int)redirectlock, false);
}
}
#endif