+++ /dev/null
-#ifdef MULTICORE_GC
-
-#include "GCSharedHash.h"
-#ifdef MULTICORE
-#include "runtime_arch.h"
-#else
-#include <stdio.h>
-#endif
-
-#ifndef INTPTR
-#ifdef BIT64
-#define INTPTR long
-#define INTPTRSHIFT 3
-#else
-#define INTPTR int
-#define INTPTRSHIFT 2
-#endif
-#endif
-
-#ifndef INLINE
-#define INLINE inline __attribute__((always_inline))
-#endif // #ifndef INLINE
-
-#define GC_SHIFT_BITS 4
-
-/* GCSHARED HASH ********************************************************/
-
-// params: startaddr -- the start addr of the shared memory
-// rsize -- remaining size of the available shared memory
-struct GCSharedHash * noargallocateGCSharedHash() {
- return allocateGCSharedHash(100);
-}
-
-struct GCSharedHash * allocateGCSharedHash(int size) {
- struct GCSharedHash *thisvar;
- if (size <= 0) {
-#ifdef MULTICORE
- BAMBOO_EXIT(0xf201);
-#else
- printf("Negative Hashtable size Exception\n");
- exit(-1);
-#endif
- }
- thisvar=(struct GCSharedHash *)FREEMALLOC_NGC(sizeof(struct GCSharedHash));
- if(thisvar == NULL) {
- return NULL;
- }
- thisvar->size = size;
- thisvar->bucket =
- (struct GCSharedNode **)FREEMALLOC_NGC(sizeof(struct GCSharedNode *)*size);
- if(thisvar->bucket == NULL) {
- FREE_NGC(thisvar);
- return NULL;
- }
- /* Set allocation blocks*/
- thisvar->listhead=NULL;
- thisvar->listtail=NULL;
- /*Set data counts*/
- thisvar->numelements = 0;
- return thisvar;
-}
-
-void freeGCSharedHash(struct GCSharedHash *thisvar) {
- struct GCSharedNode *ptr=thisvar->listhead;
- FREE_NGC(thisvar->bucket);
- while(ptr) {
- struct GCSharedNode *next=ptr->lnext;
- FREE_NGC(ptr);
- ptr=next;
- }
- FREE_NGC(thisvar);
-}
-
-bool GCSharedHashrehash(struct GCSharedHash * thisvar) {
- int newsize=thisvar->size;
- struct GCSharedNode ** newbucket = (struct GCSharedNode **)
- FREEMALLOC_NGC(sizeof(struct GCSharedNode *)*newsize);
- if(newbucket == NULL) {
- return false;
- }
- int i;
- for(i=thisvar->size-1; i>=0; i--) {
- struct GCSharedNode *ptr;
- for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
- struct GCSharedNode * nextptr=ptr->next;
- unsigned int newhashkey=(unsigned int)ptr->key % newsize;
- ptr->next=newbucket[newhashkey];
- newbucket[newhashkey]=ptr;
- ptr=nextptr;
- }
- }
- thisvar->size=newsize;
- FREE_NGC(thisvar->bucket);
- thisvar->bucket=newbucket;
- return true;
-}
-
-int GCSharedHashadd(struct GCSharedHash * thisvar,int key, int data) {
- /* Rehash code */
- unsigned int hashkey;
- struct GCSharedNode **ptr;
-
- if (thisvar->numelements>=thisvar->size) {
- int newsize=2*thisvar->size+1;
- struct GCSharedNode ** newbucket =
- (struct GCSharedNode **)FREEMALLOC_NGC(
- sizeof(struct GCSharedNode *)*newsize);
- if(newbucket == NULL) {
- return -1;
- }
- int i;
- for(i=thisvar->size-1; i>=0; i--) {
- struct GCSharedNode *ptr;
- for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
- struct GCSharedNode * nextptr=ptr->next;
- unsigned int newhashkey=(unsigned int)ptr->key % newsize;
- ptr->next=newbucket[newhashkey];
- newbucket[newhashkey]=ptr;
- ptr=nextptr;
- }
- }
- thisvar->size=newsize;
- FREE_NGC(thisvar->bucket);
- thisvar->bucket=newbucket;
- }
-
- hashkey = (unsigned int)key % thisvar->size;
- ptr = &thisvar->bucket[hashkey];
-
- /* check that thisvar key/object pair isn't already here */
- /* TBD can be optimized for set v. relation */
-
- while (*ptr) {
- if ((*ptr)->key == key && (*ptr)->data == data) {
- return 0;
- }
- ptr = &((*ptr)->next);
- }
-
- {
- struct GCSharedNode *node=FREEMALLOC_NGC(sizeof(struct GCSharedNode));
- if(node == NULL) {
- return -1;
- }
- node->data=data;
- node->key=key;
- node->next=(*ptr);
- *ptr=node;
- if (thisvar->listhead==NULL) {
- thisvar->listhead=node;
- thisvar->listtail=node;
- node->lnext=NULL;
- node->lprev=NULL;
- } else {
- node->lprev=NULL;
- node->lnext=thisvar->listhead;
- thisvar->listhead->lprev=node;
- thisvar->listhead=node;
- }
- }
-
- thisvar->numelements++;
- return 1;
-}
-
-#ifdef MULTICORE
-struct GCSharedHash * allocateGCSharedHash_I(int size) {
- struct GCSharedHash *thisvar;
- if (size <= 0) {
-#ifdef MULTICORE
- BAMBOO_EXIT(0xf202);
-#else
- printf("Negative Hashtable size Exception\n");
- exit(-1);
-#endif
- }
- thisvar=(struct GCSharedHash *)FREEMALLOC_NGC_I(sizeof(struct GCSharedHash));
- if(thisvar == NULL) {
- return NULL;
- }
- thisvar->size = size;
- thisvar->bucket =
- (struct GCSharedNode **)FREEMALLOC_NGC_I(
- sizeof(struct GCSharedNode *)*size);
- if(thisvar->bucket == NULL) {
- FREE_NGC_I(thisvar);
- return NULL;
- }
- /* Set allocation blocks*/
- thisvar->listhead=NULL;
- thisvar->listtail=NULL;
- /*Set data counts*/
- thisvar->numelements = 0;
- return thisvar;
-}
-
-int GCSharedHashadd_I(struct GCSharedHash * thisvar,int key, int data) {
- /* Rehash code */
- unsigned int hashkey;
- struct GCSharedNode **ptr;
-
- if (thisvar->numelements>=thisvar->size) {
- int newsize=2*thisvar->size+1;
- struct GCSharedNode ** newbucket =
- (struct GCSharedNode **)FREEMALLOC_NGC_I(
- sizeof(struct GCSharedNode *)*newsize);
- if(newbucket == NULL) {
- return -1;
- }
- int i;
- for(i=thisvar->size-1; i>=0; i--) {
- struct GCSharedNode *ptr;
- for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
- struct GCSharedNode * nextptr=ptr->next;
- unsigned int newhashkey=(unsigned int)ptr->key % newsize;
- ptr->next=newbucket[newhashkey];
- newbucket[newhashkey]=ptr;
- ptr=nextptr;
- }
- }
- thisvar->size=newsize;
- FREE_NGC_I(thisvar->bucket);
- thisvar->bucket=newbucket;
- }
-
- hashkey = (unsigned int)key % thisvar->size;
- ptr = &thisvar->bucket[hashkey];
-
- /* check that thisvar key/object pair isn't already here */
- /* TBD can be optimized for set v. relation */
-
- while (*ptr) {
- if ((*ptr)->key == key && (*ptr)->data == data) {
- return 0;
- }
- ptr = &((*ptr)->next);
- }
-
- {
- struct GCSharedNode *node=FREEMALLOC_NGC_I(sizeof(struct GCSharedNode));
- if(node == NULL) {
- return -1;
- }
- node->data=data;
- node->key=key;
- node->next=(*ptr);
- *ptr=node;
- if (thisvar->listhead==NULL) {
- thisvar->listhead=node;
- thisvar->listtail=node;
- node->lnext=NULL;
- node->lprev=NULL;
- } else {
- node->lprev=NULL;
- node->lnext=thisvar->listhead;
- thisvar->listhead->lprev=node;
- thisvar->listhead=node;
- }
- }
-
- thisvar->numelements++;
- return 1;
-}
-#endif
-
-int GCSharedHashget(struct GCSharedHash *thisvar, int key, int *data) {
- unsigned int hashkey = (unsigned int)key % thisvar->size;
-
- struct GCSharedNode *ptr = thisvar->bucket[hashkey];
- while (ptr) {
- if (ptr->key == key) {
- *data = ptr->data;
- return 1; /* success */
- }
- ptr = ptr->next;
- }
-
- return 0; /* failure */
-}
-
-/* MGCSHAREDHASH ********************************************************/
-
-mgcsharedhashtbl_t * mgcsharedhashCreate(unsigned int size,
- double loadfactor) {
- mgcsharedhashtbl_t * ctable;
- mgcsharedhashlistnode_t * nodes;
- int i;
-
- ctable = (mgcsharedhashtbl_t *)FREEMALLOC_NGC(sizeof(mgcsharedhashtbl_t));
- if(ctable == NULL) {
- // TODO
- BAMBOO_EXIT(0xf203);
- return NULL;
- }
- // Allocate space for the hash table
- ctable->table = (mgcsharedhashlistnode_t *)FREEMALLOC_NGC(
- size*sizeof(mgcsharedhashlistnode_t));
- if(ctable->table == NULL) {
- BAMBOO_EXIT(0xf204); // TODO
- return NULL;
- }
- ctable->size = size;
- ctable->loadfactor = loadfactor;
- ctable->threshold = size*loadfactor;
-
- ctable->mask = (size << (GC_SHIFT_BITS))-1;
-
- ctable->structs = NULL ; //FREEMALLOC_NGC(1*sizeof(mgcliststruct_t));
- ctable->numelements = 0; // Initial number of elements in the hash
- ctable->list = NULL;
-
- return ctable;
-}
-
-mgcsharedhashtbl_t * mgcsharedhashCreate_I(unsigned int size,
- double loadfactor) {
- mgcsharedhashtbl_t * ctable;
- mgcsharedhashlistnode_t * nodes;
- int i;
-
- ctable = (mgcsharedhashtbl_t *)FREEMALLOC_NGC_I(sizeof(mgcsharedhashtbl_t));
- if(ctable == NULL) {
- // TODO
- BAMBOO_EXIT(0xf205);
- return NULL;
- }
- // Allocate space for the hash table
- ctable->table = (mgcsharedhashlistnode_t *)FREEMALLOC_NGC_I(
- size*sizeof(mgcsharedhashlistnode_t));
- if(ctable->table == NULL) {
- BAMBOO_EXIT(0xf206); // TODO
- return NULL;
- }
- ctable->size = size;
- ctable->loadfactor = loadfactor;
- ctable->threshold = size*loadfactor;
-
- ctable->mask = (size << (GC_SHIFT_BITS))-1;
-
- ctable->structs = NULL ; //FREEMALLOC_NGC(1*sizeof(mgcliststruct_t));
- ctable->numelements = 0; // Initial number of elements in the hash
- ctable->list = NULL;
-
- return ctable;
-}
-
-void mgcsharedhashReset(mgcsharedhashtbl_t * tbl) {
- mgcsharedhashlistnode_t * ptr = tbl->table;
-
- if ((tbl->numelements) < (tbl->size>>6)) {
- mgcsharedhashlistnode_t *top = &ptr[tbl->size];
- mgcsharedhashlistnode_t * list = tbl->list;
- while(list != NULL) {
- mgcsharedhashlistnode_t * next = list->next;
- if ((list >= ptr) && (list < top)) {
- //zero in list
- list->key=NULL;
- list->next=NULL;
- }
- list = next;
- }
- } else {
- BAMBOO_MEMSET_WH(tbl->table, '\0',
- sizeof(mgcsharedhashlistnode_t)*tbl->size);
- }
-
- mgcsharedliststruct_t * structs = tbl->structs;
- while(structs != NULL) {
- mgcsharedliststruct_t * next = structs->next;
- BAMBOO_MEMSET_WH(structs->array, '\0',
- structs->num * sizeof(mgcsharedhashlistnode_t));
- structs->num = 0;
- structs = next;
- }
- tbl->numelements = 0;
-}
-
-//Store objects and their pointers into hash
-//Using open addressing
-int mgcsharedhashInsert(mgcsharedhashtbl_t * tbl, void * key, void * val) {
- mgcsharedhashlistnode_t * ptr;
-
- if(tbl->numelements > (tbl->threshold)) {
- //Never resize, simply don't insert any more
- return -1;
- }
-
- //int keyto = ((unsigned INTPTR)key) % (tbl->size);
- //ptr=&tbl->table[keyto];
- ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
-
- if(ptr->key==0) {
- // the first time insert a value for the key
- ptr->key=key;
- ptr->val=val;
- } else { // Insert to the next empty place
- mgcsharedhashlistnode_t *top = &tbl->table[tbl->size];
- do {
- ptr++;
- } while((ptr < top) && (ptr->key != NULL));
- if(ptr >= top) {
- return -1;
- } else {
- ptr->key = key;
- ptr->val = val;
- }
- }
- ptr->next = tbl->list;
- tbl->list = ptr;
- tbl->numelements++;
- return 1;
-}
-
-int mgcsharedhashInsert_I(mgcsharedhashtbl_t * tbl, void * key, void * val) {
- mgcsharedhashlistnode_t * ptr;
-
- if(tbl->numelements > (tbl->threshold)) {
- //Never resize, simply don't insert any more
- return -1;
- }
-
- //int keyto = ((unsigned INTPTR)key) % (tbl->size);
- //ptr=&tbl->table[keyto];
- ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
-
- if(ptr->key==0) {
- // the first time insert a value for the key
- ptr->key=key;
- ptr->val=val;
- } else { // Insert to the next empty place
- mgcsharedhashlistnode_t * top = &tbl->table[tbl->size];
- mgcsharedhashlistnode_t * start = ptr;
- do {
- ptr++;
- if(ptr->key == 0) {
- break;
- }
- } while(ptr < top);
- if(ptr >= top) {
- return -1;
- } else {
- ptr->key = key;
- ptr->val = val;
- }
- }
- ptr->next = tbl->list;
- tbl->list = ptr;
- tbl->numelements++;
- return 1;
-}
-
-// Search for an address for a given oid
-INLINE void * mgcsharedhashSearch(mgcsharedhashtbl_t * tbl, void * key) {
- //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
- //int keyto = ((unsigned INTPTR)key) % (tbl->size);
- //mgcsharedhashlistnode_t * node=&tbl->table[keyto];
- mgcsharedhashlistnode_t * node =
- &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
- mgcsharedhashlistnode_t *top = &tbl->table[tbl->size];
-
- do {
- //i++;
- if(node->key == key) {
- return node->val;
- }
- node++;
- } while(node < top);
-
- return NULL;
-}
-
-#endif
+++ /dev/null
-#ifdef MULTICORE_GC
-
-#ifndef GCSHAREDHASH_H
-#define GCSHAREDHASH_H
-
-#ifndef bool
-#define bool int
-#endif
-
-#ifndef true
-#define true 1
-#endif
-
-#ifndef false
-#define false 0
-#endif
-
-#include "mem.h"
-
-/* GCSharedHash *********************************************************/
-
-struct GCSharedHash * noargallocateGCSharedHash();
-struct GCSharedHash * allocateGCSharedHash(int size);
-void freeGCSharedHash(struct GCSharedHash *);
-
-bool GCSharedHashrehash(struct GCSharedHash * thisvar);
-int GCSharedHashadd(struct GCSharedHash *, int key, int data);
-#ifdef MULTICORE
-struct GCSharedHash * allocateGCSharedHash_I(int size);
-int GCSharedHashadd_I(struct GCSharedHash *, int key, int data);
-#endif
-int GCSharedHashget(struct GCSharedHash *,int key, int* data);
-
-struct GCSharedHash {
- int numelements;
- int size;
- struct GCSharedNode **bucket;
- struct GCSharedNode *listhead;
- struct GCSharedNode *listtail;
-};
-
-inline int GCSharedHashcountset(struct GCSharedHash * thisvar);
-
-/* RuntimeHashException *************************************************/
-
-
-/* RuntimeIterator *****************************************************/
-struct GCSharedNode {
- struct GCSharedNode *next;
- struct GCSharedNode *lnext;
- struct GCSharedNode *lprev;
- int data;
- int key;
-};
-
-/* MGCSharedHash *********************************************************/
-typedef struct mgcsharedhashlistnode {
- void * key;
- void * val; //this can be cast to another type or used to point to a
- //larger structure
- struct mgcsharedhashlistnode * next;
-} mgcsharedhashlistnode_t;
-
-#define NUMMGCSHAREDLIST 250
-typedef struct mgcsharedlist {
- struct mgcsharedhashlistnode array[NUMMGCSHAREDLIST];
- int num;
- struct mgcsharedlist *next;
-} mgcsharedliststruct_t;
-
-typedef struct mgcsharedhashtbl {
- mgcsharedhashlistnode_t * table; // points to beginning of hash table
- mgcsharedhashlistnode_t * list;
- mgcsharedliststruct_t * structs;
- unsigned int size;
- unsigned int mask;
- unsigned int numelements;
- unsigned int threshold;
- double loadfactor;
-} mgcsharedhashtbl_t;
-
-mgcsharedhashtbl_t * mgcsharedhashCreate(unsigned int size, double loadfactor);
-mgcsharedhashtbl_t * mgcsharedhashCreate_I(unsigned int size,double loadfactor);
-int mgcsharedhashInsert(mgcsharedhashtbl_t * tbl, void * key, void * val);
-void * mgcsharedhashSearch(mgcsharedhashtbl_t * tbl, void * key);
-//unsigned int mgchashResize(unsigned int newsize);
-int mgcsharedhashInsert_I(mgcsharedhashtbl_t * tbl, void * key, void * val);
-//unsigned int mgchashResize_I(unsigned int newsize);
-//void mgcsharedhashDelete(mgcsharedhashtbl_t * tbl);
-void mgcsharedhashReset(mgcsharedhashtbl_t * tbl);
-
-#endif
-
-#endif
+++ /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
-
-#define GC_SHIFT_BITS 4
-
-/* mgchash ********************************************************/
-mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor) {
- mgchashtable_t *ctable;
- mgchashlistnode_t *nodes;
- int i;
-
- if (size <= 0) {
-#ifdef MULTICORE
- BAMBOO_EXIT(0xf101);
-#else
- printf("Negative Hashtable size Exception\n");
- exit(-1);
-#endif
- }
-
- // Allocate space for the hash table
- ctable = (mgchashtable_t *)RUNMALLOC(sizeof(mgchashtable_t));
- if(ctable == NULL) {
- // Run out of local memory
- BAMBOO_EXIT(0xf102);
- }
- ctable->table = (mgchashlistnode_t*)RUNMALLOC(size*sizeof(mgchashlistnode_t));
- if(ctable->table == NULL) {
- // Run out of local memory
- BAMBOO_EXIT(0xf103);
- }
- ctable->loadfactor = loadfactor;
- ctable->size = size;
- ctable->threshold=size*loadfactor;
-
- ctable->mask = (size << (GC_SHIFT_BITS))-1;
- //ctable->list = NULL;
- ctable->structs = (mgcliststruct_t*)RUNMALLOC(1*sizeof(mgcliststruct_t));
- ctable->numelements = 0; // Initial number of elements in the hash
-
- return ctable;
-}
-
-void mgchashreset(mgchashtable_t * tbl) {
- mgchashlistnode_t *ptr = tbl->table;
- int i;
-
- /*if (tbl->numelements<(tbl->size>>6)) {
- mgchashlistnode_t *top=&ptr[tbl->size];
- mgchashlistnode_t * list = tbl->list;
- while(list != NULL) {
- mgchashlistnode_t * next = list->lnext;
- if ((list >= ptr) && (list < top)) {
- //zero in list
- list->key=NULL;
- list->next=NULL;
- }
- list = next;
- }
- } else {*/
- BAMBOO_MEMSET_WH(tbl->table, '\0', sizeof(mgchashlistnode_t)*tbl->size);
- //}
- // TODO now never release any allocated memory, may need to be changed
- //mgcliststruct_t * next = tbl->structs;
- while(tbl->structs->next!=NULL) {
- mgcliststruct_t * next = tbl->structs->next;
- RUNFREE(tbl->structs);
- tbl->structs=next;
- /*next->num = 0;
- next = next->next;*/
- }
- tbl->structs->num = 0;
- tbl->numelements = 0;
-}
-
-//Store objects and their pointers into hash
-void mgchashInsert(mgchashtable_t * tbl, void * key, void *val) {
- mgchashlistnode_t *ptr;
-
- if(tbl->numelements > (tbl->threshold)) {
- //Resize
- unsigned int newsize = tbl->size << 1 + 1;
- mgchashResize(tbl, newsize);
- }
-
- ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
- tbl->numelements++;
-
- if(ptr->key==0) {
- // the first time insert a value for the key
- ptr->key=key;
- ptr->val=val;
- /*ptr->lnext = tbl->list;
- tbl->list = ptr;*/
- } else { // Insert in the beginning of linked list
- mgchashlistnode_t * node;
- if (tbl->structs->num<NUMMGCLIST) {
- node=&tbl->structs->array[tbl->structs->num];
- tbl->structs->num++;
- } else {
- //get new list
- mgcliststruct_t *tcl=RUNMALLOC(1*sizeof(mgcliststruct_t));
- tcl->next=tbl->structs;
- tbl->structs=tcl;
- node=&tcl->array[0];
- tcl->num=1;
- }
- node->key = key;
- node->val = val;
- node->next = ptr->next;
- ptr->next = node;
- /*node->lnext = tbl->list;
- tbl->list = node;*/
- }
-}
-
-#ifdef MULTICORE_GC
-mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor) {
- mgchashtable_t *ctable;
- mgchashlistnode_t *nodes;
- int i;
-
- if (size <= 0) {
-#ifdef MULTICORE
- BAMBOO_EXIT(0xf101);
-#else
- printf("Negative Hashtable size Exception\n");
- exit(-1);
-#endif
- }
-
- // Allocate space for the hash table
- ctable = (mgchashtable_t*)RUNMALLOC_I(sizeof(mgchashtable_t));
- if(ctable == NULL) {
- // Run out of local memory
- BAMBOO_EXIT(0xf102);
- }
- ctable->table=(mgchashlistnode_t*)RUNMALLOC_I(size*sizeof(mgchashlistnode_t));
- if(ctable->table == NULL) {
- // Run out of local memory
- BAMBOO_EXIT(0xf103);
- }
- ctable->loadfactor = loadfactor;
- ctable->size = size;
- ctable->threshold=size*loadfactor;
-
- ctable->mask = (size << (GC_SHIFT_BITS))-1;
- //ctable->list = NULL;
- ctable->structs = (mgcliststruct_t*)RUNMALLOC_I(1*sizeof(mgcliststruct_t));
- ctable->numelements = 0; // Initial number of elements in the hash
-
- return ctable;
-}
-
-void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val) {
- mgchashlistnode_t *ptr;
-
- if(tbl->numelements > (tbl->threshold)) {
- //Resize
- unsigned int newsize = tbl->size << 1 + 1;
- mgchashResize_I(tbl, newsize);
- }
-
- ptr = &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
- tbl->numelements++;
-
- if(ptr->key==0) {
- ptr->key=key;
- ptr->val=val;
- /*ptr->lnext = tbl->list;
- tbl->list = ptr;*/
- return;
- } else { // Insert in the beginning of linked list
- mgchashlistnode_t * node;
- if (tbl->structs->num<NUMMGCLIST) {
- node=&tbl->structs->array[tbl->structs->num];
- tbl->structs->num++;
- } else {
- //get new list
- mgcliststruct_t *tcl=RUNMALLOC_I(1*sizeof(mgcliststruct_t));
- tcl->next=tbl->structs;
- tbl->structs=tcl;
- node=&tcl->array[0];
- tcl->num=1;
- }
- node->key = key;
- node->val = val;
- node->next = ptr->next;
- ptr->next = node;
- /*node->lnext = tbl->list;
- tbl->list = node;*/
- }
-}
-#endif
-
-// Search for an address for a given oid
-INLINE void * mgchashSearch(mgchashtable_t * tbl, void * key) {
- //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
- mgchashlistnode_t *node =
- &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
-
- do {
- if(node->key == key) {
- return node->val;
- }
- node = node->next;
- } while(node != NULL);
-
- return NULL;
-}
-
-unsigned int mgchashResize(mgchashtable_t * tbl, 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 = tbl->table;
- oldsize = tbl->size;
-
- if((node = RUNMALLOC(newsize*sizeof(mgchashlistnode_t))) == NULL) {
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- tbl->table = node; //Update the global hashtable upon resize()
- tbl->size = newsize;
- tbl->threshold = newsize * tbl->loadfactor;
- mask = tbl->mask = (newsize << (GC_SHIFT_BITS)) - 1;
- //tbl->list = NULL;
-
- 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 INTPTR)key) & mask) >> (GC_SHIFT_BITS);
- tmp=&node[index];
- next = curr->next;
- // Insert into the new table
- if(tmp->key == 0) {
- tmp->key = key;
- tmp->val = curr->val;
- /*tmp->lnext = tbl->list;
- tbl->list = tmp;*/
- } /*
- 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(1*sizeof(mgchashlistnode_t));
- newnode->key = curr->key;
- newnode->val = curr->val;
- newnode->next = tmp->next;
- tmp->next=newnode;
- /*newnode->lnext = tbl->list;
- tbl->list = newnode;*/
- }
- else {
- curr->next=tmp->next;
- tmp->next=curr;
- /*curr->lnext = tbl->list;
- tbl->list = 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(mgchashtable_t * tbl, 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 = tbl->table;
- oldsize = tbl->size;
-
- if((node = RUNMALLOC_I(newsize*sizeof(mgchashlistnode_t))) == NULL) {
- BAMBOO_EXIT(0xf104);
- printf("Calloc error %s %d\n", __FILE__, __LINE__);
- return 1;
- }
-
- tbl->table = node; //Update the global hashtable upon resize()
- tbl->size = newsize;
- tbl->threshold = newsize * tbl->loadfactor;
- mask = tbl->mask = (newsize << (GC_SHIFT_BITS))-1;
- //tbl->list = NULL;
-
- 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 INTPTR)key) & mask) >> (GC_SHIFT_BITS);
- tmp=&node[index];
- next = curr->next;
- // Insert into the new table
- if(tmp->key == 0) {
- tmp->key = key;
- tmp->val = curr->val;
- /*tmp->lnext = tbl->list;
- tbl->list = tmp;*/
- } /*
- 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;
- /*newnode->lnext = tbl->list;
- tbl->list = newnode;*/
- } else {
- curr->next=tmp->next;
- tmp->next=curr;
- /*curr->lnext = tbl->list;
- tbl->list = 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(mgchashtable_t * tbl) {
- int i;
- mgcliststruct_t *ptr=tbl->structs;
- while(ptr!=NULL) {
- mgcliststruct_t *next=ptr->next;
- RUNFREE(ptr);
- ptr=next;
- }
- RUNFREE(tbl->table);
- tbl->table=NULL;
- tbl->structs=NULL;
-}
-
-/* MGCHASH ********************************************************/
-
-struct MGCHash * allocateMGCHash(int size,
- int conflicts) {
- struct MGCHash *thisvar;
- if (size <= 0) {
-#ifdef MULTICORE
- BAMBOO_EXIT(0xf105);
-#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);
- //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);
-}
-
-int MGCHashadd(struct MGCHash * thisvar, int data) {
- // Rehash code
- unsigned int hashkey;
- struct MGCNode *ptr;
-
- int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
- hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
- //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
-struct MGCHash * allocateMGCHash_I(int size,
- int conflicts) {
- struct MGCHash *thisvar;
- if (size <= 0) {
-#ifdef MULTICORE
- BAMBOO_EXIT(0xf106);
-#else
- printf("Negative Hashtable size Exception\n");
- exit(-1);
-#endif
- }
- thisvar=(struct MGCHash *)RUNMALLOC_I(sizeof(struct MGCHash));
- thisvar->size = size;
- thisvar->bucket =
- (struct MGCNode *) RUNMALLOC_I(sizeof(struct MGCNode)*size);
- //Set data counts
- thisvar->num4conflicts = conflicts;
- return thisvar;
-}
-
-int MGCHashadd_I(struct MGCHash * thisvar, int data) {
- // Rehash code
- unsigned int hashkey;
- struct MGCNode *ptr;
-
- int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
- hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
- //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) {
- int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
- unsigned int hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
- //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;
- //struct mgchashlistnode *lnext;
-} mgchashlistnode_t;
-
-#define NUMMGCLIST 250
-typedef struct mgclist {
- struct mgchashlistnode array[NUMMGCLIST];
- int num;
- struct mgclist *next;
-} mgcliststruct_t;
-
-typedef struct mgchashtable {
- mgchashlistnode_t * table; // points to beginning of hash table
- //mgchashlistnode_t * list;
- mgcliststruct_t * structs;
- unsigned int size;
- unsigned int mask;
- unsigned int numelements;
- unsigned int threshold;
- double loadfactor;
-} mgchashtable_t;
-
-mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor);
-void mgchashInsert(mgchashtable_t * tbl, void * key, void *val);
-void * mgchashSearch(mgchashtable_t * tbl, void * key);
-unsigned int mgchashResize(mgchashtable_t * tbl, unsigned int newsize);
-#ifdef MULTICORE_GC
-mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor);
-void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val);
-unsigned int mgchashResize_I(mgchashtable_t * tbl, unsigned int newsize);
-#endif
-void mgchashDelete(mgchashtable_t * tbl);
-void mgchashreset(mgchashtable_t * tbl);
-
-
-/** MGCHash *******************************************************************/
-struct MGCHash * allocateMGCHash(int size, int conflicts);
-void freeMGCHash(struct MGCHash *);
-
-//void MGCHashrehash(struct MGCHash * thisvar);
-int MGCHashadd(struct MGCHash *, int data);
-#ifdef MULTICORE
-struct MGCHash * allocateMGCHash_I(int size, int conflicts);
-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
+++ /dev/null
-TOPDIR=/home/jzhou/starsearch
-include $(TOPDIR)/Makefile.include
-
-RGCCFLAGS += -O2
-RGCCFLAGS += ${RAWRGCCFLAGS}
-
-USE_SLGCC=1
-
-SIM-CYCLES = 10000
-
-ATTRIBUTES += HWIC
-
-TILE_PATTERN = 4x1
-
-OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
- GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
- methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt.o
-
-# this is for a multi-tile test
-include $(COMMONDIR)/Makefile.all
-
+++ /dev/null
-TOPDIR=/home/jzhou/starsearch
-include $(TOPDIR)/Makefile.include
-
-RGCCFLAGS += -O2
-RGCCFLAGS += ${RAWRGCCFLAGS}
-
-USE_SLGCC=1
-
-SIM-CYCLES = 10000
-
-ATTRIBUTES += HWIC
-
-TILE_PATTERN = 4x2
-
-OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
- GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
- methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt2.o
-
-# this is for a multi-tile test
-include $(COMMONDIR)/Makefile.all
-
+++ /dev/null
-TOPDIR=/home/jzhou/starsearch
-include $(TOPDIR)/Makefile.include
-
-RGCCFLAGS += -O2
-RGCCFLAGS += ${RAWRGCCFLAGS}
-
-USE_SLGCC=1
-
-SIM-CYCLES = 10000
-
-ATTRIBUTES += HWIC
-
-TILE_PATTERN = 4x4
-
-OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
- GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
- methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt4.o
-
-# this is for a multi-tile test
-include $(COMMONDIR)/Makefile.all
-
+++ /dev/null
-
-USEBOOTLOADER=no
-
-ifeq ($(USEBOOTLOADER),yes)
-ATTRIBUTES += LARGE_STATIC_DATA
-endif
-
-# We need to define the host OS to get access
-# to the host specific OS defines! - VS
-DEFS += -D$(shell uname -s) -D__raw__
-
-TOPDIR=/home/jzhou/starsearch
-include $(TOPDIR)/Makefile.include
-
-RGCCFLAGS += -O2
-RGCCFLAGS += ${RAWRGCCFLAGS}
-
-USE_SLGCC=1
-
-SIM-CYCLES = 10000
-
-ATTRIBUTES += HWIC
-
-TILES = 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
-
-#TILE_PATTERN = 4x1
-
-OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
- GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
- methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt.o
-
-OBJECT_FILES_00 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_01 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_02 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_03 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_04 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_05 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_06 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_07 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_08 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_09 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_10 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_11 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_12 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_13 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_14 = $(OBJECT_FILES_COMMON)
-OBJECT_FILES_15 = $(OBJECT_FILES_COMMON)
-
-# this is for a multi-tile test
-include $(COMMONDIR)/Makefile.all
-
-ifneq ($(USEBOOTLOADER),yes)
-# Load the host interface and host OS simulator into btl
-BTL-ARGS += -host # -imem_size 65536
-endif
-
-BTL-ARGS += -host_stop_time
-
+++ /dev/null
-.text
-.global flushAddr
-.global invalidateAddr
-.global flushCacheline
-.global invalidateCacheline
-
-flushAddr:
-# arguments come in on $4 and $5
-# $4 has the address
-# $5 has the length, eventually
-
- afl $4, 0
- jr $31
-
-
-invalidateAddr:
-# arguments come in on $4 and $5
-# $4 has the address
-# $5 has the length, eventually
-
- ainv $4, 0
- jr $31
-
-
-flushCacheline:
-# arguments come in on $4
-# $4 has the base tag address
-
- tagfl $4
- jr $31
-
-invalidateCacheline:
-# arguments come in on $4
-# $4 has the base tag address
-
- tagsw $0, $4
-# mtsri PASS, 0x1111
-# mtsr PASS, $8
-# ainv $8, 0
- jr $31
+++ /dev/null
-#include <raw_asm.h>
-
-.text
- .align 2
- .globl setup_ints
- .ent setup_ints
-setup_ints:
- # set up dynamic network
- uintoff
- intoff
-
- # set gdn_cfg
- xor $8,$8,$8
- aui $8,$8,(3<<11)|(0 <<6)|(0 <<1)
- ori $8, (0 <<12)|(2<<9)
- mtsr GDN_CFG,$8
-# mtsr PASS,$8
-
- # set exception vector
- la $3, interrupt_table
-# mtsri PASS, 0xaaa
-# mtsr PASS, $3
- mtsr EX_BASE_ADDR, $3
-
- # set EX_MASK
- mfsr $8,EX_MASK
- ori $8,$8,0x20 # 1 << kVEC_GDN_AVAIL
- mtsr EX_MASK,$8
-
- inton
- uinton
- jr $31
- .end setup_ints
-
-.macro empty_vec fail_code
- mtsri FAIL, \fail_code
-1: b 1b
- nop
- nop
-.endm
-
-interrupt_table:
-
-vec_gdn_refill:
- empty_vec 0x2300
-vec_gdn_complete:
- empty_vec 0x2301
-vec_trace:
- empty_vec 0x2302
-vec_extern:
- empty_vec 0x2303
-vec_timer:
- empty_vec 0x2304
-vec_gdn_avail:
-# mtsri PASS, 0xef00
- uintoff
-
- addiu $sp,$sp,-112
- sw $31,0x64($sp)
- sw $30,0x60($sp)
- sw $23,0x5c($sp)
- sw $22,0x58($sp)
- sw $21,0x54($sp)
- sw $20,0x50($sp)
- sw $19,0x4c($sp)
- sw $18,0x48($sp)
- sw $17,0x44($sp)
- sw $16,0x40($sp)
- sw $15,0x3c($sp)
- sw $14,0x38($sp)
- sw $13,0x34($sp)
- sw $12,0x30($sp)
- sw $11,0x2c($sp)
- sw $10,0x28($sp)
- sw $9,0x24($sp)
- sw $8,0x20($sp)
- sw $7,0x1c($sp)
- sw $6,0x18($sp)
- sw $5,0x14($sp)
- sw $4,0x10($sp)
- sw $3,0xc($sp)
- sw $2,0x8($sp)
- .set noat
- sw $1,0x4($sp)
- .set at
- mfhi $8
- mflo $9
- sw $8,0x68($sp)
- sw $9,0x6c($sp)
- lw $8,0x20($sp)
- lw $9,0x24($sp)
-
- jal receiveObject
-
- lw $8,0x68($sp)
- lw $9,0x6c($sp)
- mthi $8
- mtlo $9
- lw $31,0x64($sp)
- lw $30,0x60($sp)
- lw $23,0x5c($sp)
- lw $22,0x58($sp)
- lw $21,0x54($sp)
- lw $20,0x50($sp)
- lw $19,0x4c($sp)
- lw $18,0x48($sp)
- lw $17,0x44($sp)
- lw $16,0x40($sp)
- lw $15,0x3c($sp)
- lw $14,0x38($sp)
- lw $13,0x34($sp)
- lw $12,0x30($sp)
- lw $11,0x2c($sp)
- lw $10,0x28($sp)
- lw $9,0x24($sp)
- lw $8,0x20($sp)
- lw $7,0x1c($sp)
- lw $6,0x18($sp)
- lw $5,0x14($sp)
- lw $4,0x10($sp)
- lw $3,0xc($sp)
- lw $2,0x8($sp)
- .set noat
- lw $1,0x4($sp)
- .set at
- addiu $sp,$sp,112
-
-# mtsri PASS, 0xefff
- dret
-vec_event_counters:
- empty_vec 0x2306
+++ /dev/null
-#include <raw_asm.h>
-
- .text
- .align 2
- .globl setup_ints
- .ent setup_ints
-setup_ints:
- # set up dynamic network
- uintoff
- intoff
-
- # set gdn_cfg
- xor $8,$8,$8
- aui $8,$8,(3<<11)|(1 <<6)|(0 <<1)
- ori $8, (0 <<12)|(2<<9)
- mtsr GDN_CFG,$8
-# mtsr PASS,$8
-
- # set exception vector
- la $3, interrupt_table
-# mtsri PASS, 0xaaa
-# mtsr PASS, $3
- mtsr EX_BASE_ADDR, $3
-
- # set EX_MASK
- mfsr $8,EX_MASK
- ori $8,$8,0x20 # 1 << kVEC_GDN_AVAIL
- mtsr EX_MASK,$8
-
- inton
- uinton
- jr $31
- .end setup_ints
-
-.macro empty_vec fail_code
- mtsri FAIL, \fail_code
-1: b 1b
- nop
- nop
-.endm
-
-interrupt_table:
-
-vec_gdn_refill:
- empty_vec 0x2300
-vec_gdn_complete:
- empty_vec 0x2301
-vec_trace:
- empty_vec 0x2302
-vec_extern:
- empty_vec 0x2303
-vec_timer:
- empty_vec 0x2304
-vec_gdn_avail:
-# mtsri PASS, 0xef00
- uintoff
-
- addiu $sp,$sp,-112
- sw $31,0x64($sp)
- sw $30,0x60($sp)
- sw $23,0x5c($sp)
- sw $22,0x58($sp)
- sw $21,0x54($sp)
- sw $20,0x50($sp)
- sw $19,0x4c($sp)
- sw $18,0x48($sp)
- sw $17,0x44($sp)
- sw $16,0x40($sp)
- sw $15,0x3c($sp)
- sw $14,0x38($sp)
- sw $13,0x34($sp)
- sw $12,0x30($sp)
- sw $11,0x2c($sp)
- sw $10,0x28($sp)
- sw $9,0x24($sp)
- sw $8,0x20($sp)
- sw $7,0x1c($sp)
- sw $6,0x18($sp)
- sw $5,0x14($sp)
- sw $4,0x10($sp)
- sw $3,0xc($sp)
- sw $2,0x8($sp)
- .set noat
- sw $1,0x4($sp)
- .set at
- mfhi $8
- mflo $9
- sw $8,0x68($sp)
- sw $9,0x6c($sp)
- lw $8,0x20($sp)
- lw $9,0x24($sp)
-
- jal receiveObject
-
- lw $8,0x68($sp)
- lw $9,0x6c($sp)
- mthi $8
- mtlo $9
- lw $31,0x64($sp)
- lw $30,0x60($sp)
- lw $23,0x5c($sp)
- lw $22,0x58($sp)
- lw $21,0x54($sp)
- lw $20,0x50($sp)
- lw $19,0x4c($sp)
- lw $18,0x48($sp)
- lw $17,0x44($sp)
- lw $16,0x40($sp)
- lw $15,0x3c($sp)
- lw $14,0x38($sp)
- lw $13,0x34($sp)
- lw $12,0x30($sp)
- lw $11,0x2c($sp)
- lw $10,0x28($sp)
- lw $9,0x24($sp)
- lw $8,0x20($sp)
- lw $7,0x1c($sp)
- lw $6,0x18($sp)
- lw $5,0x14($sp)
- lw $4,0x10($sp)
- lw $3,0xc($sp)
- lw $2,0x8($sp)
- .set noat
- lw $1,0x4($sp)
- .set at
- addiu $sp,$sp,112
-
-# mtsri PASS, 0xefff
- dret
-vec_event_counters:
- empty_vec 0x2306
-
+++ /dev/null
-#include <raw_asm.h>
-
- .text
- .align 2
- .globl setup_ints
- .ent setup_ints
-setup_ints:
- # set up dynamic network
- uintoff
- intoff
-
- # set gdn_cfg
- xor $8,$8,$8
- aui $8,$8,(3<<11)|(3 <<6)|(0 <<1)
- ori $8, (0 <<12)|(2<<9)
- mtsr GDN_CFG,$8
-# mtsr PASS,$8
-
- # set exception vector
- la $3, interrupt_table
-# mtsri PASS, 0xaaa
-# mtsr PASS, $3
- mtsr EX_BASE_ADDR, $3
-
- # set EX_MASK
- mfsr $8,EX_MASK
- ori $8,$8,0x20 # 1 << kVEC_GDN_AVAIL
- mtsr EX_MASK,$8
-
- inton
- uinton
- jr $31
- .end setup_ints
-
-.macro empty_vec fail_code
- mtsri FAIL, \fail_code
-1: b 1b
- nop
- nop
-.endm
-
-interrupt_table:
-
-vec_gdn_refill:
- empty_vec 0x2300
-vec_gdn_complete:
- empty_vec 0x2301
-vec_trace:
- empty_vec 0x2302
-vec_extern:
- empty_vec 0x2303
-vec_timer:
- empty_vec 0x2304
-vec_gdn_avail:
-# mtsri PASS, 0xef00
- uintoff
-
- addiu $sp,$sp,-112
- sw $31,0x64($sp)
- sw $30,0x60($sp)
- sw $23,0x5c($sp)
- sw $22,0x58($sp)
- sw $21,0x54($sp)
- sw $20,0x50($sp)
- sw $19,0x4c($sp)
- sw $18,0x48($sp)
- sw $17,0x44($sp)
- sw $16,0x40($sp)
- sw $15,0x3c($sp)
- sw $14,0x38($sp)
- sw $13,0x34($sp)
- sw $12,0x30($sp)
- sw $11,0x2c($sp)
- sw $10,0x28($sp)
- sw $9,0x24($sp)
- sw $8,0x20($sp)
- sw $7,0x1c($sp)
- sw $6,0x18($sp)
- sw $5,0x14($sp)
- sw $4,0x10($sp)
- sw $3,0xc($sp)
- sw $2,0x8($sp)
- .set noat
- sw $1,0x4($sp)
- .set at
- mfhi $8
- mflo $9
- sw $8,0x68($sp)
- sw $9,0x6c($sp)
- lw $8,0x20($sp)
- lw $9,0x24($sp)
-
- jal receiveObject
-
- lw $8,0x68($sp)
- lw $9,0x6c($sp)
- mthi $8
- mtlo $9
- lw $31,0x64($sp)
- lw $30,0x60($sp)
- lw $23,0x5c($sp)
- lw $22,0x58($sp)
- lw $21,0x54($sp)
- lw $20,0x50($sp)
- lw $19,0x4c($sp)
- lw $18,0x48($sp)
- lw $17,0x44($sp)
- lw $16,0x40($sp)
- lw $15,0x3c($sp)
- lw $14,0x38($sp)
- lw $13,0x34($sp)
- lw $12,0x30($sp)
- lw $11,0x2c($sp)
- lw $10,0x28($sp)
- lw $9,0x24($sp)
- lw $8,0x20($sp)
- lw $7,0x1c($sp)
- lw $6,0x18($sp)
- lw $5,0x14($sp)
- lw $4,0x10($sp)
- lw $3,0xc($sp)
- lw $2,0x8($sp)
- .set noat
- lw $1,0x4($sp)
- .set at
- addiu $sp,$sp,112
-
-# mtsri PASS, 0xefff
- dret
-vec_event_counters:
- empty_vec 0x2306
-
+++ /dev/null
-#ifndef RUNTIME_ARCH
-#define RUNTIME_ARCH
-
-#ifdef PROFILE
-#ifdef RAWUSEIO
-#include "stdio.h"
-#include "string.h"
-#endif
-#endif
-#include <raw.h>
-#include <raw_compiler_defs.h>
-
-#define BAMBOO_CACHE_LINE_SIZE (kCacheLineSize)
-#define BAMBOO_CACHE_LINE_MASK (kCacheLineMask)
-
-#define BAMBOO_NUM_OF_CORE corenum // the # of current residing core
-#define BAMBOO_GET_NUM_OF_CORE() (raw_get_abs_pos_x() + raw_get_array_size_x() * raw_get_abs_pos_y()) // compute the # of current residing core
-#define BAMBOO_DEBUGPRINT(x) (raw_test_pass((x)))
-#define BAMBOO_DEBUGPRINT_REG(x) (raw_test_pass_reg((x)))
-
-#define BAMBOO_SHARE_MEM_CALLOC(x, y) (calloc((x), (y))) // allocate an array of x elements each of whose size in bytes is y on shared memory
-
-#ifdef INTERRUPT
-// locks for global data structures related to obj queue
-#define BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE() raw_user_interrupts_off()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE() raw_user_interrupts_on()
-// locks for global data structures related to status data
-#define BAMBOO_START_CRITICAL_SECTION_STATUS() raw_user_interrupts_off()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_STATUS() raw_user_interrupts_on()
-// locks for global data structures related to msg data
-#define BAMBOO_START_CRITICAL_SECTION_MSG() raw_user_interrupts_off()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_MSG() raw_user_interrupts_on()
-// locks for global data structures related to lock table
-#define BAMBOO_START_CRITICAL_SECTION_LOCK() raw_user_interrupts_off()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_LOCK() raw_user_interrupts_on()
-// locks for allocating memory
-#define BAMBOO_START_CRITICAL_SECTION_MEM() raw_user_interrupts_off()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_MEM() raw_user_interrupts_on()
-// locks for all global data structures
-#define BAMBOO_START_CRITICAL_SECTION() raw_user_interrupts_off()
-#define BAMBOO_CLOSE_CRITICAL_SECTION() raw_user_interrupts_on()
-#else
-// locks for global data structures related to obj queue
-#define BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE()
-// locks for global data structures related to status data
-#define BAMBOO_START_CRITICAL_SECTION_STATUS()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_STATUS()
-// locks for global data structures related to msg data
-#define BAMBOO_START_CRITICAL_SECTION_MSG()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_MSG()
-// locks for global data structures related to lock table
-#define BAMBOO_START_CRITICAL_SECTION_LOCK()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_LOCK()
-// locks for allocating memory
-#define BAMBOO_START_CRITICAL_SECTION_MEM()
-#define BAMBOO_CLOSE_CRITICAL_SECTION_MEM()
-// locks for all global data structures
-#define BAMBOO_START_CRITICAL_SECTION()
-#define BAMBOO_CLOSE_CRITICAL_SECTION()
-#endif
-
-#define BAMBOO_WAITING_FOR_LOCK() (receiveObject())
-#define BAMBOO_CACHE_FLUSH_RANGE(x, y) (raw_invalidate_cache_range((x), (y)))
-#define BAMBOO_CACHE_FLUSH_ALL() (raw_flush_entire_cache())
-#define BAMBOO_EXIT(x) (raw_test_done((x)))
-#define BAMBOO_MSG_AVAIL() (gdn_input_avail())
-#define BAMBOO_GET_EXE_TIME() (raw_get_cycle())
-
-#endif // #ifndef RUNTIME_ARCH
+++ /dev/null
-#ifdef TASK
-#include "runtime.h"
-#include "multicoreruntime.h"
-#include "runtime_arch.h"
-
-__attribute__((always_inline)) inline void initialization() {
-} // initialization()
-
-__attribute__((always_inline)) inline void initCommunication() {
-#ifdef INTERRUPT
- if (corenum < NUMCORES) {
- // set up interrupts
- setup_ints();
- raw_user_interrupts_on();
- }
-#endif
-}
-
-__attribute__((always_inline)) inline void fakeExecution() {
- // handle communications
- while(true) {
- receiveObject();
- }
-}
-
-#ifdef USEIO
-int main(void) {
-#else
-void begin() {
-#endif // #ifdef USEIO
- run(NULL);
-}
-
-__attribute__((always_inline)) inline void terminate() {
- raw_test_done(1);
-}
-
-// helper function to compute the coordinates of a core from the core number
-#define calCoords(core_num, coordX, coordY) \
- *(coordX) = (core_num) % raw_get_array_size_x();\
- *(coordY) = core_num / raw_get_array_size_x();
-
-// transfer an object to targetcore
-// format: object
-inline void transferObject(struct transObjInfo * transObj) {// __attribute__((always_inline)){
- void * obj = transObj->objptr;
- int type=((int *)obj)[0];
- int targetcore = transObj->targetcore;
-
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- // for 32 bit machine, the size of fixed part is always 3 words
- int msgsize = 3 + transObj->length * 2;
- int i = 0;
-
- struct ___Object___ * newobj = (struct ___Object___ *)obj;
-
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msgsize, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- // start sending msg, set sand msg flag
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0);
-#endif
- gdn_send(msgsize);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(msgsize);
-#endif
- gdn_send((int)obj);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(obj);
-#endif
- for(i = 0; i < transObj->length; ++i) {
- int taskindex = transObj->queues[2*i];
- int paramindex = transObj->queues[2*i+1];
- gdn_send(taskindex);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(taskindex);
-#endif
- gdn_send(paramindex);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(paramindex);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // end of sending this msg, set sand msg flag false
- isMsgSending = false;
- ++(self_numsendobjs);
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void send_msg_1 (int targetcore,
- int n0) {
- // send this msg
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- msglength = 1;
-
- // get the x-coord and y-coord of the target core
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
-
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr); // Send the message header
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(n0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n0);
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void send_msg_2 (int targetcore,
- int n0,
- int n1) {
- // send this msg
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- msglength = 2;
-
- // get the x-coord and y-coord of the target core
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
-
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr); // Send the message header
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(n0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n0);
-#endif
- gdn_send(n1);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n1);
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void send_msg_3 (int targetcore,
- int n0,
- int n1,
- int n2) {
- // send this msg
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- msglength = 3;
-
- // get the x-coord and y-coord of the target core
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
-
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr); // Send the message header
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(n0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n0);
-#endif
- gdn_send(n1);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n1);
-#endif
- gdn_send(n2);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n2);
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void send_msg_4 (int targetcore,
- int n0,
- int n1,
- int n2,
- int n3) {
- // send this msg
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- msglength = 4;
-
- // get the x-coord and y-coord of the target core
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
-
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr); // Send the message header
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(n0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n0);
-#endif
- gdn_send(n1);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n1);
-#endif
- gdn_send(n2);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n2);
-#endif
- gdn_send(n3);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n3);
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void send_msg_5 (int targetcore,
- int n0,
- int n1,
- int n2,
- int n3,
- int n4) {
- // send this msg
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- msglength = 5;
-
- // get the x-coord and y-coord of the target core
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
-
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr); // Send the message header
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(n0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n0);
-#endif
- gdn_send(n1);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n1);
-#endif
- gdn_send(n2);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n2);
-#endif
- gdn_send(n3);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n3);
-#endif
- gdn_send(n4);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n4);
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void send_msg_6 (int targetcore,
- int n0,
- int n1,
- int n2,
- int n3,
- int n4,
- int n5) {
- // send this msg
- unsigned msgHdr;
- int self_y, self_x, target_y, target_x;
- msglength = 6;
-
- // get the x-coord and y-coord of the target core
- calCoords(corenum, &self_x, &self_y);
- calCoords(targetcore, &target_x, &target_y);
-
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr); // Send the message header
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
-#endif
- gdn_send(n0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n0);
-#endif
- gdn_send(n1);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n1);
-#endif
- gdn_send(n2);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n2);
-#endif
- gdn_send(n3);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n3);
-#endif
- gdn_send(n4);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n4);
-#endif
- gdn_send(n5);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(n5);
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- // check if there are pending msgs
- while(isMsgHanging) {
- // get the msg from outmsgdata[]
- // length + target + msg
- outmsgleft = outmsgdata[outmsgindex++];
- int target = outmsgdata[outmsgindex++];
- calCoords(target, &target_x, &target_y);
- // mark to start sending the msg
- isMsgSending = true;
- // Build the message header
- msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
- self_y, self_x,
- target_y, target_x);
- gdn_send(msgHdr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
-#endif
- while(outmsgleft-- > 0) {
- gdn_send(outmsgdata[outmsgindex++]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
-#endif
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- // mark to end sending the msg
- isMsgSending = false;
- BAMBOO_START_CRITICAL_SECTION_MSG();
- // check if there are still msg hanging
- if(outmsgindex == outmsglast) {
- // no more msgs
- outmsgindex = outmsglast = 0;
- isMsgHanging = false;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
- }
-}
-
-__attribute__((always_inline)) inline void cache_msg_2 (int targetcore,
- int n0,
- int n1) {
- // cache this msg
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xdede);
-#endif
- isMsgHanging = true;
- // cache the msg in outmsgdata and send it later
- // msglength + target core + msg
- outmsgdata[outmsglast++] = 2;
- outmsgdata[outmsglast++] = targetcore;
- outmsgdata[outmsglast++] = n0;
- outmsgdata[outmsglast++] = n1;
-}
-
-__attribute__((always_inline)) inline void cache_msg_3 (int targetcore,
- int n0,
- int n1,
- int n2) {
- // cache this msg
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xdede);
-#endif
- isMsgHanging = true;
- // cache the msg in outmsgdata and send it later
- // msglength + target core + msg
- outmsgdata[outmsglast++] = 3;
- outmsgdata[outmsglast++] = targetcore;
- outmsgdata[outmsglast++] = n0;
- outmsgdata[outmsglast++] = n1;
- outmsgdata[outmsglast++] = n2;
-}
-
-__attribute__((always_inline)) inline void cache_msg_4 (int targetcore,
- int n0,
- int n1,
- int n2,
- int n3) {
- // cache this msg
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xdede);
-#endif
- isMsgHanging = true;
- // cache the msg in outmsgdata and send it later
- // msglength + target core + msg
- outmsgdata[outmsglast++] = 4;
- outmsgdata[outmsglast++] = targetcore;
- outmsgdata[outmsglast++] = n0;
- outmsgdata[outmsglast++] = n1;
- outmsgdata[outmsglast++] = n2;
- outmsgdata[outmsglast++] = n3;
-}
-
-__attribute__((always_inline)) inline void cache_msg_5 (int targetcore,
- int n0,
- int n1,
- int n2,
- int n3,
- int n4) {
- // cache this msg
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xdede);
-#endif
- isMsgHanging = true;
- // cache the msg in outmsgdata and send it later
- // msglength + target core + msg
- outmsgdata[outmsglast++] = 5;
- outmsgdata[outmsglast++] = targetcore;
- outmsgdata[outmsglast++] = n0;
- outmsgdata[outmsglast++] = n1;
- outmsgdata[outmsglast++] = n2;
- outmsgdata[outmsglast++] = n3;
- outmsgdata[outmsglast++] = n4;
-}
-
-
-__attribute__((always_inline)) inline void cache_msg_6 (int targetcore,
- int n0,
- int n1,
- int n2,
- int n3,
- int n4,
- int n5) {
- // cache this msg
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xdede);
-#endif
- isMsgHanging = true;
- // cache the msg in outmsgdata and send it later
- // msglength + target core + msg
- outmsgdata[outmsglast++] = 6;
- outmsgdata[outmsglast++] = targetcore;
- outmsgdata[outmsglast++] = n0;
- outmsgdata[outmsglast++] = n1;
- outmsgdata[outmsglast++] = n2;
- outmsgdata[outmsglast++] = n3;
- outmsgdata[outmsglast++] = n4;
- outmsgdata[outmsglast++] = n5;
-}
-
-__attribute__((always_inline)) inline int receiveMsg() {
- if(gdn_input_avail() == 0) {
-#ifdef DEBUG
- if(corenum < NUMCORES) {
- BAMBOO_DEBUGPRINT(0xd001);
- }
-#endif
- return -1;
- }
-#ifdef PROFILE
- /*if(isInterrupt && (!interruptInfoOverflow)) {
- // BAMBOO_DEBUGPRINT(0xffff);
- interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
- interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
- interruptInfoArray[interruptInfoIndex]->endTime = -1;
- }*/
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcccc);
-#endif
- while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
- msgdata[msgdataindex] = gdn_receive();
- if(msgdataindex == 0) {
- if(msgdata[0] > 0xc) {
- msglength = 3;
- } else if (msgdata[0] == 0xc) {
- msglength = 1;
- } else if(msgdata[0] > 8) {
- msglength = 4;
- } else if(msgdata[0] == 8) {
- msglength = 6;
- } else if(msgdata[0] > 5) {
- msglength = 2;
- } else if (msgdata[0] > 2) {
- msglength = 4;
- } else if (msgdata[0] == 2) {
- msglength = 5;
- } else if (msgdata[0] > 0) {
- msglength = 4;
- }
- } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
- msglength = msgdata[msgdataindex];
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
-#endif
- msgdataindex++;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- return msgdataindex;
-}
-
-bool getreadlock(void * ptr) {
- int targetcore = 0;
- lockobj = (int)ptr;
- if(((struct ___Object___ *)ptr)->lock == NULL) {
- lock2require = lockobj;
- } else {
- lock2require = (int)(((struct ___Object___ *)ptr)->lock);
- }
- targetcore = (lock2require >> 5) % NUMCORES;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- int deny = 0;
- BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
- BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(lockobj == (int)ptr) {
- if(deny) {
- lockresult = 0;
- } else {
- lockresult = 1;
- }
- lockflag = true;
-#ifndef INTERRUPT
- reside = true;
-#endif
- } else {
- // conflicts on lockresults
- BAMBOO_EXIT(0xa018);
- }
- }
- return true;
- } else {
- // send lock request msg
- // for 32 bit machine, the size is always 5 words
- send_msg_5(targetcore, LOCKREQUEST, 0, (int)ptr,
- lock2require, BAMBOO_NUM_OF_CORE);
- }
- return true;
-}
-
-bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
-bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
-
-void releasereadlock(void * ptr) {
- int targetcore = 0;
- int reallock = 0;
- if(((struct ___Object___ *)ptr)->lock == NULL) {
- reallock = (int)ptr;
- } else {
- reallock = (int)(((struct ___Object___ *)ptr)->lock);
- }
- targetcore = (reallock >> 5) % NUMCORES;
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- // reside on this core
- if(!RuntimeHashcontainskey(locktbl, reallock)) {
- // no locks for this object, something is wrong
- BAMBOO_EXIT(0xa019);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
- RuntimeHashget(locktbl, reallock, &rwlock_obj);
- lockvalue = (struct LockValue *)rwlock_obj;
- lockvalue->value--;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- return;
- } else {
- // send lock release msg
- // for 32 bit machine, the size is always 4 words
- send_msg_4(targetcore, LOCKRELEASE, 0, (int)ptr, reallock);
- }
-}
-
-// redirected lock request
-bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
- int targetcore = 0;
-
- if(core == BAMBOO_NUM_OF_CORE) {
- lockobj = (int)ptr;
- lock2require = (int)redirectlock;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
- }
- targetcore = ((int)redirectlock >> 5) % NUMCORES;
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- int deny = processlockrequest(0, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(core == BAMBOO_NUM_OF_CORE) {
- if(lockobj == (int)ptr) {
- if(deny) {
- lockresult = 0;
- } else {
- lockresult = 1;
- RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
- }
- lockflag = true;
-#ifndef INTERRUPT
- reside = true;
-#endif
- } else {
- // conflicts on lockresults
- BAMBOO_EXIT(0xa01a);
- }
- return true;
- } else {
- // send lock grant/deny request to the root requiring core
- // check if there is still some msg on sending
- if((!cache) || (cache && !isMsgSending)) {
- send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
- (int)ptr, (int)redirectlock);
- } else {
- cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
- (int)ptr, (int)redirectlock);
- }
- }
- }
- } else {
- // redirect the lock request
- // for 32 bit machine, the size is always 6 words
- if((!cache) || (cache && !isMsgSending)) {
- send_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
- core, BAMBOO_NUM_OF_CORE);
- } else {
- cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
- core, BAMBOO_NUM_OF_CORE);
- }
- }
- return true;
-}
-
-// not reentrant
-bool getwritelock(void * ptr) {
- int targetcore = 0;
-
- // for 32 bit machine, the size is always 5 words
- //int msgsize = 5;
-
- lockobj = (int)ptr;
- if(((struct ___Object___ *)ptr)->lock == NULL) {
- lock2require = lockobj;
- } else {
- lock2require = (int)(((struct ___Object___ *)ptr)->lock);
- }
- targetcore = (lock2require >> 5) % NUMCORES;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe551);
- BAMBOO_DEBUGPRINT_REG(lockobj);
- BAMBOO_DEBUGPRINT_REG(lock2require);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- int deny = 0;
- BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
- BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe555);
- BAMBOO_DEBUGPRINT_REG(lockresult);
-#endif
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(lockobj == (int)ptr) {
- if(deny) {
- lockresult = 0;
- } else {
- lockresult = 1;
- }
- lockflag = true;
-#ifndef INTERRUPT
- reside = true;
-#endif
- } else {
- // conflicts on lockresults
- BAMBOO_EXIT(0xa01b);
- }
- }
- return true;
- } else {
- // send lock request msg
- // for 32 bit machine, the size is always 5 words
- send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
- BAMBOO_NUM_OF_CORE);
- }
- return true;
-}
-
-void releasewritelock(void * ptr) {
- int targetcore = 0;
- int reallock = 0;
- if(((struct ___Object___ *)ptr)->lock == NULL) {
- reallock = (int)ptr;
- } else {
- reallock = (int)(((struct ___Object___ *)ptr)->lock);
- }
- targetcore = (reallock >> 5) % NUMCORES;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe661);
- BAMBOO_DEBUGPRINT_REG((int)ptr);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- // reside on this core
- if(!RuntimeHashcontainskey(locktbl, reallock)) {
- // no locks for this object, something is wrong
- BAMBOO_EXIT(0xa01c);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
- RuntimeHashget(locktbl, reallock, &rwlock_obj);
- lockvalue = (struct LockValue *)rwlock_obj;
- lockvalue->value++;
- }
- BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- return;
- } else {
- // send lock release msg
- // for 32 bit machine, the size is always 4 words
- send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
- }
-}
-
-bool getwritelock_I(void * ptr) {
- int targetcore = 0;
- lockobj = (int)ptr;
- if(((struct ___Object___ *)ptr)->lock == NULL) {
- lock2require = lockobj;
- } else {
- lock2require = (int)(((struct ___Object___ *)ptr)->lock);
- }
- targetcore = (lock2require >> 5) % NUMCORES;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe561);
- BAMBOO_DEBUGPRINT_REG(lockobj);
- BAMBOO_DEBUGPRINT_REG(lock2require);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- int deny = processlockrequest(1, (int)lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(lockobj == (int)ptr) {
- if(deny) {
- lockresult = 0;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0);
-#endif
- } else {
- lockresult = 1;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(1);
-#endif
- }
- lockflag = true;
-#ifndef INTERRUPT
- reside = true;
-#endif
- } else {
- // conflicts on lockresults
- BAMBOO_EXIT(0xa01e);
- }
- return true;
- }
- } else {
- // send lock request msg
- // for 32 bit machine, the size is always 5 words
- send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
- BAMBOO_NUM_OF_CORE);
- }
- return true;
-}
-
-// redirected lock request
-bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
- int targetcore = 0;
-
- if(core == BAMBOO_NUM_OF_CORE) {
- lockobj = (int)ptr;
- lock2require = (int)redirectlock;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
- }
- targetcore = ((int)redirectlock >> 5) % NUMCORES;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe571);
- BAMBOO_DEBUGPRINT_REG((int)ptr);
- BAMBOO_DEBUGPRINT_REG((int)redirectlock);
- BAMBOO_DEBUGPRINT_REG(core);
- BAMBOO_DEBUGPRINT_REG((int)cache);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- int deny = processlockrequest(1, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(core == BAMBOO_NUM_OF_CORE) {
- if(lockobj == (int)ptr) {
- if(deny) {
- lockresult = 0;
- } else {
- lockresult = 1;
- RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
- }
- lockflag = true;
-#ifndef INTERRUPT
- reside = true;
-#endif
- } else {
- // conflicts on lockresults
- BAMBOO_EXIT(0xa01f);
- }
- return true;
- } else {
- // send lock grant/deny request to the root requiring core
- // check if there is still some msg on sending
- if((!cache) || (cache && !isMsgSending)) {
- send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
- (int)ptr, (int)redirectlock);
- } else {
- cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
- (int)ptr, (int)redirectlock);
- }
- }
- }
- } else {
- // redirect the lock request
- // for 32 bit machine, the size is always 6 words
- if((!cache) || (cache && !isMsgSending)) {
- send_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
- core, BAMBOO_NUM_OF_CORE);
- } else {
- cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
- core, BAMBOO_NUM_OF_CORE);
- }
- }
- return true;
-}
-
-void releasewritelock_I(void * ptr) {
- int targetcore = 0;
- int reallock = 0;
- if(((struct ___Object___ *)ptr)->lock == NULL) {
- reallock = (int)ptr;
- } else {
- reallock = (int)(((struct ___Object___ *)ptr)->lock);
- }
- targetcore = (reallock >> 5) % NUMCORES;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe681);
- BAMBOO_DEBUGPRINT_REG((int)ptr);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- if(!RuntimeHashcontainskey(locktbl, reallock)) {
- // no locks for this object, something is wrong
- BAMBOO_EXIT(0xa020);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
- RuntimeHashget(locktbl, reallock, &rwlock_obj);
- lockvalue = (struct LockValue *)rwlock_obj;
- lockvalue->value++;
- }
- return;
- } else {
- // send lock release msg
- // for 32 bit machine, the size is always 4 words
- send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
- }
-}
-
-void releasewritelock_I_r(void * lock, void * redirectlock) {
- int targetcore = 0;
- int reallock = (int)lock;
- targetcore = (reallock >> 5) % NUMCORES;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe691);
- BAMBOO_DEBUGPRINT_REG((int)lock);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- // reside on this core
- if(!RuntimeHashcontainskey(locktbl, reallock)) {
- // no locks for this object, something is wrong
- BAMBOO_EXIT(0xa021);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe692);
-#endif
- RuntimeHashget(locktbl, reallock, &rwlock_obj);
- lockvalue = (struct LockValue *)rwlock_obj;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
- lockvalue->value++;
- lockvalue->redirectlock = (int)redirectlock;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
- }
- return;
- } else {
- // send lock release msg
- // for 32 bit machine, the size is always 4 words
- send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
- }
-}
-
-/* this function is to process lock requests.
- * can only be invoked in receiveObject() */
-// if return -1: the lock request is redirected
-// 0: the lock request is approved
-// 1: the lock request is denied
-__attribute__((always_inline)) int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
- int deny = 0;
- if( ((lock >> 5) % NUMCORES) != BAMBOO_NUM_OF_CORE ) {
- // the lock should not be on this core
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(requestcore);
- BAMBOO_DEBUGPRINT_REG(lock);
- BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
-#endif
- BAMBOO_EXIT(0xa017);
- }
- if(!RuntimeHashcontainskey(locktbl, lock)) {
- // no locks for this object
- // first time to operate on this shared object
- // create a lock for it
- // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
- struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
- lockvalue->redirectlock = 0;
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe110);
-#endif
-#endif
- if(locktype == 0) {
- lockvalue->value = 1;
- } else {
- lockvalue->value = -1;
- }
- RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe111);
-#endif
-#endif
- RuntimeHashget(locktbl, lock, &rwlock_obj);
- lockvalue = (struct LockValue *)(rwlock_obj);
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
-#endif
-#endif
- if(lockvalue->redirectlock != 0) {
- // this lock is redirected
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe112);
-#endif
-#endif
- if(locktype == 0) {
- getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
- } else {
- getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
- }
- return -1; // redirected
- } else {
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
- if(0 == lockvalue->value) {
- if(locktype == 0) {
- lockvalue->value = 1;
- } else {
- lockvalue->value = -1;
- }
- } else if((lockvalue->value > 0) && (locktype == 0)) {
- // read lock request and there are only read locks
- lockvalue->value++;
- } else {
- deny = 1;
- }
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
- }
- }
- return deny;
-}
-
-__attribute__((always_inline)) void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) {
- if(!RuntimeHashcontainskey(locktbl, lock)) {
- // no locks for this object, something is wrong
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(lock);
-#endif
- BAMBOO_EXIT(0xa00b);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
- RuntimeHashget(locktbl, lock, &rwlock_obj);
- lockvalue = (struct LockValue*)(rwlock_obj);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe884);
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
- if(locktype == 0) {
- lockvalue->value--;
- } else {
- lockvalue->value++;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
- if(isredirect) {
- lockvalue->redirectlock = redirectlock;
- }
- }
-}
-
-#ifdef PROFILE
-__attribute__((always_inline)) inline void profileTaskStart(char * taskname) {
- if(!taskInfoOverflow) {
- TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
- taskInfoArray[taskInfoIndex] = taskInfo;
- taskInfo->taskName = taskname;
- taskInfo->startTime = raw_get_cycle();
- taskInfo->endTime = -1;
- taskInfo->exitIndex = -1;
- taskInfo->newObjs = NULL;
- }
-}
-
-__attribute__((always_inline)) inline void profileTaskEnd() {
- if(!taskInfoOverflow) {
- taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
- taskInfoIndex++;
- if(taskInfoIndex == TASKINFOLENGTH) {
- taskInfoOverflow = true;
- }
- }
-}
-
-// output the profiling data
-void outputProfileData() {
-#ifdef USEIO
- FILE * fp;
- char fn[50];
- int self_y, self_x;
- char c_y, c_x;
- int i;
- int totaltasktime = 0;
- int preprocessingtime = 0;
- int objqueuecheckingtime = 0;
- int postprocessingtime = 0;
- //int interruptiontime = 0;
- int other = 0;
- int averagetasktime = 0;
- int tasknum = 0;
-
- for(i = 0; i < 50; i++) {
- fn[i] = 0;
- }
-
- calCoords(corenum, &self_y, &self_x);
- c_y = (char)self_y + '0';
- c_x = (char)self_x + '0';
- strcat(fn, "profile_");
- strcat(fn, &c_x);
- strcat(fn, "_");
- strcat(fn, &c_y);
- strcat(fn, ".rst");
-
- if((fp = fopen(fn, "w+")) == NULL) {
- fprintf(stderr, "fopen error\n");
- return;
- }
-
- fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
- // output task related info
- for(i = 0; i < taskInfoIndex; i++) {
- TaskInfo* tmpTInfo = taskInfoArray[i];
- int duration = tmpTInfo->endTime - tmpTInfo->startTime;
- fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
- // summarize new obj info
- if(tmpTInfo->newObjs != NULL) {
- struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
- struct RuntimeIterator * iter = NULL;
- while(0 == isEmpty(tmpTInfo->newObjs)) {
- char * objtype = (char *)(getItem(tmpTInfo->newObjs));
- if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
- int num = 0;
- RuntimeHashget(nobjtbl, (int)objtype, &num);
- RuntimeHashremovekey(nobjtbl, (int)objtype);
- num++;
- RuntimeHashadd(nobjtbl, (int)objtype, num);
- } else {
- RuntimeHashadd(nobjtbl, (int)objtype, 1);
- }
- //fprintf(stderr, "new obj!\n");
- }
-
- // output all new obj info
- iter = RuntimeHashcreateiterator(nobjtbl);
- while(RunhasNext(iter)) {
- char * objtype = (char *)Runkey(iter);
- int num = Runnext(iter);
- fprintf(fp, ", %s, %d", objtype, num);
- }
- }
- fprintf(fp, "\n");
- if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
- preprocessingtime += duration;
- } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
- postprocessingtime += duration;
- } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
- objqueuecheckingtime += duration;
- } else {
- totaltasktime += duration;
- averagetasktime += duration;
- tasknum++;
- }
- }
-
- if(taskInfoOverflow) {
- fprintf(stderr, "Caution: task info overflow!\n");
- }
-
- other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
- averagetasktime /= tasknum;
-
- fprintf(fp, "\nTotal time: %d\n", totalexetime);
- fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
- fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
- fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
- fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
- fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
-
- fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
-
- fclose(fp);
-#else
- int i = 0;
- int j = 0;
-
- BAMBOO_DEBUGPRINT(0xdddd);
- // output task related info
- for(i= 0; i < taskInfoIndex; i++) {
- TaskInfo* tmpTInfo = taskInfoArray[i];
- char* tmpName = tmpTInfo->taskName;
- int nameLen = strlen(tmpName);
- BAMBOO_DEBUGPRINT(0xddda);
- for(j = 0; j < nameLen; j++) {
- BAMBOO_DEBUGPRINT_REG(tmpName[j]);
- }
- BAMBOO_DEBUGPRINT(0xdddb);
- BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
- BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
- BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
- if(tmpTInfo->newObjs != NULL) {
- struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
- struct RuntimeIterator * iter = NULL;
- while(0 == isEmpty(tmpTInfo->newObjs)) {
- char * objtype = (char *)(getItem(tmpTInfo->newObjs));
- if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
- int num = 0;
- RuntimeHashget(nobjtbl, (int)objtype, &num);
- RuntimeHashremovekey(nobjtbl, (int)objtype);
- num++;
- RuntimeHashadd(nobjtbl, (int)objtype, num);
- } else {
- RuntimeHashadd(nobjtbl, (int)objtype, 1);
- }
- }
-
- // ouput all new obj info
- iter = RuntimeHashcreateiterator(nobjtbl);
- while(RunhasNext(iter)) {
- char * objtype = (char *)Runkey(iter);
- int num = Runnext(iter);
- int nameLen = strlen(objtype);
- BAMBOO_DEBUGPRINT(0xddda);
- for(j = 0; j < nameLen; j++) {
- BAMBOO_DEBUGPRINT_REG(objtype[j]);
- }
- BAMBOO_DEBUGPRINT(0xdddb);
- BAMBOO_DEBUGPRINT_REG(num);
- }
- }
- BAMBOO_DEBUGPRINT(0xdddc);
- }
-
- if(taskInfoOverflow) {
- BAMBOO_DEBUGPRINT(0xefee);
- }
-
- // output interrupt related info
- /*for(i = 0; i < interruptInfoIndex; i++) {
- InterruptInfo* tmpIInfo = interruptInfoArray[i];
- BAMBOO_DEBUGPRINT(0xddde);
- BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
- BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
- BAMBOO_DEBUGPRINT(0xdddf);
- }
-
- if(interruptInfoOverflow) {
- BAMBOO_DEBUGPRINT(0xefef);
- }*/
-
- BAMBOO_DEBUGPRINT(0xeeee);
-#endif
-}
-#endif // #ifdef PROFILE
-
-#endif // #ifdef TASK
--- /dev/null
+#ifdef MULTICORE_GC
+
+#include "GCSharedHash.h"
+#ifdef MULTICORE
+#include "runtime_arch.h"
+#else
+#include <stdio.h>
+#endif
+
+#ifndef INTPTR
+#ifdef BIT64
+#define INTPTR long
+#define INTPTRSHIFT 3
+#else
+#define INTPTR int
+#define INTPTRSHIFT 2
+#endif
+#endif
+
+#ifndef INLINE
+#define INLINE inline __attribute__((always_inline))
+#endif // #ifndef INLINE
+
+#define GC_SHIFT_BITS 4
+
+/* GCSHARED HASH ********************************************************/
+
+// params: startaddr -- the start addr of the shared memory
+// rsize -- remaining size of the available shared memory
+struct GCSharedHash * noargallocateGCSharedHash() {
+ return allocateGCSharedHash(100);
+}
+
+struct GCSharedHash * allocateGCSharedHash(int size) {
+ struct GCSharedHash *thisvar;
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf201);
+#else
+ printf("Negative Hashtable size Exception\n");
+ exit(-1);
+#endif
+ }
+ thisvar=(struct GCSharedHash *)FREEMALLOC_NGC(sizeof(struct GCSharedHash));
+ if(thisvar == NULL) {
+ return NULL;
+ }
+ thisvar->size = size;
+ thisvar->bucket =
+ (struct GCSharedNode **)FREEMALLOC_NGC(sizeof(struct GCSharedNode *)*size);
+ if(thisvar->bucket == NULL) {
+ FREE_NGC(thisvar);
+ return NULL;
+ }
+ /* Set allocation blocks*/
+ thisvar->listhead=NULL;
+ thisvar->listtail=NULL;
+ /*Set data counts*/
+ thisvar->numelements = 0;
+ return thisvar;
+}
+
+void freeGCSharedHash(struct GCSharedHash *thisvar) {
+ struct GCSharedNode *ptr=thisvar->listhead;
+ FREE_NGC(thisvar->bucket);
+ while(ptr) {
+ struct GCSharedNode *next=ptr->lnext;
+ FREE_NGC(ptr);
+ ptr=next;
+ }
+ FREE_NGC(thisvar);
+}
+
+bool GCSharedHashrehash(struct GCSharedHash * thisvar) {
+ int newsize=thisvar->size;
+ struct GCSharedNode ** newbucket = (struct GCSharedNode **)
+ FREEMALLOC_NGC(sizeof(struct GCSharedNode *)*newsize);
+ if(newbucket == NULL) {
+ return false;
+ }
+ int i;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct GCSharedNode *ptr;
+ for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
+ struct GCSharedNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ FREE_NGC(thisvar->bucket);
+ thisvar->bucket=newbucket;
+ return true;
+}
+
+int GCSharedHashadd(struct GCSharedHash * thisvar,int key, int data) {
+ /* Rehash code */
+ unsigned int hashkey;
+ struct GCSharedNode **ptr;
+
+ if (thisvar->numelements>=thisvar->size) {
+ int newsize=2*thisvar->size+1;
+ struct GCSharedNode ** newbucket =
+ (struct GCSharedNode **)FREEMALLOC_NGC(
+ sizeof(struct GCSharedNode *)*newsize);
+ if(newbucket == NULL) {
+ return -1;
+ }
+ int i;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct GCSharedNode *ptr;
+ for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
+ struct GCSharedNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ FREE_NGC(thisvar->bucket);
+ thisvar->bucket=newbucket;
+ }
+
+ hashkey = (unsigned int)key % thisvar->size;
+ ptr = &thisvar->bucket[hashkey];
+
+ /* check that thisvar key/object pair isn't already here */
+ /* TBD can be optimized for set v. relation */
+
+ while (*ptr) {
+ if ((*ptr)->key == key && (*ptr)->data == data) {
+ return 0;
+ }
+ ptr = &((*ptr)->next);
+ }
+
+ {
+ struct GCSharedNode *node=FREEMALLOC_NGC(sizeof(struct GCSharedNode));
+ if(node == NULL) {
+ return -1;
+ }
+ node->data=data;
+ node->key=key;
+ node->next=(*ptr);
+ *ptr=node;
+ if (thisvar->listhead==NULL) {
+ thisvar->listhead=node;
+ thisvar->listtail=node;
+ node->lnext=NULL;
+ node->lprev=NULL;
+ } else {
+ node->lprev=NULL;
+ node->lnext=thisvar->listhead;
+ thisvar->listhead->lprev=node;
+ thisvar->listhead=node;
+ }
+ }
+
+ thisvar->numelements++;
+ return 1;
+}
+
+#ifdef MULTICORE
+struct GCSharedHash * allocateGCSharedHash_I(int size) {
+ struct GCSharedHash *thisvar;
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf202);
+#else
+ printf("Negative Hashtable size Exception\n");
+ exit(-1);
+#endif
+ }
+ thisvar=(struct GCSharedHash *)FREEMALLOC_NGC_I(sizeof(struct GCSharedHash));
+ if(thisvar == NULL) {
+ return NULL;
+ }
+ thisvar->size = size;
+ thisvar->bucket =
+ (struct GCSharedNode **)FREEMALLOC_NGC_I(
+ sizeof(struct GCSharedNode *)*size);
+ if(thisvar->bucket == NULL) {
+ FREE_NGC_I(thisvar);
+ return NULL;
+ }
+ /* Set allocation blocks*/
+ thisvar->listhead=NULL;
+ thisvar->listtail=NULL;
+ /*Set data counts*/
+ thisvar->numelements = 0;
+ return thisvar;
+}
+
+int GCSharedHashadd_I(struct GCSharedHash * thisvar,int key, int data) {
+ /* Rehash code */
+ unsigned int hashkey;
+ struct GCSharedNode **ptr;
+
+ if (thisvar->numelements>=thisvar->size) {
+ int newsize=2*thisvar->size+1;
+ struct GCSharedNode ** newbucket =
+ (struct GCSharedNode **)FREEMALLOC_NGC_I(
+ sizeof(struct GCSharedNode *)*newsize);
+ if(newbucket == NULL) {
+ return -1;
+ }
+ int i;
+ for(i=thisvar->size-1; i>=0; i--) {
+ struct GCSharedNode *ptr;
+ for(ptr=thisvar->bucket[i]; ptr!=NULL;) {
+ struct GCSharedNode * nextptr=ptr->next;
+ unsigned int newhashkey=(unsigned int)ptr->key % newsize;
+ ptr->next=newbucket[newhashkey];
+ newbucket[newhashkey]=ptr;
+ ptr=nextptr;
+ }
+ }
+ thisvar->size=newsize;
+ FREE_NGC_I(thisvar->bucket);
+ thisvar->bucket=newbucket;
+ }
+
+ hashkey = (unsigned int)key % thisvar->size;
+ ptr = &thisvar->bucket[hashkey];
+
+ /* check that thisvar key/object pair isn't already here */
+ /* TBD can be optimized for set v. relation */
+
+ while (*ptr) {
+ if ((*ptr)->key == key && (*ptr)->data == data) {
+ return 0;
+ }
+ ptr = &((*ptr)->next);
+ }
+
+ {
+ struct GCSharedNode *node=FREEMALLOC_NGC_I(sizeof(struct GCSharedNode));
+ if(node == NULL) {
+ return -1;
+ }
+ node->data=data;
+ node->key=key;
+ node->next=(*ptr);
+ *ptr=node;
+ if (thisvar->listhead==NULL) {
+ thisvar->listhead=node;
+ thisvar->listtail=node;
+ node->lnext=NULL;
+ node->lprev=NULL;
+ } else {
+ node->lprev=NULL;
+ node->lnext=thisvar->listhead;
+ thisvar->listhead->lprev=node;
+ thisvar->listhead=node;
+ }
+ }
+
+ thisvar->numelements++;
+ return 1;
+}
+#endif
+
+int GCSharedHashget(struct GCSharedHash *thisvar, int key, int *data) {
+ unsigned int hashkey = (unsigned int)key % thisvar->size;
+
+ struct GCSharedNode *ptr = thisvar->bucket[hashkey];
+ while (ptr) {
+ if (ptr->key == key) {
+ *data = ptr->data;
+ return 1; /* success */
+ }
+ ptr = ptr->next;
+ }
+
+ return 0; /* failure */
+}
+
+/* MGCSHAREDHASH ********************************************************/
+
+mgcsharedhashtbl_t * mgcsharedhashCreate(unsigned int size,
+ double loadfactor) {
+ mgcsharedhashtbl_t * ctable;
+ mgcsharedhashlistnode_t * nodes;
+ int i;
+
+ ctable = (mgcsharedhashtbl_t *)FREEMALLOC_NGC(sizeof(mgcsharedhashtbl_t));
+ if(ctable == NULL) {
+ // TODO
+ BAMBOO_EXIT(0xf203);
+ return NULL;
+ }
+ // Allocate space for the hash table
+ ctable->table = (mgcsharedhashlistnode_t *)FREEMALLOC_NGC(
+ size*sizeof(mgcsharedhashlistnode_t));
+ if(ctable->table == NULL) {
+ BAMBOO_EXIT(0xf204); // TODO
+ return NULL;
+ }
+ ctable->size = size;
+ ctable->loadfactor = loadfactor;
+ ctable->threshold = size*loadfactor;
+
+ ctable->mask = (size << (GC_SHIFT_BITS))-1;
+
+ ctable->structs = NULL ; //FREEMALLOC_NGC(1*sizeof(mgcliststruct_t));
+ ctable->numelements = 0; // Initial number of elements in the hash
+ ctable->list = NULL;
+
+ return ctable;
+}
+
+mgcsharedhashtbl_t * mgcsharedhashCreate_I(unsigned int size,
+ double loadfactor) {
+ mgcsharedhashtbl_t * ctable;
+ mgcsharedhashlistnode_t * nodes;
+ int i;
+
+ ctable = (mgcsharedhashtbl_t *)FREEMALLOC_NGC_I(sizeof(mgcsharedhashtbl_t));
+ if(ctable == NULL) {
+ // TODO
+ BAMBOO_EXIT(0xf205);
+ return NULL;
+ }
+ // Allocate space for the hash table
+ ctable->table = (mgcsharedhashlistnode_t *)FREEMALLOC_NGC_I(
+ size*sizeof(mgcsharedhashlistnode_t));
+ if(ctable->table == NULL) {
+ BAMBOO_EXIT(0xf206); // TODO
+ return NULL;
+ }
+ ctable->size = size;
+ ctable->loadfactor = loadfactor;
+ ctable->threshold = size*loadfactor;
+
+ ctable->mask = (size << (GC_SHIFT_BITS))-1;
+
+ ctable->structs = NULL ; //FREEMALLOC_NGC(1*sizeof(mgcliststruct_t));
+ ctable->numelements = 0; // Initial number of elements in the hash
+ ctable->list = NULL;
+
+ return ctable;
+}
+
+void mgcsharedhashReset(mgcsharedhashtbl_t * tbl) {
+ mgcsharedhashlistnode_t * ptr = tbl->table;
+
+ if ((tbl->numelements) < (tbl->size>>6)) {
+ mgcsharedhashlistnode_t *top = &ptr[tbl->size];
+ mgcsharedhashlistnode_t * list = tbl->list;
+ while(list != NULL) {
+ mgcsharedhashlistnode_t * next = list->next;
+ if ((list >= ptr) && (list < top)) {
+ //zero in list
+ list->key=NULL;
+ list->next=NULL;
+ }
+ list = next;
+ }
+ } else {
+ BAMBOO_MEMSET_WH(tbl->table, '\0',
+ sizeof(mgcsharedhashlistnode_t)*tbl->size);
+ }
+
+ mgcsharedliststruct_t * structs = tbl->structs;
+ while(structs != NULL) {
+ mgcsharedliststruct_t * next = structs->next;
+ BAMBOO_MEMSET_WH(structs->array, '\0',
+ structs->num * sizeof(mgcsharedhashlistnode_t));
+ structs->num = 0;
+ structs = next;
+ }
+ tbl->numelements = 0;
+}
+
+//Store objects and their pointers into hash
+//Using open addressing
+int mgcsharedhashInsert(mgcsharedhashtbl_t * tbl, void * key, void * val) {
+ mgcsharedhashlistnode_t * ptr;
+
+ if(tbl->numelements > (tbl->threshold)) {
+ //Never resize, simply don't insert any more
+ return -1;
+ }
+
+ //int keyto = ((unsigned INTPTR)key) % (tbl->size);
+ //ptr=&tbl->table[keyto];
+ ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
+
+ if(ptr->key==0) {
+ // the first time insert a value for the key
+ ptr->key=key;
+ ptr->val=val;
+ } else { // Insert to the next empty place
+ mgcsharedhashlistnode_t *top = &tbl->table[tbl->size];
+ do {
+ ptr++;
+ } while((ptr < top) && (ptr->key != NULL));
+ if(ptr >= top) {
+ return -1;
+ } else {
+ ptr->key = key;
+ ptr->val = val;
+ }
+ }
+ ptr->next = tbl->list;
+ tbl->list = ptr;
+ tbl->numelements++;
+ return 1;
+}
+
+int mgcsharedhashInsert_I(mgcsharedhashtbl_t * tbl, void * key, void * val) {
+ mgcsharedhashlistnode_t * ptr;
+
+ if(tbl->numelements > (tbl->threshold)) {
+ //Never resize, simply don't insert any more
+ return -1;
+ }
+
+ //int keyto = ((unsigned INTPTR)key) % (tbl->size);
+ //ptr=&tbl->table[keyto];
+ ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
+
+ if(ptr->key==0) {
+ // the first time insert a value for the key
+ ptr->key=key;
+ ptr->val=val;
+ } else { // Insert to the next empty place
+ mgcsharedhashlistnode_t * top = &tbl->table[tbl->size];
+ mgcsharedhashlistnode_t * start = ptr;
+ do {
+ ptr++;
+ if(ptr->key == 0) {
+ break;
+ }
+ } while(ptr < top);
+ if(ptr >= top) {
+ return -1;
+ } else {
+ ptr->key = key;
+ ptr->val = val;
+ }
+ }
+ ptr->next = tbl->list;
+ tbl->list = ptr;
+ tbl->numelements++;
+ return 1;
+}
+
+// Search for an address for a given oid
+INLINE void * mgcsharedhashSearch(mgcsharedhashtbl_t * tbl, void * key) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
+ //int keyto = ((unsigned INTPTR)key) % (tbl->size);
+ //mgcsharedhashlistnode_t * node=&tbl->table[keyto];
+ mgcsharedhashlistnode_t * node =
+ &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
+ mgcsharedhashlistnode_t *top = &tbl->table[tbl->size];
+
+ do {
+ //i++;
+ if(node->key == key) {
+ return node->val;
+ }
+ node++;
+ } while(node < top);
+
+ return NULL;
+}
+
+#endif
--- /dev/null
+#ifdef MULTICORE_GC
+
+#ifndef GCSHAREDHASH_H
+#define GCSHAREDHASH_H
+
+#ifndef bool
+#define bool int
+#endif
+
+#ifndef true
+#define true 1
+#endif
+
+#ifndef false
+#define false 0
+#endif
+
+#include "mem.h"
+
+/* GCSharedHash *********************************************************/
+
+struct GCSharedHash * noargallocateGCSharedHash();
+struct GCSharedHash * allocateGCSharedHash(int size);
+void freeGCSharedHash(struct GCSharedHash *);
+
+bool GCSharedHashrehash(struct GCSharedHash * thisvar);
+int GCSharedHashadd(struct GCSharedHash *, int key, int data);
+#ifdef MULTICORE
+struct GCSharedHash * allocateGCSharedHash_I(int size);
+int GCSharedHashadd_I(struct GCSharedHash *, int key, int data);
+#endif
+int GCSharedHashget(struct GCSharedHash *,int key, int* data);
+
+struct GCSharedHash {
+ int numelements;
+ int size;
+ struct GCSharedNode **bucket;
+ struct GCSharedNode *listhead;
+ struct GCSharedNode *listtail;
+};
+
+inline int GCSharedHashcountset(struct GCSharedHash * thisvar);
+
+/* RuntimeHashException *************************************************/
+
+
+/* RuntimeIterator *****************************************************/
+struct GCSharedNode {
+ struct GCSharedNode *next;
+ struct GCSharedNode *lnext;
+ struct GCSharedNode *lprev;
+ int data;
+ int key;
+};
+
+/* MGCSharedHash *********************************************************/
+typedef struct mgcsharedhashlistnode {
+ void * key;
+ void * val; //this can be cast to another type or used to point to a
+ //larger structure
+ struct mgcsharedhashlistnode * next;
+} mgcsharedhashlistnode_t;
+
+#define NUMMGCSHAREDLIST 250
+typedef struct mgcsharedlist {
+ struct mgcsharedhashlistnode array[NUMMGCSHAREDLIST];
+ int num;
+ struct mgcsharedlist *next;
+} mgcsharedliststruct_t;
+
+typedef struct mgcsharedhashtbl {
+ mgcsharedhashlistnode_t * table; // points to beginning of hash table
+ mgcsharedhashlistnode_t * list;
+ mgcsharedliststruct_t * structs;
+ unsigned int size;
+ unsigned int mask;
+ unsigned int numelements;
+ unsigned int threshold;
+ double loadfactor;
+} mgcsharedhashtbl_t;
+
+mgcsharedhashtbl_t * mgcsharedhashCreate(unsigned int size, double loadfactor);
+mgcsharedhashtbl_t * mgcsharedhashCreate_I(unsigned int size,double loadfactor);
+int mgcsharedhashInsert(mgcsharedhashtbl_t * tbl, void * key, void * val);
+void * mgcsharedhashSearch(mgcsharedhashtbl_t * tbl, void * key);
+//unsigned int mgchashResize(unsigned int newsize);
+int mgcsharedhashInsert_I(mgcsharedhashtbl_t * tbl, void * key, void * val);
+//unsigned int mgchashResize_I(unsigned int newsize);
+//void mgcsharedhashDelete(mgcsharedhashtbl_t * tbl);
+void mgcsharedhashReset(mgcsharedhashtbl_t * tbl);
+
+#endif
+
+#endif
--- /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
+
+#define GC_SHIFT_BITS 4
+
+/* mgchash ********************************************************/
+mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor) {
+ mgchashtable_t *ctable;
+ mgchashlistnode_t *nodes;
+ int i;
+
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf101);
+#else
+ printf("Negative Hashtable size Exception\n");
+ exit(-1);
+#endif
+ }
+
+ // Allocate space for the hash table
+ ctable = (mgchashtable_t *)RUNMALLOC(sizeof(mgchashtable_t));
+ if(ctable == NULL) {
+ // Run out of local memory
+ BAMBOO_EXIT(0xf102);
+ }
+ ctable->table = (mgchashlistnode_t*)RUNMALLOC(size*sizeof(mgchashlistnode_t));
+ if(ctable->table == NULL) {
+ // Run out of local memory
+ BAMBOO_EXIT(0xf103);
+ }
+ ctable->loadfactor = loadfactor;
+ ctable->size = size;
+ ctable->threshold=size*loadfactor;
+
+ ctable->mask = (size << (GC_SHIFT_BITS))-1;
+ //ctable->list = NULL;
+ ctable->structs = (mgcliststruct_t*)RUNMALLOC(1*sizeof(mgcliststruct_t));
+ ctable->numelements = 0; // Initial number of elements in the hash
+
+ return ctable;
+}
+
+void mgchashreset(mgchashtable_t * tbl) {
+ mgchashlistnode_t *ptr = tbl->table;
+ int i;
+
+ /*if (tbl->numelements<(tbl->size>>6)) {
+ mgchashlistnode_t *top=&ptr[tbl->size];
+ mgchashlistnode_t * list = tbl->list;
+ while(list != NULL) {
+ mgchashlistnode_t * next = list->lnext;
+ if ((list >= ptr) && (list < top)) {
+ //zero in list
+ list->key=NULL;
+ list->next=NULL;
+ }
+ list = next;
+ }
+ } else {*/
+ BAMBOO_MEMSET_WH(tbl->table, '\0', sizeof(mgchashlistnode_t)*tbl->size);
+ //}
+ // TODO now never release any allocated memory, may need to be changed
+ //mgcliststruct_t * next = tbl->structs;
+ while(tbl->structs->next!=NULL) {
+ mgcliststruct_t * next = tbl->structs->next;
+ RUNFREE(tbl->structs);
+ tbl->structs=next;
+ /*next->num = 0;
+ next = next->next;*/
+ }
+ tbl->structs->num = 0;
+ tbl->numelements = 0;
+}
+
+//Store objects and their pointers into hash
+void mgchashInsert(mgchashtable_t * tbl, void * key, void *val) {
+ mgchashlistnode_t *ptr;
+
+ if(tbl->numelements > (tbl->threshold)) {
+ //Resize
+ unsigned int newsize = tbl->size << 1 + 1;
+ mgchashResize(tbl, newsize);
+ }
+
+ ptr=&tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
+ tbl->numelements++;
+
+ if(ptr->key==0) {
+ // the first time insert a value for the key
+ ptr->key=key;
+ ptr->val=val;
+ /*ptr->lnext = tbl->list;
+ tbl->list = ptr;*/
+ } else { // Insert in the beginning of linked list
+ mgchashlistnode_t * node;
+ if (tbl->structs->num<NUMMGCLIST) {
+ node=&tbl->structs->array[tbl->structs->num];
+ tbl->structs->num++;
+ } else {
+ //get new list
+ mgcliststruct_t *tcl=RUNMALLOC(1*sizeof(mgcliststruct_t));
+ tcl->next=tbl->structs;
+ tbl->structs=tcl;
+ node=&tcl->array[0];
+ tcl->num=1;
+ }
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next = node;
+ /*node->lnext = tbl->list;
+ tbl->list = node;*/
+ }
+}
+
+#ifdef MULTICORE_GC
+mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor) {
+ mgchashtable_t *ctable;
+ mgchashlistnode_t *nodes;
+ int i;
+
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf101);
+#else
+ printf("Negative Hashtable size Exception\n");
+ exit(-1);
+#endif
+ }
+
+ // Allocate space for the hash table
+ ctable = (mgchashtable_t*)RUNMALLOC_I(sizeof(mgchashtable_t));
+ if(ctable == NULL) {
+ // Run out of local memory
+ BAMBOO_EXIT(0xf102);
+ }
+ ctable->table=(mgchashlistnode_t*)RUNMALLOC_I(size*sizeof(mgchashlistnode_t));
+ if(ctable->table == NULL) {
+ // Run out of local memory
+ BAMBOO_EXIT(0xf103);
+ }
+ ctable->loadfactor = loadfactor;
+ ctable->size = size;
+ ctable->threshold=size*loadfactor;
+
+ ctable->mask = (size << (GC_SHIFT_BITS))-1;
+ //ctable->list = NULL;
+ ctable->structs = (mgcliststruct_t*)RUNMALLOC_I(1*sizeof(mgcliststruct_t));
+ ctable->numelements = 0; // Initial number of elements in the hash
+
+ return ctable;
+}
+
+void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val) {
+ mgchashlistnode_t *ptr;
+
+ if(tbl->numelements > (tbl->threshold)) {
+ //Resize
+ unsigned int newsize = tbl->size << 1 + 1;
+ mgchashResize_I(tbl, newsize);
+ }
+
+ ptr = &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
+ tbl->numelements++;
+
+ if(ptr->key==0) {
+ ptr->key=key;
+ ptr->val=val;
+ /*ptr->lnext = tbl->list;
+ tbl->list = ptr;*/
+ return;
+ } else { // Insert in the beginning of linked list
+ mgchashlistnode_t * node;
+ if (tbl->structs->num<NUMMGCLIST) {
+ node=&tbl->structs->array[tbl->structs->num];
+ tbl->structs->num++;
+ } else {
+ //get new list
+ mgcliststruct_t *tcl=RUNMALLOC_I(1*sizeof(mgcliststruct_t));
+ tcl->next=tbl->structs;
+ tbl->structs=tcl;
+ node=&tcl->array[0];
+ tcl->num=1;
+ }
+ node->key = key;
+ node->val = val;
+ node->next = ptr->next;
+ ptr->next = node;
+ /*node->lnext = tbl->list;
+ tbl->list = node;*/
+ }
+}
+#endif
+
+// Search for an address for a given oid
+INLINE void * mgchashSearch(mgchashtable_t * tbl, void * key) {
+ //REMOVE HASH FUNCTION CALL TO MAKE SURE IT IS INLINED HERE]
+ mgchashlistnode_t *node =
+ &tbl->table[(((unsigned INTPTR)key)&tbl->mask)>>(GC_SHIFT_BITS)];
+
+ do {
+ if(node->key == key) {
+ return node->val;
+ }
+ node = node->next;
+ } while(node != NULL);
+
+ return NULL;
+}
+
+unsigned int mgchashResize(mgchashtable_t * tbl, 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 = tbl->table;
+ oldsize = tbl->size;
+
+ if((node = RUNMALLOC(newsize*sizeof(mgchashlistnode_t))) == NULL) {
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ tbl->table = node; //Update the global hashtable upon resize()
+ tbl->size = newsize;
+ tbl->threshold = newsize * tbl->loadfactor;
+ mask = tbl->mask = (newsize << (GC_SHIFT_BITS)) - 1;
+ //tbl->list = NULL;
+
+ 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 INTPTR)key) & mask) >> (GC_SHIFT_BITS);
+ tmp=&node[index];
+ next = curr->next;
+ // Insert into the new table
+ if(tmp->key == 0) {
+ tmp->key = key;
+ tmp->val = curr->val;
+ /*tmp->lnext = tbl->list;
+ tbl->list = tmp;*/
+ } /*
+ 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(1*sizeof(mgchashlistnode_t));
+ newnode->key = curr->key;
+ newnode->val = curr->val;
+ newnode->next = tmp->next;
+ tmp->next=newnode;
+ /*newnode->lnext = tbl->list;
+ tbl->list = newnode;*/
+ }
+ else {
+ curr->next=tmp->next;
+ tmp->next=curr;
+ /*curr->lnext = tbl->list;
+ tbl->list = 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(mgchashtable_t * tbl, 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 = tbl->table;
+ oldsize = tbl->size;
+
+ if((node = RUNMALLOC_I(newsize*sizeof(mgchashlistnode_t))) == NULL) {
+ BAMBOO_EXIT(0xf104);
+ printf("Calloc error %s %d\n", __FILE__, __LINE__);
+ return 1;
+ }
+
+ tbl->table = node; //Update the global hashtable upon resize()
+ tbl->size = newsize;
+ tbl->threshold = newsize * tbl->loadfactor;
+ mask = tbl->mask = (newsize << (GC_SHIFT_BITS))-1;
+ //tbl->list = NULL;
+
+ 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 INTPTR)key) & mask) >> (GC_SHIFT_BITS);
+ tmp=&node[index];
+ next = curr->next;
+ // Insert into the new table
+ if(tmp->key == 0) {
+ tmp->key = key;
+ tmp->val = curr->val;
+ /*tmp->lnext = tbl->list;
+ tbl->list = tmp;*/
+ } /*
+ 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;
+ /*newnode->lnext = tbl->list;
+ tbl->list = newnode;*/
+ } else {
+ curr->next=tmp->next;
+ tmp->next=curr;
+ /*curr->lnext = tbl->list;
+ tbl->list = 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(mgchashtable_t * tbl) {
+ int i;
+ mgcliststruct_t *ptr=tbl->structs;
+ while(ptr!=NULL) {
+ mgcliststruct_t *next=ptr->next;
+ RUNFREE(ptr);
+ ptr=next;
+ }
+ RUNFREE(tbl->table);
+ tbl->table=NULL;
+ tbl->structs=NULL;
+}
+
+/* MGCHASH ********************************************************/
+
+struct MGCHash * allocateMGCHash(int size,
+ int conflicts) {
+ struct MGCHash *thisvar;
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf105);
+#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);
+ //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);
+}
+
+int MGCHashadd(struct MGCHash * thisvar, int data) {
+ // Rehash code
+ unsigned int hashkey;
+ struct MGCNode *ptr;
+
+ int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
+ hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
+ //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
+struct MGCHash * allocateMGCHash_I(int size,
+ int conflicts) {
+ struct MGCHash *thisvar;
+ if (size <= 0) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(0xf106);
+#else
+ printf("Negative Hashtable size Exception\n");
+ exit(-1);
+#endif
+ }
+ thisvar=(struct MGCHash *)RUNMALLOC_I(sizeof(struct MGCHash));
+ thisvar->size = size;
+ thisvar->bucket =
+ (struct MGCNode *) RUNMALLOC_I(sizeof(struct MGCNode)*size);
+ //Set data counts
+ thisvar->num4conflicts = conflicts;
+ return thisvar;
+}
+
+int MGCHashadd_I(struct MGCHash * thisvar, int data) {
+ // Rehash code
+ unsigned int hashkey;
+ struct MGCNode *ptr;
+
+ int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
+ hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
+ //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) {
+ int mask = (thisvar->size << (GC_SHIFT_BITS))-1;
+ unsigned int hashkey = (((unsigned INTPTR)data)&mask)>>(GC_SHIFT_BITS);
+ //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;
+ //struct mgchashlistnode *lnext;
+} mgchashlistnode_t;
+
+#define NUMMGCLIST 250
+typedef struct mgclist {
+ struct mgchashlistnode array[NUMMGCLIST];
+ int num;
+ struct mgclist *next;
+} mgcliststruct_t;
+
+typedef struct mgchashtable {
+ mgchashlistnode_t * table; // points to beginning of hash table
+ //mgchashlistnode_t * list;
+ mgcliststruct_t * structs;
+ unsigned int size;
+ unsigned int mask;
+ unsigned int numelements;
+ unsigned int threshold;
+ double loadfactor;
+} mgchashtable_t;
+
+mgchashtable_t * mgchashCreate(unsigned int size, double loadfactor);
+void mgchashInsert(mgchashtable_t * tbl, void * key, void *val);
+void * mgchashSearch(mgchashtable_t * tbl, void * key);
+unsigned int mgchashResize(mgchashtable_t * tbl, unsigned int newsize);
+#ifdef MULTICORE_GC
+mgchashtable_t * mgchashCreate_I(unsigned int size, double loadfactor);
+void mgchashInsert_I(mgchashtable_t * tbl, void * key, void *val);
+unsigned int mgchashResize_I(mgchashtable_t * tbl, unsigned int newsize);
+#endif
+void mgchashDelete(mgchashtable_t * tbl);
+void mgchashreset(mgchashtable_t * tbl);
+
+
+/** MGCHash *******************************************************************/
+struct MGCHash * allocateMGCHash(int size, int conflicts);
+void freeMGCHash(struct MGCHash *);
+
+//void MGCHashrehash(struct MGCHash * thisvar);
+int MGCHashadd(struct MGCHash *, int data);
+#ifdef MULTICORE
+struct MGCHash * allocateMGCHash_I(int size, int conflicts);
+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
--- /dev/null
+TOPDIR=/home/jzhou/starsearch
+include $(TOPDIR)/Makefile.include
+
+RGCCFLAGS += -O2
+RGCCFLAGS += ${RAWRGCCFLAGS}
+
+USE_SLGCC=1
+
+SIM-CYCLES = 10000
+
+ATTRIBUTES += HWIC
+
+TILE_PATTERN = 4x1
+
+OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
+ GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
+ methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt.o
+
+# this is for a multi-tile test
+include $(COMMONDIR)/Makefile.all
+
--- /dev/null
+TOPDIR=/home/jzhou/starsearch
+include $(TOPDIR)/Makefile.include
+
+RGCCFLAGS += -O2
+RGCCFLAGS += ${RAWRGCCFLAGS}
+
+USE_SLGCC=1
+
+SIM-CYCLES = 10000
+
+ATTRIBUTES += HWIC
+
+TILE_PATTERN = 4x2
+
+OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
+ GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
+ methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt2.o
+
+# this is for a multi-tile test
+include $(COMMONDIR)/Makefile.all
+
--- /dev/null
+TOPDIR=/home/jzhou/starsearch
+include $(TOPDIR)/Makefile.include
+
+RGCCFLAGS += -O2
+RGCCFLAGS += ${RAWRGCCFLAGS}
+
+USE_SLGCC=1
+
+SIM-CYCLES = 10000
+
+ATTRIBUTES += HWIC
+
+TILE_PATTERN = 4x4
+
+OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
+ GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
+ methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt4.o
+
+# this is for a multi-tile test
+include $(COMMONDIR)/Makefile.all
+
--- /dev/null
+
+USEBOOTLOADER=no
+
+ifeq ($(USEBOOTLOADER),yes)
+ATTRIBUTES += LARGE_STATIC_DATA
+endif
+
+# We need to define the host OS to get access
+# to the host specific OS defines! - VS
+DEFS += -D$(shell uname -s) -D__raw__
+
+TOPDIR=/home/jzhou/starsearch
+include $(TOPDIR)/Makefile.include
+
+RGCCFLAGS += -O2
+RGCCFLAGS += ${RAWRGCCFLAGS}
+
+USE_SLGCC=1
+
+SIM-CYCLES = 10000
+
+ATTRIBUTES += HWIC
+
+TILES = 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
+
+#TILE_PATTERN = 4x1
+
+OBJECT_FILES_COMMON = multicoretask.o multicoreruntime.o Queue.o file.o math.o object.o \
+ GenericHashtable.o SimpleHash.o ObjectHash.o socket.o taskdefs.o \
+ methods.o mem.o task_arch.o raw_dataCache.o raw_interrupt.o
+
+OBJECT_FILES_00 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_01 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_02 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_03 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_04 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_05 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_06 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_07 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_08 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_09 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_10 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_11 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_12 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_13 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_14 = $(OBJECT_FILES_COMMON)
+OBJECT_FILES_15 = $(OBJECT_FILES_COMMON)
+
+# this is for a multi-tile test
+include $(COMMONDIR)/Makefile.all
+
+ifneq ($(USEBOOTLOADER),yes)
+# Load the host interface and host OS simulator into btl
+BTL-ARGS += -host # -imem_size 65536
+endif
+
+BTL-ARGS += -host_stop_time
+
--- /dev/null
+.text
+.global flushAddr
+.global invalidateAddr
+.global flushCacheline
+.global invalidateCacheline
+
+flushAddr:
+# arguments come in on $4 and $5
+# $4 has the address
+# $5 has the length, eventually
+
+ afl $4, 0
+ jr $31
+
+
+invalidateAddr:
+# arguments come in on $4 and $5
+# $4 has the address
+# $5 has the length, eventually
+
+ ainv $4, 0
+ jr $31
+
+
+flushCacheline:
+# arguments come in on $4
+# $4 has the base tag address
+
+ tagfl $4
+ jr $31
+
+invalidateCacheline:
+# arguments come in on $4
+# $4 has the base tag address
+
+ tagsw $0, $4
+# mtsri PASS, 0x1111
+# mtsr PASS, $8
+# ainv $8, 0
+ jr $31
--- /dev/null
+#include <raw_asm.h>
+
+.text
+ .align 2
+ .globl setup_ints
+ .ent setup_ints
+setup_ints:
+ # set up dynamic network
+ uintoff
+ intoff
+
+ # set gdn_cfg
+ xor $8,$8,$8
+ aui $8,$8,(3<<11)|(0 <<6)|(0 <<1)
+ ori $8, (0 <<12)|(2<<9)
+ mtsr GDN_CFG,$8
+# mtsr PASS,$8
+
+ # set exception vector
+ la $3, interrupt_table
+# mtsri PASS, 0xaaa
+# mtsr PASS, $3
+ mtsr EX_BASE_ADDR, $3
+
+ # set EX_MASK
+ mfsr $8,EX_MASK
+ ori $8,$8,0x20 # 1 << kVEC_GDN_AVAIL
+ mtsr EX_MASK,$8
+
+ inton
+ uinton
+ jr $31
+ .end setup_ints
+
+.macro empty_vec fail_code
+ mtsri FAIL, \fail_code
+1: b 1b
+ nop
+ nop
+.endm
+
+interrupt_table:
+
+vec_gdn_refill:
+ empty_vec 0x2300
+vec_gdn_complete:
+ empty_vec 0x2301
+vec_trace:
+ empty_vec 0x2302
+vec_extern:
+ empty_vec 0x2303
+vec_timer:
+ empty_vec 0x2304
+vec_gdn_avail:
+# mtsri PASS, 0xef00
+ uintoff
+
+ addiu $sp,$sp,-112
+ sw $31,0x64($sp)
+ sw $30,0x60($sp)
+ sw $23,0x5c($sp)
+ sw $22,0x58($sp)
+ sw $21,0x54($sp)
+ sw $20,0x50($sp)
+ sw $19,0x4c($sp)
+ sw $18,0x48($sp)
+ sw $17,0x44($sp)
+ sw $16,0x40($sp)
+ sw $15,0x3c($sp)
+ sw $14,0x38($sp)
+ sw $13,0x34($sp)
+ sw $12,0x30($sp)
+ sw $11,0x2c($sp)
+ sw $10,0x28($sp)
+ sw $9,0x24($sp)
+ sw $8,0x20($sp)
+ sw $7,0x1c($sp)
+ sw $6,0x18($sp)
+ sw $5,0x14($sp)
+ sw $4,0x10($sp)
+ sw $3,0xc($sp)
+ sw $2,0x8($sp)
+ .set noat
+ sw $1,0x4($sp)
+ .set at
+ mfhi $8
+ mflo $9
+ sw $8,0x68($sp)
+ sw $9,0x6c($sp)
+ lw $8,0x20($sp)
+ lw $9,0x24($sp)
+
+ jal receiveObject
+
+ lw $8,0x68($sp)
+ lw $9,0x6c($sp)
+ mthi $8
+ mtlo $9
+ lw $31,0x64($sp)
+ lw $30,0x60($sp)
+ lw $23,0x5c($sp)
+ lw $22,0x58($sp)
+ lw $21,0x54($sp)
+ lw $20,0x50($sp)
+ lw $19,0x4c($sp)
+ lw $18,0x48($sp)
+ lw $17,0x44($sp)
+ lw $16,0x40($sp)
+ lw $15,0x3c($sp)
+ lw $14,0x38($sp)
+ lw $13,0x34($sp)
+ lw $12,0x30($sp)
+ lw $11,0x2c($sp)
+ lw $10,0x28($sp)
+ lw $9,0x24($sp)
+ lw $8,0x20($sp)
+ lw $7,0x1c($sp)
+ lw $6,0x18($sp)
+ lw $5,0x14($sp)
+ lw $4,0x10($sp)
+ lw $3,0xc($sp)
+ lw $2,0x8($sp)
+ .set noat
+ lw $1,0x4($sp)
+ .set at
+ addiu $sp,$sp,112
+
+# mtsri PASS, 0xefff
+ dret
+vec_event_counters:
+ empty_vec 0x2306
--- /dev/null
+#include <raw_asm.h>
+
+ .text
+ .align 2
+ .globl setup_ints
+ .ent setup_ints
+setup_ints:
+ # set up dynamic network
+ uintoff
+ intoff
+
+ # set gdn_cfg
+ xor $8,$8,$8
+ aui $8,$8,(3<<11)|(1 <<6)|(0 <<1)
+ ori $8, (0 <<12)|(2<<9)
+ mtsr GDN_CFG,$8
+# mtsr PASS,$8
+
+ # set exception vector
+ la $3, interrupt_table
+# mtsri PASS, 0xaaa
+# mtsr PASS, $3
+ mtsr EX_BASE_ADDR, $3
+
+ # set EX_MASK
+ mfsr $8,EX_MASK
+ ori $8,$8,0x20 # 1 << kVEC_GDN_AVAIL
+ mtsr EX_MASK,$8
+
+ inton
+ uinton
+ jr $31
+ .end setup_ints
+
+.macro empty_vec fail_code
+ mtsri FAIL, \fail_code
+1: b 1b
+ nop
+ nop
+.endm
+
+interrupt_table:
+
+vec_gdn_refill:
+ empty_vec 0x2300
+vec_gdn_complete:
+ empty_vec 0x2301
+vec_trace:
+ empty_vec 0x2302
+vec_extern:
+ empty_vec 0x2303
+vec_timer:
+ empty_vec 0x2304
+vec_gdn_avail:
+# mtsri PASS, 0xef00
+ uintoff
+
+ addiu $sp,$sp,-112
+ sw $31,0x64($sp)
+ sw $30,0x60($sp)
+ sw $23,0x5c($sp)
+ sw $22,0x58($sp)
+ sw $21,0x54($sp)
+ sw $20,0x50($sp)
+ sw $19,0x4c($sp)
+ sw $18,0x48($sp)
+ sw $17,0x44($sp)
+ sw $16,0x40($sp)
+ sw $15,0x3c($sp)
+ sw $14,0x38($sp)
+ sw $13,0x34($sp)
+ sw $12,0x30($sp)
+ sw $11,0x2c($sp)
+ sw $10,0x28($sp)
+ sw $9,0x24($sp)
+ sw $8,0x20($sp)
+ sw $7,0x1c($sp)
+ sw $6,0x18($sp)
+ sw $5,0x14($sp)
+ sw $4,0x10($sp)
+ sw $3,0xc($sp)
+ sw $2,0x8($sp)
+ .set noat
+ sw $1,0x4($sp)
+ .set at
+ mfhi $8
+ mflo $9
+ sw $8,0x68($sp)
+ sw $9,0x6c($sp)
+ lw $8,0x20($sp)
+ lw $9,0x24($sp)
+
+ jal receiveObject
+
+ lw $8,0x68($sp)
+ lw $9,0x6c($sp)
+ mthi $8
+ mtlo $9
+ lw $31,0x64($sp)
+ lw $30,0x60($sp)
+ lw $23,0x5c($sp)
+ lw $22,0x58($sp)
+ lw $21,0x54($sp)
+ lw $20,0x50($sp)
+ lw $19,0x4c($sp)
+ lw $18,0x48($sp)
+ lw $17,0x44($sp)
+ lw $16,0x40($sp)
+ lw $15,0x3c($sp)
+ lw $14,0x38($sp)
+ lw $13,0x34($sp)
+ lw $12,0x30($sp)
+ lw $11,0x2c($sp)
+ lw $10,0x28($sp)
+ lw $9,0x24($sp)
+ lw $8,0x20($sp)
+ lw $7,0x1c($sp)
+ lw $6,0x18($sp)
+ lw $5,0x14($sp)
+ lw $4,0x10($sp)
+ lw $3,0xc($sp)
+ lw $2,0x8($sp)
+ .set noat
+ lw $1,0x4($sp)
+ .set at
+ addiu $sp,$sp,112
+
+# mtsri PASS, 0xefff
+ dret
+vec_event_counters:
+ empty_vec 0x2306
+
--- /dev/null
+#include <raw_asm.h>
+
+ .text
+ .align 2
+ .globl setup_ints
+ .ent setup_ints
+setup_ints:
+ # set up dynamic network
+ uintoff
+ intoff
+
+ # set gdn_cfg
+ xor $8,$8,$8
+ aui $8,$8,(3<<11)|(3 <<6)|(0 <<1)
+ ori $8, (0 <<12)|(2<<9)
+ mtsr GDN_CFG,$8
+# mtsr PASS,$8
+
+ # set exception vector
+ la $3, interrupt_table
+# mtsri PASS, 0xaaa
+# mtsr PASS, $3
+ mtsr EX_BASE_ADDR, $3
+
+ # set EX_MASK
+ mfsr $8,EX_MASK
+ ori $8,$8,0x20 # 1 << kVEC_GDN_AVAIL
+ mtsr EX_MASK,$8
+
+ inton
+ uinton
+ jr $31
+ .end setup_ints
+
+.macro empty_vec fail_code
+ mtsri FAIL, \fail_code
+1: b 1b
+ nop
+ nop
+.endm
+
+interrupt_table:
+
+vec_gdn_refill:
+ empty_vec 0x2300
+vec_gdn_complete:
+ empty_vec 0x2301
+vec_trace:
+ empty_vec 0x2302
+vec_extern:
+ empty_vec 0x2303
+vec_timer:
+ empty_vec 0x2304
+vec_gdn_avail:
+# mtsri PASS, 0xef00
+ uintoff
+
+ addiu $sp,$sp,-112
+ sw $31,0x64($sp)
+ sw $30,0x60($sp)
+ sw $23,0x5c($sp)
+ sw $22,0x58($sp)
+ sw $21,0x54($sp)
+ sw $20,0x50($sp)
+ sw $19,0x4c($sp)
+ sw $18,0x48($sp)
+ sw $17,0x44($sp)
+ sw $16,0x40($sp)
+ sw $15,0x3c($sp)
+ sw $14,0x38($sp)
+ sw $13,0x34($sp)
+ sw $12,0x30($sp)
+ sw $11,0x2c($sp)
+ sw $10,0x28($sp)
+ sw $9,0x24($sp)
+ sw $8,0x20($sp)
+ sw $7,0x1c($sp)
+ sw $6,0x18($sp)
+ sw $5,0x14($sp)
+ sw $4,0x10($sp)
+ sw $3,0xc($sp)
+ sw $2,0x8($sp)
+ .set noat
+ sw $1,0x4($sp)
+ .set at
+ mfhi $8
+ mflo $9
+ sw $8,0x68($sp)
+ sw $9,0x6c($sp)
+ lw $8,0x20($sp)
+ lw $9,0x24($sp)
+
+ jal receiveObject
+
+ lw $8,0x68($sp)
+ lw $9,0x6c($sp)
+ mthi $8
+ mtlo $9
+ lw $31,0x64($sp)
+ lw $30,0x60($sp)
+ lw $23,0x5c($sp)
+ lw $22,0x58($sp)
+ lw $21,0x54($sp)
+ lw $20,0x50($sp)
+ lw $19,0x4c($sp)
+ lw $18,0x48($sp)
+ lw $17,0x44($sp)
+ lw $16,0x40($sp)
+ lw $15,0x3c($sp)
+ lw $14,0x38($sp)
+ lw $13,0x34($sp)
+ lw $12,0x30($sp)
+ lw $11,0x2c($sp)
+ lw $10,0x28($sp)
+ lw $9,0x24($sp)
+ lw $8,0x20($sp)
+ lw $7,0x1c($sp)
+ lw $6,0x18($sp)
+ lw $5,0x14($sp)
+ lw $4,0x10($sp)
+ lw $3,0xc($sp)
+ lw $2,0x8($sp)
+ .set noat
+ lw $1,0x4($sp)
+ .set at
+ addiu $sp,$sp,112
+
+# mtsri PASS, 0xefff
+ dret
+vec_event_counters:
+ empty_vec 0x2306
+
--- /dev/null
+#ifndef RUNTIME_ARCH
+#define RUNTIME_ARCH
+
+#ifdef PROFILE
+#ifdef RAWUSEIO
+#include "stdio.h"
+#include "string.h"
+#endif
+#endif
+#include <raw.h>
+#include <raw_compiler_defs.h>
+
+#define BAMBOO_CACHE_LINE_SIZE (kCacheLineSize)
+#define BAMBOO_CACHE_LINE_MASK (kCacheLineMask)
+
+#define BAMBOO_NUM_OF_CORE corenum // the # of current residing core
+#define BAMBOO_GET_NUM_OF_CORE() (raw_get_abs_pos_x() + raw_get_array_size_x() * raw_get_abs_pos_y()) // compute the # of current residing core
+#define BAMBOO_DEBUGPRINT(x) (raw_test_pass((x)))
+#define BAMBOO_DEBUGPRINT_REG(x) (raw_test_pass_reg((x)))
+
+#define BAMBOO_SHARE_MEM_CALLOC(x, y) (calloc((x), (y))) // allocate an array of x elements each of whose size in bytes is y on shared memory
+
+#ifdef INTERRUPT
+// locks for global data structures related to obj queue
+#define BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE() raw_user_interrupts_off()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE() raw_user_interrupts_on()
+// locks for global data structures related to status data
+#define BAMBOO_START_CRITICAL_SECTION_STATUS() raw_user_interrupts_off()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_STATUS() raw_user_interrupts_on()
+// locks for global data structures related to msg data
+#define BAMBOO_START_CRITICAL_SECTION_MSG() raw_user_interrupts_off()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_MSG() raw_user_interrupts_on()
+// locks for global data structures related to lock table
+#define BAMBOO_START_CRITICAL_SECTION_LOCK() raw_user_interrupts_off()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_LOCK() raw_user_interrupts_on()
+// locks for allocating memory
+#define BAMBOO_START_CRITICAL_SECTION_MEM() raw_user_interrupts_off()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_MEM() raw_user_interrupts_on()
+// locks for all global data structures
+#define BAMBOO_START_CRITICAL_SECTION() raw_user_interrupts_off()
+#define BAMBOO_CLOSE_CRITICAL_SECTION() raw_user_interrupts_on()
+#else
+// locks for global data structures related to obj queue
+#define BAMBOO_START_CRITICAL_SECTION_OBJ_QUEUE()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_OBJ_QUEUE()
+// locks for global data structures related to status data
+#define BAMBOO_START_CRITICAL_SECTION_STATUS()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_STATUS()
+// locks for global data structures related to msg data
+#define BAMBOO_START_CRITICAL_SECTION_MSG()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_MSG()
+// locks for global data structures related to lock table
+#define BAMBOO_START_CRITICAL_SECTION_LOCK()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_LOCK()
+// locks for allocating memory
+#define BAMBOO_START_CRITICAL_SECTION_MEM()
+#define BAMBOO_CLOSE_CRITICAL_SECTION_MEM()
+// locks for all global data structures
+#define BAMBOO_START_CRITICAL_SECTION()
+#define BAMBOO_CLOSE_CRITICAL_SECTION()
+#endif
+
+#define BAMBOO_WAITING_FOR_LOCK() (receiveObject())
+#define BAMBOO_CACHE_FLUSH_RANGE(x, y) (raw_invalidate_cache_range((x), (y)))
+#define BAMBOO_CACHE_FLUSH_ALL() (raw_flush_entire_cache())
+#define BAMBOO_EXIT(x) (raw_test_done((x)))
+#define BAMBOO_MSG_AVAIL() (gdn_input_avail())
+#define BAMBOO_GET_EXE_TIME() (raw_get_cycle())
+
+#endif // #ifndef RUNTIME_ARCH
--- /dev/null
+#ifdef TASK
+#include "runtime.h"
+#include "multicoreruntime.h"
+#include "runtime_arch.h"
+
+__attribute__((always_inline)) inline void initialization() {
+} // initialization()
+
+__attribute__((always_inline)) inline void initCommunication() {
+#ifdef INTERRUPT
+ if (corenum < NUMCORES) {
+ // set up interrupts
+ setup_ints();
+ raw_user_interrupts_on();
+ }
+#endif
+}
+
+__attribute__((always_inline)) inline void fakeExecution() {
+ // handle communications
+ while(true) {
+ receiveObject();
+ }
+}
+
+#ifdef USEIO
+int main(void) {
+#else
+void begin() {
+#endif // #ifdef USEIO
+ run(NULL);
+}
+
+__attribute__((always_inline)) inline void terminate() {
+ raw_test_done(1);
+}
+
+// helper function to compute the coordinates of a core from the core number
+#define calCoords(core_num, coordX, coordY) \
+ *(coordX) = (core_num) % raw_get_array_size_x();\
+ *(coordY) = core_num / raw_get_array_size_x();
+
+// transfer an object to targetcore
+// format: object
+inline void transferObject(struct transObjInfo * transObj) {// __attribute__((always_inline)){
+ void * obj = transObj->objptr;
+ int type=((int *)obj)[0];
+ int targetcore = transObj->targetcore;
+
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ // for 32 bit machine, the size of fixed part is always 3 words
+ int msgsize = 3 + transObj->length * 2;
+ int i = 0;
+
+ struct ___Object___ * newobj = (struct ___Object___ *)obj;
+
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msgsize, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ // start sending msg, set sand msg flag
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0);
+#endif
+ gdn_send(msgsize);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(msgsize);
+#endif
+ gdn_send((int)obj);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(obj);
+#endif
+ for(i = 0; i < transObj->length; ++i) {
+ int taskindex = transObj->queues[2*i];
+ int paramindex = transObj->queues[2*i+1];
+ gdn_send(taskindex);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(taskindex);
+#endif
+ gdn_send(paramindex);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(paramindex);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // end of sending this msg, set sand msg flag false
+ isMsgSending = false;
+ ++(self_numsendobjs);
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void send_msg_1 (int targetcore,
+ int n0) {
+ // send this msg
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ msglength = 1;
+
+ // get the x-coord and y-coord of the target core
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(n0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n0);
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void send_msg_2 (int targetcore,
+ int n0,
+ int n1) {
+ // send this msg
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ msglength = 2;
+
+ // get the x-coord and y-coord of the target core
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(n0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n0);
+#endif
+ gdn_send(n1);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n1);
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void send_msg_3 (int targetcore,
+ int n0,
+ int n1,
+ int n2) {
+ // send this msg
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ msglength = 3;
+
+ // get the x-coord and y-coord of the target core
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(n0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n0);
+#endif
+ gdn_send(n1);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n1);
+#endif
+ gdn_send(n2);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n2);
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void send_msg_4 (int targetcore,
+ int n0,
+ int n1,
+ int n2,
+ int n3) {
+ // send this msg
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ msglength = 4;
+
+ // get the x-coord and y-coord of the target core
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(n0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n0);
+#endif
+ gdn_send(n1);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n1);
+#endif
+ gdn_send(n2);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n2);
+#endif
+ gdn_send(n3);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n3);
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void send_msg_5 (int targetcore,
+ int n0,
+ int n1,
+ int n2,
+ int n3,
+ int n4) {
+ // send this msg
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ msglength = 5;
+
+ // get the x-coord and y-coord of the target core
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(n0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n0);
+#endif
+ gdn_send(n1);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n1);
+#endif
+ gdn_send(n2);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n2);
+#endif
+ gdn_send(n3);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n3);
+#endif
+ gdn_send(n4);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n4);
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void send_msg_6 (int targetcore,
+ int n0,
+ int n1,
+ int n2,
+ int n3,
+ int n4,
+ int n5) {
+ // send this msg
+ unsigned msgHdr;
+ int self_y, self_x, target_y, target_x;
+ msglength = 6;
+
+ // get the x-coord and y-coord of the target core
+ calCoords(corenum, &self_x, &self_y);
+ calCoords(targetcore, &target_x, &target_y);
+
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, msglength, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr); // Send the message header
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + targetcore); // targetcore
+#endif
+ gdn_send(n0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n0);
+#endif
+ gdn_send(n1);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n1);
+#endif
+ gdn_send(n2);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n2);
+#endif
+ gdn_send(n3);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n3);
+#endif
+ gdn_send(n4);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n4);
+#endif
+ gdn_send(n5);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(n5);
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ // check if there are pending msgs
+ while(isMsgHanging) {
+ // get the msg from outmsgdata[]
+ // length + target + msg
+ outmsgleft = outmsgdata[outmsgindex++];
+ int target = outmsgdata[outmsgindex++];
+ calCoords(target, &target_x, &target_y);
+ // mark to start sending the msg
+ isMsgSending = true;
+ // Build the message header
+ msgHdr = construct_dyn_hdr(0, outmsgleft, 0, // msgsize word sent.
+ self_y, self_x,
+ target_y, target_x);
+ gdn_send(msgHdr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT(0xb000 + target); // targetcore
+#endif
+ while(outmsgleft-- > 0) {
+ gdn_send(outmsgdata[outmsgindex++]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(outmsgdata[outmsgindex - 1]);
+#endif
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ // mark to end sending the msg
+ isMsgSending = false;
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+ // check if there are still msg hanging
+ if(outmsgindex == outmsglast) {
+ // no more msgs
+ outmsgindex = outmsglast = 0;
+ isMsgHanging = false;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+ }
+}
+
+__attribute__((always_inline)) inline void cache_msg_2 (int targetcore,
+ int n0,
+ int n1) {
+ // cache this msg
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xdede);
+#endif
+ isMsgHanging = true;
+ // cache the msg in outmsgdata and send it later
+ // msglength + target core + msg
+ outmsgdata[outmsglast++] = 2;
+ outmsgdata[outmsglast++] = targetcore;
+ outmsgdata[outmsglast++] = n0;
+ outmsgdata[outmsglast++] = n1;
+}
+
+__attribute__((always_inline)) inline void cache_msg_3 (int targetcore,
+ int n0,
+ int n1,
+ int n2) {
+ // cache this msg
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xdede);
+#endif
+ isMsgHanging = true;
+ // cache the msg in outmsgdata and send it later
+ // msglength + target core + msg
+ outmsgdata[outmsglast++] = 3;
+ outmsgdata[outmsglast++] = targetcore;
+ outmsgdata[outmsglast++] = n0;
+ outmsgdata[outmsglast++] = n1;
+ outmsgdata[outmsglast++] = n2;
+}
+
+__attribute__((always_inline)) inline void cache_msg_4 (int targetcore,
+ int n0,
+ int n1,
+ int n2,
+ int n3) {
+ // cache this msg
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xdede);
+#endif
+ isMsgHanging = true;
+ // cache the msg in outmsgdata and send it later
+ // msglength + target core + msg
+ outmsgdata[outmsglast++] = 4;
+ outmsgdata[outmsglast++] = targetcore;
+ outmsgdata[outmsglast++] = n0;
+ outmsgdata[outmsglast++] = n1;
+ outmsgdata[outmsglast++] = n2;
+ outmsgdata[outmsglast++] = n3;
+}
+
+__attribute__((always_inline)) inline void cache_msg_5 (int targetcore,
+ int n0,
+ int n1,
+ int n2,
+ int n3,
+ int n4) {
+ // cache this msg
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xdede);
+#endif
+ isMsgHanging = true;
+ // cache the msg in outmsgdata and send it later
+ // msglength + target core + msg
+ outmsgdata[outmsglast++] = 5;
+ outmsgdata[outmsglast++] = targetcore;
+ outmsgdata[outmsglast++] = n0;
+ outmsgdata[outmsglast++] = n1;
+ outmsgdata[outmsglast++] = n2;
+ outmsgdata[outmsglast++] = n3;
+ outmsgdata[outmsglast++] = n4;
+}
+
+
+__attribute__((always_inline)) inline void cache_msg_6 (int targetcore,
+ int n0,
+ int n1,
+ int n2,
+ int n3,
+ int n4,
+ int n5) {
+ // cache this msg
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xdede);
+#endif
+ isMsgHanging = true;
+ // cache the msg in outmsgdata and send it later
+ // msglength + target core + msg
+ outmsgdata[outmsglast++] = 6;
+ outmsgdata[outmsglast++] = targetcore;
+ outmsgdata[outmsglast++] = n0;
+ outmsgdata[outmsglast++] = n1;
+ outmsgdata[outmsglast++] = n2;
+ outmsgdata[outmsglast++] = n3;
+ outmsgdata[outmsglast++] = n4;
+ outmsgdata[outmsglast++] = n5;
+}
+
+__attribute__((always_inline)) inline int receiveMsg() {
+ if(gdn_input_avail() == 0) {
+#ifdef DEBUG
+ if(corenum < NUMCORES) {
+ BAMBOO_DEBUGPRINT(0xd001);
+ }
+#endif
+ return -1;
+ }
+#ifdef PROFILE
+ /*if(isInterrupt && (!interruptInfoOverflow)) {
+ // BAMBOO_DEBUGPRINT(0xffff);
+ interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
+ interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
+ interruptInfoArray[interruptInfoIndex]->endTime = -1;
+ }*/
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcccc);
+#endif
+ while((gdn_input_avail() != 0) && (msgdataindex < msglength)) {
+ msgdata[msgdataindex] = gdn_receive();
+ if(msgdataindex == 0) {
+ if(msgdata[0] > 0xc) {
+ msglength = 3;
+ } else if (msgdata[0] == 0xc) {
+ msglength = 1;
+ } else if(msgdata[0] > 8) {
+ msglength = 4;
+ } else if(msgdata[0] == 8) {
+ msglength = 6;
+ } else if(msgdata[0] > 5) {
+ msglength = 2;
+ } else if (msgdata[0] > 2) {
+ msglength = 4;
+ } else if (msgdata[0] == 2) {
+ msglength = 5;
+ } else if (msgdata[0] > 0) {
+ msglength = 4;
+ }
+ } else if((msgdataindex == 1) && (msgdata[0] == 0)) {
+ msglength = msgdata[msgdataindex];
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
+#endif
+ msgdataindex++;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ return msgdataindex;
+}
+
+bool getreadlock(void * ptr) {
+ int targetcore = 0;
+ lockobj = (int)ptr;
+ if(((struct ___Object___ *)ptr)->lock == NULL) {
+ lock2require = lockobj;
+ } else {
+ lock2require = (int)(((struct ___Object___ *)ptr)->lock);
+ }
+ targetcore = (lock2require >> 5) % NUMCORES;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ lockresult = 0;
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ int deny = 0;
+ BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ deny = processlockrequest(0, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
+ BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ if(deny == -1) {
+ // redirected
+ return true;
+ } else {
+ if(lockobj == (int)ptr) {
+ if(deny) {
+ lockresult = 0;
+ } else {
+ lockresult = 1;
+ }
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = true;
+#endif
+ } else {
+ // conflicts on lockresults
+ BAMBOO_EXIT(0xa018);
+ }
+ }
+ return true;
+ } else {
+ // send lock request msg
+ // for 32 bit machine, the size is always 5 words
+ send_msg_5(targetcore, LOCKREQUEST, 0, (int)ptr,
+ lock2require, BAMBOO_NUM_OF_CORE);
+ }
+ return true;
+}
+
+bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
+bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
+
+void releasereadlock(void * ptr) {
+ int targetcore = 0;
+ int reallock = 0;
+ if(((struct ___Object___ *)ptr)->lock == NULL) {
+ reallock = (int)ptr;
+ } else {
+ reallock = (int)(((struct ___Object___ *)ptr)->lock);
+ }
+ targetcore = (reallock >> 5) % NUMCORES;
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ // reside on this core
+ if(!RuntimeHashcontainskey(locktbl, reallock)) {
+ // no locks for this object, something is wrong
+ BAMBOO_EXIT(0xa019);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+ RuntimeHashget(locktbl, reallock, &rwlock_obj);
+ lockvalue = (struct LockValue *)rwlock_obj;
+ lockvalue->value--;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ return;
+ } else {
+ // send lock release msg
+ // for 32 bit machine, the size is always 4 words
+ send_msg_4(targetcore, LOCKRELEASE, 0, (int)ptr, reallock);
+ }
+}
+
+// redirected lock request
+bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
+ int targetcore = 0;
+
+ if(core == BAMBOO_NUM_OF_CORE) {
+ lockobj = (int)ptr;
+ lock2require = (int)redirectlock;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ lockresult = 0;
+ }
+ targetcore = ((int)redirectlock >> 5) % NUMCORES;
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ int deny = processlockrequest(0, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
+ if(deny == -1) {
+ // redirected
+ return true;
+ } else {
+ if(core == BAMBOO_NUM_OF_CORE) {
+ if(lockobj == (int)ptr) {
+ if(deny) {
+ lockresult = 0;
+ } else {
+ lockresult = 1;
+ RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
+ }
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = true;
+#endif
+ } else {
+ // conflicts on lockresults
+ BAMBOO_EXIT(0xa01a);
+ }
+ return true;
+ } else {
+ // send lock grant/deny request to the root requiring core
+ // check if there is still some msg on sending
+ if((!cache) || (cache && !isMsgSending)) {
+ send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
+ (int)ptr, (int)redirectlock);
+ } else {
+ cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 0,
+ (int)ptr, (int)redirectlock);
+ }
+ }
+ }
+ } else {
+ // redirect the lock request
+ // for 32 bit machine, the size is always 6 words
+ if((!cache) || (cache && !isMsgSending)) {
+ send_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
+ core, BAMBOO_NUM_OF_CORE);
+ } else {
+ cache_msg_6(targetcore, REDIRECTLOCK, 0, (int)ptr, lock2require,
+ core, BAMBOO_NUM_OF_CORE);
+ }
+ }
+ return true;
+}
+
+// not reentrant
+bool getwritelock(void * ptr) {
+ int targetcore = 0;
+
+ // for 32 bit machine, the size is always 5 words
+ //int msgsize = 5;
+
+ lockobj = (int)ptr;
+ if(((struct ___Object___ *)ptr)->lock == NULL) {
+ lock2require = lockobj;
+ } else {
+ lock2require = (int)(((struct ___Object___ *)ptr)->lock);
+ }
+ targetcore = (lock2require >> 5) % NUMCORES;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ lockresult = 0;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe551);
+ BAMBOO_DEBUGPRINT_REG(lockobj);
+ BAMBOO_DEBUGPRINT_REG(lock2require);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ int deny = 0;
+ BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ deny = processlockrequest(1, lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
+ BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe555);
+ BAMBOO_DEBUGPRINT_REG(lockresult);
+#endif
+ if(deny == -1) {
+ // redirected
+ return true;
+ } else {
+ if(lockobj == (int)ptr) {
+ if(deny) {
+ lockresult = 0;
+ } else {
+ lockresult = 1;
+ }
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = true;
+#endif
+ } else {
+ // conflicts on lockresults
+ BAMBOO_EXIT(0xa01b);
+ }
+ }
+ return true;
+ } else {
+ // send lock request msg
+ // for 32 bit machine, the size is always 5 words
+ send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
+ BAMBOO_NUM_OF_CORE);
+ }
+ return true;
+}
+
+void releasewritelock(void * ptr) {
+ int targetcore = 0;
+ int reallock = 0;
+ if(((struct ___Object___ *)ptr)->lock == NULL) {
+ reallock = (int)ptr;
+ } else {
+ reallock = (int)(((struct ___Object___ *)ptr)->lock);
+ }
+ targetcore = (reallock >> 5) % NUMCORES;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe661);
+ BAMBOO_DEBUGPRINT_REG((int)ptr);
+ BAMBOO_DEBUGPRINT_REG(reallock);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ BAMBOO_START_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ // reside on this core
+ if(!RuntimeHashcontainskey(locktbl, reallock)) {
+ // no locks for this object, something is wrong
+ BAMBOO_EXIT(0xa01c);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+ RuntimeHashget(locktbl, reallock, &rwlock_obj);
+ lockvalue = (struct LockValue *)rwlock_obj;
+ lockvalue->value++;
+ }
+ BAMBOO_CLOSE_CRITICAL_SECTION_LOCK();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ return;
+ } else {
+ // send lock release msg
+ // for 32 bit machine, the size is always 4 words
+ send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
+ }
+}
+
+bool getwritelock_I(void * ptr) {
+ int targetcore = 0;
+ lockobj = (int)ptr;
+ if(((struct ___Object___ *)ptr)->lock == NULL) {
+ lock2require = lockobj;
+ } else {
+ lock2require = (int)(((struct ___Object___ *)ptr)->lock);
+ }
+ targetcore = (lock2require >> 5) % NUMCORES;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ lockresult = 0;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe561);
+ BAMBOO_DEBUGPRINT_REG(lockobj);
+ BAMBOO_DEBUGPRINT_REG(lock2require);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ int deny = processlockrequest(1, (int)lock2require, (int)ptr, BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, false);
+ if(deny == -1) {
+ // redirected
+ return true;
+ } else {
+ if(lockobj == (int)ptr) {
+ if(deny) {
+ lockresult = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0);
+#endif
+ } else {
+ lockresult = 1;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(1);
+#endif
+ }
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = true;
+#endif
+ } else {
+ // conflicts on lockresults
+ BAMBOO_EXIT(0xa01e);
+ }
+ return true;
+ }
+ } else {
+ // send lock request msg
+ // for 32 bit machine, the size is always 5 words
+ send_msg_5(targetcore, LOCKREQUEST, 1, (int)ptr, lock2require,
+ BAMBOO_NUM_OF_CORE);
+ }
+ return true;
+}
+
+// redirected lock request
+bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
+ int targetcore = 0;
+
+ if(core == BAMBOO_NUM_OF_CORE) {
+ lockobj = (int)ptr;
+ lock2require = (int)redirectlock;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ lockresult = 0;
+ }
+ targetcore = ((int)redirectlock >> 5) % NUMCORES;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe571);
+ BAMBOO_DEBUGPRINT_REG((int)ptr);
+ BAMBOO_DEBUGPRINT_REG((int)redirectlock);
+ BAMBOO_DEBUGPRINT_REG(core);
+ BAMBOO_DEBUGPRINT_REG((int)cache);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ int deny = processlockrequest(1, (int)redirectlock, (int)ptr, BAMBOO_NUM_OF_CORE, core, cache);
+ if(deny == -1) {
+ // redirected
+ return true;
+ } else {
+ if(core == BAMBOO_NUM_OF_CORE) {
+ if(lockobj == (int)ptr) {
+ if(deny) {
+ lockresult = 0;
+ } else {
+ lockresult = 1;
+ RuntimeHashadd_I(objRedirectLockTbl, (int)ptr, (int)redirectlock);
+ }
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = true;
+#endif
+ } else {
+ // conflicts on lockresults
+ BAMBOO_EXIT(0xa01f);
+ }
+ return true;
+ } else {
+ // send lock grant/deny request to the root requiring core
+ // check if there is still some msg on sending
+ if((!cache) || (cache && !isMsgSending)) {
+ send_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
+ (int)ptr, (int)redirectlock);
+ } else {
+ cache_msg_4(core, deny==1?REDIRECTDENY:REDIRECTGROUNT, 1,
+ (int)ptr, (int)redirectlock);
+ }
+ }
+ }
+ } else {
+ // redirect the lock request
+ // for 32 bit machine, the size is always 6 words
+ if((!cache) || (cache && !isMsgSending)) {
+ send_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
+ core, BAMBOO_NUM_OF_CORE);
+ } else {
+ cache_msg_6(targetcore, REDIRECTLOCK, 1, (int)ptr, (int)redirectlock,
+ core, BAMBOO_NUM_OF_CORE);
+ }
+ }
+ return true;
+}
+
+void releasewritelock_I(void * ptr) {
+ int targetcore = 0;
+ int reallock = 0;
+ if(((struct ___Object___ *)ptr)->lock == NULL) {
+ reallock = (int)ptr;
+ } else {
+ reallock = (int)(((struct ___Object___ *)ptr)->lock);
+ }
+ targetcore = (reallock >> 5) % NUMCORES;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe681);
+ BAMBOO_DEBUGPRINT_REG((int)ptr);
+ BAMBOO_DEBUGPRINT_REG(reallock);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ if(!RuntimeHashcontainskey(locktbl, reallock)) {
+ // no locks for this object, something is wrong
+ BAMBOO_EXIT(0xa020);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+ RuntimeHashget(locktbl, reallock, &rwlock_obj);
+ lockvalue = (struct LockValue *)rwlock_obj;
+ lockvalue->value++;
+ }
+ return;
+ } else {
+ // send lock release msg
+ // for 32 bit machine, the size is always 4 words
+ send_msg_4(targetcore, LOCKRELEASE, 1, (int)ptr, reallock);
+ }
+}
+
+void releasewritelock_I_r(void * lock, void * redirectlock) {
+ int targetcore = 0;
+ int reallock = (int)lock;
+ targetcore = (reallock >> 5) % NUMCORES;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe691);
+ BAMBOO_DEBUGPRINT_REG((int)lock);
+ BAMBOO_DEBUGPRINT_REG(reallock);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ // reside on this core
+ if(!RuntimeHashcontainskey(locktbl, reallock)) {
+ // no locks for this object, something is wrong
+ BAMBOO_EXIT(0xa021);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe692);
+#endif
+ RuntimeHashget(locktbl, reallock, &rwlock_obj);
+ lockvalue = (struct LockValue *)rwlock_obj;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+ lockvalue->value++;
+ lockvalue->redirectlock = (int)redirectlock;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+ }
+ return;
+ } else {
+ // send lock release msg
+ // for 32 bit machine, the size is always 4 words
+ send_msg_4(targetcore, REDIRECTRELEASE, 1, (int)lock, (int)redirectlock);
+ }
+}
+
+/* this function is to process lock requests.
+ * can only be invoked in receiveObject() */
+// if return -1: the lock request is redirected
+// 0: the lock request is approved
+// 1: the lock request is denied
+__attribute__((always_inline)) int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
+ int deny = 0;
+ if( ((lock >> 5) % NUMCORES) != BAMBOO_NUM_OF_CORE ) {
+ // the lock should not be on this core
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(requestcore);
+ BAMBOO_DEBUGPRINT_REG(lock);
+ BAMBOO_DEBUGPRINT_REG(BAMBOO_NUM_OF_CORE);
+#endif
+ BAMBOO_EXIT(0xa017);
+ }
+ if(!RuntimeHashcontainskey(locktbl, lock)) {
+ // no locks for this object
+ // first time to operate on this shared object
+ // create a lock for it
+ // the lock is an integer: 0 -- stall, >0 -- read lock, -1 -- write lock
+ struct LockValue * lockvalue = (struct LockValue *)(RUNMALLOC_I(sizeof(struct LockValue)));
+ lockvalue->redirectlock = 0;
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xe110);
+#endif
+#endif
+ if(locktype == 0) {
+ lockvalue->value = 1;
+ } else {
+ lockvalue->value = -1;
+ }
+ RuntimeHashadd_I(locktbl, lock, (int)lockvalue);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xe111);
+#endif
+#endif
+ RuntimeHashget(locktbl, lock, &rwlock_obj);
+ lockvalue = (struct LockValue *)(rwlock_obj);
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(lockvalue->redirectlock);
+#endif
+#endif
+ if(lockvalue->redirectlock != 0) {
+ // this lock is redirected
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xe112);
+#endif
+#endif
+ if(locktype == 0) {
+ getreadlock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
+ } else {
+ getwritelock_I_r((void *)obj, (void *)lockvalue->redirectlock, rootrequestcore, cache);
+ }
+ return -1; // redirected
+ } else {
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+#endif
+ if(0 == lockvalue->value) {
+ if(locktype == 0) {
+ lockvalue->value = 1;
+ } else {
+ lockvalue->value = -1;
+ }
+ } else if((lockvalue->value > 0) && (locktype == 0)) {
+ // read lock request and there are only read locks
+ lockvalue->value++;
+ } else {
+ deny = 1;
+ }
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+#endif
+ }
+ }
+ return deny;
+}
+
+__attribute__((always_inline)) void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) {
+ if(!RuntimeHashcontainskey(locktbl, lock)) {
+ // no locks for this object, something is wrong
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(lock);
+#endif
+ BAMBOO_EXIT(0xa00b);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+ RuntimeHashget(locktbl, lock, &rwlock_obj);
+ lockvalue = (struct LockValue*)(rwlock_obj);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe884);
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+ if(locktype == 0) {
+ lockvalue->value--;
+ } else {
+ lockvalue->value++;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+ if(isredirect) {
+ lockvalue->redirectlock = redirectlock;
+ }
+ }
+}
+
+#ifdef PROFILE
+__attribute__((always_inline)) inline void profileTaskStart(char * taskname) {
+ if(!taskInfoOverflow) {
+ TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
+ taskInfoArray[taskInfoIndex] = taskInfo;
+ taskInfo->taskName = taskname;
+ taskInfo->startTime = raw_get_cycle();
+ taskInfo->endTime = -1;
+ taskInfo->exitIndex = -1;
+ taskInfo->newObjs = NULL;
+ }
+}
+
+__attribute__((always_inline)) inline void profileTaskEnd() {
+ if(!taskInfoOverflow) {
+ taskInfoArray[taskInfoIndex]->endTime = raw_get_cycle();
+ taskInfoIndex++;
+ if(taskInfoIndex == TASKINFOLENGTH) {
+ taskInfoOverflow = true;
+ }
+ }
+}
+
+// output the profiling data
+void outputProfileData() {
+#ifdef USEIO
+ FILE * fp;
+ char fn[50];
+ int self_y, self_x;
+ char c_y, c_x;
+ int i;
+ int totaltasktime = 0;
+ int preprocessingtime = 0;
+ int objqueuecheckingtime = 0;
+ int postprocessingtime = 0;
+ //int interruptiontime = 0;
+ int other = 0;
+ int averagetasktime = 0;
+ int tasknum = 0;
+
+ for(i = 0; i < 50; i++) {
+ fn[i] = 0;
+ }
+
+ calCoords(corenum, &self_y, &self_x);
+ c_y = (char)self_y + '0';
+ c_x = (char)self_x + '0';
+ strcat(fn, "profile_");
+ strcat(fn, &c_x);
+ strcat(fn, "_");
+ strcat(fn, &c_y);
+ strcat(fn, ".rst");
+
+ if((fp = fopen(fn, "w+")) == NULL) {
+ fprintf(stderr, "fopen error\n");
+ return;
+ }
+
+ fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
+ // output task related info
+ for(i = 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ int duration = tmpTInfo->endTime - tmpTInfo->startTime;
+ fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
+ // summarize new obj info
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ //fprintf(stderr, "new obj!\n");
+ }
+
+ // output all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ fprintf(fp, ", %s, %d", objtype, num);
+ }
+ }
+ fprintf(fp, "\n");
+ if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
+ preprocessingtime += duration;
+ } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
+ postprocessingtime += duration;
+ } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
+ objqueuecheckingtime += duration;
+ } else {
+ totaltasktime += duration;
+ averagetasktime += duration;
+ tasknum++;
+ }
+ }
+
+ if(taskInfoOverflow) {
+ fprintf(stderr, "Caution: task info overflow!\n");
+ }
+
+ other = totalexetime - totaltasktime - preprocessingtime - postprocessingtime;
+ averagetasktime /= tasknum;
+
+ fprintf(fp, "\nTotal time: %d\n", totalexetime);
+ fprintf(fp, "Total task execution time: %d (%f%%)\n", totaltasktime, ((double)totaltasktime/(double)totalexetime)*100);
+ fprintf(fp, "Total objqueue checking time: %d (%f%%)\n", objqueuecheckingtime, ((double)objqueuecheckingtime/(double)totalexetime)*100);
+ fprintf(fp, "Total pre-processing time: %d (%f%%)\n", preprocessingtime, ((double)preprocessingtime/(double)totalexetime)*100);
+ fprintf(fp, "Total post-processing time: %d (%f%%)\n", postprocessingtime, ((double)postprocessingtime/(double)totalexetime)*100);
+ fprintf(fp, "Other time: %d (%f%%)\n", other, ((double)other/(double)totalexetime)*100);
+
+ fprintf(fp, "\nAverage task execution time: %d\n", averagetasktime);
+
+ fclose(fp);
+#else
+ int i = 0;
+ int j = 0;
+
+ BAMBOO_DEBUGPRINT(0xdddd);
+ // output task related info
+ for(i= 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ char* tmpName = tmpTInfo->taskName;
+ int nameLen = strlen(tmpName);
+ BAMBOO_DEBUGPRINT(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ BAMBOO_DEBUGPRINT_REG(tmpName[j]);
+ }
+ BAMBOO_DEBUGPRINT(0xdddb);
+ BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
+ BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
+ BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ }
+
+ // ouput all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ int nameLen = strlen(objtype);
+ BAMBOO_DEBUGPRINT(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ BAMBOO_DEBUGPRINT_REG(objtype[j]);
+ }
+ BAMBOO_DEBUGPRINT(0xdddb);
+ BAMBOO_DEBUGPRINT_REG(num);
+ }
+ }
+ BAMBOO_DEBUGPRINT(0xdddc);
+ }
+
+ if(taskInfoOverflow) {
+ BAMBOO_DEBUGPRINT(0xefee);
+ }
+
+ // output interrupt related info
+ /*for(i = 0; i < interruptInfoIndex; i++) {
+ InterruptInfo* tmpIInfo = interruptInfoArray[i];
+ BAMBOO_DEBUGPRINT(0xddde);
+ BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
+ BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
+ BAMBOO_DEBUGPRINT(0xdddf);
+ }
+
+ if(interruptInfoOverflow) {
+ BAMBOO_DEBUGPRINT(0xefef);
+ }*/
+
+ BAMBOO_DEBUGPRINT(0xeeee);
+#endif
+}
+#endif // #ifdef PROFILE
+
+#endif // #ifdef TASK
--- /dev/null
+#ifdef MULTICORE_GC
+#include "runtime.h"
+#include "multicoregarbage.h"
+#include "multicoreruntime.h"
+#include "runtime_arch.h"
+#include "SimpleHash.h"
+#include "GenericHashtable.h"
+#include "ObjectHash.h"
+#include "GCSharedHash.h"
+
+// TODO for profiling the flush phase
+#ifdef GC_PROFILE
+/*int num_mapinforequest;
+int num_markrequest;
+unsigned long long marktime;*/
+#endif
+
+extern int corenum;
+extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
+extern int numqueues[][NUMCLASSES];
+
+extern struct genhashtable * activetasks;
+extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
+extern struct taskparamdescriptor *currtpd;
+
+extern struct LockValue runtime_locks[MAXTASKPARAMS];
+extern int runtime_locklen;
+
+#ifdef SMEMM
+extern unsigned int gcmem_mixed_threshold;
+extern unsigned int gcmem_mixed_usedmem;
+#endif
+
+struct pointerblock {
+ void * ptrs[NUMPTRS];
+ struct pointerblock *next;
+};
+
+struct pointerblock *gchead=NULL;
+int gcheadindex=0;
+struct pointerblock *gctail=NULL;
+int gctailindex=0;
+struct pointerblock *gctail2=NULL;
+int gctailindex2=0;
+struct pointerblock *gcspare=NULL;
+
+#define NUMLOBJPTRS 20
+
+struct lobjpointerblock {
+ void * lobjs[NUMLOBJPTRS];
+ //void * dsts[NUMLOBJPTRS];
+ int lengths[NUMLOBJPTRS];
+ //void * origs[NUMLOBJPTRS];
+ int hosts[NUMLOBJPTRS];
+ struct lobjpointerblock *next;
+ struct lobjpointerblock *prev;
+};
+
+struct lobjpointerblock *gclobjhead=NULL;
+int gclobjheadindex=0;
+struct lobjpointerblock *gclobjtail=NULL;
+int gclobjtailindex=0;
+struct lobjpointerblock *gclobjtail2=NULL;
+int gclobjtailindex2=0;
+struct lobjpointerblock *gclobjspare=NULL;
+
+#ifdef GC_DEBUG
+// dump whole mem in blocks
+inline void dumpSMem() {
+ int block = 0;
+ int sblock = 0;
+ int j = 0;
+ int i = 0;
+ int coren = 0;
+ int x = 0;
+ int y = 0;
+ printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ // reserved blocks for sblocktbl
+ printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
+ printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
+ udn_tile_coord_x(), udn_tile_coord_y(),
+ *((int *)(i)), *((int *)(i + 4)),
+ *((int *)(i + 4*2)), *((int *)(i + 4*3)),
+ *((int *)(i + 4*4)), *((int *)(i + 4*5)),
+ *((int *)(i + 4*6)), *((int *)(i + 4*7)),
+ *((int *)(i + 4*8)), *((int *)(i + 4*9)),
+ *((int *)(i + 4*10)), *((int *)(i + 4*11)),
+ *((int *)(i + 4*12)), *((int *)(i + 4*13)),
+ *((int *)(i + 4*14)), *((int *)(i + 4*15)));
+ }
+ sblock = gcreservedsb;
+ bool advanceblock = false;
+ // remaining memory
+ for(i=gcbaseva; i<gcbaseva+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
+ advanceblock = false;
+ // computing sblock # and block #, core coordinate (x,y) also
+ if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
+ // finished a sblock
+ if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
+ if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
+ // finished a block
+ block++;
+ advanceblock = true;
+ }
+ } else {
+ // finished a block
+ block++;
+ advanceblock = true;
+ }
+ // compute core #
+ if(advanceblock) {
+ coren = gc_block2core[block%(NUMCORES4GC*2)];
+ }
+ // compute core coordinate
+ BAMBOO_COORDS(coren, &x, &y);
+ printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
+ udn_tile_coord_x(), udn_tile_coord_y(),
+ block, sblock++, x, y,
+ (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
+ }
+ j++;
+ printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
+ udn_tile_coord_x(), udn_tile_coord_y(),
+ *((int *)(i)), *((int *)(i + 4)),
+ *((int *)(i + 4*2)), *((int *)(i + 4*3)),
+ *((int *)(i + 4*4)), *((int *)(i + 4*5)),
+ *((int *)(i + 4*6)), *((int *)(i + 4*7)),
+ *((int *)(i + 4*8)), *((int *)(i + 4*9)),
+ *((int *)(i + 4*10)), *((int *)(i + 4*11)),
+ *((int *)(i + 4*12)), *((int *)(i + 4*13)),
+ *((int *)(i + 4*14)), *((int *)(i + 4*15)));
+ }
+ printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
+}
+#endif
+
+// should be invoked with interruption closed
+inline void gc_enqueue_I(void *ptr) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe601);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+#endif
+ if (gcheadindex==NUMPTRS) {
+ struct pointerblock * tmp;
+ if (gcspare!=NULL) {
+ tmp=gcspare;
+ gcspare=NULL;
+ } else {
+ tmp=RUNMALLOC_I(sizeof(struct pointerblock));
+ } // if (gcspare!=NULL)
+ gchead->next=tmp;
+ gchead=tmp;
+ gcheadindex=0;
+ } // if (gcheadindex==NUMPTRS)
+ gchead->ptrs[gcheadindex++]=ptr;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe602);
+#endif
+} // void gc_enqueue_I(void *ptr)
+
+// dequeue and destroy the queue
+inline void * gc_dequeue_I() {
+ if (gctailindex==NUMPTRS) {
+ struct pointerblock *tmp=gctail;
+ gctail=gctail->next;
+ gctailindex=0;
+ if (gcspare!=NULL) {
+ RUNFREE(tmp);
+ } else {
+ gcspare=tmp;
+ } // if (gcspare!=NULL)
+ } // if (gctailindex==NUMPTRS)
+ return gctail->ptrs[gctailindex++];
+} // void * gc_dequeue()
+
+// dequeue and do not destroy the queue
+inline void * gc_dequeue2_I() {
+ if (gctailindex2==NUMPTRS) {
+ struct pointerblock *tmp=gctail2;
+ gctail2=gctail2->next;
+ gctailindex2=0;
+ } // if (gctailindex2==NUMPTRS)
+ return gctail2->ptrs[gctailindex2++];
+} // void * gc_dequeue2()
+
+inline int gc_moreItems_I() {
+ if ((gchead==gctail)&&(gctailindex==gcheadindex))
+ return 0;
+ return 1;
+} // int gc_moreItems()
+
+inline int gc_moreItems2_I() {
+ if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
+ return 0;
+ return 1;
+} // int gc_moreItems2()
+
+// should be invoked with interruption closed
+// enqueue a large obj: start addr & length
+inline void gc_lobjenqueue_I(void *ptr,
+ int length,
+ int host) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe901);
+#endif
+ if (gclobjheadindex==NUMLOBJPTRS) {
+ struct lobjpointerblock * tmp;
+ if (gclobjspare!=NULL) {
+ tmp=gclobjspare;
+ gclobjspare=NULL;
+ } else {
+ tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
+ } // if (gclobjspare!=NULL)
+ gclobjhead->next=tmp;
+ tmp->prev = gclobjhead;
+ gclobjhead=tmp;
+ gclobjheadindex=0;
+ } // if (gclobjheadindex==NUMLOBJPTRS)
+ gclobjhead->lobjs[gclobjheadindex]=ptr;
+ gclobjhead->lengths[gclobjheadindex]=length;
+ gclobjhead->hosts[gclobjheadindex++]=host;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
+ BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
+ BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
+#endif
+} // void gc_lobjenqueue_I(void *ptr...)
+
+// dequeue and destroy the queue
+inline void * gc_lobjdequeue_I(int * length,
+ int * host) {
+ if (gclobjtailindex==NUMLOBJPTRS) {
+ struct lobjpointerblock *tmp=gclobjtail;
+ gclobjtail=gclobjtail->next;
+ gclobjtailindex=0;
+ gclobjtail->prev = NULL;
+ if (gclobjspare!=NULL) {
+ RUNFREE(tmp);
+ } else {
+ gclobjspare=tmp;
+ tmp->next = NULL;
+ tmp->prev = NULL;
+ } // if (gclobjspare!=NULL)
+ } // if (gclobjtailindex==NUMLOBJPTRS)
+ if(length != NULL) {
+ *length = gclobjtail->lengths[gclobjtailindex];
+ }
+ if(host != NULL) {
+ *host = (int)(gclobjtail->hosts[gclobjtailindex]);
+ }
+ return gclobjtail->lobjs[gclobjtailindex++];
+} // void * gc_lobjdequeue()
+
+inline int gc_lobjmoreItems_I() {
+ if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
+ return 0;
+ return 1;
+} // int gc_lobjmoreItems()
+
+// dequeue and don't destroy the queue
+inline void gc_lobjdequeue2_I() {
+ if (gclobjtailindex2==NUMLOBJPTRS) {
+ gclobjtail2=gclobjtail2->next;
+ gclobjtailindex2=1;
+ } else {
+ gclobjtailindex2++;
+ } // if (gclobjtailindex2==NUMLOBJPTRS)
+} // void * gc_lobjdequeue2()
+
+inline int gc_lobjmoreItems2_I() {
+ if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
+ return 0;
+ return 1;
+} // int gc_lobjmoreItems2()
+
+// 'reversly' dequeue and don't destroy the queue
+inline void gc_lobjdequeue3_I() {
+ if (gclobjtailindex2==0) {
+ gclobjtail2=gclobjtail2->prev;
+ gclobjtailindex2=NUMLOBJPTRS-1;
+ } else {
+ gclobjtailindex2--;
+ } // if (gclobjtailindex2==NUMLOBJPTRS)
+} // void * gc_lobjdequeue3()
+
+inline int gc_lobjmoreItems3_I() {
+ if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
+ return 0;
+ return 1;
+} // int gc_lobjmoreItems3()
+
+inline void gc_lobjqueueinit4_I() {
+ gclobjtail2 = gclobjtail;
+ gclobjtailindex2 = gclobjtailindex;
+} // void gc_lobjqueueinit2()
+
+inline void * gc_lobjdequeue4_I(int * length,
+ int * host) {
+ if (gclobjtailindex2==NUMLOBJPTRS) {
+ gclobjtail2=gclobjtail2->next;
+ gclobjtailindex2=0;
+ } // if (gclobjtailindex==NUMLOBJPTRS)
+ if(length != NULL) {
+ *length = gclobjtail2->lengths[gclobjtailindex2];
+ }
+ if(host != NULL) {
+ *host = (int)(gclobjtail2->hosts[gclobjtailindex2]);
+ }
+ return gclobjtail2->lobjs[gclobjtailindex2++];
+} // void * gc_lobjdequeue()
+
+inline int gc_lobjmoreItems4_I() {
+ if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
+ return 0;
+ return 1;
+} // int gc_lobjmoreItems(
+
+INTPTR gccurr_heapbound = 0;
+
+inline void gettype_size(void * ptr,
+ int * ttype,
+ int * tsize) {
+ int type = ((int *)ptr)[0];
+ int size = 0;
+ if(type < NUMCLASSES) {
+ // a normal object
+ size = classsize[type];
+ } else {
+ // an array
+ struct ArrayObject *ao=(struct ArrayObject *)ptr;
+ int elementsize=classsize[type];
+ int length=ao->___length___;
+ size=sizeof(struct ArrayObject)+length*elementsize;
+ } // if(type < NUMCLASSES)
+ *ttype = type;
+ *tsize = size;
+}
+
+inline bool isLarge(void * ptr,
+ int * ttype,
+ int * tsize) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe701);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+#endif
+ // check if a pointer is referring to a large object
+ gettype_size(ptr, ttype, tsize);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(*tsize);
+#endif
+ int bound = (BAMBOO_SMEM_SIZE);
+ if(((int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
+ bound = (BAMBOO_SMEM_SIZE_L);
+ }
+ if((((int)ptr-gcbaseva)%(bound))==0) {
+ // ptr is a start of a block
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe702);
+ BAMBOO_DEBUGPRINT(1);
+#endif
+ return true;
+ }
+ if((bound-(((int)ptr-gcbaseva)%bound)) < (*tsize)) {
+ // it acrosses the boundary of current block
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe703);
+ BAMBOO_DEBUGPRINT(1);
+#endif
+ return true;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0);
+#endif
+ return false;
+} // bool isLarge(void * ptr, int * ttype, int * tsize)
+
+inline int hostcore(void * ptr) {
+ // check the host core of ptr
+ int host = 0;
+ RESIDECORE(ptr, &host);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xedd0);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(host);
+#endif
+ return host;
+} // int hostcore(void * ptr)
+
+inline bool isLocal(void * ptr) {
+ // check if a pointer is in shared heap on this core
+ return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
+} // bool isLocal(void * ptr)
+
+inline bool gc_checkCoreStatus_I() {
+ bool allStall = true;
+ for(int i = 0; i < NUMCORES4GC; ++i) {
+ if(gccorestatus[i] != 0) {
+ allStall = false;
+ break;
+ } // if(gccorestatus[i] != 0)
+ } // for(i = 0; i < NUMCORES4GC; ++i)
+ return allStall;
+}
+
+inline bool gc_checkAllCoreStatus_I() {
+ bool allStall = true;
+ for(int i = 0; i < NUMCORESACTIVE; ++i) {
+ if(gccorestatus[i] != 0) {
+ allStall = false;
+ break;
+ } // if(gccorestatus[i] != 0)
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+ return allStall;
+}
+
+inline void checkMarkStatue() {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee01);
+#endif
+ int i;
+ if((!waitconfirm) ||
+ (waitconfirm && (numconfirm == 0))) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee02);
+#endif
+ int entry_index = 0;
+ if(waitconfirm) {
+ // phase 2
+ entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+ } else {
+ // phase 1
+ entry_index = gcnumsrobjs_index;
+ }
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
+ gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
+ // check the status of all cores
+ bool allStall = gc_checkAllCoreStatus_I();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee03);
+#endif
+ if(allStall) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee04);
+#endif
+ // ask for confirm
+ if(!waitconfirm) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee05);
+#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 = NUMCORESACTIVE - 1;
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ for(i = 1; i < NUMCORESACTIVE; ++i) {
+ gccorestatus[i] = 1;
+ // send mark phase finish confirm request msg to core i
+ send_msg_1(i, GCMARKCONFIRM, false);
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+ } else {
+ // Phase 2
+ // 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 < NUMCORESACTIVE; ++i) {
+ sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee06);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee07);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ if(0 == sumsendobj) {
+ // Check if there are changes of the numsendobjs or numreceiveobjs on
+ // each core
+ bool ischanged = false;
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ if((gcnumsendobjs[0][i] != gcnumsendobjs[1][i]) ||
+ (gcnumreceiveobjs[0][i] != gcnumreceiveobjs[1][i]) ) {
+ ischanged = true;
+ break;
+ }
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee08);
+ BAMBOO_DEBUGPRINT_REG(ischanged);
+#endif
+ if(!ischanged) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee09);
+#endif
+ // all the core status info are the latest
+ // stop mark phase
+ gcphase = COMPACTPHASE;
+ // restore the gcstatus for all cores
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ gccorestatus[i] = 1;
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+ } else {
+ waitconfirm = false;
+ gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+ } // if(!ischanged)
+ } else {
+ // There were changes between phase 1 and phase 2, can not decide
+ // whether the mark phase has been finished
+ waitconfirm = false;
+ // As it fails in phase 2, flip the entries
+ gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+ } // if(0 == sumsendobj) else ...
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // if(!gcwaitconfirm) else()
+ } else {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // if(allStall)
+ } // if((!waitconfirm)...
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee0a);
+#endif
+} // void checkMarkStatue()
+/*
+inline bool preGC() {
+ // preparation for gc
+ // make sure to clear all incoming msgs espacially transfer obj msgs
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec01);
+#endif
+ int i;
+ if((!waitconfirm) ||
+ (waitconfirm && (numconfirm == 0))) {
+ // send out status confirm msgs to all cores to check if there are
+ // transfer obj msgs on-the-fly
+ waitconfirm = true;
+ numconfirm = NUMCORESACTIVE - 1;
+ for(i = 1; i < NUMCORESACTIVE; ++i) {
+ corestatus[i] = 1;
+ // send status confirm msg to core i
+ send_msg_1(i, STATUSCONFIRM, false);
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec02);
+#endif
+ while(true) {
+ if(numconfirm == 0) {
+ break;
+ }
+ } // wait for confirmations
+ waitconfirm = false;
+ numconfirm = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec03);
+#endif
+ numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
+ numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
+ int sumsendobj = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec04);
+#endif
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj += numsendobjs[i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
+#endif
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec05);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj -= numreceiveobjs[i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
+#endif
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec06);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ if(0 == sumsendobj) {
+ return true;
+ } else {
+ // still have some transfer obj msgs on-the-fly, can not start gc
+ return false;
+ } // if(0 == sumsendobj)
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec07);
+#endif
+ // previously asked for status confirmation and do not have all the
+ // confirmations yet, can not start gc
+ return false;
+ } // if((!waitconfirm) ||
+} // bool preGC()*/
+
+inline void initGC() {
+ int i;
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ for(i = 0; i < NUMCORES4GC; ++i) {
+ gccorestatus[i] = 1;
+ gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
+ gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
+ gcloads[i] = 0;
+ gcrequiredmems[i] = 0;
+ gcfilledblocks[i] = 0;
+ gcstopblock[i] = 0;
+ } // for(i = 0; i < NUMCORES4GC; ++i)
+ for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
+ gccorestatus[i] = 1;
+ gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
+ gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
+ }
+ gcheaptop = 0;
+ gctopcore = 0;
+ gctopblock = 0;
+ } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
+ gcself_numsendobjs = 0;
+ gcself_numreceiveobjs = 0;
+ gcmarkedptrbound = 0;
+ gcobj2map = 0;
+ gcmappedobj = 0;
+ //gcismapped = false;
+ gcnumlobjs = 0;
+ gcmovestartaddr = 0;
+ gctomove = false;
+ gcblock2fill = 0;
+ gcmovepending = 0;
+ gccurr_heaptop = 0;
+ gcdstcore = 0;
+
+ // initialize queue
+ if (gchead==NULL) {
+ gcheadindex=gctailindex=gctailindex2 = 0;
+ gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
+ } else {
+ gctailindex = gctailindex2 = gcheadindex;
+ gctail = gctail2 = gchead;
+ }
+
+ // initialize the large obj queues
+ if (gclobjhead==NULL) {
+ gclobjheadindex=0;
+ gclobjtailindex=0;
+ gclobjtailindex2 = 0;
+ gclobjhead=gclobjtail=gclobjtail2=
+ RUNMALLOC(sizeof(struct lobjpointerblock));
+ } else {
+ gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
+ gclobjtail = gclobjtail2 = gclobjhead;
+ }
+ gclobjhead->next = gclobjhead->prev = NULL;
+
+#ifdef LOCALHASHTBL_TEST
+ freeRuntimeHash(gcpointertbl);
+ gcpointertbl = allocateRuntimeHash(20);
+#else
+ mgchashreset(gcpointertbl);
+#endif
+ //gcpointertbl = allocateMGCHash(20);
+
+ freeMGCHash(gcforwardobjtbl);
+ gcforwardobjtbl = allocateMGCHash(20, 3);
+
+ // initialize the mapping info related structures
+ if((BAMBOO_NUM_OF_CORE < NUMCORES4GC) && (gcsharedptbl != NULL)) {
+ // Never free the shared hash table, just reset it
+ /*freeGCSharedHash(gcsharedptbl);
+ gcsharedptbl = allocateGCSharedHash(20);*/
+ mgcsharedhashReset(gcsharedptbl);
+ }
+ // Zero out the remaining bamboo_cur_msp
+ // Only zero out the first 4 bytes of the remaining memory
+ /*if((bamboo_cur_msp != 0)
+ && (bamboo_smem_zero_top == bamboo_cur_msp)
+ && (bamboo_smem_size > 0)) {
+ *((int *)bamboo_cur_msp) = 0;
+ }*/
+#ifdef GC_PROFILE
+ // TODO
+ /*num_mapinforequest = 0;
+ num_mapinforequest_i = 0;
+ flushstalltime = 0;
+ flushstalltime_i = 0;
+ num_markrequest = 0;
+ marktime = 0;*/
+ gc_num_livespace = 0;
+ gc_num_freespace = 0;
+ gc_num_lobj = 0;
+ gc_num_lobjspace = 0;
+ gc_num_liveobj = 0;
+ gc_num_forwardobj = 0;
+ gc_num_profiles = NUMCORESACTIVE - 1;
+#endif
+} // void initGC()
+
+// compute load balance for all cores
+inline int loadbalance(int * heaptop) {
+ // compute load balance
+ int i;
+
+ // get the total loads
+ int tloads = gcloads[STARTUPCORE];
+ for(i = 1; i < NUMCORES4GC; i++) {
+ tloads += gcloads[i];
+ }
+ *heaptop = gcbaseva + tloads;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xdddd);
+ BAMBOO_DEBUGPRINT_REG(tloads);
+ BAMBOO_DEBUGPRINT_REG(*heaptop);
+#endif
+ int b = 0;
+ BLOCKINDEX(*heaptop, &b);
+ int numbpc = b / NUMCORES4GC; // num of blocks per core
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(b);
+ BAMBOO_DEBUGPRINT_REG(numbpc);
+#endif
+ gctopblock = b;
+ RESIDECORE(heaptop, &gctopcore);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(gctopcore);
+#endif
+ return numbpc;
+} // void loadbalance(int * heaptop)
+
+inline bool cacheLObjs() {
+ // check the total mem size need for large objs
+ unsigned long long sumsize = 0;
+ int size = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe801);
+#endif
+ gclobjtail2 = gclobjtail;
+ gclobjtailindex2 = gclobjtailindex;
+ int tmp_lobj = 0;
+ int tmp_len = 0;
+ int tmp_host = 0;
+ // compute total mem size required and sort the lobjs in ascending order
+ while(gc_lobjmoreItems2_I()) {
+ gc_lobjdequeue2_I();
+ tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
+ tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
+ tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
+ sumsize += tmp_len;
+#ifdef GC_PROFILE
+ gc_num_lobj++;
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
+ BAMBOO_DEBUGPRINT_REG(tmp_len);
+ BAMBOO_DEBUGPRINT_REG(sumsize);
+#endif
+ int i = gclobjtailindex2-1;
+ struct lobjpointerblock * tmp_block = gclobjtail2;
+ // find the place to insert
+ while(true) {
+ if(i == 0) {
+ if(tmp_block->prev == NULL) {
+ break;
+ }
+ if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
+ tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
+ tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
+ tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
+ tmp_block = tmp_block->prev;
+ i = NUMLOBJPTRS-1;
+ } else {
+ break;
+ } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
+ } else {
+ if(tmp_block->lobjs[i-1] > tmp_lobj) {
+ tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
+ tmp_block->lengths[i] = tmp_block->lengths[i-1];
+ tmp_block->hosts[i] = tmp_block->hosts[i-1];
+ i--;
+ } else {
+ break;
+ } // if(tmp_block->lobjs[i-1] < tmp_lobj)
+ } // if(i ==0 ) else {}
+ } // while(true)
+ // insert it
+ if(i != gclobjtailindex2 - 1) {
+ tmp_block->lobjs[i] = tmp_lobj;
+ tmp_block->lengths[i] = tmp_len;
+ tmp_block->hosts[i] = tmp_host;
+ }
+ } // while(gc_lobjmoreItems2())
+
+#ifdef GC_PROFILE
+ gc_num_lobjspace = sumsize;
+#endif
+ // check if there are enough space to cache these large objs
+ INTPTR dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
+ if((unsigned long long)gcheaptop > (unsigned long long)dst) {
+ // do not have enough room to cache large objs
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe802);
+ BAMBOO_DEBUGPRINT_REG(dst);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+ BAMBOO_DEBUGPRINT_REG(sumsize);
+#endif
+ return false;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe803);
+ BAMBOO_DEBUGPRINT_REG(dst);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+#endif
+
+ gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
+ // cache the largeObjs to the top of the shared heap
+ //gclobjtail2 = gclobjtail;
+ //gclobjtailindex2 = gclobjtailindex;
+ dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
+ while(gc_lobjmoreItems3_I()) {
+ gc_lobjdequeue3_I();
+ size = gclobjtail2->lengths[gclobjtailindex2];
+ // set the mark field to , indicating that this obj has been moved
+ // and need to be flushed
+ ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[6] = COMPACTED;
+ dst -= size;
+ if((int)dst < (int)(gclobjtail2->lobjs[gclobjtailindex2])+size) {
+ memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
+ } else {
+ //BAMBOO_WRITE_HINT_CACHE(dst, size);
+ memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0x804);
+ BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
+ BAMBOO_DEBUGPRINT(dst);
+ BAMBOO_DEBUGPRINT_REG(size);
+ BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
+ BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
+#endif
+ }
+ return true;
+} // void cacheLObjs()
+
+// update the bmmboo_smemtbl to record current shared mem usage
+void updateSmemTbl(int coren,
+ int localtop) {
+ int ltopcore = 0;
+ int bound = BAMBOO_SMEM_SIZE_L;
+ BLOCKINDEX(localtop, <opcore);
+ if(localtop >= (gcbaseva+(BAMBOO_LARGE_SMEM_BOUND))) {
+ bound = BAMBOO_SMEM_SIZE;
+ }
+ int load = (localtop-gcbaseva)%bound;
+ int i = 0;
+ int j = 0;
+ int toset = 0;
+ do {
+ toset = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
+ if(toset < ltopcore) {
+ bamboo_smemtbl[toset]=
+ (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+#ifdef SMEMM
+ gcmem_mixed_usedmem += bamboo_smemtbl[toset];
+#endif
+ } else if(toset == ltopcore) {
+ bamboo_smemtbl[toset] = load;
+#ifdef SMEMM
+ gcmem_mixed_usedmem += bamboo_smemtbl[toset];
+#endif
+ break;
+ } else {
+ break;
+ }
+ i++;
+ if(i == 2) {
+ i = 0;
+ j++;
+ }
+ } while(true);
+} // void updateSmemTbl(int, int)
+
+inline void moveLObjs() {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea01);
+#endif
+#ifdef SMEMM
+ // update the gcmem_mixed_usedmem
+ gcmem_mixed_usedmem = 0;
+#endif
+ // zero out the smemtbl
+ BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
+ // find current heap top
+ // flush all gcloads to indicate the real heap top on one core
+ // previous it represents the next available ptr on a core
+ if((gcloads[0] > (gcbaseva+(BAMBOO_SMEM_SIZE_L)))
+ && ((gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
+ // edge of a block, check if this is exactly the heaptop
+ BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
+ gcloads[0]+=(gcfilledblocks[0]>1 ?
+ (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
+ }
+ updateSmemTbl(0, gcloads[0]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea02);
+ BAMBOO_DEBUGPRINT_REG(gcloads[0]);
+ BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
+#endif
+ for(int i = 1; i < NUMCORES4GC; i++) {
+ int tmptop = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000+i);
+ BAMBOO_DEBUGPRINT_REG(gcloads[i]);
+ BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
+#endif
+ if((gcfilledblocks[i] > 0)
+ && ((gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
+ // edge of a block, check if this is exactly the heaptop
+ BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
+ gcloads[i] +=
+ (gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
+ tmptop = gcloads[i];
+ }
+ updateSmemTbl(i, gcloads[i]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(gcloads[i]);
+#endif
+ } // for(int i = 1; i < NUMCORES4GC; i++) {
+
+ // find current heap top
+ // TODO
+ // a bug here: when using local allocation, directly move large objects
+ // to the highest free chunk might not be memory efficient
+ int tmpheaptop = 0;
+ int size = 0;
+ int bound = 0;
+ int i = 0;
+ for(i = gcnumblock-1; i >= 0; i--) {
+ if(bamboo_smemtbl[i] > 0) {
+ break;
+ }
+ }
+ if(i == -1) {
+ tmpheaptop = gcbaseva;
+ } else {
+ tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
+ (BAMBOO_SMEM_SIZE_L*i) :
+ (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
+ }
+
+ // move large objs from gcheaptop to tmpheaptop
+ // write the header first
+ unsigned int tomove = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -gcheaptop;
+#ifdef SMEMM
+ gcmem_mixed_usedmem += tomove;
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea03);
+ BAMBOO_DEBUGPRINT_REG(tomove);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+#endif
+ // flush the sbstartbl
+ BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
+ (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-gcreservedsb)*sizeof(INTPTR));
+ if(tomove == 0) {
+ gcheaptop = tmpheaptop;
+ } else {
+ // check how many blocks it acrosses
+ int remain = tmpheaptop-gcbaseva;
+ int sb = remain/(BAMBOO_SMEM_SIZE) + gcreservedsb;//number of the sblock
+ int b = 0; // number of the block
+ BLOCKINDEX(tmpheaptop, &b);
+ // check the remaining space in this block
+ bound = (BAMBOO_SMEM_SIZE);
+ if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
+ bound = (BAMBOO_SMEM_SIZE_L);
+ }
+ remain = bound - remain%bound;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea04);
+#endif
+ size = 0;
+ int isize = 0;
+ int host = 0;
+ int ptr = 0;
+ int base = tmpheaptop;
+ int cpysize = 0;
+ remain -= BAMBOO_CACHE_LINE_SIZE;
+ tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
+ gc_lobjqueueinit4_I();
+ while(gc_lobjmoreItems4_I()) {
+ ptr = (int)(gc_lobjdequeue4_I(&size, &host));
+ ALIGNSIZE(size, &isize);
+ if(remain < isize) {
+ // this object acrosses blocks
+ if(cpysize > 0) {
+ // close current block, fill its header
+ BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
+ *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
+ bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE;//add the size of header
+ cpysize = 0;
+ base = tmpheaptop;
+ if(remain == 0) {
+ remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
+ BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ }
+ remain -= BAMBOO_CACHE_LINE_SIZE;
+ tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
+ BLOCKINDEX(tmpheaptop, &b);
+ sb = (tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE) + gcreservedsb;
+ } // if(cpysize > 0)
+
+ // move the large obj
+ if((int)gcheaptop < (int)(tmpheaptop)+size) {
+ memmove(tmpheaptop, gcheaptop, size);
+ } else {
+ //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
+ memcpy(tmpheaptop, gcheaptop, size);
+ }
+ // fill the remaining space with -2 padding
+ BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea05);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+ BAMBOO_DEBUGPRINT_REG(size);
+ BAMBOO_DEBUGPRINT_REG(isize);
+ BAMBOO_DEBUGPRINT_REG(base);
+#endif
+ gcheaptop += size;
+ // cache the mapping info anyway
+ //if(ptr != tmpheaptop) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
+#else
+ mgchashInsert_I(gcpointertbl, ptr, tmpheaptop);
+#endif
+ //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ //}
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcdca);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+#endif
+ if(host != BAMBOO_NUM_OF_CORE) {
+ // send the original host core with the mapping info
+ send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcdcb);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+#endif
+ } // if(host != BAMBOO_NUM_OF_CORE)
+ tmpheaptop += isize;
+
+ // set the gcsbstarttbl and bamboo_smemtbl
+ int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
+ for(int k = 1; k < tmpsbs; k++) {
+ gcsbstarttbl[sb+k] = (INTPTR)(-1);
+ }
+ sb += tmpsbs;
+ bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ BLOCKINDEX(tmpheaptop-1, &tmpsbs);
+ for(; b < tmpsbs; b++) {
+ bamboo_smemtbl[b] = bound;
+ if(b==NUMCORES4GC-1) {
+ bound = BAMBOO_SMEM_SIZE;
+ }
+ }
+ if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
+ gcsbstarttbl[sb] = (INTPTR)(-1);
+ remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
+ BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ bamboo_smemtbl[b] = bound;
+ } else {
+ gcsbstarttbl[sb] = (INTPTR)(tmpheaptop);
+ remain = tmpheaptop-gcbaseva;
+ bamboo_smemtbl[b] = remain%bound;
+ remain = bound - bamboo_smemtbl[b];
+ } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
+
+ // close current block and fill the header
+ BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
+ *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
+ cpysize = 0;
+ base = tmpheaptop;
+ if(remain == BAMBOO_CACHE_LINE_SIZE) {
+ // fill with 0 in case
+ BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
+ }
+ remain -= BAMBOO_CACHE_LINE_SIZE;
+ tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
+ } else {
+ remain -= isize;
+ // move the large obj
+ if((int)gcheaptop < (int)(tmpheaptop)+size) {
+ memmove(tmpheaptop, gcheaptop, size);
+ } else {
+ //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
+ memcpy(tmpheaptop, gcheaptop, size);
+ }
+ // fill the remaining space with -2 padding
+ BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
+ // zero out original mem caching the lobj
+ //BAMBOO_MEMSET_WH(gcheaptop, '\0', size); // TODO ??
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea06);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+ BAMBOO_DEBUGPRINT_REG(size);
+ BAMBOO_DEBUGPRINT_REG(isize);
+#endif
+
+ gcheaptop += size;
+ cpysize += isize;
+ // cache the mapping info anyway
+ //if(ptr != tmpheaptop) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
+#else
+ mgchashInsert_I(gcpointertbl, ptr, tmpheaptop);
+#endif
+ //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ //}
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcdcc);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+ BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
+#endif
+ if(host != BAMBOO_NUM_OF_CORE) {
+ // send the original host core with the mapping info
+ send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcdcd);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(tmpheaptop);
+#endif
+ } // if(host != BAMBOO_NUM_OF_CORE)
+ tmpheaptop += isize;
+
+ // update bamboo_smemtbl
+ bamboo_smemtbl[b] += isize;
+ } // if(remain < isize) else ...
+ } // while(gc_lobjmoreItems())
+ if(cpysize > 0) {
+ // close current block, fill the header
+ BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
+ *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
+ bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE;// add the size of the header
+ } else {
+ tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
+ }
+ gcheaptop = tmpheaptop;
+
+ } // if(tomove == 0)
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea07);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+#endif
+
+ bamboo_free_block = 0;
+ int tbound = 0;
+ do {
+ tbound = (bamboo_free_block<NUMCORES4GC) ?
+ BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ if(bamboo_smemtbl[bamboo_free_block] == tbound) {
+ bamboo_free_block++;
+ } else {
+ // the first non-full partition
+ break;
+ }
+ } while(true);
+
+ // TODO
+ /*unsigned long long gc_num_livespace = 0;
+ for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
+ gc_num_livespace += bamboo_smemtbl[tmpi];
+ }
+ BAMBOO_DEBUGPRINT_REG(gc_num_livespace);
+ BAMBOO_DEBUGPRINT_REG(bamboo_free_block);*/
+
+#ifdef GC_PROFILE
+ // check how many live space there are
+ gc_num_livespace = 0;
+ for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
+ gc_num_livespace += bamboo_smemtbl[tmpi];
+ }
+ gc_num_freespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_livespace;
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xea08);
+ BAMBOO_DEBUGPRINT_REG(gcheaptop);
+#endif
+} // void moveLObjs()
+
+inline void markObj(void * objptr) {
+ if(objptr == NULL) {
+ return;
+ }
+ if(ISSHAREDOBJ(objptr)) {
+ int host = hostcore(objptr);
+ if(BAMBOO_NUM_OF_CORE == host) {
+ // on this core
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(((int *)objptr)[6] == INIT) {
+ // this is the first time that this object is discovered,
+ // set the flag as DISCOVERED
+ ((int *)objptr)[6] |= DISCOVERED;
+ gc_enqueue_I(objptr);
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT_REG(host);
+ BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+ // check if this obj has been forwarded
+ if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
+#ifdef GC_PROFILE
+ // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
+#endif
+ // send a msg to host informing that objptr is active
+ send_msg_2(host, GCMARKEDOBJ, objptr, /*BAMBOO_NUM_OF_CORE,*/ false);
+#ifdef GC_PROFILE
+ // TODO
+ /*
+ marktime += BAMBOO_GET_EXE_TIME() - ttime;
+ num_markrequest++;*/
+ gc_num_forwardobj++;
+#endif // GC_PROFILE
+ gcself_numsendobjs++;
+ MGCHashadd(gcforwardobjtbl, (int)objptr);
+ }
+ }
+ } else {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ gc_enqueue_I(objptr);
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // if(ISSHAREDOBJ(objptr))
+} // void markObj(void * objptr)
+
+// enqueue root objs
+inline void tomark(struct garbagelist * stackptr) {
+ if(MARKPHASE != gcphase) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(gcphase);
+#endif
+ BAMBOO_EXIT(0xb101);
+ }
+ gcbusystatus = true;
+ gcnumlobjs = 0;
+
+ int i,j;
+ // enqueue current stack
+ while(stackptr!=NULL) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe501);
+ BAMBOO_DEBUGPRINT_REG(stackptr->size);
+ BAMBOO_DEBUGPRINT_REG(stackptr->next);
+ BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
+#endif
+ for(i=0; i<stackptr->size; i++) {
+ if(stackptr->array[i] != NULL) {
+ markObj(stackptr->array[i]);
+ }
+ }
+ stackptr=stackptr->next;
+ }
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe503);
+#endif
+ // enqueue objectsets
+ if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
+ for(i=0; i<NUMCLASSES; i++) {
+ struct parameterwrapper ** queues =
+ objectqueues[BAMBOO_NUM_OF_CORE][i];
+ int length = numqueues[BAMBOO_NUM_OF_CORE][i];
+ for(j = 0; j < length; ++j) {
+ struct parameterwrapper * parameter = queues[j];
+ struct ObjectHash * set=parameter->objectset;
+ struct ObjectNode * ptr=set->listhead;
+ while(ptr!=NULL) {
+ markObj((void *)ptr->key);
+ ptr=ptr->lnext;
+ }
+ }
+ }
+ }
+
+ // euqueue current task descriptor
+ if(currtpd != NULL) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe504);
+#endif
+ for(i=0; i<currtpd->numParameters; i++) {
+ markObj(currtpd->parameterArray[i]);
+ }
+ }
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe505);
+#endif
+ // euqueue active tasks
+ if(activetasks != NULL) {
+ struct genpointerlist * ptr=activetasks->list;
+ while(ptr!=NULL) {
+ struct taskparamdescriptor *tpd=ptr->src;
+ int i;
+ for(i=0; i<tpd->numParameters; i++) {
+ markObj(tpd->parameterArray[i]);
+ }
+ ptr=ptr->inext;
+ }
+ }
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe506);
+#endif
+ // enqueue cached transferred obj
+ struct QueueItem * tmpobjptr = getHead(&objqueue);
+ while(tmpobjptr != NULL) {
+ struct transObjInfo * objInfo =
+ (struct transObjInfo *)(tmpobjptr->objectptr);
+ markObj(objInfo->objptr);
+ tmpobjptr = getNextQueueItem(tmpobjptr);
+ }
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe507);
+#endif
+ // enqueue cached objs to be transferred
+ struct QueueItem * item = getHead(totransobjqueue);
+ while(item != NULL) {
+ struct transObjInfo * totransobj =
+ (struct transObjInfo *)(item->objectptr);
+ markObj(totransobj->objptr);
+ item = getNextQueueItem(item);
+ } // while(item != NULL)
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe508);
+#endif
+ // enqueue lock related info
+ for(i = 0; i < runtime_locklen; ++i) {
+ markObj((void *)(runtime_locks[i].redirectlock));
+ if(runtime_locks[i].value != NULL) {
+ markObj((void *)(runtime_locks[i].value));
+ }
+ }
+
+} // void tomark(struct garbagelist * stackptr)
+
+inline void mark(bool isfirst,
+ struct garbagelist * stackptr) {
+#ifdef DEBUG
+ if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed01);
+#endif
+ if(isfirst) {
+#ifdef DEBUG
+ if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed02);
+#endif
+ // enqueue root objs
+ tomark(stackptr);
+ gccurr_heaptop = 0; // record the size of all active objs in this core
+ // aligned but does not consider block boundaries
+ gcmarkedptrbound = 0;
+ }
+#ifdef DEBUG
+ if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed03);
+#endif
+ int isize = 0;
+ bool checkfield = true;
+ bool sendStall = false;
+ // mark phase
+ while(MARKPHASE == gcphase) {
+#ifdef DEBUG
+ if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed04);
+#endif
+ while(true) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ bool hasItems = gc_moreItems2_I();
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed05);
+#endif
+ if(!hasItems) {
+ break;
+ }
+ sendStall = false;
+ gcbusystatus = true;
+ checkfield = true;
+ void * ptr = gc_dequeue2_I();
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(ptr);
+#endif
+ int size = 0;
+ int isize = 0;
+ int type = 0;
+ // check if it is a shared obj
+ if(ISSHAREDOBJ(ptr)) {
+ // a shared obj, check if it is a local obj on this core
+ int host = hostcore(ptr);
+ bool islocal = (host == BAMBOO_NUM_OF_CORE);
+ if(islocal) {
+ bool isnotmarked = ((((int *)ptr)[6] & DISCOVERED) != 0);
+ if(isLarge(ptr, &type, &size) && isnotmarked) {
+ // ptr is a large object and not marked or enqueued
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xecec);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
+#endif
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
+ gcnumlobjs++;
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ // mark this obj
+ ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
+ } else if(isnotmarked) {
+ // ptr is an unmarked active object on this core
+ ALIGNSIZE(size, &isize);
+ gccurr_heaptop += isize;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xaaaa);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(isize);
+ BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
+#endif
+ // mark this obj
+ ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
+
+ if(ptr + size > gcmarkedptrbound) {
+ gcmarkedptrbound = ptr + size;
+ } // if(ptr + size > gcmarkedptrbound)
+ } else {
+ // ptr is not an active obj or has been marked
+ checkfield = false;
+ } // if(isLarge(ptr, &type, &size)) else ...
+ } /* can never reach here
+ else {
+#ifdef DEBUG
+ if(BAMBOO_NUM_OF_CORE == 0) {
+ BAMBOO_DEBUGPRINT(0xbbbb);
+ BAMBOO_DEBUGPRINT_REG(host);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ }
+#endif
+ // 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))
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed06);
+#endif
+
+ if(checkfield) {
+ // scan all pointers in ptr
+ unsigned INTPTR * pointer;
+ pointer=pointerarray[type];
+ if (pointer==0) {
+ /* Array of primitives */
+ /* Do nothing */
+ } else if (((INTPTR)pointer)==1) {
+ /* Array of pointers */
+ struct ArrayObject *ao=(struct ArrayObject *) ptr;
+ int length=ao->___length___;
+ int j;
+ for(j=0; j<length; j++) {
+ void *objptr =
+ ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
+ markObj(objptr);
+ }
+ } else {
+ INTPTR size=pointer[0];
+ int i;
+ for(i=1; i<=size; i++) {
+ unsigned int offset=pointer[i];
+ void * objptr=*((void **)(((char *)ptr)+offset));
+ markObj(objptr);
+ }
+ } // if (pointer==0) else if ... else ...
+ } // if(checkfield)
+ } // while(gc_moreItems2())
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed07);
+#endif
+ gcbusystatus = false;
+ // send mark finish msg to core coordinator
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed08);
+#endif
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ gcnumsendobjs[gcnumsrobjs_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
+ gcnumreceiveobjs[gcnumsrobjs_index][BAMBOO_NUM_OF_CORE]=
+ gcself_numreceiveobjs;
+ gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
+ } else {
+ if(!sendStall) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed09);
+#endif
+ send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
+ gcself_numsendobjs, gcself_numreceiveobjs, false);
+ sendStall = true;
+ }
+ } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed0a);
+#endif
+
+ if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xed0b);
+#endif
+ return;
+ }
+ } // while(MARKPHASE == gcphase)
+} // mark()
+
+inline void compact2Heaptophelper_I(int coren,
+ int* p,
+ int* numblocks,
+ int* remain) {
+ int b;
+ int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
+ if(STARTUPCORE == coren) {
+ gctomove = true;
+ gcmovestartaddr = *p;
+ gcdstcore = gctopcore;
+ gcblock2fill = *numblocks + 1;
+ } else {
+ send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(coren);
+ BAMBOO_DEBUGPRINT_REG(gctopcore);
+ BAMBOO_DEBUGPRINT_REG(*p);
+ BAMBOO_DEBUGPRINT_REG(*numblocks+1);
+#endif
+ if(memneed < *remain) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd104);
+#endif
+ *p = *p + memneed;
+ gcrequiredmems[coren] = 0;
+ gcloads[gctopcore] += memneed;
+ *remain = *remain - memneed;
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd105);
+#endif
+ // next available block
+ *p = *p + *remain;
+ gcfilledblocks[gctopcore] += 1;
+ int newbase = 0;
+ BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
+ gcloads[gctopcore] = newbase;
+ gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
+ gcstopblock[gctopcore]++;
+ gctopcore = NEXTTOPCORE(gctopblock);
+ gctopblock++;
+ *numblocks = gcstopblock[gctopcore];
+ *p = gcloads[gctopcore];
+ BLOCKINDEX(*p, &b);
+ *remain=(b<NUMCORES4GC) ?
+ ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
+ : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd106);
+ BAMBOO_DEBUGPRINT_REG(gctopcore);
+ BAMBOO_DEBUGPRINT_REG(*p);
+ BAMBOO_DEBUGPRINT_REG(b);
+ BAMBOO_DEBUGPRINT_REG(*remain);
+#endif
+ } // if(memneed < remain)
+ gcmovepending--;
+} // void compact2Heaptophelper_I(int, int*, int*, int*)
+
+inline void compact2Heaptop() {
+ // no cores with spare mem and some cores are blocked with pending move
+ // find the current heap top and make them move to the heap top
+ int p;
+ int numblocks = gcfilledblocks[gctopcore];
+ //BASEPTR(gctopcore, numblocks, &p);
+ p = gcloads[gctopcore];
+ int b;
+ BLOCKINDEX(p, &b);
+ int remain = (b<NUMCORES4GC) ?
+ ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
+ : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
+ // check if the top core finishes
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gccorestatus[gctopcore] != 0) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd101);
+ BAMBOO_DEBUGPRINT_REG(gctopcore);
+#endif
+ // let the top core finishes its own work first
+ compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ return;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd102);
+ BAMBOO_DEBUGPRINT_REG(gctopcore);
+ BAMBOO_DEBUGPRINT_REG(p);
+ BAMBOO_DEBUGPRINT_REG(b);
+ BAMBOO_DEBUGPRINT_REG(remain);
+#endif
+ for(int i = 0; i < NUMCORES4GC; i++) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd103);
+#endif
+ compact2Heaptophelper_I(i, &p, &numblocks, &remain);
+ if(gccorestatus[gctopcore] != 0) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd101);
+ BAMBOO_DEBUGPRINT_REG(gctopcore);
+#endif
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ // the top core is not free now
+ return;
+ }
+ } // if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0))
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // for(i = 0; i < NUMCORES4GC; i++)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xd106);
+#endif
+} // void compact2Heaptop()
+
+inline void resolvePendingMoveRequest() {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeb01);
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeeee);
+ for(int k = 0; k < NUMCORES4GC; k++) {
+ BAMBOO_DEBUGPRINT(0xf000+k);
+ BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
+ BAMBOO_DEBUGPRINT_REG(gcloads[k]);
+ BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
+ BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
+ }
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+ int i;
+ int j;
+ bool nosparemem = true;
+ bool haspending = false;
+ bool hasrunning = false;
+ bool noblock = false;
+ int dstcore = 0; // the core who need spare mem
+ int sourcecore = 0; // the core who has spare mem
+ for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
+ if(nosparemem) {
+ // check if there are cores with spare mem
+ if(gccorestatus[i] == 0) {
+ // finished working, check if it still have spare mem
+ if(gcfilledblocks[i] < gcstopblock[i]) {
+ // still have spare mem
+ nosparemem = false;
+ sourcecore = i;
+ } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
+ }
+ i++;
+ } // if(nosparemem)
+ if(!haspending) {
+ if(gccorestatus[j] != 0) {
+ // not finished, check if it has pending move requests
+ if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
+ dstcore = j;
+ haspending = true;
+ } else {
+ hasrunning = true;
+ } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
+ } // if(gccorestatus[i] == 0) else ...
+ j++;
+ } // if(!haspending)
+ if(!nosparemem && haspending) {
+ // find match
+ int tomove = 0;
+ int startaddr = 0;
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
+ gcrequiredmems[dstcore],
+ &tomove,
+ &startaddr);
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeb02);
+ BAMBOO_DEBUGPRINT_REG(sourcecore);
+ BAMBOO_DEBUGPRINT_REG(dstcore);
+ BAMBOO_DEBUGPRINT_REG(startaddr);
+ BAMBOO_DEBUGPRINT_REG(tomove);
+#endif
+ if(STARTUPCORE == dstcore) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeb03);
+#endif
+ gcdstcore = sourcecore;
+ gctomove = true;
+ gcmovestartaddr = startaddr;
+ gcblock2fill = tomove;
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeb04);
+#endif
+ send_msg_4(dstcore, GCMOVESTART, sourcecore,
+ startaddr, tomove, false);
+ }
+ gcmovepending--;
+ nosparemem = true;
+ haspending = false;
+ noblock = true;
+ }
+ } // for(i = 0; i < NUMCORES4GC; i++)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcccc);
+ BAMBOO_DEBUGPRINT_REG(hasrunning);
+ BAMBOO_DEBUGPRINT_REG(haspending);
+ BAMBOO_DEBUGPRINT_REG(noblock);
+#endif
+
+ if(!hasrunning && !noblock) {
+ gcphase = SUBTLECOMPACTPHASE;
+ compact2Heaptop();
+ }
+
+} // void resovePendingMoveRequest()
+
+struct moveHelper {
+ int numblocks; // block num for heap
+ INTPTR base; // base virtual address of current heap block
+ INTPTR ptr; // virtual address of current heap top
+ int offset; // offset in current heap block
+ int blockbase; // virtual address of current small block to check
+ int blockbound; // bound virtual address of current small blcok
+ int sblockindex; // index of the small blocks
+ int top; // real size of current heap block to check
+ int bound; // bound size of current heap block to check
+}; // struct moveHelper
+
+// If out of boundary of valid shared memory, return false, else return true
+inline bool nextSBlock(struct moveHelper * orig) {
+ orig->blockbase = orig->blockbound;
+ bool sbchanged = false;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xecc0);
+ BAMBOO_DEBUGPRINT_REG(orig->blockbase);
+ BAMBOO_DEBUGPRINT_REG(orig->blockbound);
+ BAMBOO_DEBUGPRINT_REG(orig->bound);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+#endif
+outernextSBlock:
+ // check if across a big block
+ // TODO now do not zero out the whole memory, maybe the last two conditions
+ // are useless now
+ if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)
+ || ((orig->ptr != NULL) && (*((int*)orig->ptr))==0)
+ || ((*((int*)orig->blockbase))==0)) {
+innernextSBlock:
+ // end of current heap block, jump to next one
+ orig->numblocks++;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xecc1);
+ BAMBOO_DEBUGPRINT_REG(orig->numblocks);
+#endif
+ BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(orig->base);
+#endif
+ if(orig->base >= gcbaseva + BAMBOO_SHARED_MEM_SIZE) {
+ // out of boundary
+ orig->ptr = orig->base; // set current ptr to out of boundary too
+ return false;
+ }
+ //orig->bound = orig->base + BAMBOO_SMEM_SIZE;
+ orig->blockbase = orig->base;
+ orig->sblockindex = (orig->blockbase-gcbaseva)/BAMBOO_SMEM_SIZE;
+ sbchanged = true;
+ int blocknum = 0;
+ BLOCKINDEX(orig->base, &blocknum);
+ if(bamboo_smemtbl[blocknum] == 0) {
+ // goto next block
+ goto innernextSBlock;
+ }
+ // check the bamboo_smemtbl to decide the real bound
+ orig->bound = orig->base + bamboo_smemtbl[blocknum];
+ } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
+ orig->sblockindex += 1;
+ sbchanged = true;
+ } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
+
+ // check if this sblock should be skipped or have special start point
+ if(gcsbstarttbl[orig->sblockindex] == -1) {
+ // goto next sblock
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xecc2);
+#endif
+ orig->sblockindex += 1;
+ orig->blockbase += BAMBOO_SMEM_SIZE;
+ goto outernextSBlock;
+ } else if((gcsbstarttbl[orig->sblockindex] != 0)
+ && (sbchanged)) {
+ // the first time to access this SBlock
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xecc3);
+#endif
+ // not start from the very beginning
+ orig->blockbase = gcsbstarttbl[orig->sblockindex];
+ } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
+
+ // setup information for this sblock
+ orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
+ orig->offset = BAMBOO_CACHE_LINE_SIZE;
+ orig->ptr = orig->blockbase + orig->offset;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xecc4);
+ BAMBOO_DEBUGPRINT_REG(orig->base);
+ BAMBOO_DEBUGPRINT_REG(orig->bound);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT_REG(orig->blockbound);
+ BAMBOO_DEBUGPRINT_REG(orig->blockbase);
+ BAMBOO_DEBUGPRINT_REG(orig->offset);
+#endif
+ if(orig->ptr >= orig->bound) {
+ // met a lobj, move to next block
+ goto innernextSBlock;
+ }
+
+ return true;
+} // bool nextSBlock(struct moveHelper * orig)
+
+// return false if there are no available data to compact
+inline bool initOrig_Dst(struct moveHelper * orig,
+ struct moveHelper * to) {
+ // init the dst ptr
+ to->numblocks = 0;
+ to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
+ to->bound = BAMBOO_SMEM_SIZE_L;
+ BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xef01);
+ BAMBOO_DEBUGPRINT_REG(to->base);
+#endif
+ to->ptr = to->base + to->offset;
+
+ // init the orig ptr
+ orig->numblocks = 0;
+ orig->base = to->base;
+ int blocknum = 0;
+ BLOCKINDEX(orig->base, &blocknum);
+ // check the bamboo_smemtbl to decide the real bound
+ orig->bound = orig->base + bamboo_smemtbl[blocknum];
+ orig->blockbase = orig->base;
+ orig->sblockindex = (orig->base - gcbaseva) / BAMBOO_SMEM_SIZE;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xef02);
+ BAMBOO_DEBUGPRINT_REG(orig->base);
+ BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
+ BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
+ BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
+#endif
+
+ if(gcsbstarttbl[orig->sblockindex] == -1) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xef03);
+#endif
+ // goto next sblock
+ orig->blockbound =
+ gcbaseva+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
+ return nextSBlock(orig);
+ } else if(gcsbstarttbl[orig->sblockindex] != 0) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xef04);
+#endif
+ orig->blockbase = gcsbstarttbl[orig->sblockindex];
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xef05);
+#endif
+ orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
+ orig->offset = BAMBOO_CACHE_LINE_SIZE;
+ orig->ptr = orig->blockbase + orig->offset;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xef06);
+ BAMBOO_DEBUGPRINT_REG(orig->base);
+#endif
+ return true;
+} // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
+
+inline void nextBlock(struct moveHelper * to) {
+ to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
+ to->bound += BAMBOO_SMEM_SIZE;
+ to->numblocks++;
+ BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
+ to->offset = BAMBOO_CACHE_LINE_SIZE;
+ to->ptr = to->base + to->offset;
+} // void nextBlock(struct moveHelper * to)
+
+// endaddr does not contain spaces for headers
+inline bool moveobj(struct moveHelper * orig,
+ struct moveHelper * to,
+ int stopblock) {
+ if(stopblock == 0) {
+ return true;
+ }
+
+#ifdef DEBUG
+ //if((int)orig->ptr > 0x10767a00) {
+ BAMBOO_DEBUGPRINT(0xe201);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT_REG(to->ptr);
+ //}
+#endif
+
+ int type = 0;
+ int size = 0;
+ int mark = 0;
+ int isize = 0;
+innermoveobj:
+ while((char)(*((int*)(orig->ptr))) == (char)(-2)) {
+ orig->ptr = (int*)(orig->ptr) + 1;
+ }
+ if((orig->ptr >= orig->bound) || (orig->ptr == orig->blockbound)) {
+ if(!nextSBlock(orig)) {
+ // finished, no more data
+ return true;
+ }
+ goto innermoveobj;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe202);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT(((int *)(orig->ptr))[0]);
+#endif
+ // check the obj's type, size and mark flag
+ type = ((int *)(orig->ptr))[0];
+ size = 0;
+ if(type == 0) {
+ // end of this block, go to next one
+ if(!nextSBlock(orig)) {
+ // finished, no more data
+ return true;
+ }
+ goto innermoveobj;
+ } else if(type < NUMCLASSES) {
+ // a normal object
+ size = classsize[type];
+ } else {
+ // an array
+ struct ArrayObject *ao=(struct ArrayObject *)(orig->ptr);
+ int elementsize=classsize[type];
+ int length=ao->___length___;
+ size=sizeof(struct ArrayObject)+length*elementsize;
+ }
+ mark = ((int *)(orig->ptr))[6];
+ bool isremote = ((((int *)(orig->ptr))[6] & REMOTEM) != 0);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe203);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT_REG(size);
+#endif
+ ALIGNSIZE(size, &isize); // no matter is the obj marked or not
+ // should be able to across it
+ if((mark & MARKED) != 0) {
+#ifdef DEBUG
+//if((int)orig->ptr > 0x10760f00) {
+ BAMBOO_DEBUGPRINT(0xe204);
+//}
+#endif
+#ifdef GC_PROFILE
+ gc_num_liveobj++;
+#endif
+ // marked obj, copy it to current heap top
+ // check to see if remaining space is enough
+ if(to->top + isize > to->bound) {
+ // fill 0 indicating the end of this block
+ BAMBOO_MEMSET_WH(to->ptr, '\0', to->bound - to->top);
+ // fill the header of this block and then go to next block
+ to->offset += to->bound - to->top;
+ BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
+ (*((int*)(to->base))) = to->offset;
+ nextBlock(to);
+ if(stopblock == to->numblocks) {
+ // already fulfilled the block
+ return true;
+ } // if(stopblock == to->numblocks)
+ } // if(to->top + isize > to->bound)
+ // set the mark field to 2, indicating that this obj has been moved
+ // and need to be flushed
+ ((int *)(orig->ptr))[6] = COMPACTED;
+ if(to->ptr != orig->ptr) {
+ if((int)(orig->ptr) < (int)(to->ptr)+size) {
+ memmove(to->ptr, orig->ptr, size);
+ } else {
+ //BAMBOO_WRITE_HINT_CACHE(to->ptr, size);
+ memcpy(to->ptr, orig->ptr, size);
+ }
+ // fill the remaining space with -2
+ BAMBOO_MEMSET_WH(to->ptr+size, -2, isize-size);
+ }
+ // store mapping info
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashadd_I(gcpointertbl, orig->ptr, to->ptr);
+#else
+ mgchashInsert_I(gcpointertbl, orig->ptr, to->ptr);
+#endif
+ //MGCHashadd_I(gcpointertbl, orig->ptr, to->ptr);
+ if(isremote) {
+#ifdef GC_PROFILE
+ //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
+#endif
+ // add to the sharedptbl
+ if(gcsharedptbl != NULL) {
+ //GCSharedHashadd_I(gcsharedptbl, orig->ptr, to->ptr);
+ mgcsharedhashInsert_I(gcsharedptbl, orig->ptr, to->ptr);
+ //num_mapinforequest++; // TODO
+ }
+#ifdef GC_PROFILE
+ //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
+#endif
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ //}
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xcdce);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT_REG(to->ptr);
+ BAMBOO_DEBUGPRINT_REG(isize);
+#endif
+ gccurr_heaptop -= isize;
+ to->ptr += isize;
+ to->offset += isize;
+ to->top += isize;
+ if(to->top == to->bound) {
+ // fill the header of this block and then go to next block
+ BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
+ (*((int*)(to->base))) = to->offset;
+ nextBlock(to);
+ }
+ } // if(mark == 1)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe205);
+#endif
+ // move to next obj
+ orig->ptr += size;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(isize);
+ BAMBOO_DEBUGPRINT_REG(size);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT_REG(orig->bound);
+#endif
+ if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe206);
+#endif
+ if(!nextSBlock(orig)) {
+ // finished, no more data
+ return true;
+ }
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe207);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+#endif
+ return false;
+} //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
+
+// should be invoked with interrupt closed
+inline int assignSpareMem_I(int sourcecore,
+ int * requiredmem,
+ int * tomove,
+ int * startaddr) {
+ int b = 0;
+ BLOCKINDEX(gcloads[sourcecore], &b);
+ int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
+ : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
+ int remain = boundptr - gcloads[sourcecore];
+ int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
+ *startaddr = gcloads[sourcecore];
+ *tomove = gcfilledblocks[sourcecore] + 1;
+ if(memneed < remain) {
+ gcloads[sourcecore] += memneed;
+ return 0;
+ } else {
+ // next available block
+ gcfilledblocks[sourcecore] += 1;
+ int newbase = 0;
+ BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
+ gcloads[sourcecore] = newbase;
+ return requiredmem-remain;
+ }
+} // int assignSpareMem_I(int ,int * , int * , int * )
+
+// should be invoked with interrupt closed
+inline bool gcfindSpareMem_I(int * startaddr,
+ int * tomove,
+ int * dstcore,
+ int requiredmem,
+ int requiredcore) {
+ for(int k = 0; k < NUMCORES4GC; k++) {
+ if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
+ // check if this stopped core has enough mem
+ assignSpareMem_I(k, requiredmem, tomove, startaddr);
+ *dstcore = k;
+ return true;
+ }
+ }
+ // if can not find spare mem right now, hold the request
+ gcrequiredmems[requiredcore] = requiredmem;
+ gcmovepending++;
+ return false;
+} //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
+
+inline bool compacthelper(struct moveHelper * orig,
+ struct moveHelper * to,
+ int * filledblocks,
+ int * heaptopptr,
+ bool * localcompact) {
+ // scan over all objs in this block, compact the marked objs
+ // loop stop when finishing either scanning all active objs or
+ // fulfilled the gcstopblock
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe101);
+ BAMBOO_DEBUGPRINT_REG(gcblock2fill);
+ BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
+#endif
+innercompact:
+ while(orig->ptr < gcmarkedptrbound) {
+ bool stop = moveobj(orig, to, gcblock2fill);
+ if(stop) {
+ break;
+ }
+ }
+ // if no objs have been compact, do nothing,
+ // otherwise, fill the header of this block
+ if(to->offset > BAMBOO_CACHE_LINE_SIZE) {
+ BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
+ (*((int*)(to->base))) = to->offset;
+ } else {
+ to->offset = 0;
+ to->ptr = to->base;
+ to->top -= BAMBOO_CACHE_LINE_SIZE;
+ } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
+ if(*localcompact) {
+ *heaptopptr = to->ptr;
+ *filledblocks = to->numblocks;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe102);
+ BAMBOO_DEBUGPRINT_REG(orig->ptr);
+ BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
+ BAMBOO_DEBUGPRINT_REG(*heaptopptr);
+ BAMBOO_DEBUGPRINT_REG(*filledblocks);
+ BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
+#endif
+
+ // send msgs to core coordinator indicating that the compact is finishing
+ // send compact finish message to core coordinator
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
+ gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
+ if(orig->ptr < gcmarkedptrbound) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe103);
+#endif
+ // ask for more mem
+ gctomove = false;
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
+ gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe104);
+#endif
+ gctomove = true;
+ } else {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe105);
+#endif
+ return false;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe106);
+#endif
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ gctomove = false;
+ return true;
+ }
+ } else {
+ if(orig->ptr < gcmarkedptrbound) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe107);
+#endif
+ // ask for more mem
+ gctomove = false;
+ send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
+ *filledblocks, *heaptopptr, gccurr_heaptop, false);
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe108);
+ BAMBOO_DEBUGPRINT_REG(*heaptopptr);
+#endif
+ // finish compacting
+ send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
+ *filledblocks, *heaptopptr, 0, false);
+ }
+ } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
+
+ if(orig->ptr < gcmarkedptrbound) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe109);
+#endif
+ // still have unpacked obj
+ while(true) {
+ if(gctomove) {
+ break;
+ }
+ }
+ ;
+ gctomove = false;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe10a);
+#endif
+
+ to->ptr = gcmovestartaddr;
+ to->numblocks = gcblock2fill - 1;
+ to->bound = (to->numblocks==0) ?
+ BAMBOO_SMEM_SIZE_L :
+ BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
+ BASEPTR(gcdstcore, to->numblocks, &(to->base));
+ to->offset = to->ptr - to->base;
+ to->top = (to->numblocks==0) ?
+ (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
+ to->base = to->ptr;
+ to->offset = BAMBOO_CACHE_LINE_SIZE;
+ to->ptr += to->offset; // for header
+ to->top += to->offset;
+ if(gcdstcore == BAMBOO_NUM_OF_CORE) {
+ *localcompact = true;
+ } else {
+ *localcompact = false;
+ }
+ goto innercompact;
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe10b);
+#endif
+ return true;
+} // void compacthelper()
+
+inline void compact() {
+ if(COMPACTPHASE != gcphase) {
+ BAMBOO_EXIT(0xb102);
+ }
+
+ // initialize pointers for comapcting
+ struct moveHelper * orig =
+ (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
+ struct moveHelper * to =
+ (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
+
+ if(!initOrig_Dst(orig, to)) {
+ // no available data to compact
+ // send compact finish msg to STARTUP core
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe001);
+ BAMBOO_DEBUGPRINT_REG(to->base);
+#endif
+ send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
+ 0, to->base, 0, false);
+ RUNFREE(orig);
+ RUNFREE(to);
+ return;
+ }
+
+ int filledblocks = 0;
+ INTPTR heaptopptr = 0;
+ bool localcompact = true;
+ compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
+
+ RUNFREE(orig);
+ RUNFREE(to);
+} // compact()
+
+// if return NULL, means
+// 1. objptr is NULL
+// 2. objptr is not a shared obj
+// in these cases, remain the original value is OK
+inline void * flushObj(void * objptr) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe401);
+#endif
+ if(objptr == NULL) {
+ return NULL;
+ }
+ void * dstptr = NULL;
+ if(ISSHAREDOBJ(objptr)) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe402);
+ BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+ // a shared obj ptr, change to new address
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef GC_PROFILE
+ //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
+#endif
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashget(gcpointertbl, objptr, &dstptr);
+#else
+ dstptr = mgchashSearch(gcpointertbl, objptr);
+#endif
+ //MGCHashget(gcpointertbl, objptr, &dstptr);
+#ifdef GC_PROFILE
+ //flushstalltime += BAMBOO_GET_EXE_TIME()-ttime;
+#endif
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(dstptr);
+#endif
+
+ if(NULL == dstptr) {
+ // no mapping info
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe403);
+ BAMBOO_DEBUGPRINT_REG(objptr);
+ BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
+#endif
+ if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) {
+ // error! the obj is right on this core, but cannot find it
+ //BAMBOO_DEBUGPRINT(0xecec);
+ BAMBOO_DEBUGPRINT_REG(objptr);
+ BAMBOO_EXIT(0xb103);
+ // assume that the obj has not been moved, use the original address
+ //dstptr = objptr;
+ } else {
+ int hostc = hostcore(objptr);
+#ifdef GC_PROFILE
+ //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
+#endif
+ // check the corresponsing sharedptbl
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ //struct GCSharedHash * sptbl = gcrpointertbls[hostcore(objptr)];
+ mgcsharedhashtbl_t * sptbl = gcrpointertbls[hostc];
+ if(sptbl != NULL) {
+ //GCSharedHashget(sptbl, (int)objptr, &dstptr);
+ dstptr = mgcsharedhashSearch(sptbl, (int)objptr);
+ if(dstptr != NULL) {
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashadd_I(gcpointertbl, (int)objptr, (int)dstptr);
+#else
+ mgchashInsert_I(gcpointertbl, (int)objptr, (int)dstptr);
+#endif
+ }
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef GC_PROFILE
+ //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
+#endif
+
+ if(dstptr == NULL) {
+ // still can not get the mapping info,
+ // send msg to host core for the mapping info
+ gcobj2map = (int)objptr;
+ gcismapped = false;
+ gcmappedobj = NULL;
+#ifdef GC_PROFILE
+ // TODO
+ //num_mapinforequest++;
+ //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
+#endif
+#ifdef GC_PROFILE
+ //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
+#endif
+ // the first time require the mapping, send msg to the hostcore
+ // for the mapping info
+ send_msg_3(hostc, GCMAPREQUEST, (int)objptr,
+ BAMBOO_NUM_OF_CORE, false);
+ while(true) {
+ if(gcismapped) {
+ break;
+ }
+ }
+#ifdef GC_PROFILE
+ //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
+#endif
+#ifdef GC_PROFILE
+ // TODO
+ //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
+#endif
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashget(gcpointertbl, objptr, &dstptr);
+#else
+ dstptr = mgchashSearch(gcpointertbl, objptr);
+#endif
+ //MGCHashget(gcpointertbl, objptr, &dstptr);
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // if(dstptr == NULL)
+ } // if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) else ...
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(dstptr);
+#endif
+ } // if(NULL == dstptr)
+ } // if(ISSHAREDOBJ(objptr))
+ // if not a shared obj, return NULL to indicate no need to flush
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe404);
+#endif
+ return dstptr;
+} // void flushObj(void * objptr)
+
+inline void flushRuntimeObj(struct garbagelist * stackptr) {
+ int i,j;
+ // flush current stack
+ while(stackptr!=NULL) {
+ for(i=0; i<stackptr->size; i++) {
+ if(stackptr->array[i] != NULL) {
+ void * dst = flushObj(stackptr->array[i]);
+ if(dst != NULL) {
+ stackptr->array[i] = dst;
+ }
+ }
+ }
+ stackptr=stackptr->next;
+ }
+
+ // flush objectsets
+ if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
+ for(i=0; i<NUMCLASSES; i++) {
+ struct parameterwrapper ** queues =
+ objectqueues[BAMBOO_NUM_OF_CORE][i];
+ int length = numqueues[BAMBOO_NUM_OF_CORE][i];
+ for(j = 0; j < length; ++j) {
+ struct parameterwrapper * parameter = queues[j];
+ struct ObjectHash * set=parameter->objectset;
+ struct ObjectNode * ptr=set->listhead;
+ while(ptr!=NULL) {
+ void * dst = flushObj((void *)ptr->key);
+ if(dst != NULL) {
+ ptr->key = dst;
+ }
+ ptr=ptr->lnext;
+ }
+ ObjectHashrehash(set);
+ }
+ }
+ }
+
+ // flush current task descriptor
+ if(currtpd != NULL) {
+ for(i=0; i<currtpd->numParameters; i++) {
+ void * dst = flushObj(currtpd->parameterArray[i]);
+ if(dst != NULL) {
+ currtpd->parameterArray[i] = dst;
+ }
+ }
+ }
+
+ // flush active tasks
+ if(activetasks != NULL) {
+ struct genpointerlist * ptr=activetasks->list;
+ while(ptr!=NULL) {
+ struct taskparamdescriptor *tpd=ptr->src;
+ int i;
+ for(i=0; i<tpd->numParameters; i++) {
+ void * dst = flushObj(tpd->parameterArray[i]);
+ if(dst != NULL) {
+ tpd->parameterArray[i] = dst;
+ }
+ }
+ ptr=ptr->inext;
+ }
+ genrehash(activetasks);
+ }
+
+ // flush cached transferred obj
+ struct QueueItem * tmpobjptr = getHead(&objqueue);
+ while(tmpobjptr != NULL) {
+ struct transObjInfo * objInfo =
+ (struct transObjInfo *)(tmpobjptr->objectptr);
+ void * dst = flushObj(objInfo->objptr);
+ if(dst != NULL) {
+ objInfo->objptr = dst;
+ }
+ tmpobjptr = getNextQueueItem(tmpobjptr);
+ }
+
+ // flush cached objs to be transferred
+ struct QueueItem * item = getHead(totransobjqueue);
+ while(item != NULL) {
+ struct transObjInfo * totransobj =
+ (struct transObjInfo *)(item->objectptr);
+ void * dst = flushObj(totransobj->objptr);
+ if(dst != NULL) {
+ totransobj->objptr = dst;
+ }
+ item = getNextQueueItem(item);
+ } // while(item != NULL)
+
+ // enqueue lock related info
+ for(i = 0; i < runtime_locklen; ++i) {
+ void * dst = flushObj(runtime_locks[i].redirectlock);
+ if(dst != NULL) {
+ runtime_locks[i].redirectlock = (int)dst;
+ }
+ if(runtime_locks[i].value != NULL) {
+ void * dst=flushObj(runtime_locks[i].value);
+ if(dst != NULL) {
+ runtime_locks[i].value = (int)dst;
+ }
+ }
+ }
+
+} // void flushRuntimeObj(struct garbagelist * stackptr)
+
+inline void transmappinginfo() {
+ // broadcast the sharedptbl pointer
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ if(i != BAMBOO_NUM_OF_CORE) {
+ send_msg_3(i, GCMAPTBL, gcsharedptbl, BAMBOO_NUM_OF_CORE, false);
+ }
+ }
+
+ if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
+ send_msg_2(STARTUPCORE, GCFINISHMAPINFO, BAMBOO_NUM_OF_CORE, false);
+ }
+}
+
+inline void flush(struct garbagelist * stackptr) {
+#ifdef GC_PROFILE
+ /* TODO if(BAMBOO_NUM_OF_CORE == 0) {
+ BAMBOO_DEBUGPRINT(0xcccc);
+ BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
+ }*/
+#endif
+
+ flushRuntimeObj(stackptr);
+#ifdef GC_PROFILE
+ // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
+#endif
+
+ while(true) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ bool hasItems = gc_moreItems_I();
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ if(!hasItems) {
+ break;
+ }
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe301);
+#endif
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ void * ptr = gc_dequeue_I();
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ if(ISSHAREDOBJ(ptr)) {
+ // should be a local shared obj and should have mapping info
+ ptr = flushObj(ptr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe302);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(tptr);
+ BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
+#endif
+ if(ptr == NULL) {
+ BAMBOO_EXIT(0xb105);
+ }
+ } // if(ISSHAREDOBJ(ptr))
+ if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED)) {
+ int type = ((int *)(ptr))[0];
+ // scan all pointers in ptr
+ unsigned INTPTR * pointer;
+ pointer=pointerarray[type];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe303);
+ BAMBOO_DEBUGPRINT_REG(pointer);
+#endif
+ if (pointer==0) {
+ /* Array of primitives */
+ /* Do nothing */
+ } else if (((INTPTR)pointer)==1) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe304);
+#endif
+ /* Array of pointers */
+ struct ArrayObject *ao=(struct ArrayObject *) ptr;
+ int length=ao->___length___;
+ int j;
+ for(j=0; j<length; j++) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe305);
+#endif
+ void *objptr=
+ ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+ if(objptr != NULL) {
+ void * dst = flushObj(objptr);
+ if(dst != NULL) {
+ ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
+ }
+ }
+ }
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe306);
+#endif
+ INTPTR size=pointer[0];
+ int i;
+ for(i=1; i<=size; i++) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe307);
+#endif
+ unsigned int offset=pointer[i];
+ void * objptr=*((void **)(((char *)ptr)+offset));
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+ if(objptr != NULL) {
+ void * dst = flushObj(objptr);
+ if(dst != NULL) {
+ *((void **)(((char *)ptr)+offset)) = dst;
+ }
+ }
+ } // for(i=1; i<=size; i++)
+ } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
+ // restore the mark field, indicating that this obj has been flushed
+ if(ISSHAREDOBJ(ptr)) {
+ ((int *)(ptr))[6] = INIT;
+ }
+ } // if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED))
+ } // while(gc_moreItems())
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe308);
+#endif
+#ifdef GC_PROFILE
+ // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
+#endif
+
+ // TODO bug here: the startup core contains all lobjs' info, thus all the
+ // lobjs are flushed in sequence.
+ // flush lobjs
+ while(gc_lobjmoreItems_I()) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe309);
+#endif
+ void * ptr = gc_lobjdequeue_I(NULL, NULL);
+ ptr = flushObj(ptr);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe30a);
+ BAMBOO_DEBUGPRINT_REG(ptr);
+ BAMBOO_DEBUGPRINT_REG(tptr);
+ BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
+#endif
+ if(ptr == NULL) {
+ BAMBOO_EXIT(0xb106);
+ }
+ if(((int *)(ptr))[6] == COMPACTED) {
+ int type = ((int *)(ptr))[0];
+ // scan all pointers in ptr
+ unsigned INTPTR * pointer;
+ pointer=pointerarray[type];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe30b);
+ BAMBOO_DEBUGPRINT_REG(pointer);
+#endif
+ if (pointer==0) {
+ /* Array of primitives */
+ /* Do nothing */
+ } else if (((INTPTR)pointer)==1) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe30c);
+#endif
+ /* Array of pointers */
+ struct ArrayObject *ao=(struct ArrayObject *) ptr;
+ int length=ao->___length___;
+ int j;
+ for(j=0; j<length; j++) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe30d);
+#endif
+ void *objptr=
+ ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+ if(objptr != NULL) {
+ void * dst = flushObj(objptr);
+ if(dst != NULL) {
+ ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
+ }
+ }
+ }
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe30e);
+#endif
+ INTPTR size=pointer[0];
+ int i;
+ for(i=1; i<=size; i++) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe30f);
+#endif
+ unsigned int offset=pointer[i];
+ void * objptr=*((void **)(((char *)ptr)+offset));
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(objptr);
+#endif
+ if(objptr != NULL) {
+ void * dst = flushObj(objptr);
+ if(dst != NULL) {
+ *((void **)(((char *)ptr)+offset)) = dst;
+ }
+ }
+ } // for(i=1; i<=size; i++)
+ } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
+ // restore the mark field, indicating that this obj has been flushed
+ ((int *)(ptr))[6] = INIT;
+ } // if(((int *)(ptr))[6] == COMPACTED)
+ } // while(gc_lobjmoreItems())
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe310);
+#endif
+#ifdef GC_PROFILE
+ // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
+#endif
+
+ // send flush finish message to core coordinator
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ } else {
+ send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
+ }
+#ifdef GC_PROFILE
+ // TODO
+ //if(BAMBOO_NUM_OF_CORE == 0) {
+ //BAMBOO_DEBUGPRINT(0xffff);
+ //BAMBOO_DEBUGPRINT_REG(num_mapinforequest);
+ //BAMBOO_DEBUGPRINT_REG(flushstalltime);
+ //BAMBOO_DEBUGPRINT_REG(num_mapinforequest_i);
+ //BAMBOO_DEBUGPRINT_REG(flushstalltime_i);
+ //}
+ //BAMBOO_DEBUGPRINT_REG(flushstalltime);
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe311);
+#endif
+} // flush()
+
+#ifdef GC_CACHE_ADAPT
+// prepare for cache adaption:
+// -- flush the shared heap
+// -- clean dtlb entries
+// -- change cache strategy
+void cacheAdapt(bool isgccachestage) {
+ // flush the shared heap
+ BAMBOO_CACHE_FLUSH_L2();
+
+ // clean the dtlb entries
+ BAMBOO_CLEAN_DTLB();
+
+ // change the cache strategy
+ gccachestage = isgccachestage;
+}
+#endif // GC_CACHE_ADAPT
+
+inline void gc_collect(struct garbagelist * stackptr) {
+ //BAMBOO_DEBUGPRINT(0xcccc); // TODO
+ // inform the master that this core is at a gc safe point and is ready to
+ // do gc
+ send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
+ self_numreceiveobjs, false);
+
+ // core collector routine
+ while(true) {
+ if(INITPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
+#endif
+ initGC();
+#ifdef GC_CACHE_ADAPT
+ // prepare for cache adaption:
+ cacheAdapt(true);
+#endif // GC_CACHE_ADAPT
+ //send init finish msg to core coordinator
+ send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
+
+ while(true) {
+ if(MARKPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ mark(true, stackptr);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish mark phase, start compact phase\n",
+ udn_tile_coord_x(), udn_tile_coord_y());
+#endif
+ compact();
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+
+ while(true) {
+ if(MAPPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start map phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ transmappinginfo();
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish map phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+
+ while(true) {
+ if(FLUSHPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+#ifdef GC_PROFILE
+ /*BAMBOO_DEBUGPRINT(0xaaaa);
+ BAMBOO_DEBUGPRINT_REG(gc_num_obj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_liveobj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_forwardobj);
+ BAMBOO_DEBUGPRINT(0xaaab);*/
+ // send the num of obj/liveobj/forwardobj to the startupcore
+ if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
+ send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
+ gc_num_liveobj, gc_num_forwardobj, false);
+ }
+ gc_num_obj = 0;
+#endif // GC_PROFLIE
+ flush(stackptr);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+
+#ifdef GC_CACHE_ADAPT
+ while(true) {
+ if(PREFINISHPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ cacheAdapt(false);
+ //send init finish msg to core coordinator
+ send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+#endif // GC_CACHE_ADAPT
+
+ while(true) {
+ if(FINISHPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
+#endif
+} // void gc_collect(struct garbagelist * stackptr)
+
+inline void gc_nocollect(struct garbagelist * stackptr) {
+ //BAMBOO_DEBUGPRINT(0xcccc); // TODO
+ // inform the master that this core is at a gc safe point and is ready to
+ // do gc
+ send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
+ self_numreceiveobjs, false);
+
+ while(true) {
+ if(INITPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
+#endif
+ initGC();
+#ifdef GC_CACHE_ADAPT
+ // prepare for cache adaption:
+ cacheAdapt(true);
+#endif // GC_CACHE_ADAPT
+ //send init finish msg to core coordinator
+ send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
+
+ while(true) {
+ if(MARKPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ mark(true, stackptr);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish mark phase, wait for flush\n",
+ udn_tile_coord_x(), udn_tile_coord_y());
+#endif
+
+ // non-gc core collector routine
+ while(true) {
+ if(FLUSHPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+#ifdef GC_PROFILE
+ /*BAMBOO_DEBUGPRINT(0xaaaa);
+ BAMBOO_DEBUGPRINT_REG(gc_num_obj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_liveobj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_forwardobj);
+ BAMBOO_DEBUGPRINT(0xaaab);*/
+ if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
+ send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
+ gc_num_liveobj, gc_num_forwardobj, false);
+ }
+ gc_num_obj = 0;
+#endif // GC_PROFLIE
+ flush(stackptr);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+
+#ifdef GC_CACHE_ADAPT
+ while(true) {
+ if(PREFINISHPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ cacheAdapt(false);
+ //send init finish msg to core coordinator
+ send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+#endif // GC_CACHE_ADAPT
+
+ while(true) {
+ if(FINISHPHASE == gcphase) {
+ break;
+ }
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
+#endif
+} // void gc_collect(struct garbagelist * stackptr)
+
+inline void gc_master(struct garbagelist * stackptr) {
+
+ gcphase = INITPHASE;
+ int i = 0;
+ waitconfirm = false;
+ numconfirm = 0;
+ initGC();
+
+ // Note: all cores need to init gc including non-gc cores
+ for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
+ // send GC init messages to all cores
+ send_msg_1(i, GCSTARTINIT, false);
+ }
+ bool isfirst = true;
+ bool allStall = false;
+
+#ifdef GC_CACHE_ADAPT
+ // prepare for cache adaption:
+ cacheAdapt(true);
+#endif // GC_CACHE_ADAPT
+
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ while(true) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gc_checkAllCoreStatus_I()) {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ break;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ }
+#ifdef GC_PROFILE
+ gc_profileItem();
+#endif
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ // all cores have finished compacting
+ // restore the gcstatus of all cores
+ // Note: all cores have to do mark including non-gc cores
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+ for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
+ gccorestatus[i] = 1;
+ // send GC start messages to all cores
+ send_msg_1(i, GCSTART, false);
+ }
+
+ gcphase = MARKPHASE;
+ // mark phase
+ while(MARKPHASE == gcphase) {
+ mark(isfirst, stackptr);
+ if(isfirst) {
+ isfirst = false;
+ }
+
+ // check gcstatus
+ checkMarkStatue();
+ } // while(MARKPHASE == gcphase)
+ // send msgs to all cores requiring large objs info
+ // Note: only need to ask gc cores, non-gc cores do not host any objs
+ numconfirm = NUMCORES4GC - 1;
+ for(i = 1; i < NUMCORES4GC; ++i) {
+ send_msg_1(i, GCLOBJREQUEST, false);
+ }
+ gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
+ while(true) {
+ if(numconfirm==0) {
+ break;
+ }
+ } // wait for responses
+ // check the heaptop
+ if(gcheaptop < gcmarkedptrbound) {
+ gcheaptop = gcmarkedptrbound;
+ }
+#ifdef GC_PROFILE
+ gc_profileItem();
+ // TODO
+ /*if(BAMBOO_NUM_OF_CORE == 0) {
+ BAMBOO_DEBUGPRINT(0xeeee);
+ BAMBOO_DEBUGPRINT_REG(num_markrequest);
+ BAMBOO_DEBUGPRINT_REG(marktime);
+ }*/
+#endif
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ //dumpSMem();
+#endif
+ // cache all large objs
+ if(!cacheLObjs()) {
+ // no enough space to cache large objs
+ BAMBOO_EXIT(0xb107);
+ }
+ // predict number of blocks to fill for each core
+ int tmpheaptop = 0;
+ int numpbc = loadbalance(&tmpheaptop);
+ // TODO
+ numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ //dumpSMem();
+#endif
+ //int tmptopptr = 0;
+ //BASEPTR(gctopcore, 0, &tmptopptr);
+ // TODO
+ //tmptopptr = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
+ tmpheaptop = gcbaseva + (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, numpbc, &tmpcoreptr);
+ //send start compact messages to all cores
+ //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, false);
+ } else {
+ gcblock2fill = numpbc+1;
+ } // if(i != STARTUPCORE)
+ } else {
+ gcstopblock[i] = numpbc;
+ if(i != STARTUPCORE) {
+ send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
+ } else {
+ gcblock2fill = numpbc;
+ } // if(i != STARTUPCORE)
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000+i);
+ BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
+ BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
+#endif
+ // init some data strutures for compact phase
+ gcloads[i] = 0;
+ gcfilledblocks[i] = 0;
+ gcrequiredmems[i] = 0;
+ }
+
+#ifdef GC_PROFILE
+ gc_profileItem();
+#endif
+
+ // compact phase
+ bool finalcompact = false;
+ // initialize pointers for comapcting
+ struct moveHelper * orig =
+ (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
+ struct moveHelper * to =
+ (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
+ initOrig_Dst(orig, to);
+ int filledblocks = 0;
+ INTPTR heaptopptr = 0;
+ bool finishcompact = false;
+ bool iscontinue = true;
+ bool localcompact = true;
+ while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
+ if((!finishcompact) && iscontinue) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe001);
+ BAMBOO_DEBUGPRINT_REG(numpbc);
+ BAMBOO_DEBUGPRINT_REG(gcblock2fill);
+#endif
+ finishcompact = compacthelper(orig, to, &filledblocks,
+ &heaptopptr, &localcompact);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe002);
+ BAMBOO_DEBUGPRINT_REG(finishcompact);
+ BAMBOO_DEBUGPRINT_REG(gctomove);
+ BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
+ BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
+ BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
+#endif
+ }
+
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gc_checkCoreStatus_I()) {
+ // all cores have finished compacting
+ // restore the gcstatus of all cores
+ for(i = 0; i < NUMCORES4GC; ++i) {
+ gccorestatus[i] = 1;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ break;
+ } else {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ // check if there are spare mem for pending move requires
+ if(COMPACTPHASE == gcphase) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe003);
+#endif
+ resolvePendingMoveRequest();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(gctomove);
+#endif
+ } else {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe004);
+#endif
+ compact2Heaptop();
+ }
+ } // if(gc_checkCoreStatus_I()) else ...
+
+ if(gctomove) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe005);
+ BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
+ BAMBOO_DEBUGPRINT_REG(gcblock2fill);
+ BAMBOO_DEBUGPRINT_REG(gctomove);
+#endif
+ to->ptr = gcmovestartaddr;
+ to->numblocks = gcblock2fill - 1;
+ to->bound = (to->numblocks==0) ?
+ BAMBOO_SMEM_SIZE_L :
+ BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
+ BASEPTR(gcdstcore, to->numblocks, &(to->base));
+ to->offset = to->ptr - to->base;
+ to->top = (to->numblocks==0) ?
+ (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
+ to->base = to->ptr;
+ to->offset = BAMBOO_CACHE_LINE_SIZE;
+ to->ptr += to->offset; // for header
+ to->top += to->offset;
+ if(gcdstcore == BAMBOO_NUM_OF_CORE) {
+ localcompact = true;
+ } else {
+ localcompact = false;
+ }
+ gctomove = false;
+ iscontinue = true;
+ } else if(!finishcompact) {
+ // still pending
+ iscontinue = false;
+ } // if(gctomove)
+ } // while(COMPACTPHASE == gcphase)
+#ifdef GC_PROFILE
+ gc_profileItem();
+#endif
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ //dumpSMem();
+#endif
+ // move largeObjs
+ moveLObjs();
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ //dumpSMem();
+#endif
+ RUNFREE(orig);
+ RUNFREE(to);
+ orig = to = NULL;
+
+ gcphase = MAPPHASE;
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+ // Note: all cores should flush their runtime data including non-gc
+ // cores
+ for(i = 1; i < NUMCORES4GC; ++i) {
+ // send start flush messages to all cores
+ gccorestatus[i] = 1;
+ send_msg_1(i, GCSTARTMAPINFO, false);
+ }
+#ifdef GC_PROFILE
+ gc_profileItem();
+#endif
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start map phase \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ // mapinto phase
+ transmappinginfo();
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish map phase \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ while(MAPPHASE == gcphase) {
+ // check the status of all cores
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gc_checkCoreStatus_I()) {
+ // all cores have finished sending mapping info
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ break;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // while(MAPPHASE == gcphase)
+
+ gcphase = FLUSHPHASE;
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+ // Note: all cores should flush their runtime data including non-gc
+ // cores
+ for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
+ // send start flush messages to all cores
+ gccorestatus[i] = 1;
+ send_msg_1(i, GCSTARTFLUSH, false);
+ }
+#ifdef GC_PROFILE
+ gc_profileItem();
+#endif
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ // flush phase
+ flush(stackptr);
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ while(FLUSHPHASE == gcphase) {
+ // check the status of all cores
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gc_checkAllCoreStatus_I()) {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ break;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // while(FLUSHPHASE == gcphase)
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Finish flush phase \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+
+#ifdef GC_CACHE_ADAPT
+ gcphase = PREFINISHPHASE;
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+ // Note: all cores should flush their runtime data including non-gc
+ // cores
+ for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
+ // send start flush messages to all cores
+ gccorestatus[i] = 1;
+ send_msg_1(i, GCSTARTPREF, false);
+ }
+#ifdef GC_PROFILE
+ gc_profileItem();
+#endif
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) Start prefinish phase \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ // flush phase
+ cacheAdapt(false);
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ while(PREFINISHPHASE == gcphase) {
+ // check the status of all cores
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ if(gc_checkAllCoreStatus_I()) {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ break;
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ } // while(PREFINISHPHASE == gcphase)
+#endif // GC_CACHE_ADAPT
+
+ gcphase = FINISHPHASE;
+
+ // invalidate all shared mem pointers
+ // put it here as it takes time to inform all the other cores to
+ // finish gc and it might cause problem when some core resumes
+ // mutator earlier than the other cores
+ bamboo_cur_msp = NULL;
+ bamboo_smem_size = 0;
+ bamboo_smem_zero_top = NULL;
+ gcflag = false;
+ gcprocessing = false;
+
+#ifdef GC_PROFILE
+ gc_profileEnd();
+#endif
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
+ for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
+ // send gc finish messages to all cores
+ send_msg_1(i, GCFINISH, false);
+ gccorestatus[i] = 1;
+ }
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+ //dumpSMem();
+#endif
+ //BAMBOO_DEBUGPRINT(0x1111); // TODO
+/*#ifdef GC_PROFILE_S
+ BAMBOO_DEBUGPRINT(0xaaaa);
+ BAMBOO_DEBUGPRINT_REG(gc_num_obj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_liveobj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_forwardobj);
+ BAMBOO_DEBUGPRINT_REG(gc_num_profiles);
+ BAMBOO_DEBUGPRINT(0xaaab);
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ BAMBOO_DEBUGPRINT(0xaaac);
+ BAMBOO_DEBUGPRINT_REG(gc_num_livespace);
+ BAMBOO_DEBUGPRINT_REG(gc_num_freespace);
+ BAMBOO_DEBUGPRINT(0xaaad);
+ }
+ gc_num_obj = gc_num_liveobj;
+ gc_num_liveobj = 0;
+ gc_num_forwardobj = 0;
+#endif // GC_PROFLIE_S*/
+} // void gc_master(struct garbagelist * stackptr)
+
+inline bool gc(struct garbagelist * stackptr) {
+ // check if do gc
+ if(!gcflag) {
+ gcprocessing = false;
+ return false;
+ }
+
+ // core coordinator routine
+ if(0 == BAMBOO_NUM_OF_CORE) {
+#ifdef GC_DEBUG
+ printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
+ udn_tile_coord_y());
+#endif
+ bool isallstall = true;
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ int ti = 0;
+ for(ti = 0; ti < NUMCORESACTIVE; ++ti) {
+ if(gccorestatus[ti] != 0) {
+ isallstall = false;
+ break;
+ }
+ }
+ if(!isallstall) {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ // some of the cores are still executing the mutator and did not reach
+ // some gc safe point, therefore it is not ready to do gc
+ // in case that there are some pregc information msg lost, send a confirm
+ // msg to the 'busy' core
+ send_msg_1(ti, GCSTARTPRE, false);
+ gcflag = true;
+ return false;
+ } else {
+ // TODO
+#ifdef GC_PROFILE
+ gc_profileStart();
+#endif
+ //BAMBOO_DEBUGPRINT(0x1111); // TODO
+pregccheck:
+ //BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+ gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
+ gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
+ int sumsendobj = 0;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec04);
+#endif
+ for(int i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj += gcnumsendobjs[0][i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + gcnumsendobjs[0][i]);
+#endif
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec05);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ for(int i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj -= gcnumreceiveobjs[0][i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + gcnumreceiveobjs[i]);
+#endif
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xec06);
+ BAMBOO_DEBUGPRINT_REG(sumsendobj);
+#endif
+ if(0 != sumsendobj) {
+ // there were still some msgs on the fly, wait until there
+ // are some update pregc information coming and check it again
+ gcprecheck = false;
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ //BAMBOO_DEBUGPRINT(0x2222); // TODO
+ while(true) {
+ if(gcprecheck) {
+ break;
+ }
+ }
+ goto pregccheck;
+ } else {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ }
+ }
+/*
+#ifdef GC_PROFILE
+ gc_profileStart();
+#endif
+*/
+#ifdef RAWPATH // TODO GC_DEBUG
+ printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
+ //dumpSMem();
+#endif
+ // Zero out the remaining bamboo_cur_msp
+ // Only zero out the first 4 bytes of the remaining memory
+ // Move the operation here because for the GC_CACHE_ADAPT version,
+ // we need to make sure during the gcinit phase the shared heap is not
+ // touched. Otherwise, there would be problem when adapt the cache
+ // strategy.
+ if((bamboo_cur_msp != 0)
+ && (bamboo_smem_zero_top == bamboo_cur_msp)
+ && (bamboo_smem_size > 0)) {
+ *((int *)bamboo_cur_msp) = 0;
+ }
+#ifdef GC_FLUSH_DTLB
+ if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
+ BAMBOO_CLEAN_DTLB();
+ gc_num_flush_dtlb++;
+ }
+#endif
+#ifdef GC_CACHE_ADAPT
+ //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
+ // disable the timer interrupt
+ bamboo_mask_timer_intr();
+ // get the sampling data TODO
+ bamboo_output_dtlb_sampling();
+#endif // GC_CACHE_ADAPT
+ gcprocessing = true;
+ gc_master(stackptr);
+ } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
+ // Zero out the remaining bamboo_cur_msp
+ // Only zero out the first 4 bytes of the remaining memory
+ // Move the operation here because for the GC_CACHE_ADAPT version,
+ // we need to make sure during the gcinit phase the shared heap is not
+ // touched. Otherwise, there would be problem when adapt the cache
+ // strategy.
+ if((bamboo_cur_msp != 0)
+ && (bamboo_smem_zero_top == bamboo_cur_msp)
+ && (bamboo_smem_size > 0)) {
+ *((int *)bamboo_cur_msp) = 0;
+ }
+#ifdef GC_FLUSH_DTLB
+ if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
+ BAMBOO_CLEAN_DTLB();
+ gc_num_flush_dtlb++;
+ }
+#endif
+#ifdef GC_CACHE_ADAPT
+ // disable the timer interrupt
+ bamboo_mask_timer_intr();
+ // get the sampling data TODO
+ bamboo_output_dtlb_sampling();
+#endif // GC_CACHE_ADAPT
+ gcprocessing = true;
+ gc_collect(stackptr);
+
+ // invalidate all shared mem pointers
+ bamboo_cur_msp = NULL;
+ bamboo_smem_size = 0;
+ bamboo_smem_zero_top = NULL;
+ gcflag = false;
+ gcprocessing = false;
+ } else {
+ // Zero out the remaining bamboo_cur_msp
+ // Only zero out the first 4 bytes of the remaining memory
+ // Move the operation here because for the GC_CACHE_ADAPT version,
+ // we need to make sure during the gcinit phase the shared heap is not
+ // touched. Otherwise, there would be problem when adapt the cache
+ // strategy.
+ if((bamboo_cur_msp != 0)
+ && (bamboo_smem_zero_top == bamboo_cur_msp)
+ && (bamboo_smem_size > 0)) {
+ *((int *)bamboo_cur_msp) = 0;
+ }
+#ifdef GC_FLUSH_DTLB
+ if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
+ BAMBOO_CLEAN_DTLB();
+ gc_num_flush_dtlb++;
+ }
+#endif
+#ifdef GC_CACHE_ADAPT
+ // disable the timer interrupt
+ bamboo_mask_timer_intr();
+ // get the sampling data TODO
+ bamboo_output_dtlb_sampling();
+#endif // GC_CACHE_ADAPT
+ // not a gc core, should wait for gcfinish msg
+ gcprocessing = true;
+ gc_nocollect(stackptr);
+
+ // invalidate all shared mem pointers
+ bamboo_cur_msp = NULL;
+ bamboo_smem_size = 0;
+ bamboo_smem_zero_top = NULL;
+ gcflag = false;
+ gcprocessing = false;
+ }
+#ifdef GC_CACHE_ADAPT
+ // reset the sampling arrays
+ bamboo_dtlb_sampling_reset();
+ // enable the timer interrupt
+ bamboo_tile_timer_set_next_event(500000000); // TODO
+ bamboo_unmask_timer_intr();
+#endif // GC_CACHE_ADAPT
+ //if(STARTUPCORE == BAMBOO_NUM_OF_CORE) BAMBOO_DEBUGPRINT(0xeeee); // TODO
+ return true;
+} // void gc(struct garbagelist * stackptr)
+
+#ifdef GC_PROFILE
+inline void gc_profileStart(void) {
+ if(!gc_infoOverflow) {
+ GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
+ gc_infoArray[gc_infoIndex] = gcInfo;
+ gcInfo->index = 1;
+ gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
+ }
+}
+
+inline void gc_profileItem(void) {
+ if(!gc_infoOverflow) {
+ GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
+ gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
+ }
+}
+
+inline void gc_profileEnd(void) {
+ if(!gc_infoOverflow) {
+ GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
+ gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
+ gcInfo->time[gcInfo->index++] = gc_num_livespace;
+ gcInfo->time[gcInfo->index++] = gc_num_freespace;
+ gcInfo->time[gcInfo->index++] = gc_num_lobj;
+ gcInfo->time[gcInfo->index++] = gc_num_lobjspace;
+ gcInfo->time[gcInfo->index++] = gc_num_obj;
+ gcInfo->time[gcInfo->index++] = gc_num_liveobj;
+ gcInfo->time[gcInfo->index++] = gc_num_forwardobj;
+ gc_infoIndex++;
+ if(gc_infoIndex == GCINFOLENGTH) {
+ gc_infoOverflow = true;
+ //taskInfoIndex = 0;
+ }
+ }
+}
+
+// output the profiling data
+void gc_outputProfileData() {
+/*#ifdef USEIO
+ int i,j;
+ unsigned long long totalgc = 0;
+
+ //printf("Start Time, End Time, Duration\n");
+ // output task related info
+ for(i = 0; i < gc_infoIndex; i++) {
+ GCInfo * gcInfo = gc_infoArray[i];
+ unsigned long long tmp = 0;
+ for(j = 0; j < gcInfo->index; j++) {
+ printf("%lld(%lld), ", gcInfo->time[j], (gcInfo->time[j]-tmp));
+ tmp = gcInfo->time[j];
+ }
+ tmp = (tmp-gcInfo->time[0]);
+ printf(" ++ %lld \n", tmp);
+ totalgc += tmp;
+ }
+
+ if(gc_infoOverflow) {
+ printf("Caution: gc info overflow!\n");
+ }
+
+ printf("\n\n total gc time: %lld \n", totalgc);
+#else*/
+ int i = 0;
+ int j = 0;
+ unsigned long long totalgc = 0;
+
+#ifndef BAMBOO_MEMPROF
+ BAMBOO_DEBUGPRINT(0xdddd);
+#endif
+ // output task related info
+ for(i= 0; i < gc_infoIndex; i++) {
+ GCInfo * gcInfo = gc_infoArray[i];
+#ifdef BAMBOO_MEMPROF
+ unsigned long long tmp=gcInfo->time[gcInfo->index-8]-gcInfo->time[0]; //0;
+#else
+ unsigned long long tmp = 0;
+ BAMBOO_DEBUGPRINT(0xddda);
+ for(j = 0; j < gcInfo->index - 7; j++) {
+ BAMBOO_DEBUGPRINT(gcInfo->time[j]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[j]-tmp);
+ BAMBOO_DEBUGPRINT(0xdddb);
+ tmp = gcInfo->time[j];
+ }
+ tmp = (tmp-gcInfo->time[0]);
+ BAMBOO_DEBUGPRINT_REG(tmp);
+ BAMBOO_DEBUGPRINT(0xdddc);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 7]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 6]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 5]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 4]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 3]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 2]);
+ BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 1]);
+ BAMBOO_DEBUGPRINT(0xddde);
+#endif
+ totalgc += tmp;
+ }
+#ifndef BAMBOO_MEMPROF
+ BAMBOO_DEBUGPRINT(0xdddf);
+#endif
+ BAMBOO_DEBUGPRINT_REG(totalgc);
+
+ if(gc_infoOverflow) {
+ BAMBOO_DEBUGPRINT(0xefee);
+ }
+
+#ifndef BAMBOO_MEMPROF
+ BAMBOO_DEBUGPRINT(0xeeee);
+#endif
+//#endif
+}
+#endif // #ifdef GC_PROFILE
+
+#endif
--- /dev/null
+#ifndef MULTICORE_GARBAGE_H
+#define MULTICORE_GARBAGE_H
+#include "multicoregc.h"
+#include "multicorehelper.h" // for mappins between core # and block #
+#include "structdefs.h"
+#include "MGCHash.h"
+#include "GCSharedHash.h"
+
+#ifndef bool
+#define bool int
+#endif
+
+// data structures for GC
+#ifdef GC_DEBUG
+#define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
+#else
+#define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
+#endif
+#define BAMBOO_LARGE_SMEM_BOUND (BAMBOO_SMEM_SIZE_L*NUMCORES4GC)
+// let each gc core to have one big block, this is very important
+// for the computation of NUMBLOCKS(s, n), DO NOT change this!
+
+#ifdef GC_FLUSH_DTLB
+#define GC_NUM_FLUSH_DTLB 1
+int gc_num_flush_dtlb;
+#endif
+
+#define NUMPTRS 100
+
+// for GC profile
+#ifdef GC_PROFILE
+#define GCINFOLENGTH 100
+
+#ifdef GC_CACHE_ADAPT
+#define GC_PROFILE_NUM_FIELD 16
+#else
+#define GC_PROFILE_NUM_FIELD 15
+#endif
+
+typedef struct gc_info {
+ unsigned long long time[GC_PROFILE_NUM_FIELD];
+ int index;
+} GCInfo;
+
+GCInfo * gc_infoArray[GCINFOLENGTH];
+int gc_infoIndex;
+bool gc_infoOverflow;
+unsigned long long gc_num_livespace;
+unsigned long long gc_num_freespace;
+unsigned long long gc_num_lobjspace;
+unsigned int gc_num_lobj;
+
+// TODO
+/*unsigned long long flushstalltime;
+unsigned long long flushstalltime_i;
+int num_mapinforequest_i;*/
+unsigned int gc_num_liveobj;
+unsigned int gc_num_obj;
+unsigned int gc_num_forwardobj;
+int gc_num_profiles;
+
+#endif // GC_PROFILE
+
+typedef enum {
+ INIT = 0, // 0
+ DISCOVERED = 2, // 2
+ REMOTEM = 4, // 4
+ MARKED = 8, // 8
+ COMPACTED = 16, // 16
+ FLUSHED = 32, // 32
+ END = 33 // 33
+} GCOBJFLAG;
+
+typedef enum {
+ INITPHASE = 0x0, // 0x0
+ MARKPHASE, // 0x1
+ COMPACTPHASE, // 0x2
+ SUBTLECOMPACTPHASE, // 0x3
+ MAPPHASE, // 0x4
+ FLUSHPHASE, // 0x5
+#ifdef GC_CACHE_ADAPT
+ PREFINISHPHASE, // 0x6
+#endif // GC_CACHE_ADAPT
+ FINISHPHASE // 0x6/0x7
+} GCPHASETYPE;
+
+volatile bool gcflag;
+volatile bool gcprocessing;
+volatile GCPHASETYPE gcphase; // indicating GC phase
+
+volatile bool gcpreinform; // counter for stopped cores
+volatile bool gcprecheck; // indicates if there are updated pregc information
+
+int gccurr_heaptop;
+struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
+// for mark phase termination
+volatile int gccorestatus[NUMCORESACTIVE]; // records status of each core
+ // 1: running gc
+ // 0: stall
+volatile int gcnumsendobjs[2][NUMCORESACTIVE]; // the # of objects sent out
+volatile int gcnumreceiveobjs[2][NUMCORESACTIVE]; // the # of objects received
+volatile int gcnumsrobjs_index; // indicates which entry to record the info
+ // received before phase 1 of the mark finish
+ // checking process
+ // the info received in phase 2 must be
+ // recorded in the other entry
+volatile bool gcbusystatus;
+int gcself_numsendobjs;
+int gcself_numreceiveobjs;
+
+// for load balancing
+INTPTR gcheaptop;
+int gcloads[NUMCORES4GC];
+int gctopcore; // the core host the top of the heap
+int gctopblock; // the number of current top block
+
+int gcnumlobjs;
+
+// compact instruction
+INTPTR gcmarkedptrbound;
+int gcblock2fill;
+int gcstopblock[NUMCORES4GC]; // indicate when to stop compact phase
+int gcfilledblocks[NUMCORES4GC]; //indicate how many blocks have been fulfilled
+// move instruction;
+INTPTR gcmovestartaddr;
+int gcdstcore;
+volatile bool gctomove;
+int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
+volatile int gcmovepending;
+
+// data structures to record remote cores that transferred the marked
+// objs in the mark phase
+/*struct rcoreinfo{
+ int high;
+ int low;
+};
+struct RuntimeHash * gcrcoretbl;
+#define NUM_MAPPING 40
+void * gcmappingtbl[NUMCORESACTIVE][NUM_MAPPING];*/
+
+// shared memory pointer for shared pointer mapping tbls
+// In GC version, this block of memory is located at the bottom of the
+// shared memory, right on the top of the smem tbl.
+// The bottom of the shared memory = sbstart tbl + smemtbl
+// + NUMCORES4GC bamboo_rmsp
+// These three types of table are always reside at the bottom of the shared
+// memory and will never be moved or garbage collected
+#ifdef GC_SMALLPAGESIZE
+#define BAMBOO_RMSP_SIZE (1024 * 1024)
+#else
+#define BAMBOO_RMSP_SIZE (BAMBOO_SMEM_SIZE) // (45 * 16 * 1024)
+#endif
+mspace bamboo_rmsp;
+// shared pointer mapping tbl
+//volatile struct GCSharedHash * gcsharedptbl;
+mgcsharedhashtbl_t * gcsharedptbl;
+// remote shared pointer tbls
+//struct GCSharedHash * gcrpointertbls[NUMCORES4GC];
+mgcsharedhashtbl_t * gcrpointertbls[NUMCORES4GC];
+
+#ifdef LOCALHASHTBL_TEST
+struct RuntimeHash * gcpointertbl;
+#else
+mgchashtable_t * gcpointertbl;
+#endif
+//struct MGCHash * gcpointertbl;
+int gcobj2map;
+int gcmappedobj;
+volatile bool gcismapped;
+
+// table recording the starting address of each small block
+// (size is BAMBOO_SMEM_SIZE)
+// Note: 1. this table always resides on the very bottom of the shared memory
+// 2. the first two blocks are reserved for this table, would never be
+// moved or garbage collected.
+INTPTR * gcsbstarttbl;
+int gcreservedsb; // number of reserved sblock for sbstarttbl
+int gcnumblock; // number of total blocks in the shared mem
+int gcbaseva; // base va for shared memory without reserved sblocks
+#ifdef GC_CACHE_ADAPT
+int gctopva; // top va for shared memory without reserved sblocks
+volatile bool gccachestage;
+#endif // GC_CACHE_ADAPT
+
+#define ISSHAREDOBJ(p) \
+ ((((int)p)>gcbaseva)&&(((int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
+
+#define ALIGNSIZE(s, as) \
+ (*((int*)as)) = (((s) & (~(BAMBOO_CACHE_LINE_MASK))) + (BAMBOO_CACHE_LINE_SIZE))
+
+// mapping of pointer to block # (start from 0), here the block # is
+// the global index
+#define BLOCKINDEX(p, b) \
+ { \
+ int t = (p) - gcbaseva; \
+ if(t < (BAMBOO_LARGE_SMEM_BOUND)) { \
+ (*((int*)b)) = t / (BAMBOO_SMEM_SIZE_L); \
+ } else { \
+ (*((int*)b)) = NUMCORES4GC+((t-(BAMBOO_LARGE_SMEM_BOUND))/(BAMBOO_SMEM_SIZE)); \
+ } \
+ }
+
+// mapping of pointer to core #
+#define RESIDECORE(p, c) \
+ { \
+ if(1 == (NUMCORES4GC)) { \
+ (*((int*)c)) = 0; \
+ } else { \
+ int b; \
+ BLOCKINDEX((p), &b); \
+ (*((int*)c)) = gc_block2core[(b%(NUMCORES4GC*2))]; \
+ } \
+ }
+
+// NOTE: n starts from 0
+// mapping of heaptop (how many bytes there are in the local heap) to
+// the number of the block
+// the number of the block indicates that the block is the xth block on
+// the local heap
+#define NUMBLOCKS(s, n) \
+ if(s < (BAMBOO_SMEM_SIZE_L)) { \
+ (*((int*)(n))) = 0; \
+ } else { \
+ (*((int*)(n))) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
+ }
+
+#define OFFSET(s, o) \
+ if(s < BAMBOO_SMEM_SIZE_L) { \
+ (*((int*)(o))) = (s); \
+ } else { \
+ (*((int*)(o))) = ((s) - (BAMBOO_SMEM_SIZE_L)) % (BAMBOO_SMEM_SIZE); \
+ }
+
+// mapping of (core #, index of the block) to the global block index
+#define BLOCKINDEX2(c, n) (gc_core2block[(2*(c))+((n)%2)]+((NUMCORES4GC*2)*((n)/2)))
+
+// mapping of (core #, number of the block) to the base pointer of the block
+#define BASEPTR(c, n, p) \
+ { \
+ int b = BLOCKINDEX2((c), (n)); \
+ if(b < (NUMCORES4GC)) { \
+ (*((int*)p)) = gcbaseva + b * (BAMBOO_SMEM_SIZE_L); \
+ } else { \
+ (*((int*)p)) = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+ \
+ (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE); \
+ } \
+ }
+
+// the next core in the top of the heap
+#define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
+
+inline bool gc(struct garbagelist * stackptr); // core coordinator routine
+inline void gc_collect(struct garbagelist* stackptr); //core collector routine
+inline void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
+inline void transferMarkResults_I();
+inline void gc_enqueue_I(void *ptr);
+inline void gc_lobjenqueue_I(void *ptr, int length, int host);
+inline bool gcfindSpareMem_I(int * startaddr,
+ int * tomove,
+ int * dstcore,
+ int requiredmem,
+ int requiredcore);
+
+inline void * gc_lobjdequeue4(int * length, int * host);
+inline int gc_lobjmoreItems4();
+inline void gc_lobjqueueinit4();
+
+#ifdef GC_PROFILE
+INLINE void gc_profileStart(void);
+INLINE void gc_profileItem(void);
+INLINE void gc_profileEnd(void);
+void gc_outputProfileData();
+#endif
+
+#endif
+
--- /dev/null
+#ifndef MULTICORE_GC_H
+#define MULTICORE_GC_H
+
+struct garbagelist {
+ int size;
+ struct garbagelist *next;
+ void * array[];
+};
+
+struct listitem {
+ struct listitem * prev;
+ struct listitem * next;
+ struct garbagelist * stackptr;
+};
+
+#endif // MULTICORE_GC_H
--- /dev/null
+#ifndef MULTICORE_HELPER_H
+#define MULTICORE_HELPER_H
+
+#ifdef GC_1
+// NUMCORES4GC = 1
+static int gc_core2block[2] = {0,1};
+
+static int gc_block2core[2] = { 0, 0};
+#elif defined GC_56
+// NUMCORES4GC = 56
+static int gc_core2block[112] = {
+ 0,111, 15, 96, 16,95, 31,80, 32,79, 47,64, 48,63,
+ 1,110, 14, 97, 17,94, 30,81, 33,78, 46,65, 49,62,
+ 2,109, 13, 98, 18,93, 29,82, 34,77, 45,66, 50,61,
+ 3,108, 12, 99, 19,92, 28,83, 35,76, 44,67, 51,60,
+ 4,107, 11,100, 20,91, 27,84, 36,75, 43,68, 52,59,
+ 5,106, 10,101, 21,90, 26,85, 37,74, 42,69, 53,58,
+ 6,105, 9,102, 22,89, 25,86, 38,73, 41,70, 54,57,
+ 7,104, 8,103, 23,88, 24,87, 39,72, 40,71, 55,56
+};
+
+static int gc_block2core[112] = {
+ 0, 7, 14, 21, 28, 35, 42, 49, 50, 43, 36, 29, 22, 15, 8, 1,
+ 2, 9, 16, 23, 30, 37, 44, 51, 52, 45, 38, 31, 24, 17, 10, 3,
+ 4, 11, 18, 25, 32, 39, 46, 53, 54, 47, 40, 33, 26, 19, 12, 5,
+ 6, 13, 20, 27, 34, 41, 48, 55, 55, 48, 41, 34, 27, 20, 13, 6,
+ 5, 12, 19, 26, 33, 40, 47, 54, 53, 46, 39, 32, 25, 18, 11, 4,
+ 3, 10, 17, 24, 31, 38, 45, 52, 51, 44, 37, 30, 23, 16, 9, 2,
+ 1, 8, 15, 22, 29, 36, 43, 50, 49, 42, 35, 28, 21, 14, 7, 0
+};
+#elif defined GC_62
+// NUMCORES4GC = 62
+static int gc_core2block[124] = {
+ 0,123, 15,108, 16,107, 31,92, 32,91, 47,76,
+ 1,122, 14,109, 17,106, 30,93, 33,90, 46,77, 48,75, 61,62,
+ 2,121, 13,110, 18,105, 29,94, 34,89, 45,78, 49,74, 60,63,
+ 3,120, 12,111, 19,104, 28,95, 35,88, 44,79, 50,73, 59,64,
+ 4,119, 11,112, 20,103, 27,96, 36,87, 43,80, 51,72, 58,65,
+ 5,118, 10,113, 21,102, 26,97, 37,86, 42,81, 52,71, 57,66,
+ 6,117, 9,114, 22,101, 25,98, 38,85, 41,82, 53,70, 56,67,
+ 7,116, 8,115, 23,100, 24,99, 39,84, 40,83, 54,69, 55,68
+};
+
+static int gc_block2core[124] = {
+ 0, 6, 14, 22, 30, 38, 46, 54, 55, 47, 39, 31, 23, 15, 7, 1,
+ 2, 8, 16, 24, 32, 40, 48, 56, 57, 49, 41, 33, 25, 17, 9, 3,
+ 4, 10, 18, 26, 34, 42, 50, 58, 59, 51, 43, 35, 27, 19, 11, 5,
+ 12, 20, 28, 36, 44, 52, 60, 61, 53, 45, 37, 29, 21, 13,
+ 13, 21, 29, 37, 45, 53, 61, 60, 52, 44, 36, 28, 20, 12,
+ 5, 11, 19, 27, 35, 43, 51, 59, 58, 50, 42, 34, 26, 18, 10, 4,
+ 3, 9, 17, 25, 33, 41, 49, 57, 56, 48, 40, 32, 24, 16, 8, 2,
+ 1, 7, 15, 23, 31, 39, 47, 55, 54, 46, 38, 30, 22, 14, 6, 0
+};
+#endif
+
+#endif // MULTICORE_HELPER_H
--- /dev/null
+#include "runtime.h"
+#include "structdefs.h"
+#include "mem.h"
+#ifndef MULTICORE
+#include <fcntl.h>
+#include <errno.h>
+#include <signal.h>
+#endif
+#ifndef RAW
+#include <stdio.h>
+#endif
+#ifdef MULTICORE
+#include "runtime_arch.h"
+#endif
+//#include "option.h"
+
+extern int classsize[];
+extern int typearray[];
+extern int typearray2[];
+#ifndef MULTICORE
+jmp_buf error_handler;
+int instructioncount;
+
+char *options;
+int injectfailures=0;
+float failurechance=0;
+int errors=0;
+int injectinstructionfailures;
+int failurecount;
+float instfailurechance=0;
+int numfailures;
+int instaccum=0;
+#ifdef DMALLOC
+#include "dmalloc.h"
+#endif
+#endif
+
+int debugtask=0;
+
+int instanceof(struct ___Object___ *ptr, int type) {
+ int i=ptr->type;
+ do {
+ if (i==type)
+ return 1;
+ i=typearray[i];
+ } while(i!=-1);
+ i=ptr->type;
+ if (i>NUMCLASSES) {
+ do {
+ if (i==type)
+ return 1;
+ i=typearray2[i-NUMCLASSES];
+ } while(i!=-1);
+ }
+ return 0;
+}
+
+#ifdef MULTICORE
+void initializeexithandler() {
+}
+#else
+void exithandler(int sig, siginfo_t *info, void * uap) {
+#ifdef DEBUG
+ printf("exit in exithandler\n");
+#endif
+ exit(0);
+}
+
+void initializeexithandler() {
+ struct sigaction sig;
+ sig.sa_sigaction=&exithandler;
+ sig.sa_flags=SA_SIGINFO;
+ sigemptyset(&sig.sa_mask);
+ sigaction(SIGUSR2, &sig, 0);
+}
+#endif
+
+/* This function inject failures */
+
+void injectinstructionfailure() {
+#ifdef MULTICORE
+ // not supported in MULTICORE version
+ return;
+#else
+#ifdef TASK
+ if (injectinstructionfailures) {
+ if (numfailures==0)
+ return;
+ instructioncount=failurecount;
+ instaccum+=failurecount;
+ if ((((double)random())/RAND_MAX)<instfailurechance) {
+ if (numfailures>0)
+ numfailures--;
+ printf("FAILURE!!! %d\n",numfailures);
+ longjmp(error_handler,11);
+ }
+ }
+#else
+#ifdef THREADS
+ if (injectinstructionfailures) {
+ if (numfailures==0)
+ return;
+ instaccum+=failurecount;
+ if ((((double)random())/RAND_MAX)<instfailurechance) {
+ if (numfailures>0)
+ numfailures--;
+ printf("FAILURE!!! %d\n",numfailures);
+ threadexit();
+ }
+ }
+#endif
+#endif
+#endif
+}
+
+#ifdef D___Double______nativeparsedouble____L___String___
+double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
+ int length=VAR(___str___)->___count___;
+ int maxlength=(length>60) ? 60 : length;
+ char str[maxlength+1];
+ struct ArrayObject * chararray=VAR(___str___)->___value___;
+ int i;
+ int offset=VAR(___str___)->___offset___;
+ for(i=0; i<maxlength; i++) {
+ str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
+ }
+ str[i]=0;
+ double d=atof(str);
+ return d;
+}
+#endif
+
+#ifdef D___String______convertdoubletochar____D__AR_C
+int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
+ int length=VAR(___chararray___)->___length___;
+ char str[length];
+ int i;
+ int num=snprintf(str, length, "%f",___val___);
+ if (num>=length)
+ num=length-1;
+ for(i=0; i<length; i++) {
+ ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
+ }
+ return num;
+}
+#else
+int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
+ return 0;
+}
+#endif
+
+void CALL11(___System______exit____I,int ___status___, int ___status___) {
+#ifdef MULTICORE
+ BAMBOO_EXIT(___status___);
+#else
+#ifdef DEBUG
+ printf("exit in CALL11\n");
+#endif
+ exit(___status___);
+#endif
+}
+
+//#ifdef D___Vector______removeElement_____AR_L___Object____I_I
+void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
+ char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
+ memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
+}
+//#endif
+
+void CALL11(___System______printI____I,int ___status___, int ___status___) {
+#ifdef MULTICORE
+ BAMBOO_DEBUGPRINT(0x1111);
+ BAMBOO_DEBUGPRINT_REG(___status___);
+#else
+#ifdef DEBUG
+ printf("printI in CALL11\n");
+#endif
+ printf("%d\n", ___status___);
+#endif
+}
+
+long CALL00(___System______currentTimeMillis____) {
+#ifdef MULTICORE
+ // not supported in MULTICORE version
+ return -1;
+#else
+ struct timeval tv; long long retval;
+ gettimeofday(&tv, NULL);
+ retval = tv.tv_sec; /* seconds */
+ retval*=1000; /* milliseconds */
+ retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
+ return retval;
+#endif
+}
+
+void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
+#ifdef MULTICORE
+#else
+ struct ArrayObject * chararray=VAR(___s___)->___value___;
+ int i;
+ int offset=VAR(___s___)->___offset___;
+ for(i=0; i<VAR(___s___)->___count___; i++) {
+ short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
+ putchar(sc);
+ }
+#endif
+}
+
+/* Object allocation function */
+
+#ifdef MULTICORE_GC
+void * allocate_new(void * ptr, int type) {
+ struct ___Object___ * v=(struct ___Object___ *)FREEMALLOC((struct garbagelist *) ptr, classsize[type]);
+#ifdef DEBUG
+ printf("(%x,%x): new object: %x (%d, %x) \n", udn_tile_coord_x(),
+ udn_tile_coord_y(), (int)v, type, classsize[type]);
+#endif
+ v->type=type;
+ v->version = 0;
+ v->lock = NULL;
+ v->lockcount = 0;
+ initlock(v);
+#ifdef GC_PROFILE
+ extern unsigned int gc_num_obj;
+ gc_num_obj++;
+#endif
+ return v;
+}
+
+/* Array allocation function */
+
+struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
+ struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
+#ifdef DEBUG
+ printf("(%x,%x): new array object: %x (%d, %x)\n", udn_tile_coord_x(),
+ udn_tile_coord_y(), (int)v, type,
+ sizeof(struct ArrayObject)+length*classsize[type]);
+#endif
+ v->type=type;
+ v->version = 0;
+ v->lock = NULL;
+ if (length<0) {
+ return NULL;
+ }
+ v->___length___=length;
+ initlock(v);
+#ifdef GC_PROFILE
+ extern unsigned int gc_num_obj;
+ gc_num_obj++;
+#endif
+ return v;
+}
+
+#else
+void * allocate_new(int type) {
+ struct ___Object___ * v=FREEMALLOC(classsize[type]);
+ v->type=type;
+ v->version = 0;
+ //v->numlocks = 0;
+ v->lock = NULL;
+ initlock(v);
+ return v;
+}
+
+/* Array allocation function */
+
+struct ArrayObject * allocate_newarray(int type, int length) {
+ struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
+ v->type=type;
+ v->version = 0;
+ //v->numlocks = 0;
+ v->lock = NULL;
+ v->___length___=length;
+ initlock(v);
+ return v;
+}
+#endif
+
+
+/* Converts C character arrays into Java strings */
+#ifdef MULTICORE_GC
+struct ___String___ * NewString(void * ptr, const char *str,int length) {
+#else
+struct ___String___ * NewString(const char *str,int length) {
+#endif
+ int i;
+#ifdef MULTICORE_GC
+ struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
+ int ptrarray[]={1, (int) ptr, (int) chararray};
+ struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
+ chararray=(struct ArrayObject *) ptrarray[2];
+#else
+ struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
+ struct ___String___ * strobj=allocate_new(STRINGTYPE);
+#endif
+ strobj->___value___=chararray;
+ strobj->___count___=length;
+ strobj->___offset___=0;
+
+ for(i=0; i<length; i++) {
+ ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
+ }
+ return strobj;
+}
+
+/* Generated code calls this if we fail a bounds check */
+
+void failedboundschk() {
+#ifndef TASK
+ printf("Array out of bounds\n");
+#ifdef THREADS
+ threadexit();
+#else
+ exit(-1);
+#endif
+#else
+#ifndef MULTICORE
+ printf("Array out of bounds\n");
+ longjmp(error_handler,2);
+#else
+ BAMBOO_EXIT(0xa001);
+#endif
+#endif
+}
+
+/* Abort task call */
+void abort_task() {
+#ifdef TASK
+#ifndef MULTICORE
+ printf("Aborting\n");
+ longjmp(error_handler,4);
+#endif
+#else
+ printf("Aborting\n");
+ exit(-1);
+#endif
+}
--- /dev/null
+#ifndef MULTICORE_RUNTIME
+#define MULTICORE_RUNTIME
+
+#ifndef INLINE
+#define INLINE inline __attribute__((always_inline))
+#endif
+
+#ifndef bool
+#define bool int
+#define true 1
+#define false 0
+#endif
+
+////////////////////////////////////////////////////////////////
+// global variables //
+///////////////////////////////////////////////////////////////
+
+// record the starting time
+unsigned long long bamboo_start_time;
+
+// data structures for msgs
+#define BAMBOO_OUT_BUF_LENGTH 3000
+#define BAMBOO_MSG_BUF_LENGTH 3000
+int msgdata[BAMBOO_MSG_BUF_LENGTH];
+volatile int msgdataindex;
+volatile int msgdatalast;
+int msglength;
+volatile bool msgdatafull;
+int outmsgdata[BAMBOO_OUT_BUF_LENGTH];
+int outmsgindex;
+int outmsglast;
+int outmsgleft;
+volatile bool isMsgHanging;
+//volatile bool isMsgSending;
+
+#define MSG_INDEXINC_I() \
+ msgdataindex = (msgdataindex + 1) % (BAMBOO_MSG_BUF_LENGTH)
+
+#define MSG_LASTINDEXINC_I() \
+ msgdatalast = (msgdatalast + 1) % (BAMBOO_MSG_BUF_LENGTH)
+
+#define MSG_CACHE_I(n) \
+ msgdata[msgdatalast] = (n); \
+ MSG_LASTINDEXINC_I()
+
+// NOTE: if msgdataindex == msgdatalast, it always means that the buffer if
+// full. In the case that the buffer is empty, should never call this
+// MACRO
+#define MSG_REMAINSIZE_I(s) \
+ if(msgdataindex < msgdatalast) { \
+ (*(int*)s) = msgdatalast - msgdataindex; \
+ } else if((msgdataindex == msgdatalast) && (!msgdatafull)) { \
+ (*(int*)s) = 0; \
+ } else { \
+ (*(int*)s) = (BAMBOO_MSG_BUF_LENGTH) -msgdataindex + msgdatalast; \
+ }
+
+#define OUTMSG_INDEXINC() \
+ outmsgindex = (outmsgindex + 1) % (BAMBOO_OUT_BUF_LENGTH)
+
+#define OUTMSG_LASTINDEXINC() \
+ outmsglast = (outmsglast + 1) % (BAMBOO_OUT_BUF_LENGTH); \
+ if(outmsglast == outmsgindex) { \
+ BAMBOO_EXIT(0xdd01); \
+ }
+
+#define OUTMSG_CACHE(n) \
+ outmsgdata[outmsglast] = (n); \
+ OUTMSG_LASTINDEXINC();
+
+#define MAX_PACKET_WORDS 5
+
+/* Message format:
+ * type + Msgbody
+ * type: 1 -- transfer object
+ * 2 -- transfer stall msg
+ * 3 -- lock request
+ * 4 -- lock grount
+ * 5 -- lock deny
+ * 6 -- lock release
+ * // add for profile info
+ * 7 -- transfer profile output msg
+ * 8 -- transfer profile output finish msg
+ * // add for alias lock strategy
+ * 9 -- redirect lock request
+ * a -- lock grant with redirect info
+ * b -- lock deny with redirect info
+ * c -- lock release with redirect info
+ * d -- status confirm request
+ * e -- status report msg
+ * f -- terminate
+ * 10 -- requiring for new memory
+ * 11 -- response for new memory request
+ * 12 -- GC init phase start
+ * 13 -- GC start
+ * 14 -- compact phase start
+ * 15 -- flush phase start
+ * 16 -- init phase finish
+ * 17 -- mark phase finish
+ * 18 -- compact phase finish
+ * 19 -- flush phase finish
+ * 1a -- GC finish
+ * 1b -- marked phase finish confirm request
+ * 1c -- marked phase finish confirm response
+ * 1d -- markedObj msg
+ * 1e -- start moving objs msg
+ * 1f -- ask for mapping info of a markedObj
+ * 20 -- mapping info of a markedObj
+ * 21 -- large objs info request
+ * 22 -- large objs info response
+ * 23 -- large objs mapping info
+ *
+ * ObjMsg: 1 + size of msg + obj's address + (task index + param index)+
+ * StallMsg: 2 + corenum + sendobjs + receiveobjs
+ * (size is always 4 * sizeof(int))
+ * LockMsg: 3 + lock type + obj pointer + lock + request core
+ * (size is always 5 * sizeof(int))
+ * 4/5/6 + lock type + obj pointer + lock
+ * (size is always 4 * sizeof(int))
+ * 9 + lock type + obj pointer + redirect lock + root request core
+ * + request core
+ * (size is always 6 * sizeof(int))
+ * a/b + lock type + obj pointer + redirect lock
+ * (size is always 4 * sizeof(int))
+ * c + lock type + lock + redirect lock
+ * (size is always 4 * sizeof(int))
+ * lock type: 0 -- read; 1 -- write
+ * ProfileMsg: 7 + totalexetime
+ * (size is always 2 * sizeof(int))
+ * 8 + corenum
+ * (size is always 2 * sizeof(int))
+ * StatusMsg: d (size is always 1 * sizeof(int))
+ * e + status + corenum + sendobjs + receiveobjs
+ * (size is always 5 * sizeof(int))
+ * status: 0 -- stall; 1 -- busy
+ * TerminateMsg: f (size is always 1 * sizeof(int)
+ * MemoryMsg: 10 + size + corenum
+ * (size is always 3 * sizeof(int))
+ * 11 + base_va + size
+ * (size is always 3 * sizeof(int))
+ * GCMsg: 12/13 (size is always 1 * sizeof(int))
+ * 14 + size of msg + (num of objs to move + (start address
+ * + end address + dst core + start dst)+)?
+ * + (num of incoming objs + (start dst + orig core)+)?
+ * + (num of large obj lists + (start address + lenght
+ * + start dst)+)?
+ * 15 (size is always 1 * sizeof(int))
+ * 16 + corenum
+ * (size is always 2 * sizeof(int))
+ * 17 + corenum + gcsendobjs + gcreceiveobjs
+ * (size if always 4 * sizeof(int))
+ * 18 + corenum + fulfilled blocks num + (finish compact(1) + current
+ * heap top)/(need mem(0) + mem need)
+ * size is always 5 * sizeof(int))
+ * 19 + corenum
+ * (size is always 2 * sizeof(int))
+ * 1a (size is always 1 * sizeof(int))
+ * 1b (size if always 1 * sizeof(int))
+ * 1c + size of msg + corenum + gcsendobjs + gcreceiveobjs
+ * (size is always 5 * sizeof(int))
+ * 1d + obj's address + request core
+ * (size is always 3 * sizeof(int))
+ * 1e + corenum + start addr + end addr
+ * (size if always 4 * sizeof(int))
+ * 1f + obj's address + corenum
+ * (size is always 3 * sizeof(int))
+ * 20 + obj's address + dst address
+ * (size if always 3 * sizeof(int))
+ * 21 (size is always 1 * sizeof(int))
+ * 22 + size of msg + corenum + current heap size
+ * + (num of large obj lists + (start address + length)+)?
+ * 23 + orig large obj ptr + new large obj ptr
+ * (size is always 3 * sizeof(int))
+ */
+typedef enum {
+ 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
+ GCSTARTPRE, // 0xE2
+ GCSTARTINIT, // 0xE3
+ GCSTART, // 0xE4
+ GCSTARTCOMPACT, // 0xE5
+ GCSTARTMAPINFO, // 0xE6
+ GCSTARTFLUSH, // 0xE7
+ GCFINISHPRE, // 0xE8
+ GCFINISHINIT, // 0xE9
+ GCFINISHMARK, // 0xEa
+ GCFINISHCOMPACT, // 0xEb
+ GCFINISHMAPINFO, // 0xEc
+ GCFINISHFLUSH, // 0xEd
+ GCFINISH, // 0xEe
+ GCMARKCONFIRM, // 0xEf
+ GCMARKREPORT, // 0xF0
+ GCMARKEDOBJ, // 0xF1
+ GCMOVESTART, // 0xF2
+ GCMAPREQUEST, // 0xF3
+ GCMAPINFO, // 0xF4
+ GCMAPTBL, // 0xF5
+ GCLOBJREQUEST, // 0xF6
+ GCLOBJINFO, // 0xF7
+ GCLOBJMAPPING, // 0xF8
+#ifdef GC_PROFILE
+ GCPROFILES, // 0xF9
+#endif
+#ifdef GC_CACHE_ADAPT
+ GCSTARTPOSTINIT, // 0xFa
+ GCSTARTPREF, // 0xFb
+ GCFINISHPOSTINIT, // 0xFc
+ GCFINISHPREF, // 0xFd
+#endif // GC_CACHE_ADAPT
+#endif
+ MSGEND
+} MSGTYPE;
+
+/////////////////////////////////////////////////////////////////////////////////
+// NOTE: BAMBOO_TOTALCORE -- number of the available cores in the processor.
+// No greater than the number of all the cores in
+// the processor
+// NUMCORES -- number of cores chosen to deploy the application. It can
+// be greater than that required to fully parallelize the
+// application. The same as NUMCORES.
+// NUMCORESACTIVE -- number of cores that really execute the
+// application. No greater than NUMCORES
+// NUMCORES4GC -- number of cores for gc. No greater than NUMCORES.
+// NOTE: currently only support ontinuous cores as gc
+// cores, i.e. 0~NUMCORES4GC-1
+////////////////////////////////////////////////////////////////////////////////
+// data structures of status for termination
+// only check working cores
+volatile int corestatus[NUMCORESACTIVE]; // records status of each core
+ // 1: running tasks
+ // 0: stall
+volatile int numsendobjs[NUMCORESACTIVE]; // records how many objects a core
+ // has sent out
+volatile int numreceiveobjs[NUMCORESACTIVE]; // records how many objects a
+ // core has received
+volatile int numconfirm;
+volatile bool waitconfirm;
+bool busystatus;
+int self_numsendobjs;
+int self_numreceiveobjs;
+
+// get rid of lock msgs for GC version
+#ifndef MULTICORE_GC
+// data structures for locking
+struct RuntimeHash locktable;
+static struct RuntimeHash* locktbl = &locktable;
+struct RuntimeHash * lockRedirectTbl;
+struct RuntimeHash * objRedirectLockTbl;
+#endif
+struct LockValue {
+ int redirectlock;
+ int value;
+};
+int lockobj;
+int lock2require;
+int lockresult;
+bool lockflag;
+
+// data structures for waiting objs
+struct Queue objqueue;
+struct Queue * totransobjqueue; // queue to hold objs to be transferred
+ // should be cleared whenever enter a task
+
+// data structures for shared memory allocation
+#ifdef TILERA_BME
+#define BAMBOO_BASE_VA 0xd000000
+#elif defined TILERA_ZLINUX
+#ifdef MULTICORE_GC
+#define BAMBOO_BASE_VA 0xd000000
+#endif // MULTICORE_GC
+#endif // TILERA_BME
+
+#ifdef BAMBOO_MEMPROF
+#define GC_BAMBOO_NUMCORES 56
+#else
+#define GC_BAMBOO_NUMCORES 62
+#endif
+
+#ifdef GC_DEBUG
+#include "structdefs.h"
+#define BAMBOO_NUM_PAGES (NUMCORES4GC*(2+1)+3)
+#define BAMBOO_PAGE_SIZE (64 * 64)
+#define BAMBOO_SMEM_SIZE (64 * 64) // (BAMBOO_PAGE_SIZE)
+#define BAMBOO_SHARED_MEM_SIZE ((BAMBOO_PAGE_SIZE) *(BAMBOO_NUM_PAGES))
+#else
+#ifdef GC_LARGESHAREDHEAP
+#define BAMBOO_NUM_PAGES ((GC_BAMBOO_NUMCORES)*(2+2))
+#elif defined GC_LARGESHAREDHEAP2
+#define BAMBOO_NUM_PAGES ((GC_BAMBOO_NUMCORES)*(2+2))
+#else
+#define BAMBOO_NUM_PAGES ((GC_BAMBOO_NUMCORES)*(2+3)) //(15 * 1024) //(64 * 4 * 0.75) //(1024 * 1024 * 3.5) 3G
+#endif
+#ifdef GC_LARGEPAGESIZE
+#define BAMBOO_PAGE_SIZE (4 * 1024 * 1024) // (4096)
+#define BAMBOO_SMEM_SIZE (4 * 1024 * 1024)
+#elif defined GC_SMALLPAGESIZE
+#define BAMBOO_PAGE_SIZE (256 * 1024) // (4096)
+#define BAMBOO_SMEM_SIZE (256 * 1024)
+#elif defined GC_SMALLPAGESIZE2
+#define BAMBOO_PAGE_SIZE (64 * 1024) // (4096)
+#define BAMBOO_SMEM_SIZE (64 * 1024)
+#else
+#define BAMBOO_PAGE_SIZE (1024 * 1024) // (4096)
+#define BAMBOO_SMEM_SIZE (1024 * 1024)
+#endif // GC_LARGEPAGESIZE
+#define BAMBOO_SHARED_MEM_SIZE ((BAMBOO_PAGE_SIZE) * (BAMBOO_NUM_PAGES)) //(1024 * 1024 * 240)
+//((unsigned long long int)(3.0 * 1024 * 1024 * 1024)) // 3G
+#endif // GC_DEBUG
+
+#ifdef MULTICORE_GC
+volatile bool gc_localheap_s;
+#endif
+
+#ifdef MULTICORE_GC
+#include "multicoregarbage.h"
+
+typedef enum {
+ SMEMLOCAL = 0x0,// 0x0, using local mem only
+ SMEMFIXED, // 0x1, use local mem in lower address space(1 block only)
+ // and global mem in higher address space
+ SMEMMIXED, // 0x2, like FIXED mode but use a threshold to control
+ SMEMGLOBAL, // 0x3, using global mem only
+ SMEMEND
+} SMEMSTRATEGY;
+
+SMEMSTRATEGY bamboo_smem_mode; //-DSMEML: LOCAL; -DSMEMF: FIXED;
+ //-DSMEMM: MIXED; -DSMEMG: GLOBAL;
+
+struct freeMemItem {
+ INTPTR ptr;
+ int size;
+ int startblock;
+ int endblock;
+ struct freeMemItem * next;
+};
+
+struct freeMemList {
+ struct freeMemItem * head;
+ struct freeMemItem * backuplist; // hold removed freeMemItem for reuse;
+ // only maintain 1 freemMemItem
+};
+
+// table recording the number of allocated bytes on each block
+// Note: this table resides on the bottom of the shared heap for all cores
+// to access
+volatile int * bamboo_smemtbl;
+volatile int bamboo_free_block;
+//bool bamboo_smem_flushed;
+//struct freeMemList * bamboo_free_mem_list;
+int bamboo_reserved_smem; // reserved blocks on the top of the shared heap
+ // e.g. 20% of the heap and should not be allocated
+ // otherwise gc is invoked
+volatile INTPTR bamboo_smem_zero_top;
+#define BAMBOO_SMEM_ZERO_UNIT_SIZE (4 * 1024) // 4KB
+#else
+//volatile mspace bamboo_free_msp;
+INTPTR bamboo_free_smemp;
+int bamboo_free_smem_size;
+#endif
+volatile bool smemflag;
+volatile INTPTR bamboo_cur_msp;
+volatile int bamboo_smem_size;
+
+// for test TODO
+int total_num_t6;
+
+// data structures for profile mode
+#ifdef PROFILE
+
+#define TASKINFOLENGTH 3000 // 0
+#ifdef PROFILE_INTERRUPT
+#define INTERRUPTINFOLENGTH 50 //0
+#endif // PROFILE_INTERRUPT
+
+bool stall;
+//bool isInterrupt;
+int totalexetime;
+//unsigned long long interrupttime;
+
+typedef struct task_info {
+ char* taskName;
+ unsigned long long startTime;
+ unsigned long long endTime;
+ unsigned long long exitIndex;
+ struct Queue * newObjs;
+} TaskInfo;
+
+TaskInfo * taskInfoArray[TASKINFOLENGTH];
+int taskInfoIndex;
+bool taskInfoOverflow;
+#ifdef PROFILE_INTERRUPT
+typedef struct interrupt_info {
+ unsigned long long startTime;
+ unsigned long long endTime;
+} InterruptInfo;
+
+InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
+int interruptInfoIndex;
+bool interruptInfoOverflow;
+#endif // PROFILE_INTERUPT
+volatile int profilestatus[NUMCORESACTIVE]; // records status of each core
+ // 1: running tasks
+ // 0: stall
+#endif // #ifdef PROFILE
+
+#ifndef INTERRUPT
+bool reside;
+#endif
+/////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////
+// these are functions should be implemented in //
+// multicore runtime for any multicore processors //
+////////////////////////////////////////////////////////////
+#ifdef TASK
+#ifdef MULTICORE
+INLINE void initialization(void);
+INLINE void initCommunication(void);
+INLINE void fakeExecution(void);
+INLINE void terminate(void);
+INLINE void initlock(struct ___Object___ * v);
+#ifdef BAMBOO_MEMPROF
+INLINE void terminatememprof(void);
+#endif
+
+// lock related functions
+bool getreadlock(void* ptr);
+void releasereadlock(void* ptr);
+bool getwritelock(void* ptr);
+void releasewritelock(void* ptr);
+bool getwritelock_I(void* ptr);
+void releasewritelock_I(void * ptr);
+#ifndef MULTICORE_GC
+void releasewritelock_r(void * lock, void * redirectlock);
+#endif
+/* this function is to process lock requests.
+ * can only be invoked in receiveObject() */
+// if return -1: the lock request is redirected
+// 0: the lock request is approved
+// 1: the lock request is denied
+INLINE int processlockrequest(int locktype,
+ int lock,
+ int obj,
+ int requestcore,
+ int rootrequestcore,
+ bool cache);
+INLINE void processlockrelease(int locktype,
+ int lock,
+ int redirectlock,
+ bool redirect);
+
+// msg related functions
+INLINE void send_hanging_msg(bool isInterrupt);
+INLINE void send_msg_1(int targetcore,
+ unsigned long n0,
+ bool isInterrupt);
+INLINE void send_msg_2(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ bool isInterrupt);
+INLINE void send_msg_3(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2,
+ bool isInterrupt);
+INLINE void send_msg_4(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2,
+ unsigned long n3,
+ bool isInterrupt);
+INLINE void send_msg_5(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2,
+ unsigned long n3,
+ unsigned long n4,
+ bool isInterrupt);
+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,
+ bool isInterrupt);
+INLINE void cache_msg_1(int targetcore,
+ unsigned long n0);
+INLINE void cache_msg_2(int targetcore,
+ unsigned long n0,
+ unsigned long n1);
+INLINE void cache_msg_3(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2);
+INLINE void cache_msg_4(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2,
+ unsigned long n3);
+INLINE void cache_msg_5(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2,
+ unsigned long n3,
+ unsigned long n4);
+INLINE void cache_msg_6(int targetcore,
+ unsigned long n0,
+ unsigned long n1,
+ unsigned long n2,
+ unsigned long n3,
+ unsigned long n4,
+ unsigned long n5);
+INLINE void transferObject(struct transObjInfo * transObj);
+INLINE int receiveMsg(uint32_t send_port_pending);
+
+#ifdef MULTICORE_GC
+INLINE void transferMarkResults();
+#endif
+
+#ifdef PROFILE
+INLINE void profileTaskStart(char * taskname);
+INLINE void profileTaskEnd(void);
+void outputProfileData();
+#endif // #ifdef PROFILE
+///////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////
+// For each version of BAMBOO runtime, there should be a header file named //
+// runtim_arch.h defining following MARCOS: //
+// BAMBOO_NUM_OF_CORE: the # of current residing core //
+// BAMBOO_GET_NUM_OF_CORE(): compute the # of current residing core //
+// BAMBOO_COORDS(c, x, y): convert the cpu # to coords (*x, *y) //
+// BAMBOO_DEBUGPRINT(x): print out integer x //
+// BAMBOO_DEBUGPRINT_REG(x): print out value of variable x //
+// BAMBOO_EXIT_APP(x): exit the whole application //
+// BAMBOO_EXIT(x): error exit routine with error # //
+// BAMBOO_DIE(x): error exit routine with error msg //
+// BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number //
+// BAMBOO_MSG_AVAIL(): checking if there are msgs coming in //
+// BAMBOO_GCMSG_AVAIL(): checking if there are gcmsgs coming in //
+// BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT(): change to runtime mode from //
+// client mode //
+// BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME(): change to client mode from //
+// runtime mode //
+// BAMBOO_ENTER_SEND_MODE_FROM_CLIENT(): change to send mode from //
+// client mode //
+// BAMBOO_ENTER_CLIENT_MODE_FROM_SEND(): change to client mode from //
+// send mode //
+// BAMBOO_ENTER_RUNTIME_MODE_FROM_SEND(): change to runtime mode from //
+// send mode //
+// BAMBOO_ENTER_SEND_MODE_FROM_RUNTIME(): change to send mode from //
+// runtime mode //
+// BAMBOO_WAITING_FOR_LOCK(): routine executed while waiting for lock //
+// request response //
+// BAMBOO_LOCAL_MEM_CALLOC(x, y): allocate an array of x elements each of //
+// whose size in bytes is y on local memory //
+// which is given by the hypervisor //
+// BAMBOO_LOCAL_MEM_FREE(x): free space with ptr x on local memory //
+// BAMBOO_LOCAL_MEM_CLOSE(): close the local heap //
+// BAMBOO_LOCAL_MEM_CALLOC_S(x, y): allocate an array of x elements each of//
+// whose size in bytes is y on local //
+// memory which is not from the hypervisor//
+// but is allocated from the free memory //
+// BAMBOO_LOCAL_MEM_FREE_S(x): free space with ptr x on self-allocated //
+// local memory //
+// BAMBOO_LOCAL_MEM_CLOSE_S(): close the self-allocated local heap //
+// BAMBOO_SHARE_MEM_CALLOC_I(x, y): allocate an array of x elements each of//
+// whose size in bytes is y on shared memory//
+// BAMBOO_SHARE_MEM_CLOSE(): close the shared heap //
+// BAMBOO_CACHE_LINE_SIZE: the cache line size //
+// BAMBOO_CACHE_LINE_MASK: mask for a cache line //
+// BAMBOO_CACHE_FLUSH_RANGE(x, y): flush cache lines started at x with //
+// length y //
+// BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary //
+// BAMBOO_MEMSET_WH(x, y, z): memset the specified region of memory (start //
+// address x, size z) to value y with write //
+// hint, the processor will not fetch the //
+// current content of the memory and directly //
+// write //
+// BAMBOO_CLEAN_DTLB(): zero-out all the dtlb entries //
+// BAMBOO_CACHE_FLUSH_L2(): Flush the contents of this tile's L2 back to //
+// main memory //
+/////////////////////////////////////////////////////////////////////////////
+
+#endif // #ifdef MULTICORE
+#endif // #ifdef TASK
+#endif // #ifndef MULTICORE_RUNTIME
--- /dev/null
+#ifdef TASK
+#include "runtime.h"
+#include "multicoreruntime.h"
+#include "runtime_arch.h"
+#include "GenericHashtable.h"
+
+#ifndef INLINE
+#define INLINE inline __attribute__((always_inline))
+#endif // #ifndef INLINE
+
+// data structures for task invocation
+struct genhashtable * activetasks;
+struct taskparamdescriptor * currtpd;
+struct LockValue runtime_locks[MAXTASKPARAMS];
+int runtime_locklen;
+
+// specific functions used inside critical sections
+void enqueueObject_I(void * ptr,
+ struct parameterwrapper ** queues,
+ int length);
+int enqueuetasks_I(struct parameterwrapper *parameter,
+ struct parameterwrapper *prevptr,
+ struct ___Object___ *ptr,
+ int * enterflags,
+ int numenterflags);
+
+#ifdef MULTICORE_GC
+#ifdef SMEMF
+#define NUM_CORES2TEST 5
+#ifdef GC_1
+int core2test[1][NUM_CORES2TEST] = {
+ {0, -1, -1, -1, -1}
+};
+#elif defined GC_56
+int core2test[56][NUM_CORES2TEST] = {
+ { 0, -1, 7, -1, 1}, { 1, -1, 8, 0, 2}, { 2, -1, 9, 1, 3},
+ { 3, -1, 10, 2, 4}, { 4, -1, 11, 3, 5}, { 5, -1, 12, 4, 6},
+ { 6, -1, 13, 5, -1}, { 7, 0, 14, -1, 8}, { 8, 1, 15, 7, 9},
+ { 9, 2, 16, 8, 10}, {10, 3, 17, 9, 11}, {11, 4, 18, 10, 12},
+ {12, 5, 19, 11, 13}, {13, 6, 20, 12, -1}, {14, 7, 21, -1, 15},
+ {15, 8, 22, 14, 16}, {16, 9, 23, 15, 17}, {17, 10, 24, 16, 18},
+ {18, 11, 25, 17, 19}, {19, 12, 26, 18, 20}, {20, 13, 27, 19, -1},
+ {21, 14, 28, -1, 22}, {22, 15, 29, 21, 23}, {23, 16, 30, 22, 24},
+ {24, 17, 31, 23, 25}, {25, 18, 32, 24, 26}, {26, 19, 33, 25, 27},
+ {27, 20, 34, 26, -1}, {28, 21, 35, -1, 29}, {29, 22, 36, 28, 30},
+ {30, 23, 37, 29, 31}, {31, 24, 38, 30, 32}, {32, 25, 39, 31, 33},
+ {33, 26, 40, 32, 34}, {34, 27, 41, 33, -1}, {35, 28, 42, -1, 36},
+ {36, 29, 43, 35, 37}, {37, 30, 44, 36, 38}, {38, 31, 45, 37, 39},
+ {39, 32, 46, 38, 40}, {40, 33, 47, 39, 41}, {41, 34, 48, 40, -1},
+ {42, 35, 49, -1, 43}, {43, 36, 50, 42, 44}, {44, 37, 51, 43, 45},
+ {45, 38, 52, 44, 46}, {46, 39, 53, 45, 47}, {47, 40, 54, 46, 48},
+ {48, 41, 55, 47, -1}, {49, 42, -1, -1, 50}, {50, 43, -1, 49, 51},
+ {51, 44, -1, 50, 52}, {52, 45, -1, 51, 53}, {53, 46, -1, 52, 54},
+ {54, 47, -1, 53, 55}, {55, 48, -1, 54, -1}
+};
+#elif defined GC_62
+int core2test[62][NUM_CORES2TEST] = {
+ { 0, -1, 6, -1, 1}, { 1, -1, 7, 0, 2}, { 2, -1, 8, 1, 3},
+ { 3, -1, 9, 2, 4}, { 4, -1, 10, 3, 5}, { 5, -1, 11, 4, -1},
+ { 6, 0, 14, -1, 7}, { 7, 1, 15, 6, 8}, { 8, 2, 16, 7, 9},
+ { 9, 3, 17, 8, 10}, {10, 4, 18, 9, 11}, {11, 5, 19, 10, 12},
+ {12, -1, 20, 11, 13}, {13, -1, 21, 12, -1}, {14, 6, 22, -1, 15},
+ {15, 7, 23, 14, 16}, {16, 8, 24, 15, 17}, {17, 9, 25, 16, 18},
+ {18, 10, 26, 17, 19}, {19, 11, 27, 18, 20}, {20, 12, 28, 19, 21},
+ {21, 13, 29, 28, -1}, {22, 14, 30, -1, 23}, {23, 15, 31, 22, 24},
+ {24, 16, 32, 23, 25}, {25, 17, 33, 24, 26}, {26, 18, 34, 25, 27},
+ {27, 19, 35, 26, 28}, {28, 20, 36, 27, 29}, {29, 21, 37, 28, -1},
+ {30, 22, 38, -1, 31}, {31, 23, 39, 30, 32}, {32, 24, 40, 31, 33},
+ {33, 25, 41, 32, 34}, {34, 26, 42, 33, 35}, {35, 27, 43, 34, 36},
+ {36, 28, 44, 35, 37}, {37, 29, 45, 36, -1}, {38, 30, 46, -1, 39},
+ {39, 31, 47, 38, 40}, {40, 32, 48, 39, 41}, {41, 33, 49, 40, 42},
+ {42, 34, 50, 41, 43}, {43, 35, 51, 42, 44}, {44, 36, 52, 43, 45},
+ {45, 37, 53, 44, -1}, {46, 38, 54, -1, 47}, {47, 39, 55, 46, 48},
+ {48, 40, 56, 47, 49}, {49, 41, 57, 48, 50}, {50, 42, 58, 49, 51},
+ {51, 43, 59, 50, 52}, {52, 44, 60, 51, 53}, {53, 45, 61, 52, -1},
+ {54, 46, -1, -1, 55}, {55, 47, -1, 54, 56}, {56, 48, -1, 55, 57},
+ {57, 49, -1, 56, 59}, {58, 50, -1, 57, 59}, {59, 51, -1, 58, 60},
+ {60, 52, -1, 59, 61}, {61, 53, -1, 60, -1}
+};
+#endif // GC_1
+#elif defined SMEMM
+unsigned int gcmem_mixed_threshold = 0;
+unsigned int gcmem_mixed_usedmem = 0;
+#define NUM_CORES2TEST 9
+#ifdef GC_1
+int core2test[1][NUM_CORES2TEST] = {
+ {0, -1, -1, -1, -1, -1, -1, -1, -1}
+};
+#elif defined GC_56
+int core2test[56][NUM_CORES2TEST] = {
+ { 0, -1, 7, -1, 1, -1, 14, -1, 2},
+ { 1, -1, 8, 0, 2, -1, 15, -1, 3},
+ { 2, -1, 9, 1, 3, -1, 16, 0, 4},
+ { 3, -1, 10, 2, 4, -1, 17, 1, 5},
+ { 4, -1, 11, 3, 5, -1, 18, 2, 6},
+ { 5, -1, 12, 4, 6, -1, 19, 3, -1},
+ { 6, -1, 13, 5, -1, -1, 20, 4, -1},
+ { 7, 0, 14, -1, 8, -1, 21, -1, 9},
+ { 8, 1, 15, 7, 9, -1, 22, -1, 10},
+ { 9, 2, 16, 8, 10, -1, 23, 7, 11},
+ {10, 3, 17, 9, 11, -1, 24, 8, 12},
+ {11, 4, 18, 10, 12, -1, 25, 9, 13},
+ {12, 5, 19, 11, 13, -1, 26, 10, -1},
+ {13, 6, 20, 12, -1, -1, 27, 11, -1},
+ {14, 7, 21, -1, 15, 0, 28, -1, 16},
+ {15, 8, 22, 14, 16, 1, 29, -1, 17},
+ {16, 9, 23, 15, 17, 2, 30, 14, 18},
+ {17, 10, 24, 16, 18, 3, 31, 15, 19},
+ {18, 11, 25, 17, 19, 4, 32, 16, 20},
+ {19, 12, 26, 18, 20, 5, 33, 17, -1},
+ {20, 13, 27, 19, -1, 6, 34, 18, -1},
+ {21, 14, 28, -1, 22, 7, 35, -1, 23},
+ {22, 15, 29, 21, 23, 8, 36, -1, 24},
+ {23, 16, 30, 22, 24, 9, 37, 21, 25},
+ {24, 17, 31, 23, 25, 10, 38, 22, 26},
+ {25, 18, 32, 24, 26, 11, 39, 23, 27},
+ {26, 19, 33, 25, 27, 12, 40, 24, -1},
+ {27, 20, 34, 26, -1, 13, 41, 25, -1},
+ {28, 21, 35, -1, 29, 14, 42, -1, 30},
+ {29, 22, 36, 28, 30, 15, 43, -1, 31},
+ {30, 23, 37, 29, 31, 16, 44, 28, 32},
+ {31, 24, 38, 30, 32, 17, 45, 29, 33},
+ {32, 25, 39, 31, 33, 18, 46, 30, 34},
+ {33, 26, 40, 32, 34, 19, 47, 31, -1},
+ {34, 27, 41, 33, -1, 20, 48, 32, -1},
+ {35, 28, 42, -1, 36, 21, 49, -1, 37},
+ {36, 29, 43, 35, 37, 22, 50, -1, 38},
+ {37, 30, 44, 36, 38, 23, 51, 35, 39},
+ {38, 31, 45, 37, 39, 24, 52, 36, 40},
+ {39, 32, 46, 38, 40, 25, 53, 37, 41},
+ {40, 33, 47, 39, 41, 26, 54, 38, -1},
+ {41, 34, 48, 40, -1, 27, 55, 39, -1},
+ {42, 35, 49, -1, 43, 28, -1, -1, 44},
+ {43, 36, 50, 42, 44, 29, -1, -1, 45},
+ {44, 37, 51, 43, 45, 30, -1, 42, 46},
+ {45, 38, 52, 44, 46, 31, -1, 43, 47},
+ {46, 39, 53, 45, 47, 32, -1, 44, 48},
+ {47, 40, 54, 46, 48, 33, -1, 45, -1},
+ {48, 41, 55, 47, -1, 34, -1, 46, -1},
+ {49, 42, -1, -1, 50, 35, -1, -1, 51},
+ {50, 43, -1, 49, 51, 36, -1, -1, 52},
+ {51, 44, -1, 50, 52, 37, -1, 49, 53},
+ {52, 45, -1, 51, 53, 38, -1, 50, 54},
+ {53, 46, -1, 52, 54, 39, -1, 51, 55},
+ {54, 47, -1, 53, 55, 40, -1, 52, -1},
+ {55, 48, -1, 54, -1, 41, -1, 53, -1}
+};
+#elif defined GC_62
+int core2test[62][NUM_CORES2TEST] = {
+ { 0, -1, 6, -1, 1, -1, 14, -1, 2},
+ { 1, -1, 7, 0, 2, -1, 15, -1, 3},
+ { 2, -1, 8, 1, 3, -1, 16, 0, 4},
+ { 3, -1, 9, 2, 4, -1, 17, 1, 5},
+ { 4, -1, 10, 3, 5, -1, 18, 2, -1},
+ { 5, -1, 11, 4, -1, -1, 19, 3, -1},
+ { 6, 0, 14, -1, 7, -1, 22, -1, 8},
+ { 7, 1, 15, 6, 8, -1, 23, -1, 9},
+ { 8, 2, 16, 7, 9, -1, 24, 6, 10},
+ { 9, 3, 17, 8, 10, -1, 25, 7, 11},
+ {10, 4, 18, 9, 11, -1, 26, 8, 12},
+ {11, 5, 19, 10, 12, -1, 27, 9, 13},
+ {12, -1, 20, 11, 13, -1, 28, 10, -1},
+ {13, -1, 21, 12, -1, -1, 29, 11, -1},
+ {14, 6, 22, -1, 15, 0, 30, -1, 16},
+ {15, 7, 23, 14, 16, 1, 31, -1, 17},
+ {16, 8, 24, 15, 17, 2, 32, 14, 18},
+ {17, 9, 25, 16, 18, 3, 33, 15, 19},
+ {18, 10, 26, 17, 19, 4, 34, 16, 20},
+ {19, 11, 27, 18, 20, 5, 35, 17, 21},
+ {20, 12, 28, 19, 21, -1, 36, 18, -1},
+ {21, 13, 29, 28, -1, -1, 37, 19, -1},
+ {22, 14, 30, -1, 23, 6, 38, -1, 24},
+ {23, 15, 31, 22, 24, 7, 39, -1, 25},
+ {24, 16, 32, 23, 25, 8, 40, 22, 26},
+ {25, 17, 33, 24, 26, 9, 41, 23, 27},
+ {26, 18, 34, 25, 27, 10, 42, 24, 28},
+ {27, 19, 35, 26, 28, 11, 43, 25, 29},
+ {28, 20, 36, 27, 29, 12, 44, 26, -1},
+ {29, 21, 37, 28, -1, 13, 45, 27, -1},
+ {30, 22, 38, -1, 31, 22, 46, -1, 32},
+ {31, 23, 39, 30, 32, 15, 47, -1, 33},
+ {32, 24, 40, 31, 33, 16, 48, 30, 34},
+ {33, 25, 41, 32, 34, 17, 49, 31, 35},
+ {34, 26, 42, 33, 35, 18, 50, 32, 36},
+ {35, 27, 43, 34, 36, 19, 51, 33, 37},
+ {36, 28, 44, 35, 37, 20, 52, 34, -1},
+ {37, 29, 45, 36, -1, 21, 53, 35, -1},
+ {38, 30, 46, -1, 39, 22, 54, -1, 40},
+ {39, 31, 47, 38, 40, 23, 55, -1, 41},
+ {40, 32, 48, 39, 41, 24, 56, 38, 42},
+ {41, 33, 49, 40, 42, 25, 57, 39, 43},
+ {42, 34, 50, 41, 43, 26, 58, 40, 44},
+ {43, 35, 51, 42, 44, 27, 59, 41, 45},
+ {44, 36, 52, 43, 45, 28, 60, 42, -1},
+ {45, 37, 53, 44, -1, 29, 61, 43, -1},
+ {46, 38, 54, -1, 47, 30, -1, -1, 48},
+ {47, 39, 55, 46, 48, 31, -1, -1, 49},
+ {48, 40, 56, 47, 49, 32, -1, 46, 50},
+ {49, 41, 57, 48, 50, 33, -1, 47, 51},
+ {50, 42, 58, 49, 51, 34, -1, 48, 52},
+ {51, 43, 59, 50, 52, 35, -1, 49, 53},
+ {52, 44, 60, 51, 53, 36, -1, 50, -1},
+ {53, 45, 61, 52, -1, 37, -1, 51, -1},
+ {54, 46, -1, -1, 55, 38, -1, -1, 56},
+ {55, 47, -1, 54, 56, 39, -1, -1, 57},
+ {56, 48, -1, 55, 57, 40, -1, 54, 58},
+ {57, 49, -1, 56, 59, 41, -1, 55, 59},
+ {58, 50, -1, 57, 59, 42, -1, 56, 60},
+ {59, 51, -1, 58, 60, 43, -1, 57, 61},
+ {60, 52, -1, 59, 61, 44, -1, 58, -1},
+ {61, 53, -1, 60, -1, 45, -1, 59, -1}
+};
+#endif // GC_1
+#endif
+
+inline __attribute__((always_inline))
+void setupsmemmode(void) {
+#ifdef SMEML
+ // Only allocate local mem chunks to each core.
+ // If a core has used up its local shared memory, start gc.
+ bamboo_smem_mode = SMEMLOCAL;
+#elif defined SMEMF
+ // Allocate the local shared memory to each core with the highest priority,
+ // if a core has used up its local shared memory, try to allocate the
+ // shared memory that belong to its neighbours, if also failed, start gc.
+ bamboo_smem_mode = SMEMFIXED;
+#elif defined SMEMM
+ // Allocate the local shared memory to each core with the highest priority,
+ // if a core has used up its local shared memory, try to allocate the
+ // shared memory that belong to its neighbours first, if failed, check
+ // current memory allocation rate, if it has already reached the threshold,
+ // start gc, otherwise, allocate the shared memory globally. If all the
+ // shared memory has been used up, start gc.
+ bamboo_smem_mode = SMEMMIXED;
+#elif defined SMEMG
+ // Allocate all the memory chunks globally, do not consider the host cores
+ // When all the shared memory are used up, start gc.
+ bamboo_smem_mode = SMEMGLOBAL;
+#else
+ // defaultly using local mode
+ bamboo_smem_mode = SMEMLOCAL;
+ //bamboo_smem_mode = SMEMGLOBAL;
+ //bamboo_smem_mode = SMEMFIXED;
+#endif
+} // void setupsmemmode(void)
+#endif
+
+inline __attribute__((always_inline))
+void initruntimedata() {
+ int i;
+ // initialize the arrays
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ // startup core to initialize corestatus[]
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ corestatus[i] = 1;
+ numsendobjs[i] = 0;
+ numreceiveobjs[i] = 0;
+#ifdef PROFILE
+ // initialize the profile data arrays
+ profilestatus[i] = 1;
+#endif
+#ifdef MULTICORE_GC
+ gccorestatus[i] = 1;
+ gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
+ gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
+#endif
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+#ifdef MULTICORE_GC
+ for(i = 0; i < NUMCORES4GC; ++i) {
+ gcloads[i] = 0;
+ gcrequiredmems[i] = 0;
+ gcstopblock[i] = 0;
+ gcfilledblocks[i] = 0;
+ } // for(i = 0; i < NUMCORES4GC; ++i)
+#ifdef GC_PROFILE
+ gc_infoIndex = 0;
+ gc_infoOverflow = false;
+ gc_num_livespace = 0;
+ gc_num_freespace = 0;
+#endif
+#endif
+ numconfirm = 0;
+ waitconfirm = false;
+
+ // TODO for test
+ total_num_t6 = 0;
+ }
+
+ busystatus = true;
+ self_numsendobjs = 0;
+ self_numreceiveobjs = 0;
+
+ for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
+ msgdata[i] = -1;
+ }
+ msgdataindex = 0;
+ msgdatalast = 0;
+ msglength = BAMBOO_MSG_BUF_LENGTH;
+ msgdatafull = false;
+ for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
+ outmsgdata[i] = -1;
+ }
+ outmsgindex = 0;
+ outmsglast = 0;
+ outmsgleft = 0;
+ isMsgHanging = false;
+ //isMsgSending = false;
+
+ smemflag = true;
+ bamboo_cur_msp = NULL;
+ bamboo_smem_size = 0;
+ totransobjqueue = createQueue_I();
+
+#ifdef MULTICORE_GC
+ bamboo_smem_zero_top = NULL;
+ gcflag = false;
+ gcprocessing = false;
+ gcphase = FINISHPHASE;
+ //gcnumpre = 0;
+ gcprecheck = true;
+ gccurr_heaptop = 0;
+ gcself_numsendobjs = 0;
+ gcself_numreceiveobjs = 0;
+ gcmarkedptrbound = 0;
+#ifdef LOCALHASHTBL_TEST
+ gcpointertbl = allocateRuntimeHash_I(20);
+#else
+ gcpointertbl = mgchashCreate_I(2000, 0.75);
+#endif
+ //gcpointertbl = allocateMGCHash_I(20);
+ gcforwardobjtbl = allocateMGCHash_I(20, 3);
+ gcobj2map = 0;
+ gcmappedobj = 0;
+ //gcismapped = false;
+ gcnumlobjs = 0;
+ gcheaptop = 0;
+ gctopcore = 0;
+ gctopblock = 0;
+ gcmovestartaddr = 0;
+ gctomove = false;
+ gcmovepending = 0;
+ gcblock2fill = 0;
+ gcsbstarttbl = BAMBOO_BASE_VA;
+ bamboo_smemtbl = (void *)gcsbstarttbl
+ + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
+ if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
+ int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
+ -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
+ int kk = 0;
+ unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
+ while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
+ t_size = t_size << 1;
+ kk++;
+ }
+ t_size = tmp_k >> kk;
+ gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
+ } else {
+ gcsharedptbl = NULL;
+ }
+ BAMBOO_MEMSET_WH(gcrpointertbls, 0,
+ sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
+ //sizeof(struct RuntimeHash *)*NUMCORES4GC);
+#ifdef SMEMM
+ gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
+ -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
+ gcmem_mixed_usedmem = 0;
+#endif
+#ifdef GC_PROFILE
+ gc_num_obj = 0;
+ gc_num_liveobj = 0;
+ gc_num_forwardobj = 0;
+ gc_num_profiles = NUMCORESACTIVE - 1;
+#endif
+#ifdef GC_FLUSH_DTLB
+ gc_num_flush_dtlb = 0;
+#endif
+ gc_localheap_s = false;
+#ifdef GC_CACHE_ADAPT
+ gccachestage = false;
+ // enable the timer interrupt
+ bamboo_tile_timer_set_next_event(500000000); // TODO
+ bamboo_unmask_timer_intr();
+ //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
+ bamboo_dtlb_sampling_process();
+#endif // GC_CACHE_ADAPT
+#else
+ // create the lock table, lockresult table and obj queue
+ locktable.size = 20;
+ locktable.bucket =
+ (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
+ /* Set allocation blocks*/
+ locktable.listhead=NULL;
+ locktable.listtail=NULL;
+ /*Set data counts*/
+ locktable.numelements = 0;
+ lockobj = 0;
+ lock2require = 0;
+ lockresult = 0;
+ lockflag = false;
+ lockRedirectTbl = allocateRuntimeHash_I(20);
+ objRedirectLockTbl = allocateRuntimeHash_I(20);
+#endif
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ objqueue.head = NULL;
+ objqueue.tail = NULL;
+
+ currtpd = NULL;
+
+#ifdef PROFILE
+ stall = false;
+ //isInterrupt = true;
+ totalexetime = -1;
+ //interrupttime = 0;
+ taskInfoIndex = 0;
+ taskInfoOverflow = false;
+#ifdef PROFILE_INTERRUPT
+ interruptInfoIndex = 0;
+ interruptInfoOverflow = false;
+#endif // PROFILE_INTERRUPT
+#endif // PROFILE
+
+ for(i = 0; i < MAXTASKPARAMS; i++) {
+ runtime_locks[i].redirectlock = 0;
+ runtime_locks[i].value = 0;
+ }
+ runtime_locklen = 0;
+}
+
+inline __attribute__((always_inline))
+void disruntimedata() {
+#ifdef MULTICORE_GC
+#ifdef LOCALHASHTBL_TEST
+ freeRuntimeHash(gcpointertbl);
+#else
+ mgchashDelete(gcpointertbl);
+#endif
+ //freeMGCHash(gcpointertbl);
+ freeMGCHash(gcforwardobjtbl);
+ // for mapping info structures
+ //freeRuntimeHash(gcrcoretbl);
+#else
+ freeRuntimeHash(lockRedirectTbl);
+ freeRuntimeHash(objRedirectLockTbl);
+ RUNFREE(locktable.bucket);
+#endif
+ if(activetasks != NULL) {
+ genfreehashtable(activetasks);
+ }
+ if(currtpd != NULL) {
+ RUNFREE(currtpd->parameterArray);
+ RUNFREE(currtpd);
+ currtpd = NULL;
+ }
+ BAMBOO_LOCAL_MEM_CLOSE();
+ BAMBOO_SHARE_MEM_CLOSE();
+}
+
+inline __attribute__((always_inline))
+bool checkObjQueue() {
+ bool rflag = false;
+ struct transObjInfo * objInfo = NULL;
+ int grount = 0;
+
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ bool isChecking = false;
+ if(!isEmpty(&objqueue)) {
+ profileTaskStart("objqueue checking");
+ isChecking = true;
+ } // if(!isEmpty(&objqueue))
+#endif
+#endif
+
+ while(!isEmpty(&objqueue)) {
+ void * obj = NULL;
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+#ifdef PROFILE
+ //isInterrupt = false;
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeee1);
+#endif
+ rflag = true;
+ objInfo = (struct transObjInfo *)getItem(&objqueue);
+ obj = objInfo->objptr;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG((int)obj);
+#endif
+ // grab lock and flush the obj
+ grount = 0;
+ getwritelock_I(obj);
+ while(!lockflag) {
+ BAMBOO_WAITING_FOR_LOCK(0);
+ } // while(!lockflag)
+ grount = lockresult;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(grount);
+#endif
+
+ lockresult = 0;
+ lockobj = 0;
+ lock2require = 0;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+
+ if(grount == 1) {
+ int k = 0;
+ // flush the object
+#ifdef CACHEFLUSH
+ BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
+ BAMBOO_CACHE_FLUSH_RANGE((int)obj,
+ classsize[((struct ___Object___ *)obj)->type]);
+#endif
+ // enqueue the object
+ for(k = 0; k < objInfo->length; ++k) {
+ int taskindex = objInfo->queues[2 * k];
+ int paramindex = objInfo->queues[2 * k + 1];
+ struct parameterwrapper ** queues =
+ &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(taskindex);
+ BAMBOO_DEBUGPRINT_REG(paramindex);
+ struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
+ tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
+ BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
+ (long)obj, tmpptr->flag);
+#endif
+ enqueueObject_I(obj, queues, 1);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
+#endif
+ } // for(k = 0; k < objInfo->length; ++k)
+ releasewritelock_I(obj);
+ RUNFREE(objInfo->queues);
+ RUNFREE(objInfo);
+ } else {
+ // can not get lock
+ // put it at the end of the queue if no update version in the queue
+ struct QueueItem * qitem = getHead(&objqueue);
+ struct QueueItem * prev = NULL;
+ while(qitem != NULL) {
+ struct transObjInfo * tmpinfo =
+ (struct transObjInfo *)(qitem->objectptr);
+ if(tmpinfo->objptr == obj) {
+ // the same object in the queue, which should be enqueued
+ // recently. Current one is outdate, do not re-enqueue it
+ RUNFREE(objInfo->queues);
+ RUNFREE(objInfo);
+ goto objqueuebreak;
+ } else {
+ prev = qitem;
+ } // if(tmpinfo->objptr == obj)
+ qitem = getNextQueueItem(prev);
+ } // while(qitem != NULL)
+ // try to execute active tasks already enqueued first
+ addNewItem_I(&objqueue, objInfo);
+#ifdef PROFILE
+ //isInterrupt = true;
+#endif
+objqueuebreak:
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ break;
+ } // if(grount == 1)
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ } // while(!isEmpty(&objqueue))
+
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ if(isChecking) {
+ profileTaskEnd();
+ } // if(isChecking)
+#endif
+#endif
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee02);
+#endif
+ return rflag;
+}
+
+inline __attribute__((always_inline))
+void checkCoreStatus() {
+ bool allStall = false;
+ int i = 0;
+ int sumsendobj = 0;
+ if((!waitconfirm) ||
+ (waitconfirm && (numconfirm == 0))) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee04);
+ BAMBOO_DEBUGPRINT_REG(waitconfirm);
+#endif
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ corestatus[BAMBOO_NUM_OF_CORE] = 0;
+ numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
+ numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
+ // check the status of all cores
+ allStall = true;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
+#endif
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
+#endif
+ if(corestatus[i] != 0) {
+ allStall = false;
+ break;
+ }
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+ if(allStall) {
+ // 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
+ sumsendobj = 0;
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj += numsendobjs[i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
+#endif
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+ sumsendobj -= numreceiveobjs[i];
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
+#endif
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+ if(0 == sumsendobj) {
+ if(!waitconfirm) {
+ // the first time found all cores stall
+ // send out status confirm msg to all other cores
+ // reset the corestatus array too
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee05);
+#endif
+ corestatus[BAMBOO_NUM_OF_CORE] = 1;
+ waitconfirm = true;
+ numconfirm = NUMCORESACTIVE - 1;
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ for(i = 1; i < NUMCORESACTIVE; ++i) {
+ corestatus[i] = 1;
+ // send status confirm msg to core i
+ send_msg_1(i, STATUSCONFIRM, false);
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+ return;
+ } else {
+ // all the core status info are the latest
+ // terminate; for profiling mode, send request to all
+ // other cores to pour out profiling data
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee06);
+#endif
+
+#ifdef USEIO
+ totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
+#else
+#ifdef PROFILE
+ //BAMBOO_DEBUGPRINT_REG(interrupttime);
+#endif
+
+ BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
+ //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
+#ifdef GC_FLUSH_DTLB
+ BAMBOO_DEBUGPRINT_REG(gc_num_flush_dtlb);
+#endif
+#ifndef BAMBOO_MEMPROF
+ BAMBOO_DEBUGPRINT(0xbbbbbbbb);
+#endif
+#endif
+ // profile mode, send msgs to other cores to request pouring
+ // out progiling data
+#ifdef PROFILE
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ for(i = 1; i < NUMCORESACTIVE; ++i) {
+ // send profile request msg to core i
+ send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
+ } // for(i = 1; i < NUMCORESACTIVE; ++i)
+#ifndef RT_TEST
+ // pour profiling data on startup core
+ outputProfileData();
+#endif
+ while(true) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ profilestatus[BAMBOO_NUM_OF_CORE] = 0;
+ // check the status of all cores
+ allStall = true;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
+#endif
+ for(i = 0; i < NUMCORESACTIVE; ++i) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
+#endif
+ if(profilestatus[i] != 0) {
+ allStall = false;
+ break;
+ }
+ } // for(i = 0; i < NUMCORESACTIVE; ++i)
+ if(!allStall) {
+ int halt = 100;
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ while(halt--) {
+ }
+ } else {
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ break;
+ } // if(!allStall)
+ } // while(true)
+#endif
+
+ // gc_profile mode, output gc prfiling data
+#ifdef MULTICORE_GC
+#ifdef GC_CACHE_ADAPT
+ bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
+#endif // GC_CACHE_ADAPT
+#ifdef GC_PROFILE
+ gc_outputProfileData();
+#endif // #ifdef GC_PROFILE
+#endif // #ifdef MULTICORE_GC
+ disruntimedata();
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+ terminate(); // All done.
+ } // if(!waitconfirm)
+ } else {
+ // still some objects on the fly on the network
+ // reset the waitconfirm and numconfirm
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee07);
+#endif
+ waitconfirm = false;
+ numconfirm = 0;
+ } // if(0 == sumsendobj)
+ } else {
+ // not all cores are stall, keep on waiting
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee08);
+#endif
+ waitconfirm = false;
+ numconfirm = 0;
+ } // if(allStall)
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ } // if((!waitconfirm) ||
+}
+
+// main function for each core
+inline void run(void * arg) {
+ int i = 0;
+ int argc = 1;
+ char ** argv = NULL;
+ bool sendStall = false;
+ bool isfirst = true;
+ bool tocontinue = false;
+
+ corenum = BAMBOO_GET_NUM_OF_CORE();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xeeee);
+ BAMBOO_DEBUGPRINT_REG(corenum);
+ BAMBOO_DEBUGPRINT(STARTUPCORE);
+#endif
+ //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME()); // TODO
+
+ // initialize runtime data structures
+ initruntimedata();
+
+ // other architecture related initialization
+ initialization();
+ initCommunication();
+
+ initializeexithandler();
+
+ // main process of the execution module
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+ // non-executing cores, only processing communications
+ activetasks = NULL;
+#ifdef PROFILE
+ //isInterrupt = false;
+#endif
+ fakeExecution();
+ } else {
+ /* Create queue of active tasks */
+ activetasks=
+ genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
+ (int (*)(void *,void *)) &comparetpd);
+
+ /* Process task information */
+ processtasks();
+
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ /* Create startup object */
+ createstartupobject(argc, argv);
+ }
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee00);
+#endif
+
+ while(true) {
+
+#ifdef MULTICORE_GC
+//#ifdef GC_CACHE_ADAPT
+ // do dtlb sampling if necessary
+// bamboo_dtlb_sampling_process();
+//#endif // GC_CACHE_ADAPT
+ // check if need to do GC
+ if(gcflag) {
+ gc(NULL);
+ }
+#endif // MULTICORE_GC
+
+ // check if there are new active tasks can be executed
+ executetasks();
+ if(busystatus) {
+ sendStall = false;
+ }
+
+#ifndef INTERRUPT
+ while(receiveObject() != -1) {
+ }
+#endif
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee01);
+#endif
+
+ // check if there are some pending objects,
+ // if yes, enqueue them and executetasks again
+ tocontinue = checkObjQueue();
+
+ if(!tocontinue) {
+ // check if stop
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ if(isfirst) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee03);
+#endif
+ isfirst = false;
+ }
+ checkCoreStatus();
+ } else {
+ if(!sendStall) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee09);
+#endif
+#ifdef PROFILE
+ if(!stall) {
+#endif
+ if(isfirst) {
+ // wait for some time
+ int halt = 10000;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee0a);
+#endif
+ while(halt--) {
+ }
+ isfirst = false;
+ } else {
+ // send StallMsg to startup core
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee0b);
+#endif
+ // send stall msg
+ send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs, false);
+ sendStall = true;
+ isfirst = true;
+ busystatus = false;
+ }
+#ifdef PROFILE
+ }
+#endif
+ } else {
+ isfirst = true;
+ busystatus = false;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xee0c);
+#endif
+ } // if(!sendStall)
+ } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
+ } // if(!tocontinue)
+ } // while(true)
+ } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
+
+} // run()
+
+struct ___createstartupobject____I_locals {
+ INTPTR size;
+ void * next;
+ struct ___StartupObject___ * ___startupobject___;
+ struct ArrayObject * ___stringarray___;
+}; // struct ___createstartupobject____I_locals
+
+void createstartupobject(int argc,
+ char ** argv) {
+ int i;
+
+ /* Allocate startup object */
+#ifdef MULTICORE_GC
+ struct ___createstartupobject____I_locals ___locals___ =
+ {2, NULL, NULL, NULL};
+ struct ___StartupObject___ *startupobject=
+ (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
+ ___locals___.___startupobject___ = startupobject;
+ struct ArrayObject * stringarray=
+ allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
+ ___locals___.___stringarray___ = stringarray;
+#else
+ struct ___StartupObject___ *startupobject=
+ (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
+ struct ArrayObject * stringarray=
+ allocate_newarray(STRINGARRAYTYPE, argc-1);
+#endif
+ /* Build array of strings */
+ startupobject->___parameters___=stringarray;
+ for(i=1; i<argc; i++) {
+ int length=strlen(argv[i]);
+#ifdef MULTICORE_GC
+ struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
+#else
+ struct ___String___ *newstring=NewString(argv[i],length);
+#endif
+ ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
+ newstring;
+ }
+
+ startupobject->version = 0;
+ startupobject->lock = NULL;
+
+ /* Set initialized flag for startup object */
+ flagorandinit(startupobject,1,0xFFFFFFFF);
+ enqueueObject(startupobject, NULL, 0);
+#ifdef CACHEFLUSH
+ BAMBOO_CACHE_FLUSH_ALL();
+#endif
+}
+
+int hashCodetpd(struct taskparamdescriptor *ftd) {
+ int hash=(int)ftd->task;
+ int i;
+ for(i=0; i<ftd->numParameters; i++) {
+ hash^=(int)ftd->parameterArray[i];
+ }
+ return hash;
+}
+
+int comparetpd(struct taskparamdescriptor *ftd1,
+ struct taskparamdescriptor *ftd2) {
+ int i;
+ if (ftd1->task!=ftd2->task)
+ return 0;
+ for(i=0; i<ftd1->numParameters; i++)
+ if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
+ return 0;
+ return 1;
+}
+
+/* This function sets a tag. */
+#ifdef MULTICORE_GC
+void tagset(void *ptr,
+ struct ___Object___ * obj,
+ struct ___TagDescriptor___ * tagd) {
+#else
+void tagset(struct ___Object___ * obj,
+ struct ___TagDescriptor___ * tagd) {
+#endif
+ struct ArrayObject * ao=NULL;
+ struct ___Object___ * tagptr=obj->___tags___;
+ if (tagptr==NULL) {
+ obj->___tags___=(struct ___Object___ *)tagd;
+ } else {
+ /* Have to check if it is already set */
+ if (tagptr->type==TAGTYPE) {
+ struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
+ if (td==tagd) {
+ return;
+ }
+#ifdef MULTICORE_GC
+ int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
+ struct ArrayObject * ao=
+ allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
+ obj=(struct ___Object___ *)ptrarray[2];
+ tagd=(struct ___TagDescriptor___ *)ptrarray[3];
+ td=(struct ___TagDescriptor___ *) obj->___tags___;
+#else
+ ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
+#endif
+
+ ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
+ ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
+ obj->___tags___=(struct ___Object___ *) ao;
+ ao->___cachedCode___=2;
+ } else {
+ /* Array Case */
+ int i;
+ struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+ for(i=0; i<ao->___cachedCode___; i++) {
+ struct ___TagDescriptor___ * td=
+ ARRAYGET(ao, struct ___TagDescriptor___*, i);
+ if (td==tagd) {
+ return;
+ }
+ }
+ if (ao->___cachedCode___<ao->___length___) {
+ ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
+ ao->___cachedCode___++;
+ } else {
+#ifdef MULTICORE_GC
+ int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
+ struct ArrayObject * aonew=
+ allocate_newarray(&ptrarray,TAGARRAYTYPE,
+ TAGARRAYINTERVAL+ao->___length___);
+ obj=(struct ___Object___ *)ptrarray[2];
+ tagd=(struct ___TagDescriptor___ *) ptrarray[3];
+ ao=(struct ArrayObject *)obj->___tags___;
+#else
+ struct ArrayObject * aonew=
+ allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
+#endif
+
+ aonew->___cachedCode___=ao->___length___+1;
+ for(i=0; i<ao->___length___; i++) {
+ ARRAYSET(aonew, struct ___TagDescriptor___*, i,
+ ARRAYGET(ao, struct ___TagDescriptor___*, i));
+ }
+ ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
+ }
+ }
+ }
+
+ {
+ struct ___Object___ * tagset=tagd->flagptr;
+ if(tagset==NULL) {
+ tagd->flagptr=obj;
+ } else if (tagset->type!=OBJECTARRAYTYPE) {
+#ifdef MULTICORE_GC
+ int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
+ struct ArrayObject * ao=
+ allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
+ obj=(struct ___Object___ *)ptrarray[2];
+ tagd=(struct ___TagDescriptor___ *)ptrarray[3];
+#else
+ struct ArrayObject * ao=
+ allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
+#endif
+ ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
+ ARRAYSET(ao, struct ___Object___ *, 1, obj);
+ ao->___cachedCode___=2;
+ tagd->flagptr=(struct ___Object___ *)ao;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) tagset;
+ if (ao->___cachedCode___<ao->___length___) {
+ ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
+ } else {
+ int i;
+#ifdef MULTICORE_GC
+ int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
+ struct ArrayObject * aonew=
+ allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
+ OBJECTARRAYINTERVAL+ao->___length___);
+ obj=(struct ___Object___ *)ptrarray[2];
+ tagd=(struct ___TagDescriptor___ *)ptrarray[3];
+ ao=(struct ArrayObject *)tagd->flagptr;
+#else
+ struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
+ OBJECTARRAYINTERVAL+ao->___length___);
+#endif
+ aonew->___cachedCode___=ao->___cachedCode___+1;
+ for(i=0; i<ao->___length___; i++) {
+ ARRAYSET(aonew, struct ___Object___*, i,
+ ARRAYGET(ao, struct ___Object___*, i));
+ }
+ ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
+ tagd->flagptr=(struct ___Object___ *) aonew;
+ }
+ }
+ }
+}
+
+/* This function clears a tag. */
+#ifdef MULTICORE_GC
+void tagclear(void *ptr,
+ struct ___Object___ * obj,
+ struct ___TagDescriptor___ * tagd) {
+#else
+void tagclear(struct ___Object___ * obj,
+ struct ___TagDescriptor___ * tagd) {
+#endif
+ /* We'll assume that tag is alway there.
+ Need to statically check for this of course. */
+ struct ___Object___ * tagptr=obj->___tags___;
+
+ if (tagptr->type==TAGTYPE) {
+ if ((struct ___TagDescriptor___ *)tagptr==tagd)
+ obj->___tags___=NULL;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+ int i;
+ for(i=0; i<ao->___cachedCode___; i++) {
+ struct ___TagDescriptor___ * td=
+ ARRAYGET(ao, struct ___TagDescriptor___ *, i);
+ if (td==tagd) {
+ ao->___cachedCode___--;
+ if (i<ao->___cachedCode___)
+ ARRAYSET(ao, struct ___TagDescriptor___ *, i,
+ ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
+ ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
+ if (ao->___cachedCode___==0)
+ obj->___tags___=NULL;
+ goto PROCESSCLEAR;
+ }
+ }
+ }
+PROCESSCLEAR:
+ {
+ struct ___Object___ *tagset=tagd->flagptr;
+ if (tagset->type!=OBJECTARRAYTYPE) {
+ if (tagset==obj)
+ tagd->flagptr=NULL;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) tagset;
+ int i;
+ for(i=0; i<ao->___cachedCode___; i++) {
+ struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
+ if (tobj==obj) {
+ ao->___cachedCode___--;
+ if (i<ao->___cachedCode___)
+ ARRAYSET(ao, struct ___Object___ *, i,
+ ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
+ ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
+ if (ao->___cachedCode___==0)
+ tagd->flagptr=NULL;
+ goto ENDCLEAR;
+ }
+ }
+ }
+ }
+ENDCLEAR:
+ return;
+}
+
+/* This function allocates a new tag. */
+#ifdef MULTICORE_GC
+struct ___TagDescriptor___ * allocate_tag(void *ptr,
+ int index) {
+ struct ___TagDescriptor___ * v=
+ (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
+ classsize[TAGTYPE]);
+#else
+struct ___TagDescriptor___ * allocate_tag(int index) {
+ struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
+#endif
+ v->type=TAGTYPE;
+ v->flag=index;
+ return v;
+}
+
+
+
+/* This function updates the flag for object ptr. It or's the flag
+ with the or mask and and's it with the andmask. */
+
+void flagbody(struct ___Object___ *ptr,
+ int flag,
+ struct parameterwrapper ** queues,
+ int length,
+ bool isnew);
+
+int flagcomp(const int *val1, const int *val2) {
+ return (*val1)-(*val2);
+}
+
+void flagorand(void * ptr,
+ int ormask,
+ int andmask,
+ struct parameterwrapper ** queues,
+ int length) {
+ {
+ int oldflag=((int *)ptr)[1];
+ int flag=ormask|oldflag;
+ flag&=andmask;
+ flagbody(ptr, flag, queues, length, false);
+ }
+}
+
+bool intflagorand(void * ptr,
+ int ormask,
+ int andmask) {
+ {
+ int oldflag=((int *)ptr)[1];
+ int flag=ormask|oldflag;
+ flag&=andmask;
+ if (flag==oldflag) /* Don't do anything */
+ return false;
+ else {
+ flagbody(ptr, flag, NULL, 0, false);
+ return true;
+ }
+ }
+}
+
+void flagorandinit(void * ptr,
+ int ormask,
+ int andmask) {
+ int oldflag=((int *)ptr)[1];
+ int flag=ormask|oldflag;
+ flag&=andmask;
+ flagbody(ptr,flag,NULL,0,true);
+}
+
+void flagbody(struct ___Object___ *ptr,
+ int flag,
+ struct parameterwrapper ** vqueues,
+ int vlength,
+ bool isnew) {
+ struct parameterwrapper * flagptr = NULL;
+ int i = 0;
+ struct parameterwrapper ** queues = vqueues;
+ int length = vlength;
+ int next;
+ int UNUSED, UNUSED2;
+ int * enterflags = NULL;
+ if((!isnew) && (queues == NULL)) {
+ if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
+ queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
+ length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
+ } else {
+ return;
+ }
+ }
+ ptr->flag=flag;
+
+ /*Remove object from all queues */
+ for(i = 0; i < length; ++i) {
+ flagptr = queues[i];
+ ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
+ (int *) &enterflags, &UNUSED, &UNUSED2);
+ ObjectHashremove(flagptr->objectset, (int)ptr);
+ if (enterflags!=NULL)
+ RUNFREE(enterflags);
+ }
+}
+
+void enqueueObject(void * vptr,
+ struct parameterwrapper ** vqueues,
+ int vlength) {
+ struct ___Object___ *ptr = (struct ___Object___ *)vptr;
+
+ {
+ //struct QueueItem *tmpptr;
+ struct parameterwrapper * parameter=NULL;
+ int j;
+ int i;
+ struct parameterwrapper * prevptr=NULL;
+ struct ___Object___ *tagptr=NULL;
+ struct parameterwrapper ** queues = vqueues;
+ int length = vlength;
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+ return;
+ }
+ if(queues == NULL) {
+ queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
+ length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
+ }
+ tagptr=ptr->___tags___;
+
+ /* Outer loop iterates through all parameter queues an object of
+ this type could be in. */
+ for(j = 0; j < length; ++j) {
+ parameter = queues[j];
+ /* Check tags */
+ if (parameter->numbertags>0) {
+ if (tagptr==NULL)
+ goto nextloop; //that means the object has no tag
+ //but that param needs tag
+ else if(tagptr->type==TAGTYPE) { //one tag
+ //struct ___TagDescriptor___ * tag=
+ //(struct ___TagDescriptor___*) tagptr;
+ for(i=0; i<parameter->numbertags; i++) {
+ //slotid is parameter->tagarray[2*i];
+ int tagid=parameter->tagarray[2*i+1];
+ if (tagid!=tagptr->flag)
+ goto nextloop; /*We don't have this tag */
+ }
+ } else { //multiple tags
+ struct ArrayObject * ao=(struct ArrayObject *) tagptr;
+ for(i=0; i<parameter->numbertags; i++) {
+ //slotid is parameter->tagarray[2*i];
+ int tagid=parameter->tagarray[2*i+1];
+ int j;
+ for(j=0; j<ao->___cachedCode___; j++) {
+ if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
+ goto foundtag;
+ }
+ goto nextloop;
+foundtag:
+ ;
+ }
+ }
+ }
+
+ /* Check flags */
+ for(i=0; i<parameter->numberofterms; i++) {
+ int andmask=parameter->intarray[i*2];
+ int checkmask=parameter->intarray[i*2+1];
+ if ((ptr->flag&andmask)==checkmask) {
+ enqueuetasks(parameter, prevptr, ptr, NULL, 0);
+ prevptr=parameter;
+ break;
+ }
+ }
+nextloop:
+ ;
+ }
+ }
+}
+
+void enqueueObject_I(void * vptr,
+ struct parameterwrapper ** vqueues,
+ int vlength) {
+ struct ___Object___ *ptr = (struct ___Object___ *)vptr;
+
+ {
+ //struct QueueItem *tmpptr;
+ struct parameterwrapper * parameter=NULL;
+ int j;
+ int i;
+ struct parameterwrapper * prevptr=NULL;
+ struct ___Object___ *tagptr=NULL;
+ struct parameterwrapper ** queues = vqueues;
+ int length = vlength;
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+ return;
+ }
+ if(queues == NULL) {
+ queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
+ length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
+ }
+ tagptr=ptr->___tags___;
+
+ /* Outer loop iterates through all parameter queues an object of
+ this type could be in. */
+ for(j = 0; j < length; ++j) {
+ parameter = queues[j];
+ /* Check tags */
+ if (parameter->numbertags>0) {
+ if (tagptr==NULL)
+ goto nextloop; //that means the object has no tag
+ //but that param needs tag
+ else if(tagptr->type==TAGTYPE) { //one tag
+ //struct ___TagDescriptor___*tag=(struct ___TagDescriptor___*)tagptr;
+ for(i=0; i<parameter->numbertags; i++) {
+ //slotid is parameter->tagarray[2*i];
+ int tagid=parameter->tagarray[2*i+1];
+ if (tagid!=tagptr->flag)
+ goto nextloop; /*We don't have this tag */
+ }
+ } else { //multiple tags
+ struct ArrayObject * ao=(struct ArrayObject *) tagptr;
+ for(i=0; i<parameter->numbertags; i++) {
+ //slotid is parameter->tagarray[2*i];
+ int tagid=parameter->tagarray[2*i+1];
+ int j;
+ for(j=0; j<ao->___cachedCode___; j++) {
+ if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
+ goto foundtag;
+ }
+ goto nextloop;
+foundtag:
+ ;
+ }
+ }
+ }
+
+ /* Check flags */
+ for(i=0; i<parameter->numberofterms; i++) {
+ int andmask=parameter->intarray[i*2];
+ int checkmask=parameter->intarray[i*2+1];
+ if ((ptr->flag&andmask)==checkmask) {
+ enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
+ prevptr=parameter;
+ break;
+ }
+ }
+nextloop:
+ ;
+ }
+ }
+}
+
+
+int * getAliasLock(void ** ptrs,
+ int length,
+ struct RuntimeHash * tbl) {
+ if(length == 0) {
+ return (int*)(RUNMALLOC(sizeof(int)));
+ } else {
+ int i = 0;
+ int locks[length];
+ int locklen = 0;
+ bool redirect = false;
+ int redirectlock = 0;
+ for(; i < length; i++) {
+ struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
+ int lock = 0;
+ int j = 0;
+ if(ptr->lock == NULL) {
+ lock = (int)(ptr);
+ } else {
+ lock = (int)(ptr->lock);
+ }
+ if(redirect) {
+ if(lock != redirectlock) {
+ RuntimeHashadd(tbl, lock, redirectlock);
+ }
+ } else {
+ if(RuntimeHashcontainskey(tbl, lock)) {
+ // already redirected
+ redirect = true;
+ RuntimeHashget(tbl, lock, &redirectlock);
+ for(; j < locklen; j++) {
+ if(locks[j] != redirectlock) {
+ RuntimeHashadd(tbl, locks[j], redirectlock);
+ }
+ }
+ } else {
+ bool insert = true;
+ for(j = 0; j < locklen; j++) {
+ if(locks[j] == lock) {
+ insert = false;
+ break;
+ } else if(locks[j] > lock) {
+ break;
+ }
+ }
+ if(insert) {
+ int h = locklen;
+ for(; h > j; h--) {
+ locks[h] = locks[h-1];
+ }
+ locks[j] = lock;
+ locklen++;
+ }
+ }
+ }
+ }
+ if(redirect) {
+ return (int *)redirectlock;
+ } else {
+ return (int *)(locks[0]);
+ }
+ }
+}
+
+void addAliasLock(void * ptr,
+ int lock) {
+ struct ___Object___ * obj = (struct ___Object___ *)ptr;
+ if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
+ // originally no alias lock associated or have a different alias lock
+ // flush it as the new one
+ obj->lock = (int *)lock;
+ }
+}
+
+#ifdef PROFILE
+inline void setTaskExitIndex(int index) {
+ taskInfoArray[taskInfoIndex]->exitIndex = index;
+}
+
+inline void addNewObjInfo(void * nobj) {
+ if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
+ taskInfoArray[taskInfoIndex]->newObjs = createQueue();
+ }
+ addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
+}
+#endif
+
+#ifdef MULTICORE_GC
+// Only allocate local mem chunks to each core.
+// If a core has used up its local shared memory, start gc.
+void * localmalloc_I(int coren,
+ int isize,
+ int * allocsize) {
+ void * mem = NULL;
+ int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
+ int i = 0;
+ int j = 0;
+ int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
+ int totest = tofindb;
+ int bound = BAMBOO_SMEM_SIZE_L;
+ int foundsmem = 0;
+ int size = 0;
+ do {
+ bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ int nsize = bamboo_smemtbl[totest];
+ bool islocal = true;
+ if(nsize < bound) {
+ bool tocheck = true;
+ // have some space in the block
+ if(totest == tofindb) {
+ // the first partition
+ size = bound - nsize;
+ } else if(nsize == 0) {
+ // an empty partition, can be appended
+ size += bound;
+ } else {
+ // not an empty partition, can not be appended
+ // the last continuous block is not big enough, go to check the next
+ // local block
+ islocal = true;
+ tocheck = false;
+ } // if(totest == tofindb) else if(nsize == 0) else ...
+ if(tocheck) {
+ if(size >= isize) {
+ // have enough space in the block, malloc
+ foundsmem = 1;
+ break;
+ } else {
+ // no enough space yet, try to append next continuous block
+ islocal = false;
+ } // if(size > isize) else ...
+ } // if(tocheck)
+ } // if(nsize < bound)
+ if(islocal) {
+ // no space in the block, go to check the next block
+ i++;
+ if(2==i) {
+ i = 0;
+ j++;
+ }
+ tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
+ } else {
+ totest += 1;
+ } // if(islocal) else ...
+ if(totest > gcnumblock-1-bamboo_reserved_smem) {
+ // no more local mem, do not find suitable block
+ foundsmem = 2;
+ break;
+ } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
+ } while(true);
+
+ if(foundsmem == 1) {
+ // find suitable block
+ mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
+ (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
+ (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
+ *allocsize = size;
+ // set bamboo_smemtbl
+ for(i = tofindb; i <= totest; i++) {
+ bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
+ }
+ } else if(foundsmem == 2) {
+ // no suitable block
+ *allocsize = 0;
+ }
+
+ return mem;
+} // void * localmalloc_I(int, int, int *)
+
+#ifdef SMEMF
+// Allocate the local shared memory to each core with the highest priority,
+// if a core has used up its local shared memory, try to allocate the
+// shared memory that belong to its neighbours, if also failed, start gc.
+void * fixedmalloc_I(int coren,
+ int isize,
+ int * allocsize) {
+ void * mem = NULL;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
+ int coords_x = bamboo_cpu2coords[gccorenum*2];
+ int coords_y = bamboo_cpu2coords[gccorenum*2+1];
+ int ii = 1;
+ int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
+ int totest = tofindb;
+ int bound = BAMBOO_SMEM_SIZE_L;
+ int foundsmem = 0;
+ int size = 0;
+ do {
+ bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ int nsize = bamboo_smemtbl[totest];
+ bool islocal = true;
+ if(nsize < bound) {
+ bool tocheck = true;
+ // have some space in the block
+ if(totest == tofindb) {
+ // the first partition
+ size = bound - nsize;
+ } else if(nsize == 0) {
+ // an empty partition, can be appended
+ size += bound;
+ } else {
+ // not an empty partition, can not be appended
+ // the last continuous block is not big enough, go to check the next
+ // local block
+ islocal = true;
+ tocheck = false;
+ } // if(totest == tofindb) else if(nsize == 0) else ...
+ if(tocheck) {
+ if(size >= isize) {
+ // have enough space in the block, malloc
+ foundsmem = 1;
+ break;
+ } else {
+ // no enough space yet, try to append next continuous block
+ // TODO may consider to go to next local block?
+ islocal = false;
+ } // if(size > isize) else ...
+ } // if(tocheck)
+ } // if(nsize < bound)
+ if(islocal) {
+ // no space in the block, go to check the next block
+ i++;
+ if(2==i) {
+ i = 0;
+ j++;
+ }
+ tofindb=totest=
+ gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
+ } else {
+ totest += 1;
+ } // if(islocal) else ...
+ if(totest > gcnumblock-1-bamboo_reserved_smem) {
+ // no more local mem, do not find suitable block on local mem
+ // try to malloc shared memory assigned to the neighbour cores
+ do{
+ k++;
+ if(k >= NUM_CORES2TEST) {
+ // no more memory available on either coren or its neighbour cores
+ foundsmem = 2;
+ goto memsearchresult;
+ }
+ } while(core2test[gccorenum][k] == -1);
+ i = 0;
+ j = 0;
+ tofindb=totest=
+ gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
+ } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
+ } while(true);
+
+memsearchresult:
+ if(foundsmem == 1) {
+ // find suitable block
+ mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
+ (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
+ (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
+ *allocsize = size;
+ // set bamboo_smemtbl
+ for(i = tofindb; i <= totest; i++) {
+ bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
+ }
+ } else if(foundsmem == 2) {
+ // no suitable block
+ *allocsize = 0;
+ }
+
+ return mem;
+} // void * fixedmalloc_I(int, int, int *)
+#endif // #ifdef SMEMF
+
+#ifdef SMEMM
+// Allocate the local shared memory to each core with the highest priority,
+// if a core has used up its local shared memory, try to allocate the
+// shared memory that belong to its neighbours first, if failed, check
+// current memory allocation rate, if it has already reached the threshold,
+// start gc, otherwise, allocate the shared memory globally. If all the
+// shared memory has been used up, start gc.
+void * mixedmalloc_I(int coren,
+ int isize,
+ int * allocsize) {
+ void * mem = NULL;
+ int i = 0;
+ int j = 0;
+ int k = 0;
+ int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
+ int ii = 1;
+ int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
+ int totest = tofindb;
+ int bound = BAMBOO_SMEM_SIZE_L;
+ int foundsmem = 0;
+ int size = 0;
+ do {
+ bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ int nsize = bamboo_smemtbl[totest];
+ bool islocal = true;
+ if(nsize < bound) {
+ bool tocheck = true;
+ // have some space in the block
+ if(totest == tofindb) {
+ // the first partition
+ size = bound - nsize;
+ } else if(nsize == 0) {
+ // an empty partition, can be appended
+ size += bound;
+ } else {
+ // not an empty partition, can not be appended
+ // the last continuous block is not big enough, go to check the next
+ // local block
+ islocal = true;
+ tocheck = false;
+ } // if(totest == tofindb) else if(nsize == 0) else ...
+ if(tocheck) {
+ if(size >= isize) {
+ // have enough space in the block, malloc
+ foundsmem = 1;
+ break;
+ } else {
+ // no enough space yet, try to append next continuous block
+ // TODO may consider to go to next local block?
+ islocal = false;
+ } // if(size > isize) else ...
+ } // if(tocheck)
+ } // if(nsize < bound)
+ if(islocal) {
+ // no space in the block, go to check the next block
+ i++;
+ if(2==i) {
+ i = 0;
+ j++;
+ }
+ tofindb=totest=
+ gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
+ } else {
+ totest += 1;
+ } // if(islocal) else ...
+ if(totest > gcnumblock-1-bamboo_reserved_smem) {
+ // no more local mem, do not find suitable block on local mem
+ // try to malloc shared memory assigned to the neighbour cores
+ do{
+ k++;
+ if(k >= NUM_CORES2TEST) {
+ if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
+ // no more memory available on either coren or its neighbour cores
+ foundsmem = 2;
+ goto memmixedsearchresult;
+ } else {
+ // try allocate globally
+ mem = globalmalloc_I(coren, isize, allocsize);
+ return mem;
+ }
+ }
+ } while(core2test[gccorenum][k] == -1);
+ i = 0;
+ j = 0;
+ tofindb=totest=
+ gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
+ } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
+ } while(true);
+
+memmixedsearchresult:
+ if(foundsmem == 1) {
+ // find suitable block
+ mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
+ (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
+ (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
+ *allocsize = size;
+ // set bamboo_smemtbl
+ for(i = tofindb; i <= totest; i++) {
+ bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
+ }
+ gcmem_mixed_usedmem += size;
+ if(tofindb == bamboo_free_block) {
+ bamboo_free_block = totest+1;
+ }
+ } else if(foundsmem == 2) {
+ // no suitable block
+ *allocsize = 0;
+ }
+
+ return mem;
+} // void * mixedmalloc_I(int, int, int *)
+#endif // #ifdef SMEMM
+
+// Allocate all the memory chunks globally, do not consider the host cores
+// When all the shared memory are used up, start gc.
+void * globalmalloc_I(int coren,
+ int isize,
+ int * allocsize) {
+ void * mem = NULL;
+ int tofindb = bamboo_free_block; //0;
+ int totest = tofindb;
+ int bound = BAMBOO_SMEM_SIZE_L;
+ int foundsmem = 0;
+ int size = 0;
+ if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
+ // Out of shared memory
+ *allocsize = 0;
+ return NULL;
+ }
+ do {
+ bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
+ int nsize = bamboo_smemtbl[totest];
+ bool isnext = false;
+ if(nsize < bound) {
+ bool tocheck = true;
+ // have some space in the block
+ if(totest == tofindb) {
+ // the first partition
+ size = bound - nsize;
+ } else if(nsize == 0) {
+ // an empty partition, can be appended
+ size += bound;
+ } else {
+ // not an empty partition, can not be appended
+ // the last continuous block is not big enough, start another block
+ isnext = true;
+ tocheck = false;
+ } // if(totest == tofindb) else if(nsize == 0) else ...
+ if(tocheck) {
+ if(size >= isize) {
+ // have enough space in the block, malloc
+ foundsmem = 1;
+ break;
+ } // if(size > isize)
+ } // if(tocheck)
+ } else {
+ isnext = true;
+ } // if(nsize < bound) else ...
+ totest += 1;
+ if(totest > gcnumblock-1-bamboo_reserved_smem) {
+ // no more local mem, do not find suitable block
+ foundsmem = 2;
+ break;
+ } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
+ if(isnext) {
+ // start another block
+ tofindb = totest;
+ } // if(islocal)
+ } while(true);
+
+ if(foundsmem == 1) {
+ // find suitable block
+ mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
+ (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
+ (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
+ *allocsize = size;
+ // set bamboo_smemtbl
+ for(int i = tofindb; i <= totest; i++) {
+ bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
+ }
+ if(tofindb == bamboo_free_block) {
+ bamboo_free_block = totest+1;
+ }
+ } else if(foundsmem == 2) {
+ // no suitable block
+ *allocsize = 0;
+ mem = NULL;
+ }
+
+ return mem;
+} // void * globalmalloc_I(int, int, int *)
+#endif // #ifdef MULTICORE_GC
+
+// malloc from the shared memory
+void * smemalloc_I(int coren,
+ int size,
+ int * allocsize) {
+ void * mem = NULL;
+#ifdef MULTICORE_GC
+ int isize = size+(BAMBOO_CACHE_LINE_SIZE);
+
+ // go through the bamboo_smemtbl for suitable partitions
+ switch(bamboo_smem_mode) {
+ case SMEMLOCAL: {
+ mem = localmalloc_I(coren, isize, allocsize);
+ break;
+ }
+
+ case SMEMFIXED: {
+#ifdef SMEMF
+ mem = fixedmalloc_I(coren, isize, allocsize);
+#else
+ // not supported yet
+ BAMBOO_EXIT(0xe001);
+#endif
+ break;
+ }
+
+ case SMEMMIXED: {
+#ifdef SMEMM
+ mem = mixedmalloc_I(coren, isize, allocsize);
+#else
+ // not supported yet
+ BAMBOO_EXIT(0xe002);
+#endif
+ break;
+ }
+
+ case SMEMGLOBAL: {
+ mem = globalmalloc_I(coren, isize, allocsize);
+ break;
+ }
+
+ default:
+ break;
+ }
+
+ if(mem == NULL) {
+#else
+ int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
+ if(toallocate > bamboo_free_smem_size) {
+ // no enough mem
+ mem = NULL;
+ } else {
+ mem = (void *)bamboo_free_smemp;
+ bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
+ bamboo_free_smem_size -= toallocate;
+ }
+ *allocsize = toallocate;
+ if(mem == NULL) {
+#endif // MULTICORE_GC
+ // no enough shared global memory
+ *allocsize = 0;
+#ifdef MULTICORE_GC
+ if(!gcflag) {
+ gcflag = true;
+ // inform other cores to stop and wait for gc
+ gcprecheck = true;
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ // reuse the gcnumsendobjs & gcnumreceiveobjs
+ gccorestatus[i] = 1;
+ gcnumsendobjs[0][i] = 0;
+ gcnumreceiveobjs[0][i] = 0;
+ }
+ for(int i = 0; i < NUMCORESACTIVE; i++) {
+ if(i != BAMBOO_NUM_OF_CORE) {
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_1(i, GCSTARTPRE);
+ } else {
+ send_msg_1(i, GCSTARTPRE, true);
+ }
+ }
+ }
+ }
+ return NULL;
+#else
+ BAMBOO_DEBUGPRINT(0xa001);
+ BAMBOO_EXIT(0xa001);
+#endif
+ }
+ return mem;
+} // void * smemalloc_I(int, int, int)
+
+INLINE int checkMsgLength_I(int size) {
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xcccc);
+#endif
+#endif
+ int type = msgdata[msgdataindex];
+ switch(type) {
+ case STATUSCONFIRM:
+ case TERMINATE:
+#ifdef MULTICORE_GC
+ case GCSTARTPRE:
+ case GCSTARTINIT:
+ case GCSTART:
+ case GCSTARTMAPINFO:
+ case GCSTARTFLUSH:
+ case GCFINISH:
+ case GCMARKCONFIRM:
+ case GCLOBJREQUEST:
+#ifdef GC_CACHE_ADAPT
+ case GCSTARTPREF:
+#endif // GC_CACHE_ADAPT
+#endif // MULTICORE_GC
+ {
+ msglength = 1;
+ break;
+ }
+
+ case PROFILEOUTPUT:
+ case PROFILEFINISH:
+#ifdef MULTICORE_GC
+ case GCSTARTCOMPACT:
+ case GCMARKEDOBJ:
+ case GCFINISHINIT:
+ case GCFINISHMAPINFO:
+ case GCFINISHFLUSH:
+#ifdef GC_CACHE_ADAPT
+ case GCFINISHPREF:
+#endif // GC_CACHE_ADAPT
+#endif // MULTICORE_GC
+ {
+ msglength = 2;
+ break;
+ }
+
+ case MEMREQUEST:
+ case MEMRESPONSE:
+#ifdef MULTICORE_GC
+ case GCMAPREQUEST:
+ case GCMAPINFO:
+ case GCMAPTBL:
+ case GCLOBJMAPPING:
+#endif
+ {
+ msglength = 3;
+ break;
+ }
+
+ case TRANSTALL:
+ case LOCKGROUNT:
+ case LOCKDENY:
+ case LOCKRELEASE:
+ case REDIRECTGROUNT:
+ case REDIRECTDENY:
+ case REDIRECTRELEASE:
+#ifdef MULTICORE_GC
+ case GCFINISHPRE:
+ case GCFINISHMARK:
+ case GCMOVESTART:
+#ifdef GC_PROFILE
+ case GCPROFILES:
+#endif
+#endif
+ {
+ msglength = 4;
+ break;
+ }
+
+ case LOCKREQUEST:
+ case STATUSREPORT:
+#ifdef MULTICORE_GC
+ case GCFINISHCOMPACT:
+ case GCMARKREPORT:
+#endif
+ {
+ msglength = 5;
+ break;
+ }
+
+ case REDIRECTLOCK:
+ {
+ msglength = 6;
+ break;
+ }
+
+ case TRANSOBJ: // nonfixed size
+#ifdef MULTICORE_GC
+ case GCLOBJINFO:
+#endif
+ { // nonfixed size
+ if(size > 1) {
+ msglength = msgdata[msgdataindex+1];
+ } else {
+ return -1;
+ }
+ break;
+ }
+
+ default:
+ {
+ BAMBOO_DEBUGPRINT_REG(type);
+ BAMBOO_DEBUGPRINT_REG(size);
+ BAMBOO_DEBUGPRINT_REG(msgdataindex);
+ BAMBOO_DEBUGPRINT_REG(msgdatalast);
+ BAMBOO_DEBUGPRINT_REG(msgdatafull);
+ int i = 6;
+ while(i-- > 0) {
+ BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
+ }
+ BAMBOO_EXIT(0xd005);
+ break;
+ }
+ }
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
+#endif
+#endif
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xffff);
+#endif
+#endif
+ return msglength;
+}
+
+INLINE void processmsg_transobj_I() {
+#ifdef PROFILE_INTERRUPT
+ /*if(!interruptInfoOverflow) {
+ InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
+ interruptInfoArray[interruptInfoIndex] = intInfo;
+ intInfo->startTime = BAMBOO_GET_EXE_TIME();
+ intInfo->endTime = -1;
+ }*/
+#endif
+ MSG_INDEXINC_I();
+ struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
+ int k = 0;
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe880);
+#endif
+#endif
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
+#endif
+ BAMBOO_EXIT(0xa002);
+ }
+ // store the object and its corresponding queue info, enqueue it later
+ transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
+ MSG_INDEXINC_I();
+ transObj->length = (msglength - 3) / 2;
+ transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
+ for(k = 0; k < transObj->length; ++k) {
+ transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
+ MSG_INDEXINC_I();
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
+#endif
+#endif
+ transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
+ MSG_INDEXINC_I();
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
+#endif
+#endif
+ }
+ // check if there is an existing duplicate item
+ {
+ struct QueueItem * qitem = getHead(&objqueue);
+ struct QueueItem * prev = NULL;
+ while(qitem != NULL) {
+ struct transObjInfo * tmpinfo =
+ (struct transObjInfo *)(qitem->objectptr);
+ if(tmpinfo->objptr == transObj->objptr) {
+ // the same object, remove outdate one
+ RUNFREE(tmpinfo->queues);
+ RUNFREE(tmpinfo);
+ removeItem(&objqueue, qitem);
+ //break;
+ } else {
+ prev = qitem;
+ }
+ if(prev == NULL) {
+ qitem = getHead(&objqueue);
+ } else {
+ qitem = getNextQueueItem(prev);
+ }
+ }
+ addNewItem_I(&objqueue, (void *)transObj);
+ }
+ ++(self_numreceiveobjs);
+#ifdef MULTICORE_GC
+ if(gcprocessing) {
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
+ // set the gcprecheck to enable checking again
+ gcprecheck = true;
+ } else {
+ // send a update pregc information msg to the master core
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs);
+ } else {
+ send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs, true);
+ }
+ }
+ }
+#endif
+#ifdef PROFILE_INTERRUPT
+ /*if(!interruptInfoOverflow) {
+ interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
+ interruptInfoIndex++;
+ if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
+ interruptInfoOverflow = true;
+ }
+ }*/
+#endif
+}
+
+INLINE void processmsg_transtall_I() {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive stall msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
+#endif
+ BAMBOO_EXIT(0xa003);
+ }
+ int num_core = msgdata[msgdataindex]; //[1]
+ MSG_INDEXINC_I();
+ if(num_core < NUMCORESACTIVE) {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe881);
+#endif
+#endif
+ corestatus[num_core] = 0;
+ numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
+ MSG_INDEXINC_I();
+ numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
+ MSG_INDEXINC_I();
+ }
+}
+
+#ifndef MULTICORE_GC
+INLINE void processmsg_lockrequest_I() {
+ // check to see if there is a lock exist for the required obj
+ // msgdata[1] -> lock type
+ int locktype = msgdata[msgdataindex]; //[1];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex]; // obj pointer
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex]; // lock
+ MSG_INDEXINC_I();
+ int data4 = msgdata[msgdataindex]; // request core
+ MSG_INDEXINC_I();
+ // -1: redirected, 0: approved, 1: denied
+ int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
+ if(deny == -1) {
+ // this lock request is redirected
+ return;
+ } else {
+ // send response msg
+ // for 32 bit machine, the size is always 4 words, cache the msg first
+ int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(data4, tmp, locktype, data2, data3);
+ } else {
+ send_msg_4(data4, tmp, locktype, data2, data3, true);
+ }
+ }
+}
+
+INLINE void processmsg_lockgrount_I() {
+ MSG_INDEXINC_I();
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
+#endif
+ BAMBOO_EXIT(0xa004);
+ }
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ if((lockobj == data2) && (lock2require == data3)) {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe882);
+#endif
+#endif
+ lockresult = 1;
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ } else {
+ // conflicts on lockresults
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa005);
+ }
+}
+
+INLINE void processmsg_lockdeny_I() {
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa006);
+ }
+ if((lockobj == data2) && (lock2require == data3)) {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe883);
+#endif
+#endif
+ lockresult = 0;
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ } else {
+ // conflicts on lockresults
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa007);
+ }
+}
+
+INLINE void processmsg_lockrelease_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // receive lock release msg
+ processlockrelease(data1, data2, 0, false);
+}
+
+INLINE void processmsg_redirectlock_I() {
+ // check to see if there is a lock exist for the required obj
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[1]; // lock type
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
+ int data4 = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[4]; // root request core
+ int data5 = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[5]; // request core
+ int deny = processlockrequest(data1, data3, data2, data5, data4, true);
+ if(deny == -1) {
+ // this lock request is redirected
+ return;
+ } else {
+ // send response msg
+ // for 32 bit machine, the size is always 4 words, cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
+ data1, data2, data3);
+ } else {
+ send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
+ data1, data2, data3, true);
+ }
+ }
+}
+
+INLINE void processmsg_redirectgrount_I() {
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa00a);
+ }
+ if(lockobj == data2) {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe891);
+#endif
+#endif
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ lockresult = 1;
+ lockflag = true;
+ RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ } else {
+ // conflicts on lockresults
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa00b);
+ }
+}
+
+INLINE void processmsg_redirectdeny_I() {
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa00c);
+ }
+ if(lockobj == data2) {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe892);
+#endif
+#endif
+ lockresult = 0;
+ lockflag = true;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+ } else {
+ // conflicts on lockresults
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa00d);
+ }
+}
+
+INLINE void processmsg_redirectrelease_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ processlockrelease(data1, data2, data3, true);
+}
+#endif // #ifndef MULTICORE_GC
+
+#ifdef PROFILE
+INLINE void processmsg_profileoutput_I() {
+ if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
+ // startup core can not receive profile output finish msg
+ BAMBOO_EXIT(0xa008);
+ }
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe885);
+#endif
+#endif
+ stall = true;
+ totalexetime = msgdata[msgdataindex]; //[1]
+ MSG_INDEXINC_I();
+#ifdef RT_TEST
+ BAMBOO_DEBUGPRINT_REG(dot_num);
+#else
+ outputProfileData();
+#endif
+ // cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
+ } else {
+ send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
+ }
+}
+
+INLINE void processmsg_profilefinish_I() {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive profile output finish msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
+#endif
+ BAMBOO_EXIT(0xa009);
+ }
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe886);
+#endif
+#endif
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ profilestatus[data1] = 0;
+}
+#endif // #ifdef PROFILE
+
+INLINE void processmsg_statusconfirm_I() {
+ if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
+ || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
+ // wrong core to receive such msg
+ BAMBOO_EXIT(0xa00e);
+ } else {
+ // send response msg
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe887);
+#endif
+#endif
+ // cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_5(STARTUPCORE, STATUSREPORT,
+ 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, true);
+ }
+ }
+}
+
+INLINE void processmsg_statusreport_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data4 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // receive a status confirm info
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // wrong core to receive such msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa00f);
+ } else {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe888);
+#endif
+#endif
+ if(waitconfirm) {
+ numconfirm--;
+ }
+ corestatus[data2] = data1;
+ numsendobjs[data2] = data3;
+ numreceiveobjs[data2] = data4;
+ }
+}
+
+INLINE void processmsg_terminate_I() {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe889);
+#endif
+#endif
+ disruntimedata();
+#ifdef MULTICORE_GC
+#ifdef GC_CACHE_ADAPT
+ bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
+#endif // GC_CACHE_ADAPT
+#endif // MULTICORE_GC
+ BAMBOO_EXIT_APP(0);
+}
+
+INLINE void processmsg_memrequest_I() {
+#ifdef PROFILE_INTERRUPT
+ /*if(!interruptInfoOverflow) {
+ InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
+ interruptInfoArray[interruptInfoIndex] = intInfo;
+ intInfo->startTime = BAMBOO_GET_EXE_TIME();
+ intInfo->endTime = -1;
+ }*/
+#endif
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // receive a shared memory request msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // wrong core to receive such msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xa010);
+ } else {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe88a);
+#endif
+#endif
+ int allocsize = 0;
+ void * mem = NULL;
+#ifdef MULTICORE_GC
+ if(gcprocessing) {
+ // is currently doing gc, dump this msg
+ if(INITPHASE == gcphase) {
+ // if still in the initphase of gc, send a startinit msg again,
+ // cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_1(data2, GCSTARTINIT);
+ } else {
+ send_msg_1(data2, GCSTARTINIT, true);
+ }
+ }
+ } else {
+#endif
+ mem = smemalloc_I(data2, data1, &allocsize);
+ if(mem != NULL) {
+ // send the start_va to request core, cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
+ } else {
+ send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
+ }
+ } //else
+ // if mem == NULL, the gcflag of the startup core has been set
+ // and all the other cores have been informed to start gc
+#ifdef MULTICORE_GC
+ }
+#endif
+ }
+#ifdef PROFILE_INTERRUPT
+ /*if(!interruptInfoOverflow) {
+ interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
+ interruptInfoIndex++;
+ if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
+ interruptInfoOverflow = true;
+ }
+ }*/
+#endif
+}
+
+INLINE void processmsg_memresponse_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // receive a shared memory response msg
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe88b);
+#endif
+#endif
+#ifdef MULTICORE_GC
+ // if is currently doing gc, dump this msg
+ if(!gcprocessing) {
+#endif
+ if(data2 == 0) {
+ bamboo_smem_size = 0;
+ bamboo_cur_msp = 0;
+#ifdef MULTICORE_GC
+ bamboo_smem_zero_top = 0;
+#endif
+ } else {
+#ifdef MULTICORE_GC
+ // fill header to store the size of this mem block
+ BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
+ //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
+ (*((int*)data1)) = data2;
+ bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
+ bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
+ bamboo_smem_zero_top = bamboo_cur_msp;
+#else
+ bamboo_smem_size = data2;
+ bamboo_cur_msp =(void*)(data1);
+#endif
+ }
+ smemflag = true;
+#ifdef MULTICORE_GC
+}
+#endif
+}
+
+#ifdef MULTICORE_GC
+INLINE void processmsg_gcstartpre_I() {
+ if(gcprocessing) {
+ // already stall for gc
+ // send a update pregc information msg to the master core
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs);
+ } else {
+ send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
+ self_numsendobjs, self_numreceiveobjs, true);
+ }
+ } else {
+ // the first time to be informed to start gc
+ gcflag = true;
+ if(!smemflag) {
+ // is waiting for response of mem request
+ // let it return NULL and start gc
+ bamboo_smem_size = 0;
+ bamboo_cur_msp = NULL;
+ smemflag = true;
+ bamboo_smem_zero_top = NULL;
+ }
+ }
+}
+
+INLINE void processmsg_gcstartinit_I() {
+ gcphase = INITPHASE;
+}
+
+INLINE void processmsg_gcstart_I() {
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe88c);
+#endif
+#endif
+ // set the GC flag
+ gcphase = MARKPHASE;
+}
+
+INLINE void processmsg_gcstartcompact_I() {
+ gcblock2fill = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[1];
+ gcphase = COMPACTPHASE;
+}
+
+INLINE void processmsg_gcstartmapinfo_I() {
+ gcphase = MAPPHASE;
+}
+
+INLINE void processmsg_gcstartflush_I() {
+ gcphase = FLUSHPHASE;
+}
+
+INLINE void processmsg_gcfinishpre_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a init phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb000);
+ }
+ // All cores should do init GC
+ if(!gcprecheck) {
+ gcprecheck = true;
+ }
+ gccorestatus[data1] = 0;
+ gcnumsendobjs[0][data1] = data2;
+ gcnumreceiveobjs[0][data1] = data3;
+}
+
+INLINE void processmsg_gcfinishinit_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a init phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb001);
+ }
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe88c);
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ // All cores should do init GC
+ if(data1 < NUMCORESACTIVE) {
+ gccorestatus[data1] = 0;
+ }
+}
+
+INLINE void processmsg_gcfinishmark_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a mark phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb002);
+ }
+ // all cores should do mark
+ if(data1 < NUMCORESACTIVE) {
+ gccorestatus[data1] = 0;
+ int entry_index = 0;
+ if(waitconfirm) {
+ // phase 2
+ entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+ } else {
+ // phase 1
+ entry_index = gcnumsrobjs_index;
+ }
+ gcnumsendobjs[entry_index][data1] = data2;
+ gcnumreceiveobjs[entry_index][data1] = data3;
+ }
+}
+
+INLINE void processmsg_gcfinishcompact_I() {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+ // return -1
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
+#endif
+ BAMBOO_EXIT(0xb003);
+ }
+ int cnum = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[1];
+ int filledblocks = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[2];
+ int heaptop = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[3];
+ int data4 = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[4];
+ // only gc cores need to do compact
+ if(cnum < NUMCORES4GC) {
+ if(COMPACTPHASE == gcphase) {
+ gcfilledblocks[cnum] = filledblocks;
+ gcloads[cnum] = heaptop;
+ }
+ if(data4 > 0) {
+ // ask for more mem
+ int startaddr = 0;
+ int tomove = 0;
+ int dstcore = 0;
+ if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
+ // cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
+ } else {
+ send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
+ }
+ }
+ } else {
+ gccorestatus[cnum] = 0;
+ } // if(data4>0)
+ } // if(cnum < NUMCORES4GC)
+}
+
+INLINE void processmsg_gcfinishmapinfo_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a map phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb004);
+ }
+ // all cores should do flush
+ if(data1 < NUMCORES4GC) {
+ gccorestatus[data1] = 0;
+ }
+}
+
+
+INLINE void processmsg_gcfinishflush_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a flush phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb005);
+ }
+ // all cores should do flush
+ if(data1 < NUMCORESACTIVE) {
+ gccorestatus[data1] = 0;
+ }
+}
+
+INLINE void processmsg_gcmarkconfirm_I() {
+ if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
+ || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
+ // wrong core to receive such msg
+ BAMBOO_EXIT(0xb006);
+ } else {
+ // send response msg, cahce the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
+ gcbusystatus, gcself_numsendobjs,
+ gcself_numreceiveobjs);
+ } else {
+ send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
+ gcbusystatus, gcself_numsendobjs,
+ gcself_numreceiveobjs, true);
+ }
+ }
+}
+
+INLINE void processmsg_gcmarkreport_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data4 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a marked phase finish confirm response msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // wrong core to receive such msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xb007);
+ } else {
+ int entry_index = 0;
+ if(waitconfirm) {
+ // phse 2
+ numconfirm--;
+ entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
+ } else {
+ // can never reach here
+ // phase 1
+ entry_index = gcnumsrobjs_index;
+ }
+ gccorestatus[data1] = data2;
+ gcnumsendobjs[entry_index][data1] = data3;
+ gcnumreceiveobjs[entry_index][data1] = data4;
+ }
+}
+
+INLINE void processmsg_gcmarkedobj_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a markedObj msg
+ if(((int *)data1)[6] == INIT) {
+ // this is the first time that this object is discovered,
+ // set the flag as DISCOVERED
+ ((int *)data1)[6] = DISCOVERED;
+ gc_enqueue_I(data1);
+ }
+ // set the remote flag
+ ((int *)data1)[6] |= REMOTEM;
+ gcself_numreceiveobjs++;
+ gcbusystatus = true;
+}
+
+INLINE void processmsg_gcmovestart_I() {
+ gctomove = true;
+ gcdstcore = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[1];
+ gcmovestartaddr = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[2];
+ gcblock2fill = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[3];
+}
+
+INLINE void processmsg_gcmaprequest_I() {
+#ifdef GC_PROFILE
+ //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
+#endif
+ void * dstptr = NULL;
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+#ifdef GC_PROFILE
+ // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
+#endif
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashget(gcpointertbl, data1, &dstptr);
+#else
+ dstptr = mgchashSearch(gcpointertbl, data1);
+#endif
+ //MGCHashget(gcpointertbl, data1, &dstptr);
+#ifdef GC_PROFILE
+ // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
+#endif
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+#ifdef GC_PROFILE
+ // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
+#endif
+ if(NULL == dstptr) {
+ // no such pointer in this core, something is wrong
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(data1);
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xb008);
+ //assume that the object was not moved, use the original address
+ /*if(isMsgSending) {
+ cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
+ } else {
+ send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
+ }*/
+ } else {
+ // send back the mapping info, cache the msg first
+ if(BAMBOO_CHECK_SEND_MODE()) {
+ cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
+ } else {
+ send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
+ }
+ }
+#ifdef GC_PROFILE
+ // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
+ //num_mapinforequest_i++;
+#endif
+}
+
+INLINE void processmsg_gcmapinfo_I() {
+#ifdef GC_PROFILE
+ //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
+#endif
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ gcmappedobj = msgdata[msgdataindex]; // [2]
+ MSG_INDEXINC_I();
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
+#else
+ mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
+#endif
+ //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
+ if(data1 == gcobj2map) {
+ gcismapped = true;
+ }
+#ifdef GC_PROFILE
+ //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
+#endif
+}
+
+INLINE void processmsg_gcmaptbl_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
+}
+
+INLINE void processmsg_gclobjinfo_I() {
+ numconfirm--;
+
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data2);
+#endif
+ BAMBOO_EXIT(0xb009);
+ }
+ // store the mark result info
+ int cnum = data2;
+ gcloads[cnum] = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); // msgdata[3];
+ int data4 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ if(gcheaptop < data4) {
+ gcheaptop = data4;
+ }
+ // large obj info here
+ for(int k = 5; k < data1; ) {
+ int lobj = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[k++];
+ int length = msgdata[msgdataindex];
+ MSG_INDEXINC_I(); //msgdata[k++];
+ gc_lobjenqueue_I(lobj, length, cnum);
+ gcnumlobjs++;
+ } // for(int k = 5; k < msgdata[1];)
+}
+
+INLINE void processmsg_gclobjmapping_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+#ifdef LOCALHASHTBL_TEST
+ RuntimeHashadd_I(gcpointertbl, data1, data2);
+#else
+ mgchashInsert_I(gcpointertbl, data1, data2);
+#endif
+ //MGCHashadd_I(gcpointertbl, data1, data2);
+ mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
+}
+
+#ifdef GC_PROFILE
+INLINE void processmsg_gcprofiles_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data2 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ int data3 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ gc_num_obj += data1;
+ gc_num_liveobj += data2;
+ gc_num_forwardobj += data3;
+ gc_num_profiles--;
+}
+#endif // GC_PROFILE
+
+#ifdef GC_CACHE_ADAPT
+INLINE void processmsg_gcstartpref_I() {
+ gcphase = PREFINISHPHASE;
+}
+
+INLINE void processmsg_gcfinishpref_I() {
+ int data1 = msgdata[msgdataindex];
+ MSG_INDEXINC_I();
+ // received a flush phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb00a);
+ }
+ // all cores should do flush
+ if(data1 < NUMCORESACTIVE) {
+ gccorestatus[data1] = 0;
+ }
+}
+#endif // GC_CACHE_ADAPT
+#endif // #ifdef MULTICORE_GC
+
+// receive object transferred from other cores
+// or the terminate message from other cores
+// Should be invoked in critical sections!!
+// NOTICE: following format is for threadsimulate version only
+// RAW version please see previous description
+// format: type + object
+// type: -1--stall msg
+// !-1--object
+// return value: 0--received an object
+// 1--received nothing
+// 2--received a Stall Msg
+// 3--received a lock Msg
+// RAW version: -1 -- received nothing
+// otherwise -- received msg type
+int receiveObject(int send_port_pending) {
+#ifdef PROFILE_INTERRUPT
+ if(!interruptInfoOverflow) {
+ InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
+ interruptInfoArray[interruptInfoIndex] = intInfo;
+ intInfo->startTime = BAMBOO_GET_EXE_TIME();
+ intInfo->endTime = -1;
+ }
+#endif
+msg:
+ // get the incoming msgs
+ if(receiveMsg(send_port_pending) == -1) {
+ return -1;
+ }
+processmsg:
+ // processing received msgs
+ int size = 0;
+ MSG_REMAINSIZE_I(&size);
+ if((size == 0) || (checkMsgLength_I(size) == -1)) {
+ // not a whole msg
+ // have new coming msg
+ if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
+ goto msg;
+ } else {
+ return -1;
+ }
+ }
+
+ if(msglength <= size) {
+ // have some whole msg
+ MSGTYPE type;
+ type = msgdata[msgdataindex]; //[0]
+ MSG_INDEXINC_I();
+ msgdatafull = false;
+ // TODO
+ //tprintf("msg type: %x\n", type);
+ switch(type) {
+ case TRANSOBJ: {
+ // receive a object transfer msg
+ processmsg_transobj_I();
+ break;
+ } // case TRANSOBJ
+
+ case TRANSTALL: {
+ // receive a stall msg
+ processmsg_transtall_I();
+ break;
+ } // case TRANSTALL
+
+// GC version have no lock msgs
+#ifndef MULTICORE_GC
+ case LOCKREQUEST: {
+ // receive lock request msg, handle it right now
+ processmsg_lockrequest_I();
+ break;
+ } // case LOCKREQUEST
+
+ case LOCKGROUNT: {
+ // receive lock grount msg
+ processmsg_lockgrount_I();
+ break;
+ } // case LOCKGROUNT
+
+ case LOCKDENY: {
+ // receive lock deny msg
+ processmsg_lockdeny_I();
+ break;
+ } // case LOCKDENY
+
+ case LOCKRELEASE: {
+ processmsg_lockrelease_I();
+ break;
+ } // case LOCKRELEASE
+#endif // #ifndef MULTICORE_GC
+
+#ifdef PROFILE
+ case PROFILEOUTPUT: {
+ // receive an output profile data request msg
+ processmsg_profileoutput_I();
+ break;
+ } // case PROFILEOUTPUT
+
+ case PROFILEFINISH: {
+ // receive a profile output finish msg
+ processmsg_profilefinish_I();
+ break;
+ } // case PROFILEFINISH
+#endif // #ifdef PROFILE
+
+// GC version has no lock msgs
+#ifndef MULTICORE_GC
+ case REDIRECTLOCK: {
+ // receive a redirect lock request msg, handle it right now
+ processmsg_redirectlock_I();
+ break;
+ } // case REDIRECTLOCK
+
+ case REDIRECTGROUNT: {
+ // receive a lock grant msg with redirect info
+ processmsg_redirectgrount_I();
+ break;
+ } // case REDIRECTGROUNT
+
+ case REDIRECTDENY: {
+ // receive a lock deny msg with redirect info
+ processmsg_redirectdeny_I();
+ break;
+ } // case REDIRECTDENY
+
+ case REDIRECTRELEASE: {
+ // receive a lock release msg with redirect info
+ processmsg_redirectrelease_I();
+ break;
+ } // case REDIRECTRELEASE
+#endif // #ifndef MULTICORE_GC
+
+ case STATUSCONFIRM: {
+ // receive a status confirm info
+ processmsg_statusconfirm_I();
+ break;
+ } // case STATUSCONFIRM
+
+ case STATUSREPORT: {
+ processmsg_statusreport_I();
+ break;
+ } // case STATUSREPORT
+
+ case TERMINATE: {
+ // receive a terminate msg
+ processmsg_terminate_I();
+ break;
+ } // case TERMINATE
+
+ case MEMREQUEST: {
+ processmsg_memrequest_I();
+ break;
+ } // case MEMREQUEST
+
+ case MEMRESPONSE: {
+ processmsg_memresponse_I();
+ break;
+ } // case MEMRESPONSE
+
+#ifdef MULTICORE_GC
+ // GC msgs
+ case GCSTARTPRE: {
+ processmsg_gcstartpre_I();
+ break;
+ } // case GCSTARTPRE
+
+ case GCSTARTINIT: {
+ processmsg_gcstartinit_I();
+ break;
+ } // case GCSTARTINIT
+
+ case GCSTART: {
+ // receive a start GC msg
+ processmsg_gcstart_I();
+ break;
+ } // case GCSTART
+
+ case GCSTARTCOMPACT: {
+ // a compact phase start msg
+ processmsg_gcstartcompact_I();
+ break;
+ } // case GCSTARTCOMPACT
+
+ case GCSTARTMAPINFO: {
+ // received a flush phase start msg
+ processmsg_gcstartmapinfo_I();
+ break;
+ } // case GCSTARTFLUSH
+
+ case GCSTARTFLUSH: {
+ // received a flush phase start msg
+ processmsg_gcstartflush_I();
+ break;
+ } // case GCSTARTFLUSH
+
+ case GCFINISHPRE: {
+ processmsg_gcfinishpre_I();
+ break;
+ } // case GCFINISHPRE
+
+ case GCFINISHINIT: {
+ processmsg_gcfinishinit_I();
+ break;
+ } // case GCFINISHINIT
+
+ case GCFINISHMARK: {
+ processmsg_gcfinishmark_I();
+ break;
+ } // case GCFINISHMARK
+
+ case GCFINISHCOMPACT: {
+ // received a compact phase finish msg
+ processmsg_gcfinishcompact_I();
+ break;
+ } // case GCFINISHCOMPACT
+
+ case GCFINISHMAPINFO: {
+ processmsg_gcfinishmapinfo_I();
+ break;
+ } // case GCFINISHMAPINFO
+
+ case GCFINISHFLUSH: {
+ processmsg_gcfinishflush_I();
+ break;
+ } // case GCFINISHFLUSH
+
+ case GCFINISH: {
+ // received a GC finish msg
+ gcphase = FINISHPHASE;
+ break;
+ } // case GCFINISH
+
+ case GCMARKCONFIRM: {
+ // received a marked phase finish confirm request msg
+ // all cores should do mark
+ processmsg_gcmarkconfirm_I();
+ break;
+ } // case GCMARKCONFIRM
+
+ case GCMARKREPORT: {
+ processmsg_gcmarkreport_I();
+ break;
+ } // case GCMARKREPORT
+
+ case GCMARKEDOBJ: {
+ processmsg_gcmarkedobj_I();
+ break;
+ } // case GCMARKEDOBJ
+
+ case GCMOVESTART: {
+ // received a start moving objs msg
+ processmsg_gcmovestart_I();
+ break;
+ } // case GCMOVESTART
+
+ case GCMAPREQUEST: {
+ // received a mapping info request msg
+ processmsg_gcmaprequest_I();
+ break;
+ } // case GCMAPREQUEST
+
+ case GCMAPINFO: {
+ // received a mapping info response msg
+ processmsg_gcmapinfo_I();
+ break;
+ } // case GCMAPINFO
+
+ case GCMAPTBL: {
+ // received a mapping tbl response msg
+ processmsg_gcmaptbl_I();
+ break;
+ } // case GCMAPTBL
+
+ case GCLOBJREQUEST: {
+ // received a large objs info request msg
+ transferMarkResults_I();
+ break;
+ } // case GCLOBJREQUEST
+
+ case GCLOBJINFO: {
+ // received a large objs info response msg
+ processmsg_gclobjinfo_I();
+ break;
+ } // case GCLOBJINFO
+
+ case GCLOBJMAPPING: {
+ // received a large obj mapping info msg
+ processmsg_gclobjmapping_I();
+ break;
+ } // case GCLOBJMAPPING
+
+#ifdef GC_PROFILE
+ case GCPROFILES: {
+ // received a gcprofiles msg
+ processmsg_gcprofiles_I();
+ break;
+ }
+#endif // GC_PROFILE
+
+#ifdef GC_CACHE_ADAPT
+ case GCSTARTPREF: {
+ // received a gcstartpref msg
+ processmsg_gcstartpref_I();
+ break;
+ }
+
+ case GCFINISHPREF: {
+ // received a gcfinishpref msg
+ processmsg_gcfinishpref_I();
+ break;
+ }
+#endif // GC_CACHE_ADAPT
+#endif // #ifdef MULTICORE_GC
+
+ default:
+ break;
+ } // switch(type)
+ msglength = BAMBOO_MSG_BUF_LENGTH;
+ // TODO
+ //printf("++ msg: %x \n", type);
+
+ if(msgdataindex != msgdatalast) {
+ // still have available msg
+ goto processmsg;
+ }
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe88d);
+#endif
+#endif
+
+ // have new coming msg
+ if(BAMBOO_MSG_AVAIL() != 0) {
+ goto msg;
+ } // TODO
+
+#ifdef PROFILE_INTERRUPT
+ if(!interruptInfoOverflow) {
+ interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
+ interruptInfoIndex++;
+ if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
+ interruptInfoOverflow = true;
+ }
+ }
+#endif
+ return (int)type;
+ } else {
+ // not a whole msg
+#ifdef DEBUG
+#ifndef CLOSE_PRINT
+ BAMBOO_DEBUGPRINT(0xe88e);
+#endif
+#endif
+ return -2;
+ }
+}
+
+int enqueuetasks(struct parameterwrapper *parameter,
+ struct parameterwrapper *prevptr,
+ struct ___Object___ *ptr,
+ int * enterflags,
+ int numenterflags) {
+ void * taskpointerarray[MAXTASKPARAMS];
+ int j;
+ //int numparams=parameter->task->numParameters;
+ int numiterators=parameter->task->numTotal-1;
+ int retval=1;
+
+ struct taskdescriptor * task=parameter->task;
+
+ //this add the object to parameterwrapper
+ ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
+ numenterflags, enterflags==NULL);
+
+ /* Add enqueued object to parameter vector */
+ taskpointerarray[parameter->slot]=ptr;
+
+ /* Reset iterators */
+ for(j=0; j<numiterators; j++) {
+ toiReset(¶meter->iterators[j]);
+ }
+
+ /* Find initial state */
+ for(j=0; j<numiterators; j++) {
+backtrackinit:
+ if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
+ toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
+ else if (j>0) {
+ /* Need to backtrack */
+ toiReset(¶meter->iterators[j]);
+ j--;
+ goto backtrackinit;
+ } else {
+ /* Nothing to enqueue */
+ return retval;
+ }
+ }
+
+ while(1) {
+ /* Enqueue current state */
+ //int launch = 0;
+ struct taskparamdescriptor *tpd=
+ RUNMALLOC(sizeof(struct taskparamdescriptor));
+ tpd->task=task;
+ tpd->numParameters=numiterators+1;
+ tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
+
+ for(j=0; j<=numiterators; j++) {
+ //store the actual parameters
+ tpd->parameterArray[j]=taskpointerarray[j];
+ }
+ /* Enqueue task */
+ if (( /*!gencontains(failedtasks, tpd)&&*/
+ !gencontains(activetasks,tpd))) {
+ genputtable(activetasks, tpd, tpd);
+ } else {
+ RUNFREE(tpd->parameterArray);
+ RUNFREE(tpd);
+ }
+
+ /* This loop iterates to the next parameter combination */
+ if (numiterators==0)
+ return retval;
+
+ for(j=numiterators-1; j<numiterators; j++) {
+backtrackinc:
+ if(toiHasNext(
+ ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
+ toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
+ else if (j>0) {
+ /* Need to backtrack */
+ toiReset(¶meter->iterators[j]);
+ j--;
+ goto backtrackinc;
+ } else {
+ /* Nothing more to enqueue */
+ return retval;
+ }
+ }
+ }
+ return retval;
+}
+
+int enqueuetasks_I(struct parameterwrapper *parameter,
+ struct parameterwrapper *prevptr,
+ struct ___Object___ *ptr,
+ int * enterflags,
+ int numenterflags) {
+ void * taskpointerarray[MAXTASKPARAMS];
+ int j;
+ //int numparams=parameter->task->numParameters;
+ int numiterators=parameter->task->numTotal-1;
+ int retval=1;
+ //int addnormal=1;
+ //int adderror=1;
+
+ struct taskdescriptor * task=parameter->task;
+
+ //this add the object to parameterwrapper
+ ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
+ numenterflags, enterflags==NULL);
+
+ /* Add enqueued object to parameter vector */
+ taskpointerarray[parameter->slot]=ptr;
+
+ /* Reset iterators */
+ for(j=0; j<numiterators; j++) {
+ toiReset(¶meter->iterators[j]);
+ }
+
+ /* Find initial state */
+ for(j=0; j<numiterators; j++) {
+backtrackinit:
+ if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
+ toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
+ else if (j>0) {
+ /* Need to backtrack */
+ toiReset(¶meter->iterators[j]);
+ j--;
+ goto backtrackinit;
+ } else {
+ /* Nothing to enqueue */
+ return retval;
+ }
+ }
+
+ while(1) {
+ /* Enqueue current state */
+ //int launch = 0;
+ struct taskparamdescriptor *tpd=
+ RUNMALLOC_I(sizeof(struct taskparamdescriptor));
+ tpd->task=task;
+ tpd->numParameters=numiterators+1;
+ tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
+
+ for(j=0; j<=numiterators; j++) {
+ //store the actual parameters
+ tpd->parameterArray[j]=taskpointerarray[j];
+ }
+ /* Enqueue task */
+ if (( /*!gencontains(failedtasks, tpd)&&*/
+ !gencontains(activetasks,tpd))) {
+ genputtable_I(activetasks, tpd, tpd);
+ } else {
+ RUNFREE(tpd->parameterArray);
+ RUNFREE(tpd);
+ }
+
+ /* This loop iterates to the next parameter combination */
+ if (numiterators==0)
+ return retval;
+
+ for(j=numiterators-1; j<numiterators; j++) {
+backtrackinc:
+ if(toiHasNext(
+ ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
+ toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
+ else if (j>0) {
+ /* Need to backtrack */
+ toiReset(¶meter->iterators[j]);
+ j--;
+ goto backtrackinc;
+ } else {
+ /* Nothing more to enqueue */
+ return retval;
+ }
+ }
+ }
+ return retval;
+}
+
+#ifdef MULTICORE_GC
+#define OFFSET 2
+#else
+#define OFFSET 0
+#endif
+
+int containstag(struct ___Object___ *ptr,
+ struct ___TagDescriptor___ *tag);
+
+#ifndef MULTICORE_GC
+void releasewritelock_r(void * lock, void * redirectlock) {
+ int targetcore = 0;
+ int reallock = (int)lock;
+ targetcore = (reallock >> 5) % NUMCORES;
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe671);
+ BAMBOO_DEBUGPRINT_REG((int)lock);
+ BAMBOO_DEBUGPRINT_REG(reallock);
+ BAMBOO_DEBUGPRINT_REG(targetcore);
+#endif
+
+ if(targetcore == BAMBOO_NUM_OF_CORE) {
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+ // reside on this core
+ if(!RuntimeHashcontainskey(locktbl, reallock)) {
+ // no locks for this object, something is wrong
+ BAMBOO_EXIT(0xa00b);
+ } else {
+ int rwlock_obj = 0;
+ struct LockValue * lockvalue = NULL;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe672);
+#endif
+ RuntimeHashget(locktbl, reallock, &rwlock_obj);
+ lockvalue = (struct LockValue *)rwlock_obj;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+ lockvalue->value++;
+ lockvalue->redirectlock = (int)redirectlock;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG(lockvalue->value);
+#endif
+ }
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+ return;
+ } 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, false);
+ }
+}
+#endif
+
+void executetasks() {
+ void * taskpointerarray[MAXTASKPARAMS+OFFSET];
+ int numparams=0;
+ int numtotal=0;
+ struct ___Object___ * tmpparam = NULL;
+ struct parameterdescriptor * pd=NULL;
+ struct parameterwrapper *pw=NULL;
+ int j = 0;
+ int x = 0;
+ bool islock = true;
+
+ int grount = 0;
+ int andmask=0;
+ int checkmask=0;
+
+newtask:
+ while(hashsize(activetasks)>0) {
+#ifdef MULTICORE_GC
+//#ifdef GC_CACHE_ADAPT
+ // do dtlb sampling if necessary
+// bamboo_dtlb_sampling_process();
+//#endif // GC_CACHE_ADAPT
+ if(gcflag) gc(NULL);
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe990);
+#endif
+
+ /* See if there are any active tasks */
+ //if (hashsize(activetasks)>0) {
+ int i;
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ profileTaskStart("tpd checking");
+#endif
+#endif
+ //long clock1;
+ //clock1 = BAMBOO_GET_EXE_TIME();
+
+ busystatus = true;
+ currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
+ genfreekey(activetasks, currtpd);
+
+ numparams=currtpd->task->numParameters;
+ numtotal=currtpd->task->numTotal;
+
+ // clear the lockRedirectTbl
+ // (TODO, this table should be empty after all locks are released)
+ // reset all locks
+ /*for(j = 0; j < MAXTASKPARAMS; j++) {
+ runtime_locks[j].redirectlock = 0;
+ runtime_locks[j].value = 0;
+ }*/
+ // get all required locks
+ runtime_locklen = 0;
+ // check which locks are needed
+ for(i = 0; i < numparams; i++) {
+ void * param = currtpd->parameterArray[i];
+ int tmplock = 0;
+ int j = 0;
+ bool insert = true;
+ if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
+ islock = false;
+ taskpointerarray[i+OFFSET]=param;
+ goto execute;
+ }
+ if(((struct ___Object___ *)param)->lock == NULL) {
+ tmplock = (int)param;
+ } else {
+ tmplock = (int)(((struct ___Object___ *)param)->lock);
+ }
+ // insert into the locks array
+ for(j = 0; j < runtime_locklen; j++) {
+ if(runtime_locks[j].value == tmplock) {
+ insert = false;
+ break;
+ } else if(runtime_locks[j].value > tmplock) {
+ break;
+ }
+ }
+ if(insert) {
+ int h = runtime_locklen;
+ for(; h > j; h--) {
+ runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
+ runtime_locks[h].value = runtime_locks[h-1].value;
+ }
+ runtime_locks[j].value = tmplock;
+ runtime_locks[j].redirectlock = (int)param;
+ runtime_locklen++;
+ }
+ } // line 2713: for(i = 0; i < numparams; i++)
+ // grab these required locks
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe991);
+#endif
+ //long clock2;
+ //clock2 = BAMBOO_GET_EXE_TIME();
+
+ for(i = 0; i < runtime_locklen; i++) {
+ int * lock = (int *)(runtime_locks[i].redirectlock);
+ islock = true;
+ // require locks for this parameter if it is not a startup object
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG((int)lock);
+ BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
+#endif
+ getwritelock(lock);
+ BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf001);
+#endif
+#ifdef PROFILE
+ //isInterrupt = false;
+#endif
+ while(!lockflag) {
+ BAMBOO_WAITING_FOR_LOCK(0);
+ }
+#ifndef INTERRUPT
+ if(reside) {
+ while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
+ }
+ }
+#endif
+ grount = lockresult;
+
+ lockresult = 0;
+ lockobj = 0;
+ lock2require = 0;
+ lockflag = false;
+#ifndef INTERRUPT
+ reside = false;
+#endif
+#ifdef PROFILE
+ //isInterrupt = true;
+#endif
+ BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xf000);
+#endif
+
+ if(grount == 0) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe992);
+ BAMBOO_DEBUGPRINT_REG(lock);
+#endif
+ // check if has the lock already
+ // can not get the lock, try later
+ // release all grabbed locks for previous parameters
+ for(j = 0; j < i; ++j) {
+ lock = (int*)(runtime_locks[j].redirectlock);
+ releasewritelock(lock);
+ }
+ genputtable(activetasks, currtpd, currtpd);
+ if(hashsize(activetasks) == 1) {
+ // only one task right now, wait a little while before next try
+ int halt = 10000;
+ while(halt--) {
+ }
+ }
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ // fail, set the end of the checkTaskInfo
+ profileTaskEnd();
+#endif
+#endif
+ goto newtask;
+ //}
+ }
+ } // line 2752: for(i = 0; i < runtime_locklen; i++)
+
+ /*long clock3;
+ clock3 = BAMBOO_GET_EXE_TIME();
+ //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe993);
+#endif
+ /* Make sure that the parameters are still in the queues */
+ for(i=0; i<numparams; i++) {
+ void * parameter=currtpd->parameterArray[i];
+
+ // flush the object
+#ifdef CACHEFLUSH
+ BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
+ classsize[((struct ___Object___ *)parameter)->type]);
+#endif
+ tmpparam = (struct ___Object___ *)parameter;
+ pd=currtpd->task->descriptorarray[i];
+ pw=(struct parameterwrapper *) pd->queue;
+ /* Check that object is still in queue */
+ {
+ if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe994);
+ BAMBOO_DEBUGPRINT_REG(parameter);
+#endif
+ // release grabbed locks
+ for(j = 0; j < runtime_locklen; ++j) {
+ int * lock = (int *)(runtime_locks[j].redirectlock);
+ releasewritelock(lock);
+ }
+ RUNFREE(currtpd->parameterArray);
+ RUNFREE(currtpd);
+ currtpd = NULL;
+ goto newtask;
+ }
+ } // line2865
+ /* Check if the object's flags still meets requirements */
+ {
+ int tmpi = 0;
+ bool ismet = false;
+ for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
+ andmask=pw->intarray[tmpi*2];
+ checkmask=pw->intarray[tmpi*2+1];
+ if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
+ ismet = true;
+ break;
+ }
+ }
+ if (!ismet) {
+ // flags are never suitable
+ // remove this obj from the queue
+ int next;
+ int UNUSED, UNUSED2;
+ int * enterflags;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe995);
+ BAMBOO_DEBUGPRINT_REG(parameter);
+#endif
+ ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
+ (int *) &enterflags, &UNUSED, &UNUSED2);
+ ObjectHashremove(pw->objectset, (int)parameter);
+ if (enterflags!=NULL)
+ RUNFREE(enterflags);
+ // release grabbed locks
+ for(j = 0; j < runtime_locklen; ++j) {
+ int * lock = (int *)(runtime_locks[j].redirectlock);
+ releasewritelock(lock);
+ }
+ RUNFREE(currtpd->parameterArray);
+ RUNFREE(currtpd);
+ currtpd = NULL;
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ // fail, set the end of the checkTaskInfo
+ profileTaskEnd();
+#endif
+#endif
+ goto newtask;
+ } // line 2878: if (!ismet)
+ } // line 2867
+parameterpresent:
+ ;
+ /* Check that object still has necessary tags */
+ for(j=0; j<pd->numbertags; j++) {
+ int slotid=pd->tagarray[2*j]+numparams;
+ struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
+ if (!containstag(parameter, tagd)) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe996);
+#endif
+ {
+ // release grabbed locks
+ int tmpj = 0;
+ for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
+ int * lock = (int *)(runtime_locks[tmpj].redirectlock);
+ releasewritelock(lock);
+ }
+ }
+ RUNFREE(currtpd->parameterArray);
+ RUNFREE(currtpd);
+ currtpd = NULL;
+ goto newtask;
+ } // line2911: if (!containstag(parameter, tagd))
+ } // line 2808: for(j=0; j<pd->numbertags; j++)
+
+ taskpointerarray[i+OFFSET]=parameter;
+ } // line 2824: for(i=0; i<numparams; i++)
+ /* Copy the tags */
+ for(; i<numtotal; i++) {
+ taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
+ }
+
+ {
+execute:
+ /* Actually call task */
+#ifdef MULTICORE_GC
+ ((int *)taskpointerarray)[0]=currtpd->numParameters;
+ taskpointerarray[1]=NULL;
+#endif
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ // check finish, set the end of the checkTaskInfo
+ profileTaskEnd();
+#endif
+ profileTaskStart(currtpd->task->name);
+#endif
+ // TODO
+ //long clock4;
+ //clock4 = BAMBOO_GET_EXE_TIME();
+ //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
+
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe997);
+#endif
+ ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
+ // TODO
+ //long clock5;
+ //clock5 = BAMBOO_GET_EXE_TIME();
+ // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
+
+#ifdef PROFILE
+#ifdef ACCURATEPROFILE
+ // task finish, set the end of the checkTaskInfo
+ profileTaskEnd();
+ // new a PostTaskInfo for the post-task execution
+ profileTaskStart("post task execution");
+#endif
+#endif
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe998);
+ BAMBOO_DEBUGPRINT_REG(islock);
+#endif
+
+ if(islock) {
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe999);
+#endif
+ for(i = 0; i < runtime_locklen; ++i) {
+ void * ptr = (void *)(runtime_locks[i].redirectlock);
+ int * lock = (int *)(runtime_locks[i].value);
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT_REG((int)ptr);
+ BAMBOO_DEBUGPRINT_REG((int)lock);
+ BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
+#endif
+#ifndef MULTICORE_GC
+ if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
+ int redirectlock;
+ RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
+ RuntimeHashremovekey(lockRedirectTbl, (int)lock);
+ releasewritelock_r(lock, (int *)redirectlock);
+ } else {
+#else
+ {
+#endif
+ releasewritelock(ptr);
+ }
+ }
+ } // line 3015: if(islock)
+
+ //long clock6;
+ //clock6 = BAMBOO_GET_EXE_TIME();
+ //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
+
+#ifdef PROFILE
+ // post task execution finish, set the end of the postTaskInfo
+ profileTaskEnd();
+#endif
+
+ // Free up task parameter descriptor
+ RUNFREE(currtpd->parameterArray);
+ RUNFREE(currtpd);
+ currtpd = NULL;
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe99a);
+#endif
+ //long clock7;
+ //clock7 = BAMBOO_GET_EXE_TIME();
+ //tprintf("sort: %d, grab: %d, check: %d, release: %d, other %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3), (int)(clock6-clock5), (int)(clock7-clock6));
+
+ } //
+ //} // if (hashsize(activetasks)>0)
+ } // while(hashsize(activetasks)>0)
+#ifdef DEBUG
+ BAMBOO_DEBUGPRINT(0xe99b);
+#endif
+}
+
+/* This function processes an objects tags */
+void processtags(struct parameterdescriptor *pd,
+ int index,
+ struct parameterwrapper *parameter,
+ int * iteratorcount,
+ int *statusarray,
+ int numparams) {
+ int i;
+
+ for(i=0; i<pd->numbertags; i++) {
+ int slotid=pd->tagarray[2*i];
+ int tagid=pd->tagarray[2*i+1];
+
+ if (statusarray[slotid+numparams]==0) {
+ parameter->iterators[*iteratorcount].istag=1;
+ parameter->iterators[*iteratorcount].tagid=tagid;
+ parameter->iterators[*iteratorcount].slot=slotid+numparams;
+ parameter->iterators[*iteratorcount].tagobjectslot=index;
+ statusarray[slotid+numparams]=1;
+ (*iteratorcount)++;
+ }
+ }
+}
+
+
+void processobject(struct parameterwrapper *parameter,
+ int index,
+ struct parameterdescriptor *pd,
+ int *iteratorcount,
+ int * statusarray,
+ int numparams) {
+ int i;
+ int tagcount=0;
+ struct ObjectHash * objectset=
+ ((struct parameterwrapper *)pd->queue)->objectset;
+
+ parameter->iterators[*iteratorcount].istag=0;
+ parameter->iterators[*iteratorcount].slot=index;
+ parameter->iterators[*iteratorcount].objectset=objectset;
+ statusarray[index]=1;
+
+ for(i=0; i<pd->numbertags; i++) {
+ int slotid=pd->tagarray[2*i];
+ //int tagid=pd->tagarray[2*i+1];
+ if (statusarray[slotid+numparams]!=0) {
+ /* This tag has already been enqueued, use it to narrow search */
+ parameter->iterators[*iteratorcount].tagbindings[tagcount]=
+ slotid+numparams;
+ tagcount++;
+ }
+ }
+ parameter->iterators[*iteratorcount].numtags=tagcount;
+
+ (*iteratorcount)++;
+}
+
+/* This function builds the iterators for a task & parameter */
+
+void builditerators(struct taskdescriptor * task,
+ int index,
+ struct parameterwrapper * parameter) {
+ int statusarray[MAXTASKPARAMS];
+ int i;
+ int numparams=task->numParameters;
+ int iteratorcount=0;
+ for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
+
+ statusarray[index]=1; /* Initial parameter */
+ /* Process tags for initial iterator */
+
+ processtags(task->descriptorarray[index], index, parameter,
+ &iteratorcount, statusarray, numparams);
+
+ while(1) {
+loopstart:
+ /* Check for objects with existing tags */
+ for(i=0; i<numparams; i++) {
+ if (statusarray[i]==0) {
+ struct parameterdescriptor *pd=task->descriptorarray[i];
+ int j;
+ for(j=0; j<pd->numbertags; j++) {
+ int slotid=pd->tagarray[2*j];
+ if(statusarray[slotid+numparams]!=0) {
+ processobject(parameter,i,pd,&iteratorcount,
+ statusarray,numparams);
+ processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
+ goto loopstart;
+ }
+ }
+ }
+ }
+
+ /* Next do objects w/ unbound tags*/
+
+ for(i=0; i<numparams; i++) {
+ if (statusarray[i]==0) {
+ struct parameterdescriptor *pd=task->descriptorarray[i];
+ if (pd->numbertags>0) {
+ processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
+ processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
+ goto loopstart;
+ }
+ }
+ }
+
+ /* Nothing with a tag enqueued */
+
+ for(i=0; i<numparams; i++) {
+ if (statusarray[i]==0) {
+ struct parameterdescriptor *pd=task->descriptorarray[i];
+ processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
+ processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
+ goto loopstart;
+ }
+ }
+
+ /* Nothing left */
+ return;
+ }
+}
+
+void printdebug() {
+ int i;
+ int j;
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+ return;
+ }
+ for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
+ struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
+#ifndef RAW
+ printf("%s\n", task->name);
+#endif
+ for(j=0; j<task->numParameters; j++) {
+ struct parameterdescriptor *param=task->descriptorarray[j];
+ struct parameterwrapper *parameter=param->queue;
+ struct ObjectHash * set=parameter->objectset;
+ struct ObjectIterator objit;
+#ifndef RAW
+ printf(" Parameter %d\n", j);
+#endif
+ ObjectHashiterator(set, &objit);
+ while(ObjhasNext(&objit)) {
+ struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
+ struct ___Object___ * tagptr=obj->___tags___;
+ int nonfailed=Objdata4(&objit);
+ int numflags=Objdata3(&objit);
+ int flags=Objdata2(&objit);
+ Objnext(&objit);
+#ifndef RAW
+ printf(" Contains %lx\n", obj);
+ printf(" flag=%d\n", obj->flag);
+#endif
+ if (tagptr==NULL) {
+ } else if (tagptr->type==TAGTYPE) {
+#ifndef RAW
+ printf(" tag=%lx\n",tagptr);
+#else
+ ;
+#endif
+ } else {
+ int tagindex=0;
+ struct ArrayObject *ao=(struct ArrayObject *)tagptr;
+ for(; tagindex<ao->___cachedCode___; tagindex++) {
+#ifndef RAW
+ printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
+ tagindex));
+#else
+ ;
+#endif
+ }
+ }
+ }
+ }
+ }
+}
+
+
+/* This function processes the task information to create queues for
+ each parameter type. */
+
+void processtasks() {
+ int i;
+ if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
+ return;
+ }
+ for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
+ struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
+ int j;
+
+ /* Build objectsets */
+ for(j=0; j<task->numParameters; j++) {
+ struct parameterdescriptor *param=task->descriptorarray[j];
+ struct parameterwrapper *parameter=param->queue;
+ parameter->objectset=allocateObjectHash(10);
+ parameter->task=task;
+ }
+
+ /* Build iterators for parameters */
+ for(j=0; j<task->numParameters; j++) {
+ struct parameterdescriptor *param=task->descriptorarray[j];
+ struct parameterwrapper *parameter=param->queue;
+ builditerators(task, j, parameter);
+ }
+ }
+}
+
+void toiReset(struct tagobjectiterator * it) {
+ if (it->istag) {
+ it->tagobjindex=0;
+ } else if (it->numtags>0) {
+ it->tagobjindex=0;
+ } else {
+ ObjectHashiterator(it->objectset, &it->it);
+ }
+}
+
+int toiHasNext(struct tagobjectiterator *it,
+ void ** objectarray OPTARG(int * failed)) {
+ if (it->istag) {
+ /* Iterate tag */
+ /* Get object with tags */
+ struct ___Object___ *obj=objectarray[it->tagobjectslot];
+ struct ___Object___ *tagptr=obj->___tags___;
+ if (tagptr->type==TAGTYPE) {
+ if ((it->tagobjindex==0)&& /* First object */
+ (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
+ return 1;
+ else
+ return 0;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+ int tagindex=it->tagobjindex;
+ for(; tagindex<ao->___cachedCode___; tagindex++) {
+ struct ___TagDescriptor___ *td=
+ ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
+ if (td->flag==it->tagid) {
+ it->tagobjindex=tagindex; /* Found right type of tag */
+ return 1;
+ }
+ }
+ return 0;
+ }
+ } else if (it->numtags>0) {
+ /* Use tags to locate appropriate objects */
+ struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
+ struct ___Object___ *objptr=tag->flagptr;
+ int i;
+ if (objptr->type!=OBJECTARRAYTYPE) {
+ if (it->tagobjindex>0)
+ return 0;
+ if (!ObjectHashcontainskey(it->objectset, (int) objptr))
+ return 0;
+ for(i=1; i<it->numtags; i++) {
+ struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
+ if (!containstag(objptr,tag2))
+ return 0;
+ }
+ return 1;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) objptr;
+ int tagindex;
+ int i;
+ for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
+ struct ___Object___ *objptr=
+ ARRAYGET(ao,struct ___Object___*,tagindex);
+ if (!ObjectHashcontainskey(it->objectset, (int) objptr))
+ continue;
+ for(i=1; i<it->numtags; i++) {
+ struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
+ if (!containstag(objptr,tag2))
+ goto nexttag;
+ }
+ it->tagobjindex=tagindex;
+ return 1;
+nexttag:
+ ;
+ }
+ it->tagobjindex=tagindex;
+ return 0;
+ }
+ } else {
+ return ObjhasNext(&it->it);
+ }
+}
+
+int containstag(struct ___Object___ *ptr,
+ struct ___TagDescriptor___ *tag) {
+ int j;
+ struct ___Object___ * objptr=tag->flagptr;
+ if (objptr->type==OBJECTARRAYTYPE) {
+ struct ArrayObject *ao=(struct ArrayObject *)objptr;
+ for(j=0; j<ao->___cachedCode___; j++) {
+ if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
+ return 1;
+ }
+ }
+ return 0;
+ } else {
+ return objptr==ptr;
+ }
+}
+
+void toiNext(struct tagobjectiterator *it,
+ void ** objectarray OPTARG(int * failed)) {
+ /* hasNext has all of the intelligence */
+ if(it->istag) {
+ /* Iterate tag */
+ /* Get object with tags */
+ struct ___Object___ *obj=objectarray[it->tagobjectslot];
+ struct ___Object___ *tagptr=obj->___tags___;
+ if (tagptr->type==TAGTYPE) {
+ it->tagobjindex++;
+ objectarray[it->slot]=tagptr;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) tagptr;
+ objectarray[it->slot]=
+ ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
+ }
+ } else if (it->numtags>0) {
+ /* Use tags to locate appropriate objects */
+ struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
+ struct ___Object___ *objptr=tag->flagptr;
+ if (objptr->type!=OBJECTARRAYTYPE) {
+ it->tagobjindex++;
+ objectarray[it->slot]=objptr;
+ } else {
+ struct ArrayObject *ao=(struct ArrayObject *) objptr;
+ objectarray[it->slot]=
+ ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
+ }
+ } else {
+ /* Iterate object */
+ objectarray[it->slot]=(void *)Objkey(&it->it);
+ Objnext(&it->it);
+ }
+}
+
+#ifdef PROFILE
+inline void profileTaskStart(char * taskname) {
+ if(!taskInfoOverflow) {
+ TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
+ taskInfoArray[taskInfoIndex] = taskInfo;
+ taskInfo->taskName = taskname;
+ taskInfo->startTime = BAMBOO_GET_EXE_TIME();
+ taskInfo->endTime = -1;
+ taskInfo->exitIndex = -1;
+ taskInfo->newObjs = NULL;
+ }
+}
+
+inline void profileTaskEnd() {
+ if(!taskInfoOverflow) {
+ taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
+ taskInfoIndex++;
+ if(taskInfoIndex == TASKINFOLENGTH) {
+ taskInfoOverflow = true;
+ //taskInfoIndex = 0;
+ }
+ }
+}
+
+// output the profiling data
+void outputProfileData() {
+#ifdef USEIO
+ int i;
+ unsigned long long totaltasktime = 0;
+ unsigned long long preprocessingtime = 0;
+ unsigned long long objqueuecheckingtime = 0;
+ unsigned long long postprocessingtime = 0;
+ //int interruptiontime = 0;
+ unsigned long long other = 0;
+ unsigned long long averagetasktime = 0;
+ int tasknum = 0;
+
+ printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
+ // output task related info
+ for(i = 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
+ printf("%s, %lld, %lld, %lld, %lld",
+ tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
+ duration, tmpTInfo->exitIndex);
+ // summarize new obj info
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ //printf(stderr, "new obj!\n");
+ }
+
+ // output all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ printf(", %s, %d", objtype, num);
+ }
+ }
+ printf("\n");
+ if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
+ preprocessingtime += duration;
+ } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
+ postprocessingtime += duration;
+ } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
+ objqueuecheckingtime += duration;
+ } else {
+ totaltasktime += duration;
+ averagetasktime += duration;
+ tasknum++;
+ }
+ }
+
+ if(taskInfoOverflow) {
+ printf("Caution: task info overflow!\n");
+ }
+
+ other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
+ averagetasktime /= tasknum;
+
+ printf("\nTotal time: %lld\n", totalexetime);
+ printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
+ (int)(((double)totaltasktime/(double)totalexetime)*100));
+ printf("Total objqueue checking time: %lld (%d%%)\n",
+ objqueuecheckingtime,
+ (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
+ printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
+ (int)(((double)preprocessingtime/(double)totalexetime)*100));
+ printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
+ (int)(((double)postprocessingtime/(double)totalexetime)*100));
+ printf("Other time: %lld (%d%%)\n", other,
+ (int)(((double)other/(double)totalexetime)*100));
+
+
+ printf("\nAverage task execution time: %lld\n", averagetasktime);
+
+ //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
+#else
+ int i = 0;
+ int j = 0;
+
+ BAMBOO_DEBUGPRINT(0xdddd);
+ // output task related info
+ for(i= 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ char* tmpName = tmpTInfo->taskName;
+ int nameLen = strlen(tmpName);
+ BAMBOO_DEBUGPRINT(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ BAMBOO_DEBUGPRINT_REG(tmpName[j]);
+ }
+ BAMBOO_DEBUGPRINT(0xdddb);
+ BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
+ BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
+ BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ }
+
+ // ouput all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ int nameLen = strlen(objtype);
+ BAMBOO_DEBUGPRINT(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ BAMBOO_DEBUGPRINT_REG(objtype[j]);
+ }
+ BAMBOO_DEBUGPRINT(0xdddb);
+ BAMBOO_DEBUGPRINT_REG(num);
+ }
+ }
+ BAMBOO_DEBUGPRINT(0xdddc);
+ }
+
+ if(taskInfoOverflow) {
+ BAMBOO_DEBUGPRINT(0xefee);
+ }
+
+#ifdef PROFILE_INTERRUPT
+ // output interrupt related info
+ for(i = 0; i < interruptInfoIndex; i++) {
+ InterruptInfo* tmpIInfo = interruptInfoArray[i];
+ BAMBOO_DEBUGPRINT(0xddde);
+ BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
+ BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
+ BAMBOO_DEBUGPRINT(0xdddf);
+ }
+
+ if(interruptInfoOverflow) {
+ BAMBOO_DEBUGPRINT(0xefef);
+ }
+#endif // PROFILE_INTERRUPT
+
+ BAMBOO_DEBUGPRINT(0xeeee);
+#endif
+}
+#endif // #ifdef PROFILE
+
+#endif
+++ /dev/null
-#ifdef MULTICORE_GC
-#include "runtime.h"
-#include "multicoregarbage.h"
-#include "multicoreruntime.h"
-#include "runtime_arch.h"
-#include "SimpleHash.h"
-#include "GenericHashtable.h"
-#include "ObjectHash.h"
-#include "GCSharedHash.h"
-
-// TODO for profiling the flush phase
-#ifdef GC_PROFILE
-/*int num_mapinforequest;
-int num_markrequest;
-unsigned long long marktime;*/
-#endif
-
-extern int corenum;
-extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
-extern int numqueues[][NUMCLASSES];
-
-extern struct genhashtable * activetasks;
-extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
-extern struct taskparamdescriptor *currtpd;
-
-extern struct LockValue runtime_locks[MAXTASKPARAMS];
-extern int runtime_locklen;
-
-#ifdef SMEMM
-extern unsigned int gcmem_mixed_threshold;
-extern unsigned int gcmem_mixed_usedmem;
-#endif
-
-struct pointerblock {
- void * ptrs[NUMPTRS];
- struct pointerblock *next;
-};
-
-struct pointerblock *gchead=NULL;
-int gcheadindex=0;
-struct pointerblock *gctail=NULL;
-int gctailindex=0;
-struct pointerblock *gctail2=NULL;
-int gctailindex2=0;
-struct pointerblock *gcspare=NULL;
-
-#define NUMLOBJPTRS 20
-
-struct lobjpointerblock {
- void * lobjs[NUMLOBJPTRS];
- //void * dsts[NUMLOBJPTRS];
- int lengths[NUMLOBJPTRS];
- //void * origs[NUMLOBJPTRS];
- int hosts[NUMLOBJPTRS];
- struct lobjpointerblock *next;
- struct lobjpointerblock *prev;
-};
-
-struct lobjpointerblock *gclobjhead=NULL;
-int gclobjheadindex=0;
-struct lobjpointerblock *gclobjtail=NULL;
-int gclobjtailindex=0;
-struct lobjpointerblock *gclobjtail2=NULL;
-int gclobjtailindex2=0;
-struct lobjpointerblock *gclobjspare=NULL;
-
-#ifdef GC_DEBUG
-// dump whole mem in blocks
-inline void dumpSMem() {
- int block = 0;
- int sblock = 0;
- int j = 0;
- int i = 0;
- int coren = 0;
- int x = 0;
- int y = 0;
- printf("(%x,%x) Dump shared mem: \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- // reserved blocks for sblocktbl
- printf("(%x,%x) ++++ reserved sblocks ++++ \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- for(i=BAMBOO_BASE_VA; i<gcbaseva; i+= 4*16) {
- printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
- udn_tile_coord_x(), udn_tile_coord_y(),
- *((int *)(i)), *((int *)(i + 4)),
- *((int *)(i + 4*2)), *((int *)(i + 4*3)),
- *((int *)(i + 4*4)), *((int *)(i + 4*5)),
- *((int *)(i + 4*6)), *((int *)(i + 4*7)),
- *((int *)(i + 4*8)), *((int *)(i + 4*9)),
- *((int *)(i + 4*10)), *((int *)(i + 4*11)),
- *((int *)(i + 4*12)), *((int *)(i + 4*13)),
- *((int *)(i + 4*14)), *((int *)(i + 4*15)));
- }
- sblock = gcreservedsb;
- bool advanceblock = false;
- // remaining memory
- for(i=gcbaseva; i<gcbaseva+BAMBOO_SHARED_MEM_SIZE; i+=4*16) {
- advanceblock = false;
- // computing sblock # and block #, core coordinate (x,y) also
- if(j%((BAMBOO_SMEM_SIZE)/(4*16)) == 0) {
- // finished a sblock
- if(j < ((BAMBOO_LARGE_SMEM_BOUND)/(4*16))) {
- if((j > 0) && (j%((BAMBOO_SMEM_SIZE_L)/(4*16)) == 0)) {
- // finished a block
- block++;
- advanceblock = true;
- }
- } else {
- // finished a block
- block++;
- advanceblock = true;
- }
- // compute core #
- if(advanceblock) {
- coren = gc_block2core[block%(NUMCORES4GC*2)];
- }
- // compute core coordinate
- BAMBOO_COORDS(coren, &x, &y);
- printf("(%x,%x) ==== %d, %d : core (%d,%d), saddr %x====\n",
- udn_tile_coord_x(), udn_tile_coord_y(),
- block, sblock++, x, y,
- (sblock-1)*(BAMBOO_SMEM_SIZE)+gcbaseva);
- }
- j++;
- printf("(%x,%x) 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x \n",
- udn_tile_coord_x(), udn_tile_coord_y(),
- *((int *)(i)), *((int *)(i + 4)),
- *((int *)(i + 4*2)), *((int *)(i + 4*3)),
- *((int *)(i + 4*4)), *((int *)(i + 4*5)),
- *((int *)(i + 4*6)), *((int *)(i + 4*7)),
- *((int *)(i + 4*8)), *((int *)(i + 4*9)),
- *((int *)(i + 4*10)), *((int *)(i + 4*11)),
- *((int *)(i + 4*12)), *((int *)(i + 4*13)),
- *((int *)(i + 4*14)), *((int *)(i + 4*15)));
- }
- printf("(%x,%x) \n", udn_tile_coord_x(), udn_tile_coord_y());
-}
-#endif
-
-// should be invoked with interruption closed
-inline void gc_enqueue_I(void *ptr) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe601);
- BAMBOO_DEBUGPRINT_REG(ptr);
-#endif
- if (gcheadindex==NUMPTRS) {
- struct pointerblock * tmp;
- if (gcspare!=NULL) {
- tmp=gcspare;
- gcspare=NULL;
- } else {
- tmp=RUNMALLOC_I(sizeof(struct pointerblock));
- } // if (gcspare!=NULL)
- gchead->next=tmp;
- gchead=tmp;
- gcheadindex=0;
- } // if (gcheadindex==NUMPTRS)
- gchead->ptrs[gcheadindex++]=ptr;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe602);
-#endif
-} // void gc_enqueue_I(void *ptr)
-
-// dequeue and destroy the queue
-inline void * gc_dequeue_I() {
- if (gctailindex==NUMPTRS) {
- struct pointerblock *tmp=gctail;
- gctail=gctail->next;
- gctailindex=0;
- if (gcspare!=NULL) {
- RUNFREE(tmp);
- } else {
- gcspare=tmp;
- } // if (gcspare!=NULL)
- } // if (gctailindex==NUMPTRS)
- return gctail->ptrs[gctailindex++];
-} // void * gc_dequeue()
-
-// dequeue and do not destroy the queue
-inline void * gc_dequeue2_I() {
- if (gctailindex2==NUMPTRS) {
- struct pointerblock *tmp=gctail2;
- gctail2=gctail2->next;
- gctailindex2=0;
- } // if (gctailindex2==NUMPTRS)
- return gctail2->ptrs[gctailindex2++];
-} // void * gc_dequeue2()
-
-inline int gc_moreItems_I() {
- if ((gchead==gctail)&&(gctailindex==gcheadindex))
- return 0;
- return 1;
-} // int gc_moreItems()
-
-inline int gc_moreItems2_I() {
- if ((gchead==gctail2)&&(gctailindex2==gcheadindex))
- return 0;
- return 1;
-} // int gc_moreItems2()
-
-// should be invoked with interruption closed
-// enqueue a large obj: start addr & length
-inline void gc_lobjenqueue_I(void *ptr,
- int length,
- int host) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe901);
-#endif
- if (gclobjheadindex==NUMLOBJPTRS) {
- struct lobjpointerblock * tmp;
- if (gclobjspare!=NULL) {
- tmp=gclobjspare;
- gclobjspare=NULL;
- } else {
- tmp=RUNMALLOC_I(sizeof(struct lobjpointerblock));
- } // if (gclobjspare!=NULL)
- gclobjhead->next=tmp;
- tmp->prev = gclobjhead;
- gclobjhead=tmp;
- gclobjheadindex=0;
- } // if (gclobjheadindex==NUMLOBJPTRS)
- gclobjhead->lobjs[gclobjheadindex]=ptr;
- gclobjhead->lengths[gclobjheadindex]=length;
- gclobjhead->hosts[gclobjheadindex++]=host;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(gclobjhead->lobjs[gclobjheadindex-1]);
- BAMBOO_DEBUGPRINT_REG(gclobjhead->lengths[gclobjheadindex-1]);
- BAMBOO_DEBUGPRINT_REG(gclobjhead->hosts[gclobjheadindex-1]);
-#endif
-} // void gc_lobjenqueue_I(void *ptr...)
-
-// dequeue and destroy the queue
-inline void * gc_lobjdequeue_I(int * length,
- int * host) {
- if (gclobjtailindex==NUMLOBJPTRS) {
- struct lobjpointerblock *tmp=gclobjtail;
- gclobjtail=gclobjtail->next;
- gclobjtailindex=0;
- gclobjtail->prev = NULL;
- if (gclobjspare!=NULL) {
- RUNFREE(tmp);
- } else {
- gclobjspare=tmp;
- tmp->next = NULL;
- tmp->prev = NULL;
- } // if (gclobjspare!=NULL)
- } // if (gclobjtailindex==NUMLOBJPTRS)
- if(length != NULL) {
- *length = gclobjtail->lengths[gclobjtailindex];
- }
- if(host != NULL) {
- *host = (int)(gclobjtail->hosts[gclobjtailindex]);
- }
- return gclobjtail->lobjs[gclobjtailindex++];
-} // void * gc_lobjdequeue()
-
-inline int gc_lobjmoreItems_I() {
- if ((gclobjhead==gclobjtail)&&(gclobjtailindex==gclobjheadindex))
- return 0;
- return 1;
-} // int gc_lobjmoreItems()
-
-// dequeue and don't destroy the queue
-inline void gc_lobjdequeue2_I() {
- if (gclobjtailindex2==NUMLOBJPTRS) {
- gclobjtail2=gclobjtail2->next;
- gclobjtailindex2=1;
- } else {
- gclobjtailindex2++;
- } // if (gclobjtailindex2==NUMLOBJPTRS)
-} // void * gc_lobjdequeue2()
-
-inline int gc_lobjmoreItems2_I() {
- if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
- return 0;
- return 1;
-} // int gc_lobjmoreItems2()
-
-// 'reversly' dequeue and don't destroy the queue
-inline void gc_lobjdequeue3_I() {
- if (gclobjtailindex2==0) {
- gclobjtail2=gclobjtail2->prev;
- gclobjtailindex2=NUMLOBJPTRS-1;
- } else {
- gclobjtailindex2--;
- } // if (gclobjtailindex2==NUMLOBJPTRS)
-} // void * gc_lobjdequeue3()
-
-inline int gc_lobjmoreItems3_I() {
- if ((gclobjtail==gclobjtail2)&&(gclobjtailindex2==gclobjtailindex))
- return 0;
- return 1;
-} // int gc_lobjmoreItems3()
-
-inline void gc_lobjqueueinit4_I() {
- gclobjtail2 = gclobjtail;
- gclobjtailindex2 = gclobjtailindex;
-} // void gc_lobjqueueinit2()
-
-inline void * gc_lobjdequeue4_I(int * length,
- int * host) {
- if (gclobjtailindex2==NUMLOBJPTRS) {
- gclobjtail2=gclobjtail2->next;
- gclobjtailindex2=0;
- } // if (gclobjtailindex==NUMLOBJPTRS)
- if(length != NULL) {
- *length = gclobjtail2->lengths[gclobjtailindex2];
- }
- if(host != NULL) {
- *host = (int)(gclobjtail2->hosts[gclobjtailindex2]);
- }
- return gclobjtail2->lobjs[gclobjtailindex2++];
-} // void * gc_lobjdequeue()
-
-inline int gc_lobjmoreItems4_I() {
- if ((gclobjhead==gclobjtail2)&&(gclobjtailindex2==gclobjheadindex))
- return 0;
- return 1;
-} // int gc_lobjmoreItems(
-
-INTPTR gccurr_heapbound = 0;
-
-inline void gettype_size(void * ptr,
- int * ttype,
- int * tsize) {
- int type = ((int *)ptr)[0];
- int size = 0;
- if(type < NUMCLASSES) {
- // a normal object
- size = classsize[type];
- } else {
- // an array
- struct ArrayObject *ao=(struct ArrayObject *)ptr;
- int elementsize=classsize[type];
- int length=ao->___length___;
- size=sizeof(struct ArrayObject)+length*elementsize;
- } // if(type < NUMCLASSES)
- *ttype = type;
- *tsize = size;
-}
-
-inline bool isLarge(void * ptr,
- int * ttype,
- int * tsize) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe701);
- BAMBOO_DEBUGPRINT_REG(ptr);
-#endif
- // check if a pointer is referring to a large object
- gettype_size(ptr, ttype, tsize);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(*tsize);
-#endif
- int bound = (BAMBOO_SMEM_SIZE);
- if(((int)ptr-gcbaseva) < (BAMBOO_LARGE_SMEM_BOUND)) {
- bound = (BAMBOO_SMEM_SIZE_L);
- }
- if((((int)ptr-gcbaseva)%(bound))==0) {
- // ptr is a start of a block
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe702);
- BAMBOO_DEBUGPRINT(1);
-#endif
- return true;
- }
- if((bound-(((int)ptr-gcbaseva)%bound)) < (*tsize)) {
- // it acrosses the boundary of current block
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe703);
- BAMBOO_DEBUGPRINT(1);
-#endif
- return true;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0);
-#endif
- return false;
-} // bool isLarge(void * ptr, int * ttype, int * tsize)
-
-inline int hostcore(void * ptr) {
- // check the host core of ptr
- int host = 0;
- RESIDECORE(ptr, &host);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xedd0);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(host);
-#endif
- return host;
-} // int hostcore(void * ptr)
-
-inline bool isLocal(void * ptr) {
- // check if a pointer is in shared heap on this core
- return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
-} // bool isLocal(void * ptr)
-
-inline bool gc_checkCoreStatus_I() {
- bool allStall = true;
- for(int i = 0; i < NUMCORES4GC; ++i) {
- if(gccorestatus[i] != 0) {
- allStall = false;
- break;
- } // if(gccorestatus[i] != 0)
- } // for(i = 0; i < NUMCORES4GC; ++i)
- return allStall;
-}
-
-inline bool gc_checkAllCoreStatus_I() {
- bool allStall = true;
- for(int i = 0; i < NUMCORESACTIVE; ++i) {
- if(gccorestatus[i] != 0) {
- allStall = false;
- break;
- } // if(gccorestatus[i] != 0)
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
- return allStall;
-}
-
-inline void checkMarkStatue() {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee01);
-#endif
- int i;
- if((!waitconfirm) ||
- (waitconfirm && (numconfirm == 0))) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee02);
-#endif
- int entry_index = 0;
- if(waitconfirm) {
- // phase 2
- entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
- } else {
- // phase 1
- entry_index = gcnumsrobjs_index;
- }
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- gcnumsendobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
- gcnumreceiveobjs[entry_index][BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
- // check the status of all cores
- bool allStall = gc_checkAllCoreStatus_I();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee03);
-#endif
- if(allStall) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee04);
-#endif
- // ask for confirm
- if(!waitconfirm) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee05);
-#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 = NUMCORESACTIVE - 1;
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- for(i = 1; i < NUMCORESACTIVE; ++i) {
- gccorestatus[i] = 1;
- // send mark phase finish confirm request msg to core i
- send_msg_1(i, GCMARKCONFIRM, false);
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
- } else {
- // Phase 2
- // 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 < NUMCORESACTIVE; ++i) {
- sumsendobj += gcnumsendobjs[gcnumsrobjs_index][i];
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee06);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
-#endif
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj -= gcnumreceiveobjs[gcnumsrobjs_index][i];
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee07);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
-#endif
- if(0 == sumsendobj) {
- // Check if there are changes of the numsendobjs or numreceiveobjs on
- // each core
- bool ischanged = false;
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- if((gcnumsendobjs[0][i] != gcnumsendobjs[1][i]) ||
- (gcnumreceiveobjs[0][i] != gcnumreceiveobjs[1][i]) ) {
- ischanged = true;
- break;
- }
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee08);
- BAMBOO_DEBUGPRINT_REG(ischanged);
-#endif
- if(!ischanged) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee09);
-#endif
- // all the core status info are the latest
- // stop mark phase
- gcphase = COMPACTPHASE;
- // restore the gcstatus for all cores
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- gccorestatus[i] = 1;
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
- } else {
- waitconfirm = false;
- gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
- } // if(!ischanged)
- } else {
- // There were changes between phase 1 and phase 2, can not decide
- // whether the mark phase has been finished
- waitconfirm = false;
- // As it fails in phase 2, flip the entries
- gcnumsrobjs_index = (gcnumsrobjs_index == 0) ? 1 : 0;
- } // if(0 == sumsendobj) else ...
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // if(!gcwaitconfirm) else()
- } else {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // if(allStall)
- } // if((!waitconfirm)...
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee0a);
-#endif
-} // void checkMarkStatue()
-/*
-inline bool preGC() {
- // preparation for gc
- // make sure to clear all incoming msgs espacially transfer obj msgs
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec01);
-#endif
- int i;
- if((!waitconfirm) ||
- (waitconfirm && (numconfirm == 0))) {
- // send out status confirm msgs to all cores to check if there are
- // transfer obj msgs on-the-fly
- waitconfirm = true;
- numconfirm = NUMCORESACTIVE - 1;
- for(i = 1; i < NUMCORESACTIVE; ++i) {
- corestatus[i] = 1;
- // send status confirm msg to core i
- send_msg_1(i, STATUSCONFIRM, false);
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec02);
-#endif
- while(true) {
- if(numconfirm == 0) {
- break;
- }
- } // wait for confirmations
- waitconfirm = false;
- numconfirm = 0;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec03);
-#endif
- numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
- numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
- int sumsendobj = 0;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec04);
-#endif
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj += numsendobjs[i];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
-#endif
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec05);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
-#endif
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj -= numreceiveobjs[i];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
-#endif
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec06);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
-#endif
- if(0 == sumsendobj) {
- return true;
- } else {
- // still have some transfer obj msgs on-the-fly, can not start gc
- return false;
- } // if(0 == sumsendobj)
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec07);
-#endif
- // previously asked for status confirmation and do not have all the
- // confirmations yet, can not start gc
- return false;
- } // if((!waitconfirm) ||
-} // bool preGC()*/
-
-inline void initGC() {
- int i;
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- for(i = 0; i < NUMCORES4GC; ++i) {
- gccorestatus[i] = 1;
- gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
- gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
- gcloads[i] = 0;
- gcrequiredmems[i] = 0;
- gcfilledblocks[i] = 0;
- gcstopblock[i] = 0;
- } // for(i = 0; i < NUMCORES4GC; ++i)
- for(i = NUMCORES4GC; i < NUMCORESACTIVE; ++i) {
- gccorestatus[i] = 1;
- gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
- gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
- }
- gcheaptop = 0;
- gctopcore = 0;
- gctopblock = 0;
- } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
- gcself_numsendobjs = 0;
- gcself_numreceiveobjs = 0;
- gcmarkedptrbound = 0;
- gcobj2map = 0;
- gcmappedobj = 0;
- //gcismapped = false;
- gcnumlobjs = 0;
- gcmovestartaddr = 0;
- gctomove = false;
- gcblock2fill = 0;
- gcmovepending = 0;
- gccurr_heaptop = 0;
- gcdstcore = 0;
-
- // initialize queue
- if (gchead==NULL) {
- gcheadindex=gctailindex=gctailindex2 = 0;
- gchead=gctail=gctail2=RUNMALLOC(sizeof(struct pointerblock));
- } else {
- gctailindex = gctailindex2 = gcheadindex;
- gctail = gctail2 = gchead;
- }
-
- // initialize the large obj queues
- if (gclobjhead==NULL) {
- gclobjheadindex=0;
- gclobjtailindex=0;
- gclobjtailindex2 = 0;
- gclobjhead=gclobjtail=gclobjtail2=
- RUNMALLOC(sizeof(struct lobjpointerblock));
- } else {
- gclobjtailindex = gclobjtailindex2 = gclobjheadindex = 0;
- gclobjtail = gclobjtail2 = gclobjhead;
- }
- gclobjhead->next = gclobjhead->prev = NULL;
-
-#ifdef LOCALHASHTBL_TEST
- freeRuntimeHash(gcpointertbl);
- gcpointertbl = allocateRuntimeHash(20);
-#else
- mgchashreset(gcpointertbl);
-#endif
- //gcpointertbl = allocateMGCHash(20);
-
- freeMGCHash(gcforwardobjtbl);
- gcforwardobjtbl = allocateMGCHash(20, 3);
-
- // initialize the mapping info related structures
- if((BAMBOO_NUM_OF_CORE < NUMCORES4GC) && (gcsharedptbl != NULL)) {
- // Never free the shared hash table, just reset it
- /*freeGCSharedHash(gcsharedptbl);
- gcsharedptbl = allocateGCSharedHash(20);*/
- mgcsharedhashReset(gcsharedptbl);
- }
- // Zero out the remaining bamboo_cur_msp
- // Only zero out the first 4 bytes of the remaining memory
- /*if((bamboo_cur_msp != 0)
- && (bamboo_smem_zero_top == bamboo_cur_msp)
- && (bamboo_smem_size > 0)) {
- *((int *)bamboo_cur_msp) = 0;
- }*/
-#ifdef GC_PROFILE
- // TODO
- /*num_mapinforequest = 0;
- num_mapinforequest_i = 0;
- flushstalltime = 0;
- flushstalltime_i = 0;
- num_markrequest = 0;
- marktime = 0;*/
- gc_num_livespace = 0;
- gc_num_freespace = 0;
- gc_num_lobj = 0;
- gc_num_lobjspace = 0;
- gc_num_liveobj = 0;
- gc_num_forwardobj = 0;
- gc_num_profiles = NUMCORESACTIVE - 1;
-#endif
-} // void initGC()
-
-// compute load balance for all cores
-inline int loadbalance(int * heaptop) {
- // compute load balance
- int i;
-
- // get the total loads
- int tloads = gcloads[STARTUPCORE];
- for(i = 1; i < NUMCORES4GC; i++) {
- tloads += gcloads[i];
- }
- *heaptop = gcbaseva + tloads;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xdddd);
- BAMBOO_DEBUGPRINT_REG(tloads);
- BAMBOO_DEBUGPRINT_REG(*heaptop);
-#endif
- int b = 0;
- BLOCKINDEX(*heaptop, &b);
- int numbpc = b / NUMCORES4GC; // num of blocks per core
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(b);
- BAMBOO_DEBUGPRINT_REG(numbpc);
-#endif
- gctopblock = b;
- RESIDECORE(heaptop, &gctopcore);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(gctopcore);
-#endif
- return numbpc;
-} // void loadbalance(int * heaptop)
-
-inline bool cacheLObjs() {
- // check the total mem size need for large objs
- unsigned long long sumsize = 0;
- int size = 0;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe801);
-#endif
- gclobjtail2 = gclobjtail;
- gclobjtailindex2 = gclobjtailindex;
- int tmp_lobj = 0;
- int tmp_len = 0;
- int tmp_host = 0;
- // compute total mem size required and sort the lobjs in ascending order
- while(gc_lobjmoreItems2_I()) {
- gc_lobjdequeue2_I();
- tmp_lobj = gclobjtail2->lobjs[gclobjtailindex2-1];
- tmp_host = gclobjtail2->hosts[gclobjtailindex2-1];
- tmp_len = gclobjtail2->lengths[gclobjtailindex2 - 1];
- sumsize += tmp_len;
-#ifdef GC_PROFILE
- gc_num_lobj++;
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2-1]);
- BAMBOO_DEBUGPRINT_REG(tmp_len);
- BAMBOO_DEBUGPRINT_REG(sumsize);
-#endif
- int i = gclobjtailindex2-1;
- struct lobjpointerblock * tmp_block = gclobjtail2;
- // find the place to insert
- while(true) {
- if(i == 0) {
- if(tmp_block->prev == NULL) {
- break;
- }
- if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] > tmp_lobj) {
- tmp_block->lobjs[i] = tmp_block->prev->lobjs[NUMLOBJPTRS-1];
- tmp_block->lengths[i] = tmp_block->prev->lengths[NUMLOBJPTRS-1];
- tmp_block->hosts[i] = tmp_block->prev->hosts[NUMLOBJPTRS-1];
- tmp_block = tmp_block->prev;
- i = NUMLOBJPTRS-1;
- } else {
- break;
- } // if(tmp_block->prev->lobjs[NUMLOBJPTRS-1] < tmp_lobj)
- } else {
- if(tmp_block->lobjs[i-1] > tmp_lobj) {
- tmp_block->lobjs[i] = tmp_block->lobjs[i-1];
- tmp_block->lengths[i] = tmp_block->lengths[i-1];
- tmp_block->hosts[i] = tmp_block->hosts[i-1];
- i--;
- } else {
- break;
- } // if(tmp_block->lobjs[i-1] < tmp_lobj)
- } // if(i ==0 ) else {}
- } // while(true)
- // insert it
- if(i != gclobjtailindex2 - 1) {
- tmp_block->lobjs[i] = tmp_lobj;
- tmp_block->lengths[i] = tmp_len;
- tmp_block->hosts[i] = tmp_host;
- }
- } // while(gc_lobjmoreItems2())
-
-#ifdef GC_PROFILE
- gc_num_lobjspace = sumsize;
-#endif
- // check if there are enough space to cache these large objs
- INTPTR dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -sumsize;
- if((unsigned long long)gcheaptop > (unsigned long long)dst) {
- // do not have enough room to cache large objs
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe802);
- BAMBOO_DEBUGPRINT_REG(dst);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
- BAMBOO_DEBUGPRINT_REG(sumsize);
-#endif
- return false;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe803);
- BAMBOO_DEBUGPRINT_REG(dst);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
-#endif
-
- gcheaptop = dst; // Note: record the start of cached lobjs with gcheaptop
- // cache the largeObjs to the top of the shared heap
- //gclobjtail2 = gclobjtail;
- //gclobjtailindex2 = gclobjtailindex;
- dst = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
- while(gc_lobjmoreItems3_I()) {
- gc_lobjdequeue3_I();
- size = gclobjtail2->lengths[gclobjtailindex2];
- // set the mark field to , indicating that this obj has been moved
- // and need to be flushed
- ((int *)(gclobjtail2->lobjs[gclobjtailindex2]))[6] = COMPACTED;
- dst -= size;
- if((int)dst < (int)(gclobjtail2->lobjs[gclobjtailindex2])+size) {
- memmove(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
- } else {
- //BAMBOO_WRITE_HINT_CACHE(dst, size);
- memcpy(dst, gclobjtail2->lobjs[gclobjtailindex2], size);
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0x804);
- BAMBOO_DEBUGPRINT_REG(gclobjtail2->lobjs[gclobjtailindex2]);
- BAMBOO_DEBUGPRINT(dst);
- BAMBOO_DEBUGPRINT_REG(size);
- BAMBOO_DEBUGPRINT_REG(*((int*)gclobjtail2->lobjs[gclobjtailindex2]));
- BAMBOO_DEBUGPRINT_REG(*((int*)(dst)));
-#endif
- }
- return true;
-} // void cacheLObjs()
-
-// update the bmmboo_smemtbl to record current shared mem usage
-void updateSmemTbl(int coren,
- int localtop) {
- int ltopcore = 0;
- int bound = BAMBOO_SMEM_SIZE_L;
- BLOCKINDEX(localtop, <opcore);
- if(localtop >= (gcbaseva+(BAMBOO_LARGE_SMEM_BOUND))) {
- bound = BAMBOO_SMEM_SIZE;
- }
- int load = (localtop-gcbaseva)%bound;
- int i = 0;
- int j = 0;
- int toset = 0;
- do {
- toset = gc_core2block[2*coren+i]+(NUMCORES4GC*2)*j;
- if(toset < ltopcore) {
- bamboo_smemtbl[toset]=
- (toset<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
-#ifdef SMEMM
- gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
- } else if(toset == ltopcore) {
- bamboo_smemtbl[toset] = load;
-#ifdef SMEMM
- gcmem_mixed_usedmem += bamboo_smemtbl[toset];
-#endif
- break;
- } else {
- break;
- }
- i++;
- if(i == 2) {
- i = 0;
- j++;
- }
- } while(true);
-} // void updateSmemTbl(int, int)
-
-inline void moveLObjs() {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea01);
-#endif
-#ifdef SMEMM
- // update the gcmem_mixed_usedmem
- gcmem_mixed_usedmem = 0;
-#endif
- // zero out the smemtbl
- BAMBOO_MEMSET_WH(bamboo_smemtbl, 0, sizeof(int)*gcnumblock);
- // find current heap top
- // flush all gcloads to indicate the real heap top on one core
- // previous it represents the next available ptr on a core
- if((gcloads[0] > (gcbaseva+(BAMBOO_SMEM_SIZE_L)))
- && ((gcloads[0]%(BAMBOO_SMEM_SIZE)) == 0)) {
- // edge of a block, check if this is exactly the heaptop
- BASEPTR(0, gcfilledblocks[0]-1, &(gcloads[0]));
- gcloads[0]+=(gcfilledblocks[0]>1 ?
- (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
- }
- updateSmemTbl(0, gcloads[0]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea02);
- BAMBOO_DEBUGPRINT_REG(gcloads[0]);
- BAMBOO_DEBUGPRINT_REG(bamboo_smemtbl[0]);
-#endif
- for(int i = 1; i < NUMCORES4GC; i++) {
- int tmptop = 0;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000+i);
- BAMBOO_DEBUGPRINT_REG(gcloads[i]);
- BAMBOO_DEBUGPRINT_REG(gcfilledblocks[i]);
-#endif
- if((gcfilledblocks[i] > 0)
- && ((gcloads[i] % (BAMBOO_SMEM_SIZE)) == 0)) {
- // edge of a block, check if this is exactly the heaptop
- BASEPTR(i, gcfilledblocks[i]-1, &gcloads[i]);
- gcloads[i] +=
- (gcfilledblocks[i]>1 ? (BAMBOO_SMEM_SIZE) : (BAMBOO_SMEM_SIZE_L));
- tmptop = gcloads[i];
- }
- updateSmemTbl(i, gcloads[i]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(gcloads[i]);
-#endif
- } // for(int i = 1; i < NUMCORES4GC; i++) {
-
- // find current heap top
- // TODO
- // a bug here: when using local allocation, directly move large objects
- // to the highest free chunk might not be memory efficient
- int tmpheaptop = 0;
- int size = 0;
- int bound = 0;
- int i = 0;
- for(i = gcnumblock-1; i >= 0; i--) {
- if(bamboo_smemtbl[i] > 0) {
- break;
- }
- }
- if(i == -1) {
- tmpheaptop = gcbaseva;
- } else {
- tmpheaptop = gcbaseva+bamboo_smemtbl[i]+((i<NUMCORES4GC) ?
- (BAMBOO_SMEM_SIZE_L*i) :
- (BAMBOO_SMEM_SIZE*(i-NUMCORES4GC)+BAMBOO_LARGE_SMEM_BOUND));
- }
-
- // move large objs from gcheaptop to tmpheaptop
- // write the header first
- unsigned int tomove = gcbaseva + (BAMBOO_SHARED_MEM_SIZE) -gcheaptop;
-#ifdef SMEMM
- gcmem_mixed_usedmem += tomove;
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea03);
- BAMBOO_DEBUGPRINT_REG(tomove);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
-#endif
- // flush the sbstartbl
- BAMBOO_MEMSET_WH(&(gcsbstarttbl[gcreservedsb]), '\0',
- (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE-gcreservedsb)*sizeof(INTPTR));
- if(tomove == 0) {
- gcheaptop = tmpheaptop;
- } else {
- // check how many blocks it acrosses
- int remain = tmpheaptop-gcbaseva;
- int sb = remain/(BAMBOO_SMEM_SIZE) + gcreservedsb;//number of the sblock
- int b = 0; // number of the block
- BLOCKINDEX(tmpheaptop, &b);
- // check the remaining space in this block
- bound = (BAMBOO_SMEM_SIZE);
- if(remain < (BAMBOO_LARGE_SMEM_BOUND)) {
- bound = (BAMBOO_SMEM_SIZE_L);
- }
- remain = bound - remain%bound;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea04);
-#endif
- size = 0;
- int isize = 0;
- int host = 0;
- int ptr = 0;
- int base = tmpheaptop;
- int cpysize = 0;
- remain -= BAMBOO_CACHE_LINE_SIZE;
- tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
- gc_lobjqueueinit4_I();
- while(gc_lobjmoreItems4_I()) {
- ptr = (int)(gc_lobjdequeue4_I(&size, &host));
- ALIGNSIZE(size, &isize);
- if(remain < isize) {
- // this object acrosses blocks
- if(cpysize > 0) {
- // close current block, fill its header
- BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
- *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
- bamboo_smemtbl[b]+=BAMBOO_CACHE_LINE_SIZE;//add the size of header
- cpysize = 0;
- base = tmpheaptop;
- if(remain == 0) {
- remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
- BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- }
- remain -= BAMBOO_CACHE_LINE_SIZE;
- tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
- BLOCKINDEX(tmpheaptop, &b);
- sb = (tmpheaptop-gcbaseva)/(BAMBOO_SMEM_SIZE) + gcreservedsb;
- } // if(cpysize > 0)
-
- // move the large obj
- if((int)gcheaptop < (int)(tmpheaptop)+size) {
- memmove(tmpheaptop, gcheaptop, size);
- } else {
- //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
- memcpy(tmpheaptop, gcheaptop, size);
- }
- // fill the remaining space with -2 padding
- BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea05);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
- BAMBOO_DEBUGPRINT_REG(size);
- BAMBOO_DEBUGPRINT_REG(isize);
- BAMBOO_DEBUGPRINT_REG(base);
-#endif
- gcheaptop += size;
- // cache the mapping info anyway
- //if(ptr != tmpheaptop) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
-#else
- mgchashInsert_I(gcpointertbl, ptr, tmpheaptop);
-#endif
- //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- //}
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcdca);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
-#endif
- if(host != BAMBOO_NUM_OF_CORE) {
- // send the original host core with the mapping info
- send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcdcb);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
-#endif
- } // if(host != BAMBOO_NUM_OF_CORE)
- tmpheaptop += isize;
-
- // set the gcsbstarttbl and bamboo_smemtbl
- int tmpsbs = 1+(isize-remain-1)/BAMBOO_SMEM_SIZE;
- for(int k = 1; k < tmpsbs; k++) {
- gcsbstarttbl[sb+k] = (INTPTR)(-1);
- }
- sb += tmpsbs;
- bound = (b<NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- BLOCKINDEX(tmpheaptop-1, &tmpsbs);
- for(; b < tmpsbs; b++) {
- bamboo_smemtbl[b] = bound;
- if(b==NUMCORES4GC-1) {
- bound = BAMBOO_SMEM_SIZE;
- }
- }
- if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) {
- gcsbstarttbl[sb] = (INTPTR)(-1);
- remain = ((tmpheaptop-gcbaseva)<(BAMBOO_LARGE_SMEM_BOUND)) ?
- BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- bamboo_smemtbl[b] = bound;
- } else {
- gcsbstarttbl[sb] = (INTPTR)(tmpheaptop);
- remain = tmpheaptop-gcbaseva;
- bamboo_smemtbl[b] = remain%bound;
- remain = bound - bamboo_smemtbl[b];
- } // if(((isize-remain)%(BAMBOO_SMEM_SIZE)) == 0) else ...
-
- // close current block and fill the header
- BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
- *((int*)base) = isize + BAMBOO_CACHE_LINE_SIZE;
- cpysize = 0;
- base = tmpheaptop;
- if(remain == BAMBOO_CACHE_LINE_SIZE) {
- // fill with 0 in case
- BAMBOO_MEMSET_WH(tmpheaptop, '\0', remain);
- }
- remain -= BAMBOO_CACHE_LINE_SIZE;
- tmpheaptop += BAMBOO_CACHE_LINE_SIZE;
- } else {
- remain -= isize;
- // move the large obj
- if((int)gcheaptop < (int)(tmpheaptop)+size) {
- memmove(tmpheaptop, gcheaptop, size);
- } else {
- //BAMBOO_WRITE_HINT_CACHE(tmpheaptop, size);
- memcpy(tmpheaptop, gcheaptop, size);
- }
- // fill the remaining space with -2 padding
- BAMBOO_MEMSET_WH(tmpheaptop+size, -2, isize-size);
- // zero out original mem caching the lobj
- //BAMBOO_MEMSET_WH(gcheaptop, '\0', size); // TODO ??
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea06);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
- BAMBOO_DEBUGPRINT_REG(size);
- BAMBOO_DEBUGPRINT_REG(isize);
-#endif
-
- gcheaptop += size;
- cpysize += isize;
- // cache the mapping info anyway
- //if(ptr != tmpheaptop) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashadd_I(gcpointertbl, ptr, tmpheaptop);
-#else
- mgchashInsert_I(gcpointertbl, ptr, tmpheaptop);
-#endif
- //MGCHashadd_I(gcpointertbl, ptr, tmpheaptop);
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- //}
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcdcc);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
- BAMBOO_DEBUGPRINT_REG(*((int*)tmpheaptop));
-#endif
- if(host != BAMBOO_NUM_OF_CORE) {
- // send the original host core with the mapping info
- send_msg_3(host, GCLOBJMAPPING, ptr, tmpheaptop, false);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcdcd);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(tmpheaptop);
-#endif
- } // if(host != BAMBOO_NUM_OF_CORE)
- tmpheaptop += isize;
-
- // update bamboo_smemtbl
- bamboo_smemtbl[b] += isize;
- } // if(remain < isize) else ...
- } // while(gc_lobjmoreItems())
- if(cpysize > 0) {
- // close current block, fill the header
- BAMBOO_MEMSET_WH(base, '\0', BAMBOO_CACHE_LINE_SIZE);
- *((int*)base) = cpysize + BAMBOO_CACHE_LINE_SIZE;
- bamboo_smemtbl[b] += BAMBOO_CACHE_LINE_SIZE;// add the size of the header
- } else {
- tmpheaptop -= BAMBOO_CACHE_LINE_SIZE;
- }
- gcheaptop = tmpheaptop;
-
- } // if(tomove == 0)
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea07);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
-#endif
-
- bamboo_free_block = 0;
- int tbound = 0;
- do {
- tbound = (bamboo_free_block<NUMCORES4GC) ?
- BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- if(bamboo_smemtbl[bamboo_free_block] == tbound) {
- bamboo_free_block++;
- } else {
- // the first non-full partition
- break;
- }
- } while(true);
-
- // TODO
- /*unsigned long long gc_num_livespace = 0;
- for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
- gc_num_livespace += bamboo_smemtbl[tmpi];
- }
- BAMBOO_DEBUGPRINT_REG(gc_num_livespace);
- BAMBOO_DEBUGPRINT_REG(bamboo_free_block);*/
-
-#ifdef GC_PROFILE
- // check how many live space there are
- gc_num_livespace = 0;
- for(int tmpi = 0; tmpi < gcnumblock; tmpi++) {
- gc_num_livespace += bamboo_smemtbl[tmpi];
- }
- gc_num_freespace = (BAMBOO_SHARED_MEM_SIZE) - gc_num_livespace;
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xea08);
- BAMBOO_DEBUGPRINT_REG(gcheaptop);
-#endif
-} // void moveLObjs()
-
-inline void markObj(void * objptr) {
- if(objptr == NULL) {
- return;
- }
- if(ISSHAREDOBJ(objptr)) {
- int host = hostcore(objptr);
- if(BAMBOO_NUM_OF_CORE == host) {
- // on this core
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(((int *)objptr)[6] == INIT) {
- // this is the first time that this object is discovered,
- // set the flag as DISCOVERED
- ((int *)objptr)[6] |= DISCOVERED;
- gc_enqueue_I(objptr);
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT_REG(host);
- BAMBOO_DEBUGPRINT_REG(objptr);
-#endif
- // check if this obj has been forwarded
- if(!MGCHashcontains(gcforwardobjtbl, (int)objptr)) {
-#ifdef GC_PROFILE
- // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
-#endif
- // send a msg to host informing that objptr is active
- send_msg_2(host, GCMARKEDOBJ, objptr, /*BAMBOO_NUM_OF_CORE,*/ false);
-#ifdef GC_PROFILE
- // TODO
- /*
- marktime += BAMBOO_GET_EXE_TIME() - ttime;
- num_markrequest++;*/
- gc_num_forwardobj++;
-#endif // GC_PROFILE
- gcself_numsendobjs++;
- MGCHashadd(gcforwardobjtbl, (int)objptr);
- }
- }
- } else {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- gc_enqueue_I(objptr);
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // if(ISSHAREDOBJ(objptr))
-} // void markObj(void * objptr)
-
-// enqueue root objs
-inline void tomark(struct garbagelist * stackptr) {
- if(MARKPHASE != gcphase) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(gcphase);
-#endif
- BAMBOO_EXIT(0xb101);
- }
- gcbusystatus = true;
- gcnumlobjs = 0;
-
- int i,j;
- // enqueue current stack
- while(stackptr!=NULL) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe501);
- BAMBOO_DEBUGPRINT_REG(stackptr->size);
- BAMBOO_DEBUGPRINT_REG(stackptr->next);
- BAMBOO_DEBUGPRINT_REG(stackptr->array[0]);
-#endif
- for(i=0; i<stackptr->size; i++) {
- if(stackptr->array[i] != NULL) {
- markObj(stackptr->array[i]);
- }
- }
- stackptr=stackptr->next;
- }
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe503);
-#endif
- // enqueue objectsets
- if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
- for(i=0; i<NUMCLASSES; i++) {
- struct parameterwrapper ** queues =
- objectqueues[BAMBOO_NUM_OF_CORE][i];
- int length = numqueues[BAMBOO_NUM_OF_CORE][i];
- for(j = 0; j < length; ++j) {
- struct parameterwrapper * parameter = queues[j];
- struct ObjectHash * set=parameter->objectset;
- struct ObjectNode * ptr=set->listhead;
- while(ptr!=NULL) {
- markObj((void *)ptr->key);
- ptr=ptr->lnext;
- }
- }
- }
- }
-
- // euqueue current task descriptor
- if(currtpd != NULL) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe504);
-#endif
- for(i=0; i<currtpd->numParameters; i++) {
- markObj(currtpd->parameterArray[i]);
- }
- }
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe505);
-#endif
- // euqueue active tasks
- if(activetasks != NULL) {
- struct genpointerlist * ptr=activetasks->list;
- while(ptr!=NULL) {
- struct taskparamdescriptor *tpd=ptr->src;
- int i;
- for(i=0; i<tpd->numParameters; i++) {
- markObj(tpd->parameterArray[i]);
- }
- ptr=ptr->inext;
- }
- }
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe506);
-#endif
- // enqueue cached transferred obj
- struct QueueItem * tmpobjptr = getHead(&objqueue);
- while(tmpobjptr != NULL) {
- struct transObjInfo * objInfo =
- (struct transObjInfo *)(tmpobjptr->objectptr);
- markObj(objInfo->objptr);
- tmpobjptr = getNextQueueItem(tmpobjptr);
- }
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe507);
-#endif
- // enqueue cached objs to be transferred
- struct QueueItem * item = getHead(totransobjqueue);
- while(item != NULL) {
- struct transObjInfo * totransobj =
- (struct transObjInfo *)(item->objectptr);
- markObj(totransobj->objptr);
- item = getNextQueueItem(item);
- } // while(item != NULL)
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe508);
-#endif
- // enqueue lock related info
- for(i = 0; i < runtime_locklen; ++i) {
- markObj((void *)(runtime_locks[i].redirectlock));
- if(runtime_locks[i].value != NULL) {
- markObj((void *)(runtime_locks[i].value));
- }
- }
-
-} // void tomark(struct garbagelist * stackptr)
-
-inline void mark(bool isfirst,
- struct garbagelist * stackptr) {
-#ifdef DEBUG
- if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed01);
-#endif
- if(isfirst) {
-#ifdef DEBUG
- if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed02);
-#endif
- // enqueue root objs
- tomark(stackptr);
- gccurr_heaptop = 0; // record the size of all active objs in this core
- // aligned but does not consider block boundaries
- gcmarkedptrbound = 0;
- }
-#ifdef DEBUG
- if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed03);
-#endif
- int isize = 0;
- bool checkfield = true;
- bool sendStall = false;
- // mark phase
- while(MARKPHASE == gcphase) {
-#ifdef DEBUG
- if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT(0xed04);
-#endif
- while(true) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- bool hasItems = gc_moreItems2_I();
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed05);
-#endif
- if(!hasItems) {
- break;
- }
- sendStall = false;
- gcbusystatus = true;
- checkfield = true;
- void * ptr = gc_dequeue2_I();
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(ptr);
-#endif
- int size = 0;
- int isize = 0;
- int type = 0;
- // check if it is a shared obj
- if(ISSHAREDOBJ(ptr)) {
- // a shared obj, check if it is a local obj on this core
- int host = hostcore(ptr);
- bool islocal = (host == BAMBOO_NUM_OF_CORE);
- if(islocal) {
- bool isnotmarked = ((((int *)ptr)[6] & DISCOVERED) != 0);
- if(isLarge(ptr, &type, &size) && isnotmarked) {
- // ptr is a large object and not marked or enqueued
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xecec);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(*((int*)ptr));
-#endif
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- gc_lobjenqueue_I(ptr, size, BAMBOO_NUM_OF_CORE);
- gcnumlobjs++;
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- // mark this obj
- ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
- } else if(isnotmarked) {
- // ptr is an unmarked active object on this core
- ALIGNSIZE(size, &isize);
- gccurr_heaptop += isize;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xaaaa);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(isize);
- BAMBOO_DEBUGPRINT(((int *)(ptr))[0]);
-#endif
- // mark this obj
- ((int *)ptr)[6] = ((int *)ptr)[6] & (~DISCOVERED) | MARKED;
-
- if(ptr + size > gcmarkedptrbound) {
- gcmarkedptrbound = ptr + size;
- } // if(ptr + size > gcmarkedptrbound)
- } else {
- // ptr is not an active obj or has been marked
- checkfield = false;
- } // if(isLarge(ptr, &type, &size)) else ...
- } /* can never reach here
- else {
-#ifdef DEBUG
- if(BAMBOO_NUM_OF_CORE == 0) {
- BAMBOO_DEBUGPRINT(0xbbbb);
- BAMBOO_DEBUGPRINT_REG(host);
- BAMBOO_DEBUGPRINT_REG(ptr);
- }
-#endif
- // 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))
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed06);
-#endif
-
- if(checkfield) {
- // scan all pointers in ptr
- unsigned INTPTR * pointer;
- pointer=pointerarray[type];
- if (pointer==0) {
- /* Array of primitives */
- /* Do nothing */
- } else if (((INTPTR)pointer)==1) {
- /* Array of pointers */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- int length=ao->___length___;
- int j;
- for(j=0; j<length; j++) {
- void *objptr =
- ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
- markObj(objptr);
- }
- } else {
- INTPTR size=pointer[0];
- int i;
- for(i=1; i<=size; i++) {
- unsigned int offset=pointer[i];
- void * objptr=*((void **)(((char *)ptr)+offset));
- markObj(objptr);
- }
- } // if (pointer==0) else if ... else ...
- } // if(checkfield)
- } // while(gc_moreItems2())
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed07);
-#endif
- gcbusystatus = false;
- // send mark finish msg to core coordinator
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed08);
-#endif
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- gcnumsendobjs[gcnumsrobjs_index][BAMBOO_NUM_OF_CORE]=gcself_numsendobjs;
- gcnumreceiveobjs[gcnumsrobjs_index][BAMBOO_NUM_OF_CORE]=
- gcself_numreceiveobjs;
- gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
- } else {
- if(!sendStall) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed09);
-#endif
- send_msg_4(STARTUPCORE, GCFINISHMARK, BAMBOO_NUM_OF_CORE,
- gcself_numsendobjs, gcself_numreceiveobjs, false);
- sendStall = true;
- }
- } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE) ...
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed0a);
-#endif
-
- if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xed0b);
-#endif
- return;
- }
- } // while(MARKPHASE == gcphase)
-} // mark()
-
-inline void compact2Heaptophelper_I(int coren,
- int* p,
- int* numblocks,
- int* remain) {
- int b;
- int memneed = gcrequiredmems[coren] + BAMBOO_CACHE_LINE_SIZE;
- if(STARTUPCORE == coren) {
- gctomove = true;
- gcmovestartaddr = *p;
- gcdstcore = gctopcore;
- gcblock2fill = *numblocks + 1;
- } else {
- send_msg_4(coren, GCMOVESTART, gctopcore, *p, (*numblocks) + 1, false);
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(coren);
- BAMBOO_DEBUGPRINT_REG(gctopcore);
- BAMBOO_DEBUGPRINT_REG(*p);
- BAMBOO_DEBUGPRINT_REG(*numblocks+1);
-#endif
- if(memneed < *remain) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd104);
-#endif
- *p = *p + memneed;
- gcrequiredmems[coren] = 0;
- gcloads[gctopcore] += memneed;
- *remain = *remain - memneed;
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd105);
-#endif
- // next available block
- *p = *p + *remain;
- gcfilledblocks[gctopcore] += 1;
- int newbase = 0;
- BASEPTR(gctopcore, gcfilledblocks[gctopcore], &newbase);
- gcloads[gctopcore] = newbase;
- gcrequiredmems[coren] -= *remain - BAMBOO_CACHE_LINE_SIZE;
- gcstopblock[gctopcore]++;
- gctopcore = NEXTTOPCORE(gctopblock);
- gctopblock++;
- *numblocks = gcstopblock[gctopcore];
- *p = gcloads[gctopcore];
- BLOCKINDEX(*p, &b);
- *remain=(b<NUMCORES4GC) ?
- ((BAMBOO_SMEM_SIZE_L)-((*p)%(BAMBOO_SMEM_SIZE_L)))
- : ((BAMBOO_SMEM_SIZE)-((*p)%(BAMBOO_SMEM_SIZE)));
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd106);
- BAMBOO_DEBUGPRINT_REG(gctopcore);
- BAMBOO_DEBUGPRINT_REG(*p);
- BAMBOO_DEBUGPRINT_REG(b);
- BAMBOO_DEBUGPRINT_REG(*remain);
-#endif
- } // if(memneed < remain)
- gcmovepending--;
-} // void compact2Heaptophelper_I(int, int*, int*, int*)
-
-inline void compact2Heaptop() {
- // no cores with spare mem and some cores are blocked with pending move
- // find the current heap top and make them move to the heap top
- int p;
- int numblocks = gcfilledblocks[gctopcore];
- //BASEPTR(gctopcore, numblocks, &p);
- p = gcloads[gctopcore];
- int b;
- BLOCKINDEX(p, &b);
- int remain = (b<NUMCORES4GC) ?
- ((BAMBOO_SMEM_SIZE_L)-(p%(BAMBOO_SMEM_SIZE_L)))
- : ((BAMBOO_SMEM_SIZE)-(p%(BAMBOO_SMEM_SIZE)));
- // check if the top core finishes
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gccorestatus[gctopcore] != 0) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd101);
- BAMBOO_DEBUGPRINT_REG(gctopcore);
-#endif
- // let the top core finishes its own work first
- compact2Heaptophelper_I(gctopcore, &p, &numblocks, &remain);
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- return;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd102);
- BAMBOO_DEBUGPRINT_REG(gctopcore);
- BAMBOO_DEBUGPRINT_REG(p);
- BAMBOO_DEBUGPRINT_REG(b);
- BAMBOO_DEBUGPRINT_REG(remain);
-#endif
- for(int i = 0; i < NUMCORES4GC; i++) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0)) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd103);
-#endif
- compact2Heaptophelper_I(i, &p, &numblocks, &remain);
- if(gccorestatus[gctopcore] != 0) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd101);
- BAMBOO_DEBUGPRINT_REG(gctopcore);
-#endif
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- // the top core is not free now
- return;
- }
- } // if((gccorestatus[i] != 0) && (gcrequiredmems[i] > 0))
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // for(i = 0; i < NUMCORES4GC; i++)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xd106);
-#endif
-} // void compact2Heaptop()
-
-inline void resolvePendingMoveRequest() {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeb01);
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeeee);
- for(int k = 0; k < NUMCORES4GC; k++) {
- BAMBOO_DEBUGPRINT(0xf000+k);
- BAMBOO_DEBUGPRINT_REG(gccorestatus[k]);
- BAMBOO_DEBUGPRINT_REG(gcloads[k]);
- BAMBOO_DEBUGPRINT_REG(gcfilledblocks[k]);
- BAMBOO_DEBUGPRINT_REG(gcstopblock[k]);
- }
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
- int i;
- int j;
- bool nosparemem = true;
- bool haspending = false;
- bool hasrunning = false;
- bool noblock = false;
- int dstcore = 0; // the core who need spare mem
- int sourcecore = 0; // the core who has spare mem
- for(i = j = 0; (i < NUMCORES4GC) && (j < NUMCORES4GC); ) {
- if(nosparemem) {
- // check if there are cores with spare mem
- if(gccorestatus[i] == 0) {
- // finished working, check if it still have spare mem
- if(gcfilledblocks[i] < gcstopblock[i]) {
- // still have spare mem
- nosparemem = false;
- sourcecore = i;
- } // if(gcfilledblocks[i] < gcstopblock[i]) else ...
- }
- i++;
- } // if(nosparemem)
- if(!haspending) {
- if(gccorestatus[j] != 0) {
- // not finished, check if it has pending move requests
- if((gcfilledblocks[j]==gcstopblock[j])&&(gcrequiredmems[j]>0)) {
- dstcore = j;
- haspending = true;
- } else {
- hasrunning = true;
- } // if((gcfilledblocks[i] == gcstopblock[i])...) else ...
- } // if(gccorestatus[i] == 0) else ...
- j++;
- } // if(!haspending)
- if(!nosparemem && haspending) {
- // find match
- int tomove = 0;
- int startaddr = 0;
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- gcrequiredmems[dstcore] = assignSpareMem_I(sourcecore,
- gcrequiredmems[dstcore],
- &tomove,
- &startaddr);
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeb02);
- BAMBOO_DEBUGPRINT_REG(sourcecore);
- BAMBOO_DEBUGPRINT_REG(dstcore);
- BAMBOO_DEBUGPRINT_REG(startaddr);
- BAMBOO_DEBUGPRINT_REG(tomove);
-#endif
- if(STARTUPCORE == dstcore) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeb03);
-#endif
- gcdstcore = sourcecore;
- gctomove = true;
- gcmovestartaddr = startaddr;
- gcblock2fill = tomove;
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeb04);
-#endif
- send_msg_4(dstcore, GCMOVESTART, sourcecore,
- startaddr, tomove, false);
- }
- gcmovepending--;
- nosparemem = true;
- haspending = false;
- noblock = true;
- }
- } // for(i = 0; i < NUMCORES4GC; i++)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcccc);
- BAMBOO_DEBUGPRINT_REG(hasrunning);
- BAMBOO_DEBUGPRINT_REG(haspending);
- BAMBOO_DEBUGPRINT_REG(noblock);
-#endif
-
- if(!hasrunning && !noblock) {
- gcphase = SUBTLECOMPACTPHASE;
- compact2Heaptop();
- }
-
-} // void resovePendingMoveRequest()
-
-struct moveHelper {
- int numblocks; // block num for heap
- INTPTR base; // base virtual address of current heap block
- INTPTR ptr; // virtual address of current heap top
- int offset; // offset in current heap block
- int blockbase; // virtual address of current small block to check
- int blockbound; // bound virtual address of current small blcok
- int sblockindex; // index of the small blocks
- int top; // real size of current heap block to check
- int bound; // bound size of current heap block to check
-}; // struct moveHelper
-
-// If out of boundary of valid shared memory, return false, else return true
-inline bool nextSBlock(struct moveHelper * orig) {
- orig->blockbase = orig->blockbound;
- bool sbchanged = false;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xecc0);
- BAMBOO_DEBUGPRINT_REG(orig->blockbase);
- BAMBOO_DEBUGPRINT_REG(orig->blockbound);
- BAMBOO_DEBUGPRINT_REG(orig->bound);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
-#endif
-outernextSBlock:
- // check if across a big block
- // TODO now do not zero out the whole memory, maybe the last two conditions
- // are useless now
- if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)
- || ((orig->ptr != NULL) && (*((int*)orig->ptr))==0)
- || ((*((int*)orig->blockbase))==0)) {
-innernextSBlock:
- // end of current heap block, jump to next one
- orig->numblocks++;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xecc1);
- BAMBOO_DEBUGPRINT_REG(orig->numblocks);
-#endif
- BASEPTR(BAMBOO_NUM_OF_CORE, orig->numblocks, &(orig->base));
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(orig->base);
-#endif
- if(orig->base >= gcbaseva + BAMBOO_SHARED_MEM_SIZE) {
- // out of boundary
- orig->ptr = orig->base; // set current ptr to out of boundary too
- return false;
- }
- //orig->bound = orig->base + BAMBOO_SMEM_SIZE;
- orig->blockbase = orig->base;
- orig->sblockindex = (orig->blockbase-gcbaseva)/BAMBOO_SMEM_SIZE;
- sbchanged = true;
- int blocknum = 0;
- BLOCKINDEX(orig->base, &blocknum);
- if(bamboo_smemtbl[blocknum] == 0) {
- // goto next block
- goto innernextSBlock;
- }
- // check the bamboo_smemtbl to decide the real bound
- orig->bound = orig->base + bamboo_smemtbl[blocknum];
- } else if(0 == (orig->blockbase%BAMBOO_SMEM_SIZE)) {
- orig->sblockindex += 1;
- sbchanged = true;
- } // if((orig->blockbase >= orig->bound) || (orig->ptr >= orig->bound)...
-
- // check if this sblock should be skipped or have special start point
- if(gcsbstarttbl[orig->sblockindex] == -1) {
- // goto next sblock
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xecc2);
-#endif
- orig->sblockindex += 1;
- orig->blockbase += BAMBOO_SMEM_SIZE;
- goto outernextSBlock;
- } else if((gcsbstarttbl[orig->sblockindex] != 0)
- && (sbchanged)) {
- // the first time to access this SBlock
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xecc3);
-#endif
- // not start from the very beginning
- orig->blockbase = gcsbstarttbl[orig->sblockindex];
- } // if(gcsbstarttbl[orig->sblockindex] == -1) else ...
-
- // setup information for this sblock
- orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
- orig->offset = BAMBOO_CACHE_LINE_SIZE;
- orig->ptr = orig->blockbase + orig->offset;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xecc4);
- BAMBOO_DEBUGPRINT_REG(orig->base);
- BAMBOO_DEBUGPRINT_REG(orig->bound);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT_REG(orig->blockbound);
- BAMBOO_DEBUGPRINT_REG(orig->blockbase);
- BAMBOO_DEBUGPRINT_REG(orig->offset);
-#endif
- if(orig->ptr >= orig->bound) {
- // met a lobj, move to next block
- goto innernextSBlock;
- }
-
- return true;
-} // bool nextSBlock(struct moveHelper * orig)
-
-// return false if there are no available data to compact
-inline bool initOrig_Dst(struct moveHelper * orig,
- struct moveHelper * to) {
- // init the dst ptr
- to->numblocks = 0;
- to->top = to->offset = BAMBOO_CACHE_LINE_SIZE;
- to->bound = BAMBOO_SMEM_SIZE_L;
- BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xef01);
- BAMBOO_DEBUGPRINT_REG(to->base);
-#endif
- to->ptr = to->base + to->offset;
-
- // init the orig ptr
- orig->numblocks = 0;
- orig->base = to->base;
- int blocknum = 0;
- BLOCKINDEX(orig->base, &blocknum);
- // check the bamboo_smemtbl to decide the real bound
- orig->bound = orig->base + bamboo_smemtbl[blocknum];
- orig->blockbase = orig->base;
- orig->sblockindex = (orig->base - gcbaseva) / BAMBOO_SMEM_SIZE;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xef02);
- BAMBOO_DEBUGPRINT_REG(orig->base);
- BAMBOO_DEBUGPRINT_REG(orig->sblockindex);
- BAMBOO_DEBUGPRINT_REG(gcsbstarttbl);
- BAMBOO_DEBUGPRINT_REG(gcsbstarttbl[orig->sblockindex]);
-#endif
-
- if(gcsbstarttbl[orig->sblockindex] == -1) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xef03);
-#endif
- // goto next sblock
- orig->blockbound =
- gcbaseva+BAMBOO_SMEM_SIZE*(orig->sblockindex+1);
- return nextSBlock(orig);
- } else if(gcsbstarttbl[orig->sblockindex] != 0) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xef04);
-#endif
- orig->blockbase = gcsbstarttbl[orig->sblockindex];
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xef05);
-#endif
- orig->blockbound = orig->blockbase + *((int*)(orig->blockbase));
- orig->offset = BAMBOO_CACHE_LINE_SIZE;
- orig->ptr = orig->blockbase + orig->offset;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xef06);
- BAMBOO_DEBUGPRINT_REG(orig->base);
-#endif
- return true;
-} // bool initOrig_Dst(struct moveHelper * orig, struct moveHelper * to)
-
-inline void nextBlock(struct moveHelper * to) {
- to->top = to->bound + BAMBOO_CACHE_LINE_SIZE; // header!
- to->bound += BAMBOO_SMEM_SIZE;
- to->numblocks++;
- BASEPTR(BAMBOO_NUM_OF_CORE, to->numblocks, &(to->base));
- to->offset = BAMBOO_CACHE_LINE_SIZE;
- to->ptr = to->base + to->offset;
-} // void nextBlock(struct moveHelper * to)
-
-// endaddr does not contain spaces for headers
-inline bool moveobj(struct moveHelper * orig,
- struct moveHelper * to,
- int stopblock) {
- if(stopblock == 0) {
- return true;
- }
-
-#ifdef DEBUG
- //if((int)orig->ptr > 0x10767a00) {
- BAMBOO_DEBUGPRINT(0xe201);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT_REG(to->ptr);
- //}
-#endif
-
- int type = 0;
- int size = 0;
- int mark = 0;
- int isize = 0;
-innermoveobj:
- while((char)(*((int*)(orig->ptr))) == (char)(-2)) {
- orig->ptr = (int*)(orig->ptr) + 1;
- }
- if((orig->ptr >= orig->bound) || (orig->ptr == orig->blockbound)) {
- if(!nextSBlock(orig)) {
- // finished, no more data
- return true;
- }
- goto innermoveobj;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe202);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT(((int *)(orig->ptr))[0]);
-#endif
- // check the obj's type, size and mark flag
- type = ((int *)(orig->ptr))[0];
- size = 0;
- if(type == 0) {
- // end of this block, go to next one
- if(!nextSBlock(orig)) {
- // finished, no more data
- return true;
- }
- goto innermoveobj;
- } else if(type < NUMCLASSES) {
- // a normal object
- size = classsize[type];
- } else {
- // an array
- struct ArrayObject *ao=(struct ArrayObject *)(orig->ptr);
- int elementsize=classsize[type];
- int length=ao->___length___;
- size=sizeof(struct ArrayObject)+length*elementsize;
- }
- mark = ((int *)(orig->ptr))[6];
- bool isremote = ((((int *)(orig->ptr))[6] & REMOTEM) != 0);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe203);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT_REG(size);
-#endif
- ALIGNSIZE(size, &isize); // no matter is the obj marked or not
- // should be able to across it
- if((mark & MARKED) != 0) {
-#ifdef DEBUG
-//if((int)orig->ptr > 0x10760f00) {
- BAMBOO_DEBUGPRINT(0xe204);
-//}
-#endif
-#ifdef GC_PROFILE
- gc_num_liveobj++;
-#endif
- // marked obj, copy it to current heap top
- // check to see if remaining space is enough
- if(to->top + isize > to->bound) {
- // fill 0 indicating the end of this block
- BAMBOO_MEMSET_WH(to->ptr, '\0', to->bound - to->top);
- // fill the header of this block and then go to next block
- to->offset += to->bound - to->top;
- BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
- (*((int*)(to->base))) = to->offset;
- nextBlock(to);
- if(stopblock == to->numblocks) {
- // already fulfilled the block
- return true;
- } // if(stopblock == to->numblocks)
- } // if(to->top + isize > to->bound)
- // set the mark field to 2, indicating that this obj has been moved
- // and need to be flushed
- ((int *)(orig->ptr))[6] = COMPACTED;
- if(to->ptr != orig->ptr) {
- if((int)(orig->ptr) < (int)(to->ptr)+size) {
- memmove(to->ptr, orig->ptr, size);
- } else {
- //BAMBOO_WRITE_HINT_CACHE(to->ptr, size);
- memcpy(to->ptr, orig->ptr, size);
- }
- // fill the remaining space with -2
- BAMBOO_MEMSET_WH(to->ptr+size, -2, isize-size);
- }
- // store mapping info
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashadd_I(gcpointertbl, orig->ptr, to->ptr);
-#else
- mgchashInsert_I(gcpointertbl, orig->ptr, to->ptr);
-#endif
- //MGCHashadd_I(gcpointertbl, orig->ptr, to->ptr);
- if(isremote) {
-#ifdef GC_PROFILE
- //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
-#endif
- // add to the sharedptbl
- if(gcsharedptbl != NULL) {
- //GCSharedHashadd_I(gcsharedptbl, orig->ptr, to->ptr);
- mgcsharedhashInsert_I(gcsharedptbl, orig->ptr, to->ptr);
- //num_mapinforequest++; // TODO
- }
-#ifdef GC_PROFILE
- //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
-#endif
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- //}
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xcdce);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT_REG(to->ptr);
- BAMBOO_DEBUGPRINT_REG(isize);
-#endif
- gccurr_heaptop -= isize;
- to->ptr += isize;
- to->offset += isize;
- to->top += isize;
- if(to->top == to->bound) {
- // fill the header of this block and then go to next block
- BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
- (*((int*)(to->base))) = to->offset;
- nextBlock(to);
- }
- } // if(mark == 1)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe205);
-#endif
- // move to next obj
- orig->ptr += size;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(isize);
- BAMBOO_DEBUGPRINT_REG(size);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT_REG(orig->bound);
-#endif
- if((orig->ptr > orig->bound) || (orig->ptr == orig->blockbound)) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe206);
-#endif
- if(!nextSBlock(orig)) {
- // finished, no more data
- return true;
- }
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe207);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
-#endif
- return false;
-} //bool moveobj(struct moveHelper* orig,struct moveHelper* to,int* endaddr)
-
-// should be invoked with interrupt closed
-inline int assignSpareMem_I(int sourcecore,
- int * requiredmem,
- int * tomove,
- int * startaddr) {
- int b = 0;
- BLOCKINDEX(gcloads[sourcecore], &b);
- int boundptr = (b<NUMCORES4GC) ? ((b+1)*BAMBOO_SMEM_SIZE_L)
- : (BAMBOO_LARGE_SMEM_BOUND+(b-NUMCORES4GC+1)*BAMBOO_SMEM_SIZE);
- int remain = boundptr - gcloads[sourcecore];
- int memneed = requiredmem + BAMBOO_CACHE_LINE_SIZE;
- *startaddr = gcloads[sourcecore];
- *tomove = gcfilledblocks[sourcecore] + 1;
- if(memneed < remain) {
- gcloads[sourcecore] += memneed;
- return 0;
- } else {
- // next available block
- gcfilledblocks[sourcecore] += 1;
- int newbase = 0;
- BASEPTR(sourcecore, gcfilledblocks[sourcecore], &newbase);
- gcloads[sourcecore] = newbase;
- return requiredmem-remain;
- }
-} // int assignSpareMem_I(int ,int * , int * , int * )
-
-// should be invoked with interrupt closed
-inline bool gcfindSpareMem_I(int * startaddr,
- int * tomove,
- int * dstcore,
- int requiredmem,
- int requiredcore) {
- for(int k = 0; k < NUMCORES4GC; k++) {
- if((gccorestatus[k] == 0) && (gcfilledblocks[k] < gcstopblock[k])) {
- // check if this stopped core has enough mem
- assignSpareMem_I(k, requiredmem, tomove, startaddr);
- *dstcore = k;
- return true;
- }
- }
- // if can not find spare mem right now, hold the request
- gcrequiredmems[requiredcore] = requiredmem;
- gcmovepending++;
- return false;
-} //bool gcfindSpareMem_I(int* startaddr,int* tomove,int mem,int core)
-
-inline bool compacthelper(struct moveHelper * orig,
- struct moveHelper * to,
- int * filledblocks,
- int * heaptopptr,
- bool * localcompact) {
- // scan over all objs in this block, compact the marked objs
- // loop stop when finishing either scanning all active objs or
- // fulfilled the gcstopblock
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe101);
- BAMBOO_DEBUGPRINT_REG(gcblock2fill);
- BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
-#endif
-innercompact:
- while(orig->ptr < gcmarkedptrbound) {
- bool stop = moveobj(orig, to, gcblock2fill);
- if(stop) {
- break;
- }
- }
- // if no objs have been compact, do nothing,
- // otherwise, fill the header of this block
- if(to->offset > BAMBOO_CACHE_LINE_SIZE) {
- BAMBOO_MEMSET_WH(to->base, '\0', BAMBOO_CACHE_LINE_SIZE);
- (*((int*)(to->base))) = to->offset;
- } else {
- to->offset = 0;
- to->ptr = to->base;
- to->top -= BAMBOO_CACHE_LINE_SIZE;
- } // if(to->offset > BAMBOO_CACHE_LINE_SIZE) else ...
- if(*localcompact) {
- *heaptopptr = to->ptr;
- *filledblocks = to->numblocks;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe102);
- BAMBOO_DEBUGPRINT_REG(orig->ptr);
- BAMBOO_DEBUGPRINT_REG(gcmarkedptrbound);
- BAMBOO_DEBUGPRINT_REG(*heaptopptr);
- BAMBOO_DEBUGPRINT_REG(*filledblocks);
- BAMBOO_DEBUGPRINT_REG(gccurr_heaptop);
-#endif
-
- // send msgs to core coordinator indicating that the compact is finishing
- // send compact finish message to core coordinator
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- gcfilledblocks[BAMBOO_NUM_OF_CORE] = *filledblocks;
- gcloads[BAMBOO_NUM_OF_CORE] = *heaptopptr;
- if(orig->ptr < gcmarkedptrbound) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe103);
-#endif
- // ask for more mem
- gctomove = false;
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gcfindSpareMem_I(&gcmovestartaddr, &gcblock2fill, &gcdstcore,
- gccurr_heaptop, BAMBOO_NUM_OF_CORE)) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe104);
-#endif
- gctomove = true;
- } else {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe105);
-#endif
- return false;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe106);
-#endif
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- gctomove = false;
- return true;
- }
- } else {
- if(orig->ptr < gcmarkedptrbound) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe107);
-#endif
- // ask for more mem
- gctomove = false;
- send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
- *filledblocks, *heaptopptr, gccurr_heaptop, false);
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe108);
- BAMBOO_DEBUGPRINT_REG(*heaptopptr);
-#endif
- // finish compacting
- send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
- *filledblocks, *heaptopptr, 0, false);
- }
- } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
-
- if(orig->ptr < gcmarkedptrbound) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe109);
-#endif
- // still have unpacked obj
- while(true) {
- if(gctomove) {
- break;
- }
- }
- ;
- gctomove = false;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe10a);
-#endif
-
- to->ptr = gcmovestartaddr;
- to->numblocks = gcblock2fill - 1;
- to->bound = (to->numblocks==0) ?
- BAMBOO_SMEM_SIZE_L :
- BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
- BASEPTR(gcdstcore, to->numblocks, &(to->base));
- to->offset = to->ptr - to->base;
- to->top = (to->numblocks==0) ?
- (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
- to->base = to->ptr;
- to->offset = BAMBOO_CACHE_LINE_SIZE;
- to->ptr += to->offset; // for header
- to->top += to->offset;
- if(gcdstcore == BAMBOO_NUM_OF_CORE) {
- *localcompact = true;
- } else {
- *localcompact = false;
- }
- goto innercompact;
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe10b);
-#endif
- return true;
-} // void compacthelper()
-
-inline void compact() {
- if(COMPACTPHASE != gcphase) {
- BAMBOO_EXIT(0xb102);
- }
-
- // initialize pointers for comapcting
- struct moveHelper * orig =
- (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
- struct moveHelper * to =
- (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
-
- if(!initOrig_Dst(orig, to)) {
- // no available data to compact
- // send compact finish msg to STARTUP core
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe001);
- BAMBOO_DEBUGPRINT_REG(to->base);
-#endif
- send_msg_5(STARTUPCORE, GCFINISHCOMPACT, BAMBOO_NUM_OF_CORE,
- 0, to->base, 0, false);
- RUNFREE(orig);
- RUNFREE(to);
- return;
- }
-
- int filledblocks = 0;
- INTPTR heaptopptr = 0;
- bool localcompact = true;
- compacthelper(orig, to, &filledblocks, &heaptopptr, &localcompact);
-
- RUNFREE(orig);
- RUNFREE(to);
-} // compact()
-
-// if return NULL, means
-// 1. objptr is NULL
-// 2. objptr is not a shared obj
-// in these cases, remain the original value is OK
-inline void * flushObj(void * objptr) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe401);
-#endif
- if(objptr == NULL) {
- return NULL;
- }
- void * dstptr = NULL;
- if(ISSHAREDOBJ(objptr)) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe402);
- BAMBOO_DEBUGPRINT_REG(objptr);
-#endif
- // a shared obj ptr, change to new address
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef GC_PROFILE
- //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
-#endif
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashget(gcpointertbl, objptr, &dstptr);
-#else
- dstptr = mgchashSearch(gcpointertbl, objptr);
-#endif
- //MGCHashget(gcpointertbl, objptr, &dstptr);
-#ifdef GC_PROFILE
- //flushstalltime += BAMBOO_GET_EXE_TIME()-ttime;
-#endif
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(dstptr);
-#endif
-
- if(NULL == dstptr) {
- // no mapping info
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe403);
- BAMBOO_DEBUGPRINT_REG(objptr);
- BAMBOO_DEBUGPRINT_REG(hostcore(objptr));
-#endif
- if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) {
- // error! the obj is right on this core, but cannot find it
- //BAMBOO_DEBUGPRINT(0xecec);
- BAMBOO_DEBUGPRINT_REG(objptr);
- BAMBOO_EXIT(0xb103);
- // assume that the obj has not been moved, use the original address
- //dstptr = objptr;
- } else {
- int hostc = hostcore(objptr);
-#ifdef GC_PROFILE
- //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
-#endif
- // check the corresponsing sharedptbl
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- //struct GCSharedHash * sptbl = gcrpointertbls[hostcore(objptr)];
- mgcsharedhashtbl_t * sptbl = gcrpointertbls[hostc];
- if(sptbl != NULL) {
- //GCSharedHashget(sptbl, (int)objptr, &dstptr);
- dstptr = mgcsharedhashSearch(sptbl, (int)objptr);
- if(dstptr != NULL) {
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashadd_I(gcpointertbl, (int)objptr, (int)dstptr);
-#else
- mgchashInsert_I(gcpointertbl, (int)objptr, (int)dstptr);
-#endif
- }
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef GC_PROFILE
- //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
-#endif
-
- if(dstptr == NULL) {
- // still can not get the mapping info,
- // send msg to host core for the mapping info
- gcobj2map = (int)objptr;
- gcismapped = false;
- gcmappedobj = NULL;
-#ifdef GC_PROFILE
- // TODO
- //num_mapinforequest++;
- //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
-#endif
-#ifdef GC_PROFILE
- //unsigned long long ttimet = BAMBOO_GET_EXE_TIME();
-#endif
- // the first time require the mapping, send msg to the hostcore
- // for the mapping info
- send_msg_3(hostc, GCMAPREQUEST, (int)objptr,
- BAMBOO_NUM_OF_CORE, false);
- while(true) {
- if(gcismapped) {
- break;
- }
- }
-#ifdef GC_PROFILE
- //flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimet;
-#endif
-#ifdef GC_PROFILE
- // TODO
- //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
-#endif
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashget(gcpointertbl, objptr, &dstptr);
-#else
- dstptr = mgchashSearch(gcpointertbl, objptr);
-#endif
- //MGCHashget(gcpointertbl, objptr, &dstptr);
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // if(dstptr == NULL)
- } // if(hostcore(objptr) == BAMBOO_NUM_OF_CORE) else ...
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(dstptr);
-#endif
- } // if(NULL == dstptr)
- } // if(ISSHAREDOBJ(objptr))
- // if not a shared obj, return NULL to indicate no need to flush
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe404);
-#endif
- return dstptr;
-} // void flushObj(void * objptr)
-
-inline void flushRuntimeObj(struct garbagelist * stackptr) {
- int i,j;
- // flush current stack
- while(stackptr!=NULL) {
- for(i=0; i<stackptr->size; i++) {
- if(stackptr->array[i] != NULL) {
- void * dst = flushObj(stackptr->array[i]);
- if(dst != NULL) {
- stackptr->array[i] = dst;
- }
- }
- }
- stackptr=stackptr->next;
- }
-
- // flush objectsets
- if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
- for(i=0; i<NUMCLASSES; i++) {
- struct parameterwrapper ** queues =
- objectqueues[BAMBOO_NUM_OF_CORE][i];
- int length = numqueues[BAMBOO_NUM_OF_CORE][i];
- for(j = 0; j < length; ++j) {
- struct parameterwrapper * parameter = queues[j];
- struct ObjectHash * set=parameter->objectset;
- struct ObjectNode * ptr=set->listhead;
- while(ptr!=NULL) {
- void * dst = flushObj((void *)ptr->key);
- if(dst != NULL) {
- ptr->key = dst;
- }
- ptr=ptr->lnext;
- }
- ObjectHashrehash(set);
- }
- }
- }
-
- // flush current task descriptor
- if(currtpd != NULL) {
- for(i=0; i<currtpd->numParameters; i++) {
- void * dst = flushObj(currtpd->parameterArray[i]);
- if(dst != NULL) {
- currtpd->parameterArray[i] = dst;
- }
- }
- }
-
- // flush active tasks
- if(activetasks != NULL) {
- struct genpointerlist * ptr=activetasks->list;
- while(ptr!=NULL) {
- struct taskparamdescriptor *tpd=ptr->src;
- int i;
- for(i=0; i<tpd->numParameters; i++) {
- void * dst = flushObj(tpd->parameterArray[i]);
- if(dst != NULL) {
- tpd->parameterArray[i] = dst;
- }
- }
- ptr=ptr->inext;
- }
- genrehash(activetasks);
- }
-
- // flush cached transferred obj
- struct QueueItem * tmpobjptr = getHead(&objqueue);
- while(tmpobjptr != NULL) {
- struct transObjInfo * objInfo =
- (struct transObjInfo *)(tmpobjptr->objectptr);
- void * dst = flushObj(objInfo->objptr);
- if(dst != NULL) {
- objInfo->objptr = dst;
- }
- tmpobjptr = getNextQueueItem(tmpobjptr);
- }
-
- // flush cached objs to be transferred
- struct QueueItem * item = getHead(totransobjqueue);
- while(item != NULL) {
- struct transObjInfo * totransobj =
- (struct transObjInfo *)(item->objectptr);
- void * dst = flushObj(totransobj->objptr);
- if(dst != NULL) {
- totransobj->objptr = dst;
- }
- item = getNextQueueItem(item);
- } // while(item != NULL)
-
- // enqueue lock related info
- for(i = 0; i < runtime_locklen; ++i) {
- void * dst = flushObj(runtime_locks[i].redirectlock);
- if(dst != NULL) {
- runtime_locks[i].redirectlock = (int)dst;
- }
- if(runtime_locks[i].value != NULL) {
- void * dst=flushObj(runtime_locks[i].value);
- if(dst != NULL) {
- runtime_locks[i].value = (int)dst;
- }
- }
- }
-
-} // void flushRuntimeObj(struct garbagelist * stackptr)
-
-inline void transmappinginfo() {
- // broadcast the sharedptbl pointer
- for(int i = 0; i < NUMCORESACTIVE; i++) {
- if(i != BAMBOO_NUM_OF_CORE) {
- send_msg_3(i, GCMAPTBL, gcsharedptbl, BAMBOO_NUM_OF_CORE, false);
- }
- }
-
- if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
- send_msg_2(STARTUPCORE, GCFINISHMAPINFO, BAMBOO_NUM_OF_CORE, false);
- }
-}
-
-inline void flush(struct garbagelist * stackptr) {
-#ifdef GC_PROFILE
- /* TODO if(BAMBOO_NUM_OF_CORE == 0) {
- BAMBOO_DEBUGPRINT(0xcccc);
- BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
- }*/
-#endif
-
- flushRuntimeObj(stackptr);
-#ifdef GC_PROFILE
- // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
-#endif
-
- while(true) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- bool hasItems = gc_moreItems_I();
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- if(!hasItems) {
- break;
- }
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe301);
-#endif
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- void * ptr = gc_dequeue_I();
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- if(ISSHAREDOBJ(ptr)) {
- // should be a local shared obj and should have mapping info
- ptr = flushObj(ptr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe302);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(tptr);
- BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
-#endif
- if(ptr == NULL) {
- BAMBOO_EXIT(0xb105);
- }
- } // if(ISSHAREDOBJ(ptr))
- if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED)) {
- int type = ((int *)(ptr))[0];
- // scan all pointers in ptr
- unsigned INTPTR * pointer;
- pointer=pointerarray[type];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe303);
- BAMBOO_DEBUGPRINT_REG(pointer);
-#endif
- if (pointer==0) {
- /* Array of primitives */
- /* Do nothing */
- } else if (((INTPTR)pointer)==1) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe304);
-#endif
- /* Array of pointers */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- int length=ao->___length___;
- int j;
- for(j=0; j<length; j++) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe305);
-#endif
- void *objptr=
- ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(objptr);
-#endif
- if(objptr != NULL) {
- void * dst = flushObj(objptr);
- if(dst != NULL) {
- ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
- }
- }
- }
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe306);
-#endif
- INTPTR size=pointer[0];
- int i;
- for(i=1; i<=size; i++) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe307);
-#endif
- unsigned int offset=pointer[i];
- void * objptr=*((void **)(((char *)ptr)+offset));
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(objptr);
-#endif
- if(objptr != NULL) {
- void * dst = flushObj(objptr);
- if(dst != NULL) {
- *((void **)(((char *)ptr)+offset)) = dst;
- }
- }
- } // for(i=1; i<=size; i++)
- } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
- // restore the mark field, indicating that this obj has been flushed
- if(ISSHAREDOBJ(ptr)) {
- ((int *)(ptr))[6] = INIT;
- }
- } // if((!ISSHAREDOBJ(ptr)) || (((int *)(ptr))[6] == COMPACTED))
- } // while(gc_moreItems())
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe308);
-#endif
-#ifdef GC_PROFILE
- // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
-#endif
-
- // TODO bug here: the startup core contains all lobjs' info, thus all the
- // lobjs are flushed in sequence.
- // flush lobjs
- while(gc_lobjmoreItems_I()) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe309);
-#endif
- void * ptr = gc_lobjdequeue_I(NULL, NULL);
- ptr = flushObj(ptr);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe30a);
- BAMBOO_DEBUGPRINT_REG(ptr);
- BAMBOO_DEBUGPRINT_REG(tptr);
- BAMBOO_DEBUGPRINT_REG(((int *)(tptr))[0]);
-#endif
- if(ptr == NULL) {
- BAMBOO_EXIT(0xb106);
- }
- if(((int *)(ptr))[6] == COMPACTED) {
- int type = ((int *)(ptr))[0];
- // scan all pointers in ptr
- unsigned INTPTR * pointer;
- pointer=pointerarray[type];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe30b);
- BAMBOO_DEBUGPRINT_REG(pointer);
-#endif
- if (pointer==0) {
- /* Array of primitives */
- /* Do nothing */
- } else if (((INTPTR)pointer)==1) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe30c);
-#endif
- /* Array of pointers */
- struct ArrayObject *ao=(struct ArrayObject *) ptr;
- int length=ao->___length___;
- int j;
- for(j=0; j<length; j++) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe30d);
-#endif
- void *objptr=
- ((void **)(((char *)&ao->___length___)+sizeof(int)))[j];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(objptr);
-#endif
- if(objptr != NULL) {
- void * dst = flushObj(objptr);
- if(dst != NULL) {
- ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dst;
- }
- }
- }
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe30e);
-#endif
- INTPTR size=pointer[0];
- int i;
- for(i=1; i<=size; i++) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe30f);
-#endif
- unsigned int offset=pointer[i];
- void * objptr=*((void **)(((char *)ptr)+offset));
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(objptr);
-#endif
- if(objptr != NULL) {
- void * dst = flushObj(objptr);
- if(dst != NULL) {
- *((void **)(((char *)ptr)+offset)) = dst;
- }
- }
- } // for(i=1; i<=size; i++)
- } // if (pointer==0) else if (((INTPTR)pointer)==1) else ()
- // restore the mark field, indicating that this obj has been flushed
- ((int *)(ptr))[6] = INIT;
- } // if(((int *)(ptr))[6] == COMPACTED)
- } // while(gc_lobjmoreItems())
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe310);
-#endif
-#ifdef GC_PROFILE
- // TODO if(BAMBOO_NUM_OF_CORE == 0) BAMBOO_DEBUGPRINT_REG(BAMBOO_GET_EXE_TIME());
-#endif
-
- // send flush finish message to core coordinator
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- } else {
- send_msg_2(STARTUPCORE, GCFINISHFLUSH, BAMBOO_NUM_OF_CORE, false);
- }
-#ifdef GC_PROFILE
- // TODO
- //if(BAMBOO_NUM_OF_CORE == 0) {
- //BAMBOO_DEBUGPRINT(0xffff);
- //BAMBOO_DEBUGPRINT_REG(num_mapinforequest);
- //BAMBOO_DEBUGPRINT_REG(flushstalltime);
- //BAMBOO_DEBUGPRINT_REG(num_mapinforequest_i);
- //BAMBOO_DEBUGPRINT_REG(flushstalltime_i);
- //}
- //BAMBOO_DEBUGPRINT_REG(flushstalltime);
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe311);
-#endif
-} // flush()
-
-#ifdef GC_CACHE_ADAPT
-// prepare for cache adaption:
-// -- flush the shared heap
-// -- clean dtlb entries
-// -- change cache strategy
-void cacheAdapt(bool isgccachestage) {
- // flush the shared heap
- BAMBOO_CACHE_FLUSH_L2();
-
- // clean the dtlb entries
- BAMBOO_CLEAN_DTLB();
-
- // change the cache strategy
- gccachestage = isgccachestage;
-}
-#endif // GC_CACHE_ADAPT
-
-inline void gc_collect(struct garbagelist * stackptr) {
- //BAMBOO_DEBUGPRINT(0xcccc); // TODO
- // inform the master that this core is at a gc safe point and is ready to
- // do gc
- send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
- self_numreceiveobjs, false);
-
- // core collector routine
- while(true) {
- if(INITPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%X,%X) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
-#endif
- initGC();
-#ifdef GC_CACHE_ADAPT
- // prepare for cache adaption:
- cacheAdapt(true);
-#endif // GC_CACHE_ADAPT
- //send init finish msg to core coordinator
- send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
-
- while(true) {
- if(MARKPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- mark(true, stackptr);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish mark phase, start compact phase\n",
- udn_tile_coord_x(), udn_tile_coord_y());
-#endif
- compact();
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish compact phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-
- while(true) {
- if(MAPPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start map phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- transmappinginfo();
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish map phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-
- while(true) {
- if(FLUSHPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-#ifdef GC_PROFILE
- /*BAMBOO_DEBUGPRINT(0xaaaa);
- BAMBOO_DEBUGPRINT_REG(gc_num_obj);
- BAMBOO_DEBUGPRINT_REG(gc_num_liveobj);
- BAMBOO_DEBUGPRINT_REG(gc_num_forwardobj);
- BAMBOO_DEBUGPRINT(0xaaab);*/
- // send the num of obj/liveobj/forwardobj to the startupcore
- if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
- send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
- gc_num_liveobj, gc_num_forwardobj, false);
- }
- gc_num_obj = 0;
-#endif // GC_PROFLIE
- flush(stackptr);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-
-#ifdef GC_CACHE_ADAPT
- while(true) {
- if(PREFINISHPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- cacheAdapt(false);
- //send init finish msg to core coordinator
- send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-#endif // GC_CACHE_ADAPT
-
- while(true) {
- if(FINISHPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
-#endif
-} // void gc_collect(struct garbagelist * stackptr)
-
-inline void gc_nocollect(struct garbagelist * stackptr) {
- //BAMBOO_DEBUGPRINT(0xcccc); // TODO
- // inform the master that this core is at a gc safe point and is ready to
- // do gc
- send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE, self_numsendobjs,
- self_numreceiveobjs, false);
-
- while(true) {
- if(INITPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Do initGC\n", udn_tile_coord_x(), udn_tile_coord_y());
-#endif
- initGC();
-#ifdef GC_CACHE_ADAPT
- // prepare for cache adaption:
- cacheAdapt(true);
-#endif // GC_CACHE_ADAPT
- //send init finish msg to core coordinator
- send_msg_2(STARTUPCORE, GCFINISHINIT, BAMBOO_NUM_OF_CORE, false);
-
- while(true) {
- if(MARKPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start mark phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- mark(true, stackptr);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish mark phase, wait for flush\n",
- udn_tile_coord_x(), udn_tile_coord_y());
-#endif
-
- // non-gc core collector routine
- while(true) {
- if(FLUSHPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start flush phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-#ifdef GC_PROFILE
- /*BAMBOO_DEBUGPRINT(0xaaaa);
- BAMBOO_DEBUGPRINT_REG(gc_num_obj);
- BAMBOO_DEBUGPRINT_REG(gc_num_liveobj);
- BAMBOO_DEBUGPRINT_REG(gc_num_forwardobj);
- BAMBOO_DEBUGPRINT(0xaaab);*/
- if(STARTUPCORE != BAMBOO_NUM_OF_CORE) {
- send_msg_4(STARTUPCORE, GCPROFILES, gc_num_obj,
- gc_num_liveobj, gc_num_forwardobj, false);
- }
- gc_num_obj = 0;
-#endif // GC_PROFLIE
- flush(stackptr);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish flush phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-
-#ifdef GC_CACHE_ADAPT
- while(true) {
- if(PREFINISHPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start prefinish phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- cacheAdapt(false);
- //send init finish msg to core coordinator
- send_msg_2(STARTUPCORE, GCFINISHPREF, BAMBOO_NUM_OF_CORE, false);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish prefinish phase\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-#endif // GC_CACHE_ADAPT
-
- while(true) {
- if(FINISHPHASE == gcphase) {
- break;
- }
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish gc!\n", udn_tile_coord_x(), udn_tile_coord_y());
-#endif
-} // void gc_collect(struct garbagelist * stackptr)
-
-inline void gc_master(struct garbagelist * stackptr) {
-
- gcphase = INITPHASE;
- int i = 0;
- waitconfirm = false;
- numconfirm = 0;
- initGC();
-
- // Note: all cores need to init gc including non-gc cores
- for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; i++) {
- // send GC init messages to all cores
- send_msg_1(i, GCSTARTINIT, false);
- }
- bool isfirst = true;
- bool allStall = false;
-
-#ifdef GC_CACHE_ADAPT
- // prepare for cache adaption:
- cacheAdapt(true);
-#endif // GC_CACHE_ADAPT
-
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Check core status \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- while(true) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gc_checkAllCoreStatus_I()) {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- break;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- }
-#ifdef GC_PROFILE
- gc_profileItem();
-#endif
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start mark phase \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- // all cores have finished compacting
- // restore the gcstatus of all cores
- // Note: all cores have to do mark including non-gc cores
- gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
- for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
- gccorestatus[i] = 1;
- // send GC start messages to all cores
- send_msg_1(i, GCSTART, false);
- }
-
- gcphase = MARKPHASE;
- // mark phase
- while(MARKPHASE == gcphase) {
- mark(isfirst, stackptr);
- if(isfirst) {
- isfirst = false;
- }
-
- // check gcstatus
- checkMarkStatue();
- } // while(MARKPHASE == gcphase)
- // send msgs to all cores requiring large objs info
- // Note: only need to ask gc cores, non-gc cores do not host any objs
- numconfirm = NUMCORES4GC - 1;
- for(i = 1; i < NUMCORES4GC; ++i) {
- send_msg_1(i, GCLOBJREQUEST, false);
- }
- gcloads[BAMBOO_NUM_OF_CORE] = gccurr_heaptop;
- while(true) {
- if(numconfirm==0) {
- break;
- }
- } // wait for responses
- // check the heaptop
- if(gcheaptop < gcmarkedptrbound) {
- gcheaptop = gcmarkedptrbound;
- }
-#ifdef GC_PROFILE
- gc_profileItem();
- // TODO
- /*if(BAMBOO_NUM_OF_CORE == 0) {
- BAMBOO_DEBUGPRINT(0xeeee);
- BAMBOO_DEBUGPRINT_REG(num_markrequest);
- BAMBOO_DEBUGPRINT_REG(marktime);
- }*/
-#endif
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) prepare to cache large objs \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- //dumpSMem();
-#endif
- // cache all large objs
- if(!cacheLObjs()) {
- // no enough space to cache large objs
- BAMBOO_EXIT(0xb107);
- }
- // predict number of blocks to fill for each core
- int tmpheaptop = 0;
- int numpbc = loadbalance(&tmpheaptop);
- // TODO
- numpbc = (BAMBOO_SHARED_MEM_SIZE)/(BAMBOO_SMEM_SIZE);
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) mark phase finished \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- //dumpSMem();
-#endif
- //int tmptopptr = 0;
- //BASEPTR(gctopcore, 0, &tmptopptr);
- // TODO
- //tmptopptr = gcbaseva + (BAMBOO_SHARED_MEM_SIZE);
- tmpheaptop = gcbaseva + (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, numpbc, &tmpcoreptr);
- //send start compact messages to all cores
- //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, false);
- } else {
- gcblock2fill = numpbc+1;
- } // if(i != STARTUPCORE)
- } else {
- gcstopblock[i] = numpbc;
- if(i != STARTUPCORE) {
- send_msg_2(i, GCSTARTCOMPACT, numpbc, false);
- } else {
- gcblock2fill = numpbc;
- } // if(i != STARTUPCORE)
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000+i);
- BAMBOO_DEBUGPRINT_REG(tmpcoreptr);
- BAMBOO_DEBUGPRINT_REG(gcstopblock[i]);
-#endif
- // init some data strutures for compact phase
- gcloads[i] = 0;
- gcfilledblocks[i] = 0;
- gcrequiredmems[i] = 0;
- }
-
-#ifdef GC_PROFILE
- gc_profileItem();
-#endif
-
- // compact phase
- bool finalcompact = false;
- // initialize pointers for comapcting
- struct moveHelper * orig =
- (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
- struct moveHelper * to =
- (struct moveHelper *)RUNMALLOC(sizeof(struct moveHelper));
- initOrig_Dst(orig, to);
- int filledblocks = 0;
- INTPTR heaptopptr = 0;
- bool finishcompact = false;
- bool iscontinue = true;
- bool localcompact = true;
- while((COMPACTPHASE == gcphase) || (SUBTLECOMPACTPHASE == gcphase)) {
- if((!finishcompact) && iscontinue) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe001);
- BAMBOO_DEBUGPRINT_REG(numpbc);
- BAMBOO_DEBUGPRINT_REG(gcblock2fill);
-#endif
- finishcompact = compacthelper(orig, to, &filledblocks,
- &heaptopptr, &localcompact);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe002);
- BAMBOO_DEBUGPRINT_REG(finishcompact);
- BAMBOO_DEBUGPRINT_REG(gctomove);
- BAMBOO_DEBUGPRINT_REG(gcrequiredmems[0]);
- BAMBOO_DEBUGPRINT_REG(gcfilledblocks[0]);
- BAMBOO_DEBUGPRINT_REG(gcstopblock[0]);
-#endif
- }
-
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gc_checkCoreStatus_I()) {
- // all cores have finished compacting
- // restore the gcstatus of all cores
- for(i = 0; i < NUMCORES4GC; ++i) {
- gccorestatus[i] = 1;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- break;
- } else {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- // check if there are spare mem for pending move requires
- if(COMPACTPHASE == gcphase) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe003);
-#endif
- resolvePendingMoveRequest();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(gctomove);
-#endif
- } else {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe004);
-#endif
- compact2Heaptop();
- }
- } // if(gc_checkCoreStatus_I()) else ...
-
- if(gctomove) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe005);
- BAMBOO_DEBUGPRINT_REG(gcmovestartaddr);
- BAMBOO_DEBUGPRINT_REG(gcblock2fill);
- BAMBOO_DEBUGPRINT_REG(gctomove);
-#endif
- to->ptr = gcmovestartaddr;
- to->numblocks = gcblock2fill - 1;
- to->bound = (to->numblocks==0) ?
- BAMBOO_SMEM_SIZE_L :
- BAMBOO_SMEM_SIZE_L+BAMBOO_SMEM_SIZE*to->numblocks;
- BASEPTR(gcdstcore, to->numblocks, &(to->base));
- to->offset = to->ptr - to->base;
- to->top = (to->numblocks==0) ?
- (to->offset) : (to->bound-BAMBOO_SMEM_SIZE+to->offset);
- to->base = to->ptr;
- to->offset = BAMBOO_CACHE_LINE_SIZE;
- to->ptr += to->offset; // for header
- to->top += to->offset;
- if(gcdstcore == BAMBOO_NUM_OF_CORE) {
- localcompact = true;
- } else {
- localcompact = false;
- }
- gctomove = false;
- iscontinue = true;
- } else if(!finishcompact) {
- // still pending
- iscontinue = false;
- } // if(gctomove)
- } // while(COMPACTPHASE == gcphase)
-#ifdef GC_PROFILE
- gc_profileItem();
-#endif
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) prepare to move large objs \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- //dumpSMem();
-#endif
- // move largeObjs
- moveLObjs();
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) compact phase finished \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- //dumpSMem();
-#endif
- RUNFREE(orig);
- RUNFREE(to);
- orig = to = NULL;
-
- gcphase = MAPPHASE;
- gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
- // Note: all cores should flush their runtime data including non-gc
- // cores
- for(i = 1; i < NUMCORES4GC; ++i) {
- // send start flush messages to all cores
- gccorestatus[i] = 1;
- send_msg_1(i, GCSTARTMAPINFO, false);
- }
-#ifdef GC_PROFILE
- gc_profileItem();
-#endif
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start map phase \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- // mapinto phase
- transmappinginfo();
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish map phase \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- while(MAPPHASE == gcphase) {
- // check the status of all cores
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gc_checkCoreStatus_I()) {
- // all cores have finished sending mapping info
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- break;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // while(MAPPHASE == gcphase)
-
- gcphase = FLUSHPHASE;
- gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
- // Note: all cores should flush their runtime data including non-gc
- // cores
- for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
- // send start flush messages to all cores
- gccorestatus[i] = 1;
- send_msg_1(i, GCSTARTFLUSH, false);
- }
-#ifdef GC_PROFILE
- gc_profileItem();
-#endif
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start flush phase \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- // flush phase
- flush(stackptr);
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- while(FLUSHPHASE == gcphase) {
- // check the status of all cores
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gc_checkAllCoreStatus_I()) {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- break;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // while(FLUSHPHASE == gcphase)
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Finish flush phase \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
-
-#ifdef GC_CACHE_ADAPT
- gcphase = PREFINISHPHASE;
- gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
- // Note: all cores should flush their runtime data including non-gc
- // cores
- for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
- // send start flush messages to all cores
- gccorestatus[i] = 1;
- send_msg_1(i, GCSTARTPREF, false);
- }
-#ifdef GC_PROFILE
- gc_profileItem();
-#endif
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) Start prefinish phase \n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- // flush phase
- cacheAdapt(false);
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- while(PREFINISHPHASE == gcphase) {
- // check the status of all cores
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- if(gc_checkAllCoreStatus_I()) {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- break;
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- } // while(PREFINISHPHASE == gcphase)
-#endif // GC_CACHE_ADAPT
-
- gcphase = FINISHPHASE;
-
- // invalidate all shared mem pointers
- // put it here as it takes time to inform all the other cores to
- // finish gc and it might cause problem when some core resumes
- // mutator earlier than the other cores
- bamboo_cur_msp = NULL;
- bamboo_smem_size = 0;
- bamboo_smem_zero_top = NULL;
- gcflag = false;
- gcprocessing = false;
-
-#ifdef GC_PROFILE
- gc_profileEnd();
-#endif
- gccorestatus[BAMBOO_NUM_OF_CORE] = 1;
- for(i = 1; i < NUMCORESACTIVE /*NUMCORES4GC*/; ++i) {
- // send gc finish messages to all cores
- send_msg_1(i, GCFINISH, false);
- gccorestatus[i] = 1;
- }
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) gc finished \n", udn_tile_coord_x(),
- udn_tile_coord_y());
- //dumpSMem();
-#endif
- //BAMBOO_DEBUGPRINT(0x1111); // TODO
-/*#ifdef GC_PROFILE_S
- BAMBOO_DEBUGPRINT(0xaaaa);
- BAMBOO_DEBUGPRINT_REG(gc_num_obj);
- BAMBOO_DEBUGPRINT_REG(gc_num_liveobj);
- BAMBOO_DEBUGPRINT_REG(gc_num_forwardobj);
- BAMBOO_DEBUGPRINT_REG(gc_num_profiles);
- BAMBOO_DEBUGPRINT(0xaaab);
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- BAMBOO_DEBUGPRINT(0xaaac);
- BAMBOO_DEBUGPRINT_REG(gc_num_livespace);
- BAMBOO_DEBUGPRINT_REG(gc_num_freespace);
- BAMBOO_DEBUGPRINT(0xaaad);
- }
- gc_num_obj = gc_num_liveobj;
- gc_num_liveobj = 0;
- gc_num_forwardobj = 0;
-#endif // GC_PROFLIE_S*/
-} // void gc_master(struct garbagelist * stackptr)
-
-inline bool gc(struct garbagelist * stackptr) {
- // check if do gc
- if(!gcflag) {
- gcprocessing = false;
- return false;
- }
-
- // core coordinator routine
- if(0 == BAMBOO_NUM_OF_CORE) {
-#ifdef GC_DEBUG
- printf("(%x,%X) Check if can do gc or not\n", udn_tile_coord_x(),
- udn_tile_coord_y());
-#endif
- bool isallstall = true;
- gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- int ti = 0;
- for(ti = 0; ti < NUMCORESACTIVE; ++ti) {
- if(gccorestatus[ti] != 0) {
- isallstall = false;
- break;
- }
- }
- if(!isallstall) {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- // some of the cores are still executing the mutator and did not reach
- // some gc safe point, therefore it is not ready to do gc
- // in case that there are some pregc information msg lost, send a confirm
- // msg to the 'busy' core
- send_msg_1(ti, GCSTARTPRE, false);
- gcflag = true;
- return false;
- } else {
- // TODO
-#ifdef GC_PROFILE
- gc_profileStart();
-#endif
- //BAMBOO_DEBUGPRINT(0x1111); // TODO
-pregccheck:
- //BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
- gcnumsendobjs[0][BAMBOO_NUM_OF_CORE] = self_numsendobjs;
- gcnumreceiveobjs[0][BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
- int sumsendobj = 0;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec04);
-#endif
- for(int i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj += gcnumsendobjs[0][i];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000 + gcnumsendobjs[0][i]);
-#endif
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec05);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
-#endif
- for(int i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj -= gcnumreceiveobjs[0][i];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000 + gcnumreceiveobjs[i]);
-#endif
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xec06);
- BAMBOO_DEBUGPRINT_REG(sumsendobj);
-#endif
- if(0 != sumsendobj) {
- // there were still some msgs on the fly, wait until there
- // are some update pregc information coming and check it again
- gcprecheck = false;
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- //BAMBOO_DEBUGPRINT(0x2222); // TODO
- while(true) {
- if(gcprecheck) {
- break;
- }
- }
- goto pregccheck;
- } else {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- }
- }
-/*
-#ifdef GC_PROFILE
- gc_profileStart();
-#endif
-*/
-#ifdef RAWPATH // TODO GC_DEBUG
- printf("(%x,%x) start gc! \n", udn_tile_coord_x(), udn_tile_coord_y());
- //dumpSMem();
-#endif
- // Zero out the remaining bamboo_cur_msp
- // Only zero out the first 4 bytes of the remaining memory
- // Move the operation here because for the GC_CACHE_ADAPT version,
- // we need to make sure during the gcinit phase the shared heap is not
- // touched. Otherwise, there would be problem when adapt the cache
- // strategy.
- if((bamboo_cur_msp != 0)
- && (bamboo_smem_zero_top == bamboo_cur_msp)
- && (bamboo_smem_size > 0)) {
- *((int *)bamboo_cur_msp) = 0;
- }
-#ifdef GC_FLUSH_DTLB
- if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
- BAMBOO_CLEAN_DTLB();
- gc_num_flush_dtlb++;
- }
-#endif
-#ifdef GC_CACHE_ADAPT
- //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
- // disable the timer interrupt
- bamboo_mask_timer_intr();
- // get the sampling data TODO
- bamboo_output_dtlb_sampling();
-#endif // GC_CACHE_ADAPT
- gcprocessing = true;
- gc_master(stackptr);
- } else if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
- // Zero out the remaining bamboo_cur_msp
- // Only zero out the first 4 bytes of the remaining memory
- // Move the operation here because for the GC_CACHE_ADAPT version,
- // we need to make sure during the gcinit phase the shared heap is not
- // touched. Otherwise, there would be problem when adapt the cache
- // strategy.
- if((bamboo_cur_msp != 0)
- && (bamboo_smem_zero_top == bamboo_cur_msp)
- && (bamboo_smem_size > 0)) {
- *((int *)bamboo_cur_msp) = 0;
- }
-#ifdef GC_FLUSH_DTLB
- if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
- BAMBOO_CLEAN_DTLB();
- gc_num_flush_dtlb++;
- }
-#endif
-#ifdef GC_CACHE_ADAPT
- // disable the timer interrupt
- bamboo_mask_timer_intr();
- // get the sampling data TODO
- bamboo_output_dtlb_sampling();
-#endif // GC_CACHE_ADAPT
- gcprocessing = true;
- gc_collect(stackptr);
-
- // invalidate all shared mem pointers
- bamboo_cur_msp = NULL;
- bamboo_smem_size = 0;
- bamboo_smem_zero_top = NULL;
- gcflag = false;
- gcprocessing = false;
- } else {
- // Zero out the remaining bamboo_cur_msp
- // Only zero out the first 4 bytes of the remaining memory
- // Move the operation here because for the GC_CACHE_ADAPT version,
- // we need to make sure during the gcinit phase the shared heap is not
- // touched. Otherwise, there would be problem when adapt the cache
- // strategy.
- if((bamboo_cur_msp != 0)
- && (bamboo_smem_zero_top == bamboo_cur_msp)
- && (bamboo_smem_size > 0)) {
- *((int *)bamboo_cur_msp) = 0;
- }
-#ifdef GC_FLUSH_DTLB
- if(gc_num_flush_dtlb < GC_NUM_FLUSH_DTLB) {
- BAMBOO_CLEAN_DTLB();
- gc_num_flush_dtlb++;
- }
-#endif
-#ifdef GC_CACHE_ADAPT
- // disable the timer interrupt
- bamboo_mask_timer_intr();
- // get the sampling data TODO
- bamboo_output_dtlb_sampling();
-#endif // GC_CACHE_ADAPT
- // not a gc core, should wait for gcfinish msg
- gcprocessing = true;
- gc_nocollect(stackptr);
-
- // invalidate all shared mem pointers
- bamboo_cur_msp = NULL;
- bamboo_smem_size = 0;
- bamboo_smem_zero_top = NULL;
- gcflag = false;
- gcprocessing = false;
- }
-#ifdef GC_CACHE_ADAPT
- // reset the sampling arrays
- bamboo_dtlb_sampling_reset();
- // enable the timer interrupt
- bamboo_tile_timer_set_next_event(500000000); // TODO
- bamboo_unmask_timer_intr();
-#endif // GC_CACHE_ADAPT
- //if(STARTUPCORE == BAMBOO_NUM_OF_CORE) BAMBOO_DEBUGPRINT(0xeeee); // TODO
- return true;
-} // void gc(struct garbagelist * stackptr)
-
-#ifdef GC_PROFILE
-inline void gc_profileStart(void) {
- if(!gc_infoOverflow) {
- GCInfo* gcInfo = RUNMALLOC(sizeof(struct gc_info));
- gc_infoArray[gc_infoIndex] = gcInfo;
- gcInfo->index = 1;
- gcInfo->time[0] = BAMBOO_GET_EXE_TIME();
- }
-}
-
-inline void gc_profileItem(void) {
- if(!gc_infoOverflow) {
- GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
- gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
- }
-}
-
-inline void gc_profileEnd(void) {
- if(!gc_infoOverflow) {
- GCInfo* gcInfo = gc_infoArray[gc_infoIndex];
- gcInfo->time[gcInfo->index++] = BAMBOO_GET_EXE_TIME();
- gcInfo->time[gcInfo->index++] = gc_num_livespace;
- gcInfo->time[gcInfo->index++] = gc_num_freespace;
- gcInfo->time[gcInfo->index++] = gc_num_lobj;
- gcInfo->time[gcInfo->index++] = gc_num_lobjspace;
- gcInfo->time[gcInfo->index++] = gc_num_obj;
- gcInfo->time[gcInfo->index++] = gc_num_liveobj;
- gcInfo->time[gcInfo->index++] = gc_num_forwardobj;
- gc_infoIndex++;
- if(gc_infoIndex == GCINFOLENGTH) {
- gc_infoOverflow = true;
- //taskInfoIndex = 0;
- }
- }
-}
-
-// output the profiling data
-void gc_outputProfileData() {
-/*#ifdef USEIO
- int i,j;
- unsigned long long totalgc = 0;
-
- //printf("Start Time, End Time, Duration\n");
- // output task related info
- for(i = 0; i < gc_infoIndex; i++) {
- GCInfo * gcInfo = gc_infoArray[i];
- unsigned long long tmp = 0;
- for(j = 0; j < gcInfo->index; j++) {
- printf("%lld(%lld), ", gcInfo->time[j], (gcInfo->time[j]-tmp));
- tmp = gcInfo->time[j];
- }
- tmp = (tmp-gcInfo->time[0]);
- printf(" ++ %lld \n", tmp);
- totalgc += tmp;
- }
-
- if(gc_infoOverflow) {
- printf("Caution: gc info overflow!\n");
- }
-
- printf("\n\n total gc time: %lld \n", totalgc);
-#else*/
- int i = 0;
- int j = 0;
- unsigned long long totalgc = 0;
-
-#ifndef BAMBOO_MEMPROF
- BAMBOO_DEBUGPRINT(0xdddd);
-#endif
- // output task related info
- for(i= 0; i < gc_infoIndex; i++) {
- GCInfo * gcInfo = gc_infoArray[i];
-#ifdef BAMBOO_MEMPROF
- unsigned long long tmp=gcInfo->time[gcInfo->index-8]-gcInfo->time[0]; //0;
-#else
- unsigned long long tmp = 0;
- BAMBOO_DEBUGPRINT(0xddda);
- for(j = 0; j < gcInfo->index - 7; j++) {
- BAMBOO_DEBUGPRINT(gcInfo->time[j]);
- BAMBOO_DEBUGPRINT(gcInfo->time[j]-tmp);
- BAMBOO_DEBUGPRINT(0xdddb);
- tmp = gcInfo->time[j];
- }
- tmp = (tmp-gcInfo->time[0]);
- BAMBOO_DEBUGPRINT_REG(tmp);
- BAMBOO_DEBUGPRINT(0xdddc);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 7]);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 6]);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 5]);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 4]);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 3]);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 2]);
- BAMBOO_DEBUGPRINT(gcInfo->time[gcInfo->index - 1]);
- BAMBOO_DEBUGPRINT(0xddde);
-#endif
- totalgc += tmp;
- }
-#ifndef BAMBOO_MEMPROF
- BAMBOO_DEBUGPRINT(0xdddf);
-#endif
- BAMBOO_DEBUGPRINT_REG(totalgc);
-
- if(gc_infoOverflow) {
- BAMBOO_DEBUGPRINT(0xefee);
- }
-
-#ifndef BAMBOO_MEMPROF
- BAMBOO_DEBUGPRINT(0xeeee);
-#endif
-//#endif
-}
-#endif // #ifdef GC_PROFILE
-
-#endif
+++ /dev/null
-#ifndef MULTICORE_GARBAGE_H
-#define MULTICORE_GARBAGE_H
-#include "multicoregc.h"
-#include "multicorehelper.h" // for mappins between core # and block #
-#include "structdefs.h"
-#include "MGCHash.h"
-#include "GCSharedHash.h"
-
-#ifndef bool
-#define bool int
-#endif
-
-// data structures for GC
-#ifdef GC_DEBUG
-#define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
-#else
-#define BAMBOO_SMEM_SIZE_L (BAMBOO_SMEM_SIZE * 2)
-#endif
-#define BAMBOO_LARGE_SMEM_BOUND (BAMBOO_SMEM_SIZE_L*NUMCORES4GC)
-// let each gc core to have one big block, this is very important
-// for the computation of NUMBLOCKS(s, n), DO NOT change this!
-
-#ifdef GC_FLUSH_DTLB
-#define GC_NUM_FLUSH_DTLB 1
-int gc_num_flush_dtlb;
-#endif
-
-#define NUMPTRS 100
-
-// for GC profile
-#ifdef GC_PROFILE
-#define GCINFOLENGTH 100
-
-#ifdef GC_CACHE_ADAPT
-#define GC_PROFILE_NUM_FIELD 16
-#else
-#define GC_PROFILE_NUM_FIELD 15
-#endif
-
-typedef struct gc_info {
- unsigned long long time[GC_PROFILE_NUM_FIELD];
- int index;
-} GCInfo;
-
-GCInfo * gc_infoArray[GCINFOLENGTH];
-int gc_infoIndex;
-bool gc_infoOverflow;
-unsigned long long gc_num_livespace;
-unsigned long long gc_num_freespace;
-unsigned long long gc_num_lobjspace;
-unsigned int gc_num_lobj;
-
-// TODO
-/*unsigned long long flushstalltime;
-unsigned long long flushstalltime_i;
-int num_mapinforequest_i;*/
-unsigned int gc_num_liveobj;
-unsigned int gc_num_obj;
-unsigned int gc_num_forwardobj;
-int gc_num_profiles;
-
-#endif // GC_PROFILE
-
-typedef enum {
- INIT = 0, // 0
- DISCOVERED = 2, // 2
- REMOTEM = 4, // 4
- MARKED = 8, // 8
- COMPACTED = 16, // 16
- FLUSHED = 32, // 32
- END = 33 // 33
-} GCOBJFLAG;
-
-typedef enum {
- INITPHASE = 0x0, // 0x0
- MARKPHASE, // 0x1
- COMPACTPHASE, // 0x2
- SUBTLECOMPACTPHASE, // 0x3
- MAPPHASE, // 0x4
- FLUSHPHASE, // 0x5
-#ifdef GC_CACHE_ADAPT
- PREFINISHPHASE, // 0x6
-#endif // GC_CACHE_ADAPT
- FINISHPHASE // 0x6/0x7
-} GCPHASETYPE;
-
-volatile bool gcflag;
-volatile bool gcprocessing;
-volatile GCPHASETYPE gcphase; // indicating GC phase
-
-volatile bool gcpreinform; // counter for stopped cores
-volatile bool gcprecheck; // indicates if there are updated pregc information
-
-int gccurr_heaptop;
-struct MGCHash * gcforwardobjtbl; // cache forwarded objs in mark phase
-// for mark phase termination
-volatile int gccorestatus[NUMCORESACTIVE]; // records status of each core
- // 1: running gc
- // 0: stall
-volatile int gcnumsendobjs[2][NUMCORESACTIVE]; // the # of objects sent out
-volatile int gcnumreceiveobjs[2][NUMCORESACTIVE]; // the # of objects received
-volatile int gcnumsrobjs_index; // indicates which entry to record the info
- // received before phase 1 of the mark finish
- // checking process
- // the info received in phase 2 must be
- // recorded in the other entry
-volatile bool gcbusystatus;
-int gcself_numsendobjs;
-int gcself_numreceiveobjs;
-
-// for load balancing
-INTPTR gcheaptop;
-int gcloads[NUMCORES4GC];
-int gctopcore; // the core host the top of the heap
-int gctopblock; // the number of current top block
-
-int gcnumlobjs;
-
-// compact instruction
-INTPTR gcmarkedptrbound;
-int gcblock2fill;
-int gcstopblock[NUMCORES4GC]; // indicate when to stop compact phase
-int gcfilledblocks[NUMCORES4GC]; //indicate how many blocks have been fulfilled
-// move instruction;
-INTPTR gcmovestartaddr;
-int gcdstcore;
-volatile bool gctomove;
-int gcrequiredmems[NUMCORES4GC]; //record pending mem requests
-volatile int gcmovepending;
-
-// data structures to record remote cores that transferred the marked
-// objs in the mark phase
-/*struct rcoreinfo{
- int high;
- int low;
-};
-struct RuntimeHash * gcrcoretbl;
-#define NUM_MAPPING 40
-void * gcmappingtbl[NUMCORESACTIVE][NUM_MAPPING];*/
-
-// shared memory pointer for shared pointer mapping tbls
-// In GC version, this block of memory is located at the bottom of the
-// shared memory, right on the top of the smem tbl.
-// The bottom of the shared memory = sbstart tbl + smemtbl
-// + NUMCORES4GC bamboo_rmsp
-// These three types of table are always reside at the bottom of the shared
-// memory and will never be moved or garbage collected
-#ifdef GC_SMALLPAGESIZE
-#define BAMBOO_RMSP_SIZE (1024 * 1024)
-#else
-#define BAMBOO_RMSP_SIZE (BAMBOO_SMEM_SIZE) // (45 * 16 * 1024)
-#endif
-mspace bamboo_rmsp;
-// shared pointer mapping tbl
-//volatile struct GCSharedHash * gcsharedptbl;
-mgcsharedhashtbl_t * gcsharedptbl;
-// remote shared pointer tbls
-//struct GCSharedHash * gcrpointertbls[NUMCORES4GC];
-mgcsharedhashtbl_t * gcrpointertbls[NUMCORES4GC];
-
-#ifdef LOCALHASHTBL_TEST
-struct RuntimeHash * gcpointertbl;
-#else
-mgchashtable_t * gcpointertbl;
-#endif
-//struct MGCHash * gcpointertbl;
-int gcobj2map;
-int gcmappedobj;
-volatile bool gcismapped;
-
-// table recording the starting address of each small block
-// (size is BAMBOO_SMEM_SIZE)
-// Note: 1. this table always resides on the very bottom of the shared memory
-// 2. the first two blocks are reserved for this table, would never be
-// moved or garbage collected.
-INTPTR * gcsbstarttbl;
-int gcreservedsb; // number of reserved sblock for sbstarttbl
-int gcnumblock; // number of total blocks in the shared mem
-int gcbaseva; // base va for shared memory without reserved sblocks
-#ifdef GC_CACHE_ADAPT
-int gctopva; // top va for shared memory without reserved sblocks
-volatile bool gccachestage;
-#endif // GC_CACHE_ADAPT
-
-#define ISSHAREDOBJ(p) \
- ((((int)p)>gcbaseva)&&(((int)p)<(gcbaseva+(BAMBOO_SHARED_MEM_SIZE))))
-
-#define ALIGNSIZE(s, as) \
- (*((int*)as)) = (((s) & (~(BAMBOO_CACHE_LINE_MASK))) + (BAMBOO_CACHE_LINE_SIZE))
-
-// mapping of pointer to block # (start from 0), here the block # is
-// the global index
-#define BLOCKINDEX(p, b) \
- { \
- int t = (p) - gcbaseva; \
- if(t < (BAMBOO_LARGE_SMEM_BOUND)) { \
- (*((int*)b)) = t / (BAMBOO_SMEM_SIZE_L); \
- } else { \
- (*((int*)b)) = NUMCORES4GC+((t-(BAMBOO_LARGE_SMEM_BOUND))/(BAMBOO_SMEM_SIZE)); \
- } \
- }
-
-// mapping of pointer to core #
-#define RESIDECORE(p, c) \
- { \
- if(1 == (NUMCORES4GC)) { \
- (*((int*)c)) = 0; \
- } else { \
- int b; \
- BLOCKINDEX((p), &b); \
- (*((int*)c)) = gc_block2core[(b%(NUMCORES4GC*2))]; \
- } \
- }
-
-// NOTE: n starts from 0
-// mapping of heaptop (how many bytes there are in the local heap) to
-// the number of the block
-// the number of the block indicates that the block is the xth block on
-// the local heap
-#define NUMBLOCKS(s, n) \
- if(s < (BAMBOO_SMEM_SIZE_L)) { \
- (*((int*)(n))) = 0; \
- } else { \
- (*((int*)(n))) = 1 + ((s) - (BAMBOO_SMEM_SIZE_L)) / (BAMBOO_SMEM_SIZE); \
- }
-
-#define OFFSET(s, o) \
- if(s < BAMBOO_SMEM_SIZE_L) { \
- (*((int*)(o))) = (s); \
- } else { \
- (*((int*)(o))) = ((s) - (BAMBOO_SMEM_SIZE_L)) % (BAMBOO_SMEM_SIZE); \
- }
-
-// mapping of (core #, index of the block) to the global block index
-#define BLOCKINDEX2(c, n) (gc_core2block[(2*(c))+((n)%2)]+((NUMCORES4GC*2)*((n)/2)))
-
-// mapping of (core #, number of the block) to the base pointer of the block
-#define BASEPTR(c, n, p) \
- { \
- int b = BLOCKINDEX2((c), (n)); \
- if(b < (NUMCORES4GC)) { \
- (*((int*)p)) = gcbaseva + b * (BAMBOO_SMEM_SIZE_L); \
- } else { \
- (*((int*)p)) = gcbaseva+(BAMBOO_LARGE_SMEM_BOUND)+ \
- (b-(NUMCORES4GC))*(BAMBOO_SMEM_SIZE); \
- } \
- }
-
-// the next core in the top of the heap
-#define NEXTTOPCORE(b) (gc_block2core[((b)+1)%(NUMCORES4GC*2)])
-
-inline bool gc(struct garbagelist * stackptr); // core coordinator routine
-inline void gc_collect(struct garbagelist* stackptr); //core collector routine
-inline void gc_nocollect(struct garbagelist* stackptr); //non-gc core collector routine
-inline void transferMarkResults_I();
-inline void gc_enqueue_I(void *ptr);
-inline void gc_lobjenqueue_I(void *ptr, int length, int host);
-inline bool gcfindSpareMem_I(int * startaddr,
- int * tomove,
- int * dstcore,
- int requiredmem,
- int requiredcore);
-
-inline void * gc_lobjdequeue4(int * length, int * host);
-inline int gc_lobjmoreItems4();
-inline void gc_lobjqueueinit4();
-
-#ifdef GC_PROFILE
-INLINE void gc_profileStart(void);
-INLINE void gc_profileItem(void);
-INLINE void gc_profileEnd(void);
-void gc_outputProfileData();
-#endif
-
-#endif
-
+++ /dev/null
-#ifndef MULTICORE_GC_H
-#define MULTICORE_GC_H
-
-struct garbagelist {
- int size;
- struct garbagelist *next;
- void * array[];
-};
-
-struct listitem {
- struct listitem * prev;
- struct listitem * next;
- struct garbagelist * stackptr;
-};
-
-#endif // MULTICORE_GC_H
+++ /dev/null
-#ifndef MULTICORE_HELPER_H
-#define MULTICORE_HELPER_H
-
-#ifdef GC_1
-// NUMCORES4GC = 1
-static int gc_core2block[2] = {0,1};
-
-static int gc_block2core[2] = { 0, 0};
-#elif defined GC_56
-// NUMCORES4GC = 56
-static int gc_core2block[112] = {
- 0,111, 15, 96, 16,95, 31,80, 32,79, 47,64, 48,63,
- 1,110, 14, 97, 17,94, 30,81, 33,78, 46,65, 49,62,
- 2,109, 13, 98, 18,93, 29,82, 34,77, 45,66, 50,61,
- 3,108, 12, 99, 19,92, 28,83, 35,76, 44,67, 51,60,
- 4,107, 11,100, 20,91, 27,84, 36,75, 43,68, 52,59,
- 5,106, 10,101, 21,90, 26,85, 37,74, 42,69, 53,58,
- 6,105, 9,102, 22,89, 25,86, 38,73, 41,70, 54,57,
- 7,104, 8,103, 23,88, 24,87, 39,72, 40,71, 55,56
-};
-
-static int gc_block2core[112] = {
- 0, 7, 14, 21, 28, 35, 42, 49, 50, 43, 36, 29, 22, 15, 8, 1,
- 2, 9, 16, 23, 30, 37, 44, 51, 52, 45, 38, 31, 24, 17, 10, 3,
- 4, 11, 18, 25, 32, 39, 46, 53, 54, 47, 40, 33, 26, 19, 12, 5,
- 6, 13, 20, 27, 34, 41, 48, 55, 55, 48, 41, 34, 27, 20, 13, 6,
- 5, 12, 19, 26, 33, 40, 47, 54, 53, 46, 39, 32, 25, 18, 11, 4,
- 3, 10, 17, 24, 31, 38, 45, 52, 51, 44, 37, 30, 23, 16, 9, 2,
- 1, 8, 15, 22, 29, 36, 43, 50, 49, 42, 35, 28, 21, 14, 7, 0
-};
-#elif defined GC_62
-// NUMCORES4GC = 62
-static int gc_core2block[124] = {
- 0,123, 15,108, 16,107, 31,92, 32,91, 47,76,
- 1,122, 14,109, 17,106, 30,93, 33,90, 46,77, 48,75, 61,62,
- 2,121, 13,110, 18,105, 29,94, 34,89, 45,78, 49,74, 60,63,
- 3,120, 12,111, 19,104, 28,95, 35,88, 44,79, 50,73, 59,64,
- 4,119, 11,112, 20,103, 27,96, 36,87, 43,80, 51,72, 58,65,
- 5,118, 10,113, 21,102, 26,97, 37,86, 42,81, 52,71, 57,66,
- 6,117, 9,114, 22,101, 25,98, 38,85, 41,82, 53,70, 56,67,
- 7,116, 8,115, 23,100, 24,99, 39,84, 40,83, 54,69, 55,68
-};
-
-static int gc_block2core[124] = {
- 0, 6, 14, 22, 30, 38, 46, 54, 55, 47, 39, 31, 23, 15, 7, 1,
- 2, 8, 16, 24, 32, 40, 48, 56, 57, 49, 41, 33, 25, 17, 9, 3,
- 4, 10, 18, 26, 34, 42, 50, 58, 59, 51, 43, 35, 27, 19, 11, 5,
- 12, 20, 28, 36, 44, 52, 60, 61, 53, 45, 37, 29, 21, 13,
- 13, 21, 29, 37, 45, 53, 61, 60, 52, 44, 36, 28, 20, 12,
- 5, 11, 19, 27, 35, 43, 51, 59, 58, 50, 42, 34, 26, 18, 10, 4,
- 3, 9, 17, 25, 33, 41, 49, 57, 56, 48, 40, 32, 24, 16, 8, 2,
- 1, 7, 15, 23, 31, 39, 47, 55, 54, 46, 38, 30, 22, 14, 6, 0
-};
-#endif
-
-#endif // MULTICORE_HELPER_H
+++ /dev/null
-#include "runtime.h"
-#include "structdefs.h"
-#include "mem.h"
-#ifndef MULTICORE
-#include <fcntl.h>
-#include <errno.h>
-#include <signal.h>
-#endif
-#ifndef RAW
-#include <stdio.h>
-#endif
-#ifdef MULTICORE
-#include "runtime_arch.h"
-#endif
-//#include "option.h"
-
-extern int classsize[];
-extern int typearray[];
-extern int typearray2[];
-#ifndef MULTICORE
-jmp_buf error_handler;
-int instructioncount;
-
-char *options;
-int injectfailures=0;
-float failurechance=0;
-int errors=0;
-int injectinstructionfailures;
-int failurecount;
-float instfailurechance=0;
-int numfailures;
-int instaccum=0;
-#ifdef DMALLOC
-#include "dmalloc.h"
-#endif
-#endif
-
-int debugtask=0;
-
-int instanceof(struct ___Object___ *ptr, int type) {
- int i=ptr->type;
- do {
- if (i==type)
- return 1;
- i=typearray[i];
- } while(i!=-1);
- i=ptr->type;
- if (i>NUMCLASSES) {
- do {
- if (i==type)
- return 1;
- i=typearray2[i-NUMCLASSES];
- } while(i!=-1);
- }
- return 0;
-}
-
-#ifdef MULTICORE
-void initializeexithandler() {
-}
-#else
-void exithandler(int sig, siginfo_t *info, void * uap) {
-#ifdef DEBUG
- printf("exit in exithandler\n");
-#endif
- exit(0);
-}
-
-void initializeexithandler() {
- struct sigaction sig;
- sig.sa_sigaction=&exithandler;
- sig.sa_flags=SA_SIGINFO;
- sigemptyset(&sig.sa_mask);
- sigaction(SIGUSR2, &sig, 0);
-}
-#endif
-
-/* This function inject failures */
-
-void injectinstructionfailure() {
-#ifdef MULTICORE
- // not supported in MULTICORE version
- return;
-#else
-#ifdef TASK
- if (injectinstructionfailures) {
- if (numfailures==0)
- return;
- instructioncount=failurecount;
- instaccum+=failurecount;
- if ((((double)random())/RAND_MAX)<instfailurechance) {
- if (numfailures>0)
- numfailures--;
- printf("FAILURE!!! %d\n",numfailures);
- longjmp(error_handler,11);
- }
- }
-#else
-#ifdef THREADS
- if (injectinstructionfailures) {
- if (numfailures==0)
- return;
- instaccum+=failurecount;
- if ((((double)random())/RAND_MAX)<instfailurechance) {
- if (numfailures>0)
- numfailures--;
- printf("FAILURE!!! %d\n",numfailures);
- threadexit();
- }
- }
-#endif
-#endif
-#endif
-}
-
-#ifdef D___Double______nativeparsedouble____L___String___
-double CALL01(___Double______nativeparsedouble____L___String___,struct ___String___ * ___str___) {
- int length=VAR(___str___)->___count___;
- int maxlength=(length>60) ? 60 : length;
- char str[maxlength+1];
- struct ArrayObject * chararray=VAR(___str___)->___value___;
- int i;
- int offset=VAR(___str___)->___offset___;
- for(i=0; i<maxlength; i++) {
- str[i]=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
- }
- str[i]=0;
- double d=atof(str);
- return d;
-}
-#endif
-
-#ifdef D___String______convertdoubletochar____D__AR_C
-int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
- int length=VAR(___chararray___)->___length___;
- char str[length];
- int i;
- int num=snprintf(str, length, "%f",___val___);
- if (num>=length)
- num=length-1;
- for(i=0; i<length; i++) {
- ((short *)(((char *)&VAR(___chararray___)->___length___)+sizeof(int)))[i]=(short)str[i];
- }
- return num;
-}
-#else
-int CALL12(___String______convertdoubletochar____D__AR_C, double ___val___, double ___val___, struct ArrayObject ___chararray___) {
- return 0;
-}
-#endif
-
-void CALL11(___System______exit____I,int ___status___, int ___status___) {
-#ifdef MULTICORE
- BAMBOO_EXIT(___status___);
-#else
-#ifdef DEBUG
- printf("exit in CALL11\n");
-#endif
- exit(___status___);
-#endif
-}
-
-//#ifdef D___Vector______removeElement_____AR_L___Object____I_I
-void CALL23(___Vector______removeElement_____AR_L___Object____I_I, int ___index___, int ___size___, struct ArrayObject * ___array___, int ___index___, int ___size___) {
- char* offset=((char *)(&VAR(___array___)->___length___))+sizeof(unsigned int)+sizeof(void *)*___index___;
- memmove(offset, offset+sizeof(void *),(___size___-___index___-1)*sizeof(void *));
-}
-//#endif
-
-void CALL11(___System______printI____I,int ___status___, int ___status___) {
-#ifdef MULTICORE
- BAMBOO_DEBUGPRINT(0x1111);
- BAMBOO_DEBUGPRINT_REG(___status___);
-#else
-#ifdef DEBUG
- printf("printI in CALL11\n");
-#endif
- printf("%d\n", ___status___);
-#endif
-}
-
-long CALL00(___System______currentTimeMillis____) {
-#ifdef MULTICORE
- // not supported in MULTICORE version
- return -1;
-#else
- struct timeval tv; long long retval;
- gettimeofday(&tv, NULL);
- retval = tv.tv_sec; /* seconds */
- retval*=1000; /* milliseconds */
- retval+= (tv.tv_usec/1000); /* adjust milliseconds & add them in */
- return retval;
-#endif
-}
-
-void CALL01(___System______printString____L___String___,struct ___String___ * ___s___) {
-#ifdef MULTICORE
-#else
- struct ArrayObject * chararray=VAR(___s___)->___value___;
- int i;
- int offset=VAR(___s___)->___offset___;
- for(i=0; i<VAR(___s___)->___count___; i++) {
- short sc=((short *)(((char *)&chararray->___length___)+sizeof(int)))[i+offset];
- putchar(sc);
- }
-#endif
-}
-
-/* Object allocation function */
-
-#ifdef MULTICORE_GC
-void * allocate_new(void * ptr, int type) {
- struct ___Object___ * v=(struct ___Object___ *)FREEMALLOC((struct garbagelist *) ptr, classsize[type]);
-#ifdef DEBUG
- printf("(%x,%x): new object: %x (%d, %x) \n", udn_tile_coord_x(),
- udn_tile_coord_y(), (int)v, type, classsize[type]);
-#endif
- v->type=type;
- v->version = 0;
- v->lock = NULL;
- v->lockcount = 0;
- initlock(v);
-#ifdef GC_PROFILE
- extern unsigned int gc_num_obj;
- gc_num_obj++;
-#endif
- return v;
-}
-
-/* Array allocation function */
-
-struct ArrayObject * allocate_newarray(void * ptr, int type, int length) {
- struct ArrayObject * v=(struct ArrayObject *)FREEMALLOC((struct garbagelist *) ptr, sizeof(struct ArrayObject)+length*classsize[type]);
-#ifdef DEBUG
- printf("(%x,%x): new array object: %x (%d, %x)\n", udn_tile_coord_x(),
- udn_tile_coord_y(), (int)v, type,
- sizeof(struct ArrayObject)+length*classsize[type]);
-#endif
- v->type=type;
- v->version = 0;
- v->lock = NULL;
- if (length<0) {
- return NULL;
- }
- v->___length___=length;
- initlock(v);
-#ifdef GC_PROFILE
- extern unsigned int gc_num_obj;
- gc_num_obj++;
-#endif
- return v;
-}
-
-#else
-void * allocate_new(int type) {
- struct ___Object___ * v=FREEMALLOC(classsize[type]);
- v->type=type;
- v->version = 0;
- //v->numlocks = 0;
- v->lock = NULL;
- initlock(v);
- return v;
-}
-
-/* Array allocation function */
-
-struct ArrayObject * allocate_newarray(int type, int length) {
- struct ArrayObject * v=FREEMALLOC(sizeof(struct ArrayObject)+length*classsize[type]);
- v->type=type;
- v->version = 0;
- //v->numlocks = 0;
- v->lock = NULL;
- v->___length___=length;
- initlock(v);
- return v;
-}
-#endif
-
-
-/* Converts C character arrays into Java strings */
-#ifdef MULTICORE_GC
-struct ___String___ * NewString(void * ptr, const char *str,int length) {
-#else
-struct ___String___ * NewString(const char *str,int length) {
-#endif
- int i;
-#ifdef MULTICORE_GC
- struct ArrayObject * chararray=allocate_newarray((struct garbagelist *)ptr, CHARARRAYTYPE, length);
- int ptrarray[]={1, (int) ptr, (int) chararray};
- struct ___String___ * strobj=allocate_new((struct garbagelist *) &ptrarray, STRINGTYPE);
- chararray=(struct ArrayObject *) ptrarray[2];
-#else
- struct ArrayObject * chararray=allocate_newarray(CHARARRAYTYPE, length);
- struct ___String___ * strobj=allocate_new(STRINGTYPE);
-#endif
- strobj->___value___=chararray;
- strobj->___count___=length;
- strobj->___offset___=0;
-
- for(i=0; i<length; i++) {
- ((short *)(((char *)&chararray->___length___)+sizeof(int)))[i]=(short)str[i];
- }
- return strobj;
-}
-
-/* Generated code calls this if we fail a bounds check */
-
-void failedboundschk() {
-#ifndef TASK
- printf("Array out of bounds\n");
-#ifdef THREADS
- threadexit();
-#else
- exit(-1);
-#endif
-#else
-#ifndef MULTICORE
- printf("Array out of bounds\n");
- longjmp(error_handler,2);
-#else
- BAMBOO_EXIT(0xa001);
-#endif
-#endif
-}
-
-/* Abort task call */
-void abort_task() {
-#ifdef TASK
-#ifndef MULTICORE
- printf("Aborting\n");
- longjmp(error_handler,4);
-#endif
-#else
- printf("Aborting\n");
- exit(-1);
-#endif
-}
+++ /dev/null
-#ifndef MULTICORE_RUNTIME
-#define MULTICORE_RUNTIME
-
-#ifndef INLINE
-#define INLINE inline __attribute__((always_inline))
-#endif
-
-#ifndef bool
-#define bool int
-#define true 1
-#define false 0
-#endif
-
-////////////////////////////////////////////////////////////////
-// global variables //
-///////////////////////////////////////////////////////////////
-
-// record the starting time
-unsigned long long bamboo_start_time;
-
-// data structures for msgs
-#define BAMBOO_OUT_BUF_LENGTH 3000
-#define BAMBOO_MSG_BUF_LENGTH 3000
-int msgdata[BAMBOO_MSG_BUF_LENGTH];
-volatile int msgdataindex;
-volatile int msgdatalast;
-int msglength;
-volatile bool msgdatafull;
-int outmsgdata[BAMBOO_OUT_BUF_LENGTH];
-int outmsgindex;
-int outmsglast;
-int outmsgleft;
-volatile bool isMsgHanging;
-//volatile bool isMsgSending;
-
-#define MSG_INDEXINC_I() \
- msgdataindex = (msgdataindex + 1) % (BAMBOO_MSG_BUF_LENGTH)
-
-#define MSG_LASTINDEXINC_I() \
- msgdatalast = (msgdatalast + 1) % (BAMBOO_MSG_BUF_LENGTH)
-
-#define MSG_CACHE_I(n) \
- msgdata[msgdatalast] = (n); \
- MSG_LASTINDEXINC_I()
-
-// NOTE: if msgdataindex == msgdatalast, it always means that the buffer if
-// full. In the case that the buffer is empty, should never call this
-// MACRO
-#define MSG_REMAINSIZE_I(s) \
- if(msgdataindex < msgdatalast) { \
- (*(int*)s) = msgdatalast - msgdataindex; \
- } else if((msgdataindex == msgdatalast) && (!msgdatafull)) { \
- (*(int*)s) = 0; \
- } else { \
- (*(int*)s) = (BAMBOO_MSG_BUF_LENGTH) -msgdataindex + msgdatalast; \
- }
-
-#define OUTMSG_INDEXINC() \
- outmsgindex = (outmsgindex + 1) % (BAMBOO_OUT_BUF_LENGTH)
-
-#define OUTMSG_LASTINDEXINC() \
- outmsglast = (outmsglast + 1) % (BAMBOO_OUT_BUF_LENGTH); \
- if(outmsglast == outmsgindex) { \
- BAMBOO_EXIT(0xdd01); \
- }
-
-#define OUTMSG_CACHE(n) \
- outmsgdata[outmsglast] = (n); \
- OUTMSG_LASTINDEXINC();
-
-#define MAX_PACKET_WORDS 5
-
-/* Message format:
- * type + Msgbody
- * type: 1 -- transfer object
- * 2 -- transfer stall msg
- * 3 -- lock request
- * 4 -- lock grount
- * 5 -- lock deny
- * 6 -- lock release
- * // add for profile info
- * 7 -- transfer profile output msg
- * 8 -- transfer profile output finish msg
- * // add for alias lock strategy
- * 9 -- redirect lock request
- * a -- lock grant with redirect info
- * b -- lock deny with redirect info
- * c -- lock release with redirect info
- * d -- status confirm request
- * e -- status report msg
- * f -- terminate
- * 10 -- requiring for new memory
- * 11 -- response for new memory request
- * 12 -- GC init phase start
- * 13 -- GC start
- * 14 -- compact phase start
- * 15 -- flush phase start
- * 16 -- init phase finish
- * 17 -- mark phase finish
- * 18 -- compact phase finish
- * 19 -- flush phase finish
- * 1a -- GC finish
- * 1b -- marked phase finish confirm request
- * 1c -- marked phase finish confirm response
- * 1d -- markedObj msg
- * 1e -- start moving objs msg
- * 1f -- ask for mapping info of a markedObj
- * 20 -- mapping info of a markedObj
- * 21 -- large objs info request
- * 22 -- large objs info response
- * 23 -- large objs mapping info
- *
- * ObjMsg: 1 + size of msg + obj's address + (task index + param index)+
- * StallMsg: 2 + corenum + sendobjs + receiveobjs
- * (size is always 4 * sizeof(int))
- * LockMsg: 3 + lock type + obj pointer + lock + request core
- * (size is always 5 * sizeof(int))
- * 4/5/6 + lock type + obj pointer + lock
- * (size is always 4 * sizeof(int))
- * 9 + lock type + obj pointer + redirect lock + root request core
- * + request core
- * (size is always 6 * sizeof(int))
- * a/b + lock type + obj pointer + redirect lock
- * (size is always 4 * sizeof(int))
- * c + lock type + lock + redirect lock
- * (size is always 4 * sizeof(int))
- * lock type: 0 -- read; 1 -- write
- * ProfileMsg: 7 + totalexetime
- * (size is always 2 * sizeof(int))
- * 8 + corenum
- * (size is always 2 * sizeof(int))
- * StatusMsg: d (size is always 1 * sizeof(int))
- * e + status + corenum + sendobjs + receiveobjs
- * (size is always 5 * sizeof(int))
- * status: 0 -- stall; 1 -- busy
- * TerminateMsg: f (size is always 1 * sizeof(int)
- * MemoryMsg: 10 + size + corenum
- * (size is always 3 * sizeof(int))
- * 11 + base_va + size
- * (size is always 3 * sizeof(int))
- * GCMsg: 12/13 (size is always 1 * sizeof(int))
- * 14 + size of msg + (num of objs to move + (start address
- * + end address + dst core + start dst)+)?
- * + (num of incoming objs + (start dst + orig core)+)?
- * + (num of large obj lists + (start address + lenght
- * + start dst)+)?
- * 15 (size is always 1 * sizeof(int))
- * 16 + corenum
- * (size is always 2 * sizeof(int))
- * 17 + corenum + gcsendobjs + gcreceiveobjs
- * (size if always 4 * sizeof(int))
- * 18 + corenum + fulfilled blocks num + (finish compact(1) + current
- * heap top)/(need mem(0) + mem need)
- * size is always 5 * sizeof(int))
- * 19 + corenum
- * (size is always 2 * sizeof(int))
- * 1a (size is always 1 * sizeof(int))
- * 1b (size if always 1 * sizeof(int))
- * 1c + size of msg + corenum + gcsendobjs + gcreceiveobjs
- * (size is always 5 * sizeof(int))
- * 1d + obj's address + request core
- * (size is always 3 * sizeof(int))
- * 1e + corenum + start addr + end addr
- * (size if always 4 * sizeof(int))
- * 1f + obj's address + corenum
- * (size is always 3 * sizeof(int))
- * 20 + obj's address + dst address
- * (size if always 3 * sizeof(int))
- * 21 (size is always 1 * sizeof(int))
- * 22 + size of msg + corenum + current heap size
- * + (num of large obj lists + (start address + length)+)?
- * 23 + orig large obj ptr + new large obj ptr
- * (size is always 3 * sizeof(int))
- */
-typedef enum {
- 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
- GCSTARTPRE, // 0xE2
- GCSTARTINIT, // 0xE3
- GCSTART, // 0xE4
- GCSTARTCOMPACT, // 0xE5
- GCSTARTMAPINFO, // 0xE6
- GCSTARTFLUSH, // 0xE7
- GCFINISHPRE, // 0xE8
- GCFINISHINIT, // 0xE9
- GCFINISHMARK, // 0xEa
- GCFINISHCOMPACT, // 0xEb
- GCFINISHMAPINFO, // 0xEc
- GCFINISHFLUSH, // 0xEd
- GCFINISH, // 0xEe
- GCMARKCONFIRM, // 0xEf
- GCMARKREPORT, // 0xF0
- GCMARKEDOBJ, // 0xF1
- GCMOVESTART, // 0xF2
- GCMAPREQUEST, // 0xF3
- GCMAPINFO, // 0xF4
- GCMAPTBL, // 0xF5
- GCLOBJREQUEST, // 0xF6
- GCLOBJINFO, // 0xF7
- GCLOBJMAPPING, // 0xF8
-#ifdef GC_PROFILE
- GCPROFILES, // 0xF9
-#endif
-#ifdef GC_CACHE_ADAPT
- GCSTARTPOSTINIT, // 0xFa
- GCSTARTPREF, // 0xFb
- GCFINISHPOSTINIT, // 0xFc
- GCFINISHPREF, // 0xFd
-#endif // GC_CACHE_ADAPT
-#endif
- MSGEND
-} MSGTYPE;
-
-/////////////////////////////////////////////////////////////////////////////////
-// NOTE: BAMBOO_TOTALCORE -- number of the available cores in the processor.
-// No greater than the number of all the cores in
-// the processor
-// NUMCORES -- number of cores chosen to deploy the application. It can
-// be greater than that required to fully parallelize the
-// application. The same as NUMCORES.
-// NUMCORESACTIVE -- number of cores that really execute the
-// application. No greater than NUMCORES
-// NUMCORES4GC -- number of cores for gc. No greater than NUMCORES.
-// NOTE: currently only support ontinuous cores as gc
-// cores, i.e. 0~NUMCORES4GC-1
-////////////////////////////////////////////////////////////////////////////////
-// data structures of status for termination
-// only check working cores
-volatile int corestatus[NUMCORESACTIVE]; // records status of each core
- // 1: running tasks
- // 0: stall
-volatile int numsendobjs[NUMCORESACTIVE]; // records how many objects a core
- // has sent out
-volatile int numreceiveobjs[NUMCORESACTIVE]; // records how many objects a
- // core has received
-volatile int numconfirm;
-volatile bool waitconfirm;
-bool busystatus;
-int self_numsendobjs;
-int self_numreceiveobjs;
-
-// get rid of lock msgs for GC version
-#ifndef MULTICORE_GC
-// data structures for locking
-struct RuntimeHash locktable;
-static struct RuntimeHash* locktbl = &locktable;
-struct RuntimeHash * lockRedirectTbl;
-struct RuntimeHash * objRedirectLockTbl;
-#endif
-struct LockValue {
- int redirectlock;
- int value;
-};
-int lockobj;
-int lock2require;
-int lockresult;
-bool lockflag;
-
-// data structures for waiting objs
-struct Queue objqueue;
-struct Queue * totransobjqueue; // queue to hold objs to be transferred
- // should be cleared whenever enter a task
-
-// data structures for shared memory allocation
-#ifdef TILERA_BME
-#define BAMBOO_BASE_VA 0xd000000
-#elif defined TILERA_ZLINUX
-#ifdef MULTICORE_GC
-#define BAMBOO_BASE_VA 0xd000000
-#endif // MULTICORE_GC
-#endif // TILERA_BME
-
-#ifdef BAMBOO_MEMPROF
-#define GC_BAMBOO_NUMCORES 56
-#else
-#define GC_BAMBOO_NUMCORES 62
-#endif
-
-#ifdef GC_DEBUG
-#include "structdefs.h"
-#define BAMBOO_NUM_PAGES (NUMCORES4GC*(2+1)+3)
-#define BAMBOO_PAGE_SIZE (64 * 64)
-#define BAMBOO_SMEM_SIZE (64 * 64) // (BAMBOO_PAGE_SIZE)
-#define BAMBOO_SHARED_MEM_SIZE ((BAMBOO_PAGE_SIZE) *(BAMBOO_NUM_PAGES))
-#else
-#ifdef GC_LARGESHAREDHEAP
-#define BAMBOO_NUM_PAGES ((GC_BAMBOO_NUMCORES)*(2+2))
-#elif defined GC_LARGESHAREDHEAP2
-#define BAMBOO_NUM_PAGES ((GC_BAMBOO_NUMCORES)*(2+2))
-#else
-#define BAMBOO_NUM_PAGES ((GC_BAMBOO_NUMCORES)*(2+3)) //(15 * 1024) //(64 * 4 * 0.75) //(1024 * 1024 * 3.5) 3G
-#endif
-#ifdef GC_LARGEPAGESIZE
-#define BAMBOO_PAGE_SIZE (4 * 1024 * 1024) // (4096)
-#define BAMBOO_SMEM_SIZE (4 * 1024 * 1024)
-#elif defined GC_SMALLPAGESIZE
-#define BAMBOO_PAGE_SIZE (256 * 1024) // (4096)
-#define BAMBOO_SMEM_SIZE (256 * 1024)
-#elif defined GC_SMALLPAGESIZE2
-#define BAMBOO_PAGE_SIZE (64 * 1024) // (4096)
-#define BAMBOO_SMEM_SIZE (64 * 1024)
-#else
-#define BAMBOO_PAGE_SIZE (1024 * 1024) // (4096)
-#define BAMBOO_SMEM_SIZE (1024 * 1024)
-#endif // GC_LARGEPAGESIZE
-#define BAMBOO_SHARED_MEM_SIZE ((BAMBOO_PAGE_SIZE) * (BAMBOO_NUM_PAGES)) //(1024 * 1024 * 240)
-//((unsigned long long int)(3.0 * 1024 * 1024 * 1024)) // 3G
-#endif // GC_DEBUG
-
-#ifdef MULTICORE_GC
-volatile bool gc_localheap_s;
-#endif
-
-#ifdef MULTICORE_GC
-#include "multicoregarbage.h"
-
-typedef enum {
- SMEMLOCAL = 0x0,// 0x0, using local mem only
- SMEMFIXED, // 0x1, use local mem in lower address space(1 block only)
- // and global mem in higher address space
- SMEMMIXED, // 0x2, like FIXED mode but use a threshold to control
- SMEMGLOBAL, // 0x3, using global mem only
- SMEMEND
-} SMEMSTRATEGY;
-
-SMEMSTRATEGY bamboo_smem_mode; //-DSMEML: LOCAL; -DSMEMF: FIXED;
- //-DSMEMM: MIXED; -DSMEMG: GLOBAL;
-
-struct freeMemItem {
- INTPTR ptr;
- int size;
- int startblock;
- int endblock;
- struct freeMemItem * next;
-};
-
-struct freeMemList {
- struct freeMemItem * head;
- struct freeMemItem * backuplist; // hold removed freeMemItem for reuse;
- // only maintain 1 freemMemItem
-};
-
-// table recording the number of allocated bytes on each block
-// Note: this table resides on the bottom of the shared heap for all cores
-// to access
-volatile int * bamboo_smemtbl;
-volatile int bamboo_free_block;
-//bool bamboo_smem_flushed;
-//struct freeMemList * bamboo_free_mem_list;
-int bamboo_reserved_smem; // reserved blocks on the top of the shared heap
- // e.g. 20% of the heap and should not be allocated
- // otherwise gc is invoked
-volatile INTPTR bamboo_smem_zero_top;
-#define BAMBOO_SMEM_ZERO_UNIT_SIZE (4 * 1024) // 4KB
-#else
-//volatile mspace bamboo_free_msp;
-INTPTR bamboo_free_smemp;
-int bamboo_free_smem_size;
-#endif
-volatile bool smemflag;
-volatile INTPTR bamboo_cur_msp;
-volatile int bamboo_smem_size;
-
-// for test TODO
-int total_num_t6;
-
-// data structures for profile mode
-#ifdef PROFILE
-
-#define TASKINFOLENGTH 3000 // 0
-#ifdef PROFILE_INTERRUPT
-#define INTERRUPTINFOLENGTH 50 //0
-#endif // PROFILE_INTERRUPT
-
-bool stall;
-//bool isInterrupt;
-int totalexetime;
-//unsigned long long interrupttime;
-
-typedef struct task_info {
- char* taskName;
- unsigned long long startTime;
- unsigned long long endTime;
- unsigned long long exitIndex;
- struct Queue * newObjs;
-} TaskInfo;
-
-TaskInfo * taskInfoArray[TASKINFOLENGTH];
-int taskInfoIndex;
-bool taskInfoOverflow;
-#ifdef PROFILE_INTERRUPT
-typedef struct interrupt_info {
- unsigned long long startTime;
- unsigned long long endTime;
-} InterruptInfo;
-
-InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
-int interruptInfoIndex;
-bool interruptInfoOverflow;
-#endif // PROFILE_INTERUPT
-volatile int profilestatus[NUMCORESACTIVE]; // records status of each core
- // 1: running tasks
- // 0: stall
-#endif // #ifdef PROFILE
-
-#ifndef INTERRUPT
-bool reside;
-#endif
-/////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////
-// these are functions should be implemented in //
-// multicore runtime for any multicore processors //
-////////////////////////////////////////////////////////////
-#ifdef TASK
-#ifdef MULTICORE
-INLINE void initialization(void);
-INLINE void initCommunication(void);
-INLINE void fakeExecution(void);
-INLINE void terminate(void);
-INLINE void initlock(struct ___Object___ * v);
-#ifdef BAMBOO_MEMPROF
-INLINE void terminatememprof(void);
-#endif
-
-// lock related functions
-bool getreadlock(void* ptr);
-void releasereadlock(void* ptr);
-bool getwritelock(void* ptr);
-void releasewritelock(void* ptr);
-bool getwritelock_I(void* ptr);
-void releasewritelock_I(void * ptr);
-#ifndef MULTICORE_GC
-void releasewritelock_r(void * lock, void * redirectlock);
-#endif
-/* this function is to process lock requests.
- * can only be invoked in receiveObject() */
-// if return -1: the lock request is redirected
-// 0: the lock request is approved
-// 1: the lock request is denied
-INLINE int processlockrequest(int locktype,
- int lock,
- int obj,
- int requestcore,
- int rootrequestcore,
- bool cache);
-INLINE void processlockrelease(int locktype,
- int lock,
- int redirectlock,
- bool redirect);
-
-// msg related functions
-INLINE void send_hanging_msg(bool isInterrupt);
-INLINE void send_msg_1(int targetcore,
- unsigned long n0,
- bool isInterrupt);
-INLINE void send_msg_2(int targetcore,
- unsigned long n0,
- unsigned long n1,
- bool isInterrupt);
-INLINE void send_msg_3(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2,
- bool isInterrupt);
-INLINE void send_msg_4(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2,
- unsigned long n3,
- bool isInterrupt);
-INLINE void send_msg_5(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2,
- unsigned long n3,
- unsigned long n4,
- bool isInterrupt);
-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,
- bool isInterrupt);
-INLINE void cache_msg_1(int targetcore,
- unsigned long n0);
-INLINE void cache_msg_2(int targetcore,
- unsigned long n0,
- unsigned long n1);
-INLINE void cache_msg_3(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2);
-INLINE void cache_msg_4(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2,
- unsigned long n3);
-INLINE void cache_msg_5(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2,
- unsigned long n3,
- unsigned long n4);
-INLINE void cache_msg_6(int targetcore,
- unsigned long n0,
- unsigned long n1,
- unsigned long n2,
- unsigned long n3,
- unsigned long n4,
- unsigned long n5);
-INLINE void transferObject(struct transObjInfo * transObj);
-INLINE int receiveMsg(uint32_t send_port_pending);
-
-#ifdef MULTICORE_GC
-INLINE void transferMarkResults();
-#endif
-
-#ifdef PROFILE
-INLINE void profileTaskStart(char * taskname);
-INLINE void profileTaskEnd(void);
-void outputProfileData();
-#endif // #ifdef PROFILE
-///////////////////////////////////////////////////////////
-
-/////////////////////////////////////////////////////////////////////////////
-// For each version of BAMBOO runtime, there should be a header file named //
-// runtim_arch.h defining following MARCOS: //
-// BAMBOO_NUM_OF_CORE: the # of current residing core //
-// BAMBOO_GET_NUM_OF_CORE(): compute the # of current residing core //
-// BAMBOO_COORDS(c, x, y): convert the cpu # to coords (*x, *y) //
-// BAMBOO_DEBUGPRINT(x): print out integer x //
-// BAMBOO_DEBUGPRINT_REG(x): print out value of variable x //
-// BAMBOO_EXIT_APP(x): exit the whole application //
-// BAMBOO_EXIT(x): error exit routine with error # //
-// BAMBOO_DIE(x): error exit routine with error msg //
-// BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number //
-// BAMBOO_MSG_AVAIL(): checking if there are msgs coming in //
-// BAMBOO_GCMSG_AVAIL(): checking if there are gcmsgs coming in //
-// BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT(): change to runtime mode from //
-// client mode //
-// BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME(): change to client mode from //
-// runtime mode //
-// BAMBOO_ENTER_SEND_MODE_FROM_CLIENT(): change to send mode from //
-// client mode //
-// BAMBOO_ENTER_CLIENT_MODE_FROM_SEND(): change to client mode from //
-// send mode //
-// BAMBOO_ENTER_RUNTIME_MODE_FROM_SEND(): change to runtime mode from //
-// send mode //
-// BAMBOO_ENTER_SEND_MODE_FROM_RUNTIME(): change to send mode from //
-// runtime mode //
-// BAMBOO_WAITING_FOR_LOCK(): routine executed while waiting for lock //
-// request response //
-// BAMBOO_LOCAL_MEM_CALLOC(x, y): allocate an array of x elements each of //
-// whose size in bytes is y on local memory //
-// which is given by the hypervisor //
-// BAMBOO_LOCAL_MEM_FREE(x): free space with ptr x on local memory //
-// BAMBOO_LOCAL_MEM_CLOSE(): close the local heap //
-// BAMBOO_LOCAL_MEM_CALLOC_S(x, y): allocate an array of x elements each of//
-// whose size in bytes is y on local //
-// memory which is not from the hypervisor//
-// but is allocated from the free memory //
-// BAMBOO_LOCAL_MEM_FREE_S(x): free space with ptr x on self-allocated //
-// local memory //
-// BAMBOO_LOCAL_MEM_CLOSE_S(): close the self-allocated local heap //
-// BAMBOO_SHARE_MEM_CALLOC_I(x, y): allocate an array of x elements each of//
-// whose size in bytes is y on shared memory//
-// BAMBOO_SHARE_MEM_CLOSE(): close the shared heap //
-// BAMBOO_CACHE_LINE_SIZE: the cache line size //
-// BAMBOO_CACHE_LINE_MASK: mask for a cache line //
-// BAMBOO_CACHE_FLUSH_RANGE(x, y): flush cache lines started at x with //
-// length y //
-// BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary //
-// BAMBOO_MEMSET_WH(x, y, z): memset the specified region of memory (start //
-// address x, size z) to value y with write //
-// hint, the processor will not fetch the //
-// current content of the memory and directly //
-// write //
-// BAMBOO_CLEAN_DTLB(): zero-out all the dtlb entries //
-// BAMBOO_CACHE_FLUSH_L2(): Flush the contents of this tile's L2 back to //
-// main memory //
-/////////////////////////////////////////////////////////////////////////////
-
-#endif // #ifdef MULTICORE
-#endif // #ifdef TASK
-#endif // #ifndef MULTICORE_RUNTIME
+++ /dev/null
-#ifdef TASK
-#include "runtime.h"
-#include "multicoreruntime.h"
-#include "runtime_arch.h"
-#include "GenericHashtable.h"
-
-#ifndef INLINE
-#define INLINE inline __attribute__((always_inline))
-#endif // #ifndef INLINE
-
-// data structures for task invocation
-struct genhashtable * activetasks;
-struct taskparamdescriptor * currtpd;
-struct LockValue runtime_locks[MAXTASKPARAMS];
-int runtime_locklen;
-
-// specific functions used inside critical sections
-void enqueueObject_I(void * ptr,
- struct parameterwrapper ** queues,
- int length);
-int enqueuetasks_I(struct parameterwrapper *parameter,
- struct parameterwrapper *prevptr,
- struct ___Object___ *ptr,
- int * enterflags,
- int numenterflags);
-
-#ifdef MULTICORE_GC
-#ifdef SMEMF
-#define NUM_CORES2TEST 5
-#ifdef GC_1
-int core2test[1][NUM_CORES2TEST] = {
- {0, -1, -1, -1, -1}
-};
-#elif defined GC_56
-int core2test[56][NUM_CORES2TEST] = {
- { 0, -1, 7, -1, 1}, { 1, -1, 8, 0, 2}, { 2, -1, 9, 1, 3},
- { 3, -1, 10, 2, 4}, { 4, -1, 11, 3, 5}, { 5, -1, 12, 4, 6},
- { 6, -1, 13, 5, -1}, { 7, 0, 14, -1, 8}, { 8, 1, 15, 7, 9},
- { 9, 2, 16, 8, 10}, {10, 3, 17, 9, 11}, {11, 4, 18, 10, 12},
- {12, 5, 19, 11, 13}, {13, 6, 20, 12, -1}, {14, 7, 21, -1, 15},
- {15, 8, 22, 14, 16}, {16, 9, 23, 15, 17}, {17, 10, 24, 16, 18},
- {18, 11, 25, 17, 19}, {19, 12, 26, 18, 20}, {20, 13, 27, 19, -1},
- {21, 14, 28, -1, 22}, {22, 15, 29, 21, 23}, {23, 16, 30, 22, 24},
- {24, 17, 31, 23, 25}, {25, 18, 32, 24, 26}, {26, 19, 33, 25, 27},
- {27, 20, 34, 26, -1}, {28, 21, 35, -1, 29}, {29, 22, 36, 28, 30},
- {30, 23, 37, 29, 31}, {31, 24, 38, 30, 32}, {32, 25, 39, 31, 33},
- {33, 26, 40, 32, 34}, {34, 27, 41, 33, -1}, {35, 28, 42, -1, 36},
- {36, 29, 43, 35, 37}, {37, 30, 44, 36, 38}, {38, 31, 45, 37, 39},
- {39, 32, 46, 38, 40}, {40, 33, 47, 39, 41}, {41, 34, 48, 40, -1},
- {42, 35, 49, -1, 43}, {43, 36, 50, 42, 44}, {44, 37, 51, 43, 45},
- {45, 38, 52, 44, 46}, {46, 39, 53, 45, 47}, {47, 40, 54, 46, 48},
- {48, 41, 55, 47, -1}, {49, 42, -1, -1, 50}, {50, 43, -1, 49, 51},
- {51, 44, -1, 50, 52}, {52, 45, -1, 51, 53}, {53, 46, -1, 52, 54},
- {54, 47, -1, 53, 55}, {55, 48, -1, 54, -1}
-};
-#elif defined GC_62
-int core2test[62][NUM_CORES2TEST] = {
- { 0, -1, 6, -1, 1}, { 1, -1, 7, 0, 2}, { 2, -1, 8, 1, 3},
- { 3, -1, 9, 2, 4}, { 4, -1, 10, 3, 5}, { 5, -1, 11, 4, -1},
- { 6, 0, 14, -1, 7}, { 7, 1, 15, 6, 8}, { 8, 2, 16, 7, 9},
- { 9, 3, 17, 8, 10}, {10, 4, 18, 9, 11}, {11, 5, 19, 10, 12},
- {12, -1, 20, 11, 13}, {13, -1, 21, 12, -1}, {14, 6, 22, -1, 15},
- {15, 7, 23, 14, 16}, {16, 8, 24, 15, 17}, {17, 9, 25, 16, 18},
- {18, 10, 26, 17, 19}, {19, 11, 27, 18, 20}, {20, 12, 28, 19, 21},
- {21, 13, 29, 28, -1}, {22, 14, 30, -1, 23}, {23, 15, 31, 22, 24},
- {24, 16, 32, 23, 25}, {25, 17, 33, 24, 26}, {26, 18, 34, 25, 27},
- {27, 19, 35, 26, 28}, {28, 20, 36, 27, 29}, {29, 21, 37, 28, -1},
- {30, 22, 38, -1, 31}, {31, 23, 39, 30, 32}, {32, 24, 40, 31, 33},
- {33, 25, 41, 32, 34}, {34, 26, 42, 33, 35}, {35, 27, 43, 34, 36},
- {36, 28, 44, 35, 37}, {37, 29, 45, 36, -1}, {38, 30, 46, -1, 39},
- {39, 31, 47, 38, 40}, {40, 32, 48, 39, 41}, {41, 33, 49, 40, 42},
- {42, 34, 50, 41, 43}, {43, 35, 51, 42, 44}, {44, 36, 52, 43, 45},
- {45, 37, 53, 44, -1}, {46, 38, 54, -1, 47}, {47, 39, 55, 46, 48},
- {48, 40, 56, 47, 49}, {49, 41, 57, 48, 50}, {50, 42, 58, 49, 51},
- {51, 43, 59, 50, 52}, {52, 44, 60, 51, 53}, {53, 45, 61, 52, -1},
- {54, 46, -1, -1, 55}, {55, 47, -1, 54, 56}, {56, 48, -1, 55, 57},
- {57, 49, -1, 56, 59}, {58, 50, -1, 57, 59}, {59, 51, -1, 58, 60},
- {60, 52, -1, 59, 61}, {61, 53, -1, 60, -1}
-};
-#endif // GC_1
-#elif defined SMEMM
-unsigned int gcmem_mixed_threshold = 0;
-unsigned int gcmem_mixed_usedmem = 0;
-#define NUM_CORES2TEST 9
-#ifdef GC_1
-int core2test[1][NUM_CORES2TEST] = {
- {0, -1, -1, -1, -1, -1, -1, -1, -1}
-};
-#elif defined GC_56
-int core2test[56][NUM_CORES2TEST] = {
- { 0, -1, 7, -1, 1, -1, 14, -1, 2},
- { 1, -1, 8, 0, 2, -1, 15, -1, 3},
- { 2, -1, 9, 1, 3, -1, 16, 0, 4},
- { 3, -1, 10, 2, 4, -1, 17, 1, 5},
- { 4, -1, 11, 3, 5, -1, 18, 2, 6},
- { 5, -1, 12, 4, 6, -1, 19, 3, -1},
- { 6, -1, 13, 5, -1, -1, 20, 4, -1},
- { 7, 0, 14, -1, 8, -1, 21, -1, 9},
- { 8, 1, 15, 7, 9, -1, 22, -1, 10},
- { 9, 2, 16, 8, 10, -1, 23, 7, 11},
- {10, 3, 17, 9, 11, -1, 24, 8, 12},
- {11, 4, 18, 10, 12, -1, 25, 9, 13},
- {12, 5, 19, 11, 13, -1, 26, 10, -1},
- {13, 6, 20, 12, -1, -1, 27, 11, -1},
- {14, 7, 21, -1, 15, 0, 28, -1, 16},
- {15, 8, 22, 14, 16, 1, 29, -1, 17},
- {16, 9, 23, 15, 17, 2, 30, 14, 18},
- {17, 10, 24, 16, 18, 3, 31, 15, 19},
- {18, 11, 25, 17, 19, 4, 32, 16, 20},
- {19, 12, 26, 18, 20, 5, 33, 17, -1},
- {20, 13, 27, 19, -1, 6, 34, 18, -1},
- {21, 14, 28, -1, 22, 7, 35, -1, 23},
- {22, 15, 29, 21, 23, 8, 36, -1, 24},
- {23, 16, 30, 22, 24, 9, 37, 21, 25},
- {24, 17, 31, 23, 25, 10, 38, 22, 26},
- {25, 18, 32, 24, 26, 11, 39, 23, 27},
- {26, 19, 33, 25, 27, 12, 40, 24, -1},
- {27, 20, 34, 26, -1, 13, 41, 25, -1},
- {28, 21, 35, -1, 29, 14, 42, -1, 30},
- {29, 22, 36, 28, 30, 15, 43, -1, 31},
- {30, 23, 37, 29, 31, 16, 44, 28, 32},
- {31, 24, 38, 30, 32, 17, 45, 29, 33},
- {32, 25, 39, 31, 33, 18, 46, 30, 34},
- {33, 26, 40, 32, 34, 19, 47, 31, -1},
- {34, 27, 41, 33, -1, 20, 48, 32, -1},
- {35, 28, 42, -1, 36, 21, 49, -1, 37},
- {36, 29, 43, 35, 37, 22, 50, -1, 38},
- {37, 30, 44, 36, 38, 23, 51, 35, 39},
- {38, 31, 45, 37, 39, 24, 52, 36, 40},
- {39, 32, 46, 38, 40, 25, 53, 37, 41},
- {40, 33, 47, 39, 41, 26, 54, 38, -1},
- {41, 34, 48, 40, -1, 27, 55, 39, -1},
- {42, 35, 49, -1, 43, 28, -1, -1, 44},
- {43, 36, 50, 42, 44, 29, -1, -1, 45},
- {44, 37, 51, 43, 45, 30, -1, 42, 46},
- {45, 38, 52, 44, 46, 31, -1, 43, 47},
- {46, 39, 53, 45, 47, 32, -1, 44, 48},
- {47, 40, 54, 46, 48, 33, -1, 45, -1},
- {48, 41, 55, 47, -1, 34, -1, 46, -1},
- {49, 42, -1, -1, 50, 35, -1, -1, 51},
- {50, 43, -1, 49, 51, 36, -1, -1, 52},
- {51, 44, -1, 50, 52, 37, -1, 49, 53},
- {52, 45, -1, 51, 53, 38, -1, 50, 54},
- {53, 46, -1, 52, 54, 39, -1, 51, 55},
- {54, 47, -1, 53, 55, 40, -1, 52, -1},
- {55, 48, -1, 54, -1, 41, -1, 53, -1}
-};
-#elif defined GC_62
-int core2test[62][NUM_CORES2TEST] = {
- { 0, -1, 6, -1, 1, -1, 14, -1, 2},
- { 1, -1, 7, 0, 2, -1, 15, -1, 3},
- { 2, -1, 8, 1, 3, -1, 16, 0, 4},
- { 3, -1, 9, 2, 4, -1, 17, 1, 5},
- { 4, -1, 10, 3, 5, -1, 18, 2, -1},
- { 5, -1, 11, 4, -1, -1, 19, 3, -1},
- { 6, 0, 14, -1, 7, -1, 22, -1, 8},
- { 7, 1, 15, 6, 8, -1, 23, -1, 9},
- { 8, 2, 16, 7, 9, -1, 24, 6, 10},
- { 9, 3, 17, 8, 10, -1, 25, 7, 11},
- {10, 4, 18, 9, 11, -1, 26, 8, 12},
- {11, 5, 19, 10, 12, -1, 27, 9, 13},
- {12, -1, 20, 11, 13, -1, 28, 10, -1},
- {13, -1, 21, 12, -1, -1, 29, 11, -1},
- {14, 6, 22, -1, 15, 0, 30, -1, 16},
- {15, 7, 23, 14, 16, 1, 31, -1, 17},
- {16, 8, 24, 15, 17, 2, 32, 14, 18},
- {17, 9, 25, 16, 18, 3, 33, 15, 19},
- {18, 10, 26, 17, 19, 4, 34, 16, 20},
- {19, 11, 27, 18, 20, 5, 35, 17, 21},
- {20, 12, 28, 19, 21, -1, 36, 18, -1},
- {21, 13, 29, 28, -1, -1, 37, 19, -1},
- {22, 14, 30, -1, 23, 6, 38, -1, 24},
- {23, 15, 31, 22, 24, 7, 39, -1, 25},
- {24, 16, 32, 23, 25, 8, 40, 22, 26},
- {25, 17, 33, 24, 26, 9, 41, 23, 27},
- {26, 18, 34, 25, 27, 10, 42, 24, 28},
- {27, 19, 35, 26, 28, 11, 43, 25, 29},
- {28, 20, 36, 27, 29, 12, 44, 26, -1},
- {29, 21, 37, 28, -1, 13, 45, 27, -1},
- {30, 22, 38, -1, 31, 22, 46, -1, 32},
- {31, 23, 39, 30, 32, 15, 47, -1, 33},
- {32, 24, 40, 31, 33, 16, 48, 30, 34},
- {33, 25, 41, 32, 34, 17, 49, 31, 35},
- {34, 26, 42, 33, 35, 18, 50, 32, 36},
- {35, 27, 43, 34, 36, 19, 51, 33, 37},
- {36, 28, 44, 35, 37, 20, 52, 34, -1},
- {37, 29, 45, 36, -1, 21, 53, 35, -1},
- {38, 30, 46, -1, 39, 22, 54, -1, 40},
- {39, 31, 47, 38, 40, 23, 55, -1, 41},
- {40, 32, 48, 39, 41, 24, 56, 38, 42},
- {41, 33, 49, 40, 42, 25, 57, 39, 43},
- {42, 34, 50, 41, 43, 26, 58, 40, 44},
- {43, 35, 51, 42, 44, 27, 59, 41, 45},
- {44, 36, 52, 43, 45, 28, 60, 42, -1},
- {45, 37, 53, 44, -1, 29, 61, 43, -1},
- {46, 38, 54, -1, 47, 30, -1, -1, 48},
- {47, 39, 55, 46, 48, 31, -1, -1, 49},
- {48, 40, 56, 47, 49, 32, -1, 46, 50},
- {49, 41, 57, 48, 50, 33, -1, 47, 51},
- {50, 42, 58, 49, 51, 34, -1, 48, 52},
- {51, 43, 59, 50, 52, 35, -1, 49, 53},
- {52, 44, 60, 51, 53, 36, -1, 50, -1},
- {53, 45, 61, 52, -1, 37, -1, 51, -1},
- {54, 46, -1, -1, 55, 38, -1, -1, 56},
- {55, 47, -1, 54, 56, 39, -1, -1, 57},
- {56, 48, -1, 55, 57, 40, -1, 54, 58},
- {57, 49, -1, 56, 59, 41, -1, 55, 59},
- {58, 50, -1, 57, 59, 42, -1, 56, 60},
- {59, 51, -1, 58, 60, 43, -1, 57, 61},
- {60, 52, -1, 59, 61, 44, -1, 58, -1},
- {61, 53, -1, 60, -1, 45, -1, 59, -1}
-};
-#endif // GC_1
-#endif
-
-inline __attribute__((always_inline))
-void setupsmemmode(void) {
-#ifdef SMEML
- // Only allocate local mem chunks to each core.
- // If a core has used up its local shared memory, start gc.
- bamboo_smem_mode = SMEMLOCAL;
-#elif defined SMEMF
- // Allocate the local shared memory to each core with the highest priority,
- // if a core has used up its local shared memory, try to allocate the
- // shared memory that belong to its neighbours, if also failed, start gc.
- bamboo_smem_mode = SMEMFIXED;
-#elif defined SMEMM
- // Allocate the local shared memory to each core with the highest priority,
- // if a core has used up its local shared memory, try to allocate the
- // shared memory that belong to its neighbours first, if failed, check
- // current memory allocation rate, if it has already reached the threshold,
- // start gc, otherwise, allocate the shared memory globally. If all the
- // shared memory has been used up, start gc.
- bamboo_smem_mode = SMEMMIXED;
-#elif defined SMEMG
- // Allocate all the memory chunks globally, do not consider the host cores
- // When all the shared memory are used up, start gc.
- bamboo_smem_mode = SMEMGLOBAL;
-#else
- // defaultly using local mode
- bamboo_smem_mode = SMEMLOCAL;
- //bamboo_smem_mode = SMEMGLOBAL;
- //bamboo_smem_mode = SMEMFIXED;
-#endif
-} // void setupsmemmode(void)
-#endif
-
-inline __attribute__((always_inline))
-void initruntimedata() {
- int i;
- // initialize the arrays
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- // startup core to initialize corestatus[]
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- corestatus[i] = 1;
- numsendobjs[i] = 0;
- numreceiveobjs[i] = 0;
-#ifdef PROFILE
- // initialize the profile data arrays
- profilestatus[i] = 1;
-#endif
-#ifdef MULTICORE_GC
- gccorestatus[i] = 1;
- gcnumsendobjs[0][i] = gcnumsendobjs[1][i] = 0;
- gcnumreceiveobjs[0][i] = gcnumreceiveobjs[1][i] = 0;
-#endif
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
-#ifdef MULTICORE_GC
- for(i = 0; i < NUMCORES4GC; ++i) {
- gcloads[i] = 0;
- gcrequiredmems[i] = 0;
- gcstopblock[i] = 0;
- gcfilledblocks[i] = 0;
- } // for(i = 0; i < NUMCORES4GC; ++i)
-#ifdef GC_PROFILE
- gc_infoIndex = 0;
- gc_infoOverflow = false;
- gc_num_livespace = 0;
- gc_num_freespace = 0;
-#endif
-#endif
- numconfirm = 0;
- waitconfirm = false;
-
- // TODO for test
- total_num_t6 = 0;
- }
-
- busystatus = true;
- self_numsendobjs = 0;
- self_numreceiveobjs = 0;
-
- for(i = 0; i < BAMBOO_MSG_BUF_LENGTH; ++i) {
- msgdata[i] = -1;
- }
- msgdataindex = 0;
- msgdatalast = 0;
- msglength = BAMBOO_MSG_BUF_LENGTH;
- msgdatafull = false;
- for(i = 0; i < BAMBOO_OUT_BUF_LENGTH; ++i) {
- outmsgdata[i] = -1;
- }
- outmsgindex = 0;
- outmsglast = 0;
- outmsgleft = 0;
- isMsgHanging = false;
- //isMsgSending = false;
-
- smemflag = true;
- bamboo_cur_msp = NULL;
- bamboo_smem_size = 0;
- totransobjqueue = createQueue_I();
-
-#ifdef MULTICORE_GC
- bamboo_smem_zero_top = NULL;
- gcflag = false;
- gcprocessing = false;
- gcphase = FINISHPHASE;
- //gcnumpre = 0;
- gcprecheck = true;
- gccurr_heaptop = 0;
- gcself_numsendobjs = 0;
- gcself_numreceiveobjs = 0;
- gcmarkedptrbound = 0;
-#ifdef LOCALHASHTBL_TEST
- gcpointertbl = allocateRuntimeHash_I(20);
-#else
- gcpointertbl = mgchashCreate_I(2000, 0.75);
-#endif
- //gcpointertbl = allocateMGCHash_I(20);
- gcforwardobjtbl = allocateMGCHash_I(20, 3);
- gcobj2map = 0;
- gcmappedobj = 0;
- //gcismapped = false;
- gcnumlobjs = 0;
- gcheaptop = 0;
- gctopcore = 0;
- gctopblock = 0;
- gcmovestartaddr = 0;
- gctomove = false;
- gcmovepending = 0;
- gcblock2fill = 0;
- gcsbstarttbl = BAMBOO_BASE_VA;
- bamboo_smemtbl = (void *)gcsbstarttbl
- + (BAMBOO_SHARED_MEM_SIZE/BAMBOO_SMEM_SIZE)*sizeof(INTPTR);
- if(BAMBOO_NUM_OF_CORE < NUMCORES4GC) {
- int t_size = ((BAMBOO_RMSP_SIZE)-sizeof(mgcsharedhashtbl_t)*2
- -128*sizeof(size_t))/sizeof(mgcsharedhashlistnode_t)-2;
- int kk = 0;
- unsigned int tmp_k = 1 << (sizeof(int)*8 -1);
- while(((t_size & tmp_k) == 0) && (kk < sizeof(int)*8)) {
- t_size = t_size << 1;
- kk++;
- }
- t_size = tmp_k >> kk;
- gcsharedptbl = mgcsharedhashCreate_I(t_size,0.30);//allocateGCSharedHash_I(20);
- } else {
- gcsharedptbl = NULL;
- }
- BAMBOO_MEMSET_WH(gcrpointertbls, 0,
- sizeof(mgcsharedhashtbl_t *)*NUMCORES4GC);
- //sizeof(struct RuntimeHash *)*NUMCORES4GC);
-#ifdef SMEMM
- gcmem_mixed_threshold = (unsigned int)((BAMBOO_SHARED_MEM_SIZE
- -bamboo_reserved_smem*BAMBOO_SMEM_SIZE)*0.8);
- gcmem_mixed_usedmem = 0;
-#endif
-#ifdef GC_PROFILE
- gc_num_obj = 0;
- gc_num_liveobj = 0;
- gc_num_forwardobj = 0;
- gc_num_profiles = NUMCORESACTIVE - 1;
-#endif
-#ifdef GC_FLUSH_DTLB
- gc_num_flush_dtlb = 0;
-#endif
- gc_localheap_s = false;
-#ifdef GC_CACHE_ADAPT
- gccachestage = false;
- // enable the timer interrupt
- bamboo_tile_timer_set_next_event(500000000); // TODO
- bamboo_unmask_timer_intr();
- //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME());
- bamboo_dtlb_sampling_process();
-#endif // GC_CACHE_ADAPT
-#else
- // create the lock table, lockresult table and obj queue
- locktable.size = 20;
- locktable.bucket =
- (struct RuntimeNode **) RUNMALLOC_I(sizeof(struct RuntimeNode *)*20);
- /* Set allocation blocks*/
- locktable.listhead=NULL;
- locktable.listtail=NULL;
- /*Set data counts*/
- locktable.numelements = 0;
- lockobj = 0;
- lock2require = 0;
- lockresult = 0;
- lockflag = false;
- lockRedirectTbl = allocateRuntimeHash_I(20);
- objRedirectLockTbl = allocateRuntimeHash_I(20);
-#endif
-#ifndef INTERRUPT
- reside = false;
-#endif
- objqueue.head = NULL;
- objqueue.tail = NULL;
-
- currtpd = NULL;
-
-#ifdef PROFILE
- stall = false;
- //isInterrupt = true;
- totalexetime = -1;
- //interrupttime = 0;
- taskInfoIndex = 0;
- taskInfoOverflow = false;
-#ifdef PROFILE_INTERRUPT
- interruptInfoIndex = 0;
- interruptInfoOverflow = false;
-#endif // PROFILE_INTERRUPT
-#endif // PROFILE
-
- for(i = 0; i < MAXTASKPARAMS; i++) {
- runtime_locks[i].redirectlock = 0;
- runtime_locks[i].value = 0;
- }
- runtime_locklen = 0;
-}
-
-inline __attribute__((always_inline))
-void disruntimedata() {
-#ifdef MULTICORE_GC
-#ifdef LOCALHASHTBL_TEST
- freeRuntimeHash(gcpointertbl);
-#else
- mgchashDelete(gcpointertbl);
-#endif
- //freeMGCHash(gcpointertbl);
- freeMGCHash(gcforwardobjtbl);
- // for mapping info structures
- //freeRuntimeHash(gcrcoretbl);
-#else
- freeRuntimeHash(lockRedirectTbl);
- freeRuntimeHash(objRedirectLockTbl);
- RUNFREE(locktable.bucket);
-#endif
- if(activetasks != NULL) {
- genfreehashtable(activetasks);
- }
- if(currtpd != NULL) {
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- currtpd = NULL;
- }
- BAMBOO_LOCAL_MEM_CLOSE();
- BAMBOO_SHARE_MEM_CLOSE();
-}
-
-inline __attribute__((always_inline))
-bool checkObjQueue() {
- bool rflag = false;
- struct transObjInfo * objInfo = NULL;
- int grount = 0;
-
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- bool isChecking = false;
- if(!isEmpty(&objqueue)) {
- profileTaskStart("objqueue checking");
- isChecking = true;
- } // if(!isEmpty(&objqueue))
-#endif
-#endif
-
- while(!isEmpty(&objqueue)) {
- void * obj = NULL;
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
-#ifdef PROFILE
- //isInterrupt = false;
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeee1);
-#endif
- rflag = true;
- objInfo = (struct transObjInfo *)getItem(&objqueue);
- obj = objInfo->objptr;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG((int)obj);
-#endif
- // grab lock and flush the obj
- grount = 0;
- getwritelock_I(obj);
- while(!lockflag) {
- BAMBOO_WAITING_FOR_LOCK(0);
- } // while(!lockflag)
- grount = lockresult;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(grount);
-#endif
-
- lockresult = 0;
- lockobj = 0;
- lock2require = 0;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
-
- if(grount == 1) {
- int k = 0;
- // flush the object
-#ifdef CACHEFLUSH
- BAMBOO_CACHE_FLUSH_RANGE((int)obj,sizeof(int));
- BAMBOO_CACHE_FLUSH_RANGE((int)obj,
- classsize[((struct ___Object___ *)obj)->type]);
-#endif
- // enqueue the object
- for(k = 0; k < objInfo->length; ++k) {
- int taskindex = objInfo->queues[2 * k];
- int paramindex = objInfo->queues[2 * k + 1];
- struct parameterwrapper ** queues =
- &(paramqueues[BAMBOO_NUM_OF_CORE][taskindex][paramindex]);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(taskindex);
- BAMBOO_DEBUGPRINT_REG(paramindex);
- struct ___Object___ * tmpptr = (struct ___Object___ *)obj;
- tprintf("Process %x(%d): receive obj %x(%lld), ptrflag %x\n",
- BAMBOO_NUM_OF_CORE, BAMBOO_NUM_OF_CORE, (int)obj,
- (long)obj, tmpptr->flag);
-#endif
- enqueueObject_I(obj, queues, 1);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(hashsize(activetasks));
-#endif
- } // for(k = 0; k < objInfo->length; ++k)
- releasewritelock_I(obj);
- RUNFREE(objInfo->queues);
- RUNFREE(objInfo);
- } else {
- // can not get lock
- // put it at the end of the queue if no update version in the queue
- struct QueueItem * qitem = getHead(&objqueue);
- struct QueueItem * prev = NULL;
- while(qitem != NULL) {
- struct transObjInfo * tmpinfo =
- (struct transObjInfo *)(qitem->objectptr);
- if(tmpinfo->objptr == obj) {
- // the same object in the queue, which should be enqueued
- // recently. Current one is outdate, do not re-enqueue it
- RUNFREE(objInfo->queues);
- RUNFREE(objInfo);
- goto objqueuebreak;
- } else {
- prev = qitem;
- } // if(tmpinfo->objptr == obj)
- qitem = getNextQueueItem(prev);
- } // while(qitem != NULL)
- // try to execute active tasks already enqueued first
- addNewItem_I(&objqueue, objInfo);
-#ifdef PROFILE
- //isInterrupt = true;
-#endif
-objqueuebreak:
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- break;
- } // if(grount == 1)
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- } // while(!isEmpty(&objqueue))
-
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- if(isChecking) {
- profileTaskEnd();
- } // if(isChecking)
-#endif
-#endif
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee02);
-#endif
- return rflag;
-}
-
-inline __attribute__((always_inline))
-void checkCoreStatus() {
- bool allStall = false;
- int i = 0;
- int sumsendobj = 0;
- if((!waitconfirm) ||
- (waitconfirm && (numconfirm == 0))) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee04);
- BAMBOO_DEBUGPRINT_REG(waitconfirm);
-#endif
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- corestatus[BAMBOO_NUM_OF_CORE] = 0;
- numsendobjs[BAMBOO_NUM_OF_CORE] = self_numsendobjs;
- numreceiveobjs[BAMBOO_NUM_OF_CORE] = self_numreceiveobjs;
- // check the status of all cores
- allStall = true;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
-#endif
- for(i = 0; i < NUMCORESACTIVE; ++i) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe000 + corestatus[i]);
-#endif
- if(corestatus[i] != 0) {
- allStall = false;
- break;
- }
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
- if(allStall) {
- // 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
- sumsendobj = 0;
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj += numsendobjs[i];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000 + numsendobjs[i]);
-#endif
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
- for(i = 0; i < NUMCORESACTIVE; ++i) {
- sumsendobj -= numreceiveobjs[i];
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000 + numreceiveobjs[i]);
-#endif
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
- if(0 == sumsendobj) {
- if(!waitconfirm) {
- // the first time found all cores stall
- // send out status confirm msg to all other cores
- // reset the corestatus array too
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee05);
-#endif
- corestatus[BAMBOO_NUM_OF_CORE] = 1;
- waitconfirm = true;
- numconfirm = NUMCORESACTIVE - 1;
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- for(i = 1; i < NUMCORESACTIVE; ++i) {
- corestatus[i] = 1;
- // send status confirm msg to core i
- send_msg_1(i, STATUSCONFIRM, false);
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
- return;
- } else {
- // all the core status info are the latest
- // terminate; for profiling mode, send request to all
- // other cores to pour out profiling data
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee06);
-#endif
-
-#ifdef USEIO
- totalexetime = BAMBOO_GET_EXE_TIME() - bamboo_start_time;
-#else
-#ifdef PROFILE
- //BAMBOO_DEBUGPRINT_REG(interrupttime);
-#endif
-
- BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME() - bamboo_start_time);
- //BAMBOO_DEBUGPRINT_REG(total_num_t6); // TODO for test
-#ifdef GC_FLUSH_DTLB
- BAMBOO_DEBUGPRINT_REG(gc_num_flush_dtlb);
-#endif
-#ifndef BAMBOO_MEMPROF
- BAMBOO_DEBUGPRINT(0xbbbbbbbb);
-#endif
-#endif
- // profile mode, send msgs to other cores to request pouring
- // out progiling data
-#ifdef PROFILE
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- for(i = 1; i < NUMCORESACTIVE; ++i) {
- // send profile request msg to core i
- send_msg_2(i, PROFILEOUTPUT, totalexetime, false);
- } // for(i = 1; i < NUMCORESACTIVE; ++i)
-#ifndef RT_TEST
- // pour profiling data on startup core
- outputProfileData();
-#endif
- while(true) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- profilestatus[BAMBOO_NUM_OF_CORE] = 0;
- // check the status of all cores
- allStall = true;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(NUMCORESACTIVE);
-#endif
- for(i = 0; i < NUMCORESACTIVE; ++i) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe000 + profilestatus[i]);
-#endif
- if(profilestatus[i] != 0) {
- allStall = false;
- break;
- }
- } // for(i = 0; i < NUMCORESACTIVE; ++i)
- if(!allStall) {
- int halt = 100;
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- while(halt--) {
- }
- } else {
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- break;
- } // if(!allStall)
- } // while(true)
-#endif
-
- // gc_profile mode, output gc prfiling data
-#ifdef MULTICORE_GC
-#ifdef GC_CACHE_ADAPT
- bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
-#endif // GC_CACHE_ADAPT
-#ifdef GC_PROFILE
- gc_outputProfileData();
-#endif // #ifdef GC_PROFILE
-#endif // #ifdef MULTICORE_GC
- disruntimedata();
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
- terminate(); // All done.
- } // if(!waitconfirm)
- } else {
- // still some objects on the fly on the network
- // reset the waitconfirm and numconfirm
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee07);
-#endif
- waitconfirm = false;
- numconfirm = 0;
- } // if(0 == sumsendobj)
- } else {
- // not all cores are stall, keep on waiting
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee08);
-#endif
- waitconfirm = false;
- numconfirm = 0;
- } // if(allStall)
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- } // if((!waitconfirm) ||
-}
-
-// main function for each core
-inline void run(void * arg) {
- int i = 0;
- int argc = 1;
- char ** argv = NULL;
- bool sendStall = false;
- bool isfirst = true;
- bool tocontinue = false;
-
- corenum = BAMBOO_GET_NUM_OF_CORE();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xeeee);
- BAMBOO_DEBUGPRINT_REG(corenum);
- BAMBOO_DEBUGPRINT(STARTUPCORE);
-#endif
- //BAMBOO_DEBUGPRINT(BAMBOO_GET_EXE_TIME()); // TODO
-
- // initialize runtime data structures
- initruntimedata();
-
- // other architecture related initialization
- initialization();
- initCommunication();
-
- initializeexithandler();
-
- // main process of the execution module
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
- // non-executing cores, only processing communications
- activetasks = NULL;
-#ifdef PROFILE
- //isInterrupt = false;
-#endif
- fakeExecution();
- } else {
- /* Create queue of active tasks */
- activetasks=
- genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
- (int (*)(void *,void *)) &comparetpd);
-
- /* Process task information */
- processtasks();
-
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- /* Create startup object */
- createstartupobject(argc, argv);
- }
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee00);
-#endif
-
- while(true) {
-
-#ifdef MULTICORE_GC
-//#ifdef GC_CACHE_ADAPT
- // do dtlb sampling if necessary
-// bamboo_dtlb_sampling_process();
-//#endif // GC_CACHE_ADAPT
- // check if need to do GC
- if(gcflag) {
- gc(NULL);
- }
-#endif // MULTICORE_GC
-
- // check if there are new active tasks can be executed
- executetasks();
- if(busystatus) {
- sendStall = false;
- }
-
-#ifndef INTERRUPT
- while(receiveObject() != -1) {
- }
-#endif
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee01);
-#endif
-
- // check if there are some pending objects,
- // if yes, enqueue them and executetasks again
- tocontinue = checkObjQueue();
-
- if(!tocontinue) {
- // check if stop
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- if(isfirst) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee03);
-#endif
- isfirst = false;
- }
- checkCoreStatus();
- } else {
- if(!sendStall) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee09);
-#endif
-#ifdef PROFILE
- if(!stall) {
-#endif
- if(isfirst) {
- // wait for some time
- int halt = 10000;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee0a);
-#endif
- while(halt--) {
- }
- isfirst = false;
- } else {
- // send StallMsg to startup core
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee0b);
-#endif
- // send stall msg
- send_msg_4(STARTUPCORE, TRANSTALL, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs, false);
- sendStall = true;
- isfirst = true;
- busystatus = false;
- }
-#ifdef PROFILE
- }
-#endif
- } else {
- isfirst = true;
- busystatus = false;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xee0c);
-#endif
- } // if(!sendStall)
- } // if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
- } // if(!tocontinue)
- } // while(true)
- } // if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)
-
-} // run()
-
-struct ___createstartupobject____I_locals {
- INTPTR size;
- void * next;
- struct ___StartupObject___ * ___startupobject___;
- struct ArrayObject * ___stringarray___;
-}; // struct ___createstartupobject____I_locals
-
-void createstartupobject(int argc,
- char ** argv) {
- int i;
-
- /* Allocate startup object */
-#ifdef MULTICORE_GC
- struct ___createstartupobject____I_locals ___locals___ =
- {2, NULL, NULL, NULL};
- struct ___StartupObject___ *startupobject=
- (struct ___StartupObject___*) allocate_new(&___locals___, STARTUPTYPE);
- ___locals___.___startupobject___ = startupobject;
- struct ArrayObject * stringarray=
- allocate_newarray(&___locals___, STRINGARRAYTYPE, argc-1);
- ___locals___.___stringarray___ = stringarray;
-#else
- struct ___StartupObject___ *startupobject=
- (struct ___StartupObject___*) allocate_new(STARTUPTYPE);
- struct ArrayObject * stringarray=
- allocate_newarray(STRINGARRAYTYPE, argc-1);
-#endif
- /* Build array of strings */
- startupobject->___parameters___=stringarray;
- for(i=1; i<argc; i++) {
- int length=strlen(argv[i]);
-#ifdef MULTICORE_GC
- struct ___String___ *newstring=NewString(&___locals___, argv[i],length);
-#else
- struct ___String___ *newstring=NewString(argv[i],length);
-#endif
- ((void **)(((char *)&stringarray->___length___)+sizeof(int)))[i-1]=
- newstring;
- }
-
- startupobject->version = 0;
- startupobject->lock = NULL;
-
- /* Set initialized flag for startup object */
- flagorandinit(startupobject,1,0xFFFFFFFF);
- enqueueObject(startupobject, NULL, 0);
-#ifdef CACHEFLUSH
- BAMBOO_CACHE_FLUSH_ALL();
-#endif
-}
-
-int hashCodetpd(struct taskparamdescriptor *ftd) {
- int hash=(int)ftd->task;
- int i;
- for(i=0; i<ftd->numParameters; i++) {
- hash^=(int)ftd->parameterArray[i];
- }
- return hash;
-}
-
-int comparetpd(struct taskparamdescriptor *ftd1,
- struct taskparamdescriptor *ftd2) {
- int i;
- if (ftd1->task!=ftd2->task)
- return 0;
- for(i=0; i<ftd1->numParameters; i++)
- if(ftd1->parameterArray[i]!=ftd2->parameterArray[i])
- return 0;
- return 1;
-}
-
-/* This function sets a tag. */
-#ifdef MULTICORE_GC
-void tagset(void *ptr,
- struct ___Object___ * obj,
- struct ___TagDescriptor___ * tagd) {
-#else
-void tagset(struct ___Object___ * obj,
- struct ___TagDescriptor___ * tagd) {
-#endif
- struct ArrayObject * ao=NULL;
- struct ___Object___ * tagptr=obj->___tags___;
- if (tagptr==NULL) {
- obj->___tags___=(struct ___Object___ *)tagd;
- } else {
- /* Have to check if it is already set */
- if (tagptr->type==TAGTYPE) {
- struct ___TagDescriptor___ * td=(struct ___TagDescriptor___ *) tagptr;
- if (td==tagd) {
- return;
- }
-#ifdef MULTICORE_GC
- int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
- struct ArrayObject * ao=
- allocate_newarray(&ptrarray,TAGARRAYTYPE,TAGARRAYINTERVAL);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *)ptrarray[3];
- td=(struct ___TagDescriptor___ *) obj->___tags___;
-#else
- ao=allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL);
-#endif
-
- ARRAYSET(ao, struct ___TagDescriptor___ *, 0, td);
- ARRAYSET(ao, struct ___TagDescriptor___ *, 1, tagd);
- obj->___tags___=(struct ___Object___ *) ao;
- ao->___cachedCode___=2;
- } else {
- /* Array Case */
- int i;
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- for(i=0; i<ao->___cachedCode___; i++) {
- struct ___TagDescriptor___ * td=
- ARRAYGET(ao, struct ___TagDescriptor___*, i);
- if (td==tagd) {
- return;
- }
- }
- if (ao->___cachedCode___<ao->___length___) {
- ARRAYSET(ao, struct ___TagDescriptor___ *,ao->___cachedCode___,tagd);
- ao->___cachedCode___++;
- } else {
-#ifdef MULTICORE_GC
- int ptrarray[]={2,(int) ptr, (int) obj, (int) tagd};
- struct ArrayObject * aonew=
- allocate_newarray(&ptrarray,TAGARRAYTYPE,
- TAGARRAYINTERVAL+ao->___length___);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *) ptrarray[3];
- ao=(struct ArrayObject *)obj->___tags___;
-#else
- struct ArrayObject * aonew=
- allocate_newarray(TAGARRAYTYPE,TAGARRAYINTERVAL+ao->___length___);
-#endif
-
- aonew->___cachedCode___=ao->___length___+1;
- for(i=0; i<ao->___length___; i++) {
- ARRAYSET(aonew, struct ___TagDescriptor___*, i,
- ARRAYGET(ao, struct ___TagDescriptor___*, i));
- }
- ARRAYSET(aonew, struct ___TagDescriptor___ *, ao->___length___,tagd);
- }
- }
- }
-
- {
- struct ___Object___ * tagset=tagd->flagptr;
- if(tagset==NULL) {
- tagd->flagptr=obj;
- } else if (tagset->type!=OBJECTARRAYTYPE) {
-#ifdef MULTICORE_GC
- int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
- struct ArrayObject * ao=
- allocate_newarray(&ptrarray,OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *)ptrarray[3];
-#else
- struct ArrayObject * ao=
- allocate_newarray(OBJECTARRAYTYPE,OBJECTARRAYINTERVAL);
-#endif
- ARRAYSET(ao, struct ___Object___ *, 0, tagd->flagptr);
- ARRAYSET(ao, struct ___Object___ *, 1, obj);
- ao->___cachedCode___=2;
- tagd->flagptr=(struct ___Object___ *)ao;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagset;
- if (ao->___cachedCode___<ao->___length___) {
- ARRAYSET(ao, struct ___Object___*, ao->___cachedCode___++, obj);
- } else {
- int i;
-#ifdef MULTICORE_GC
- int ptrarray[]={2, (int) ptr, (int) obj, (int)tagd};
- struct ArrayObject * aonew=
- allocate_newarray(&ptrarray,OBJECTARRAYTYPE,
- OBJECTARRAYINTERVAL+ao->___length___);
- obj=(struct ___Object___ *)ptrarray[2];
- tagd=(struct ___TagDescriptor___ *)ptrarray[3];
- ao=(struct ArrayObject *)tagd->flagptr;
-#else
- struct ArrayObject * aonew=allocate_newarray(OBJECTARRAYTYPE,
- OBJECTARRAYINTERVAL+ao->___length___);
-#endif
- aonew->___cachedCode___=ao->___cachedCode___+1;
- for(i=0; i<ao->___length___; i++) {
- ARRAYSET(aonew, struct ___Object___*, i,
- ARRAYGET(ao, struct ___Object___*, i));
- }
- ARRAYSET(aonew, struct ___Object___ *, ao->___cachedCode___, obj);
- tagd->flagptr=(struct ___Object___ *) aonew;
- }
- }
- }
-}
-
-/* This function clears a tag. */
-#ifdef MULTICORE_GC
-void tagclear(void *ptr,
- struct ___Object___ * obj,
- struct ___TagDescriptor___ * tagd) {
-#else
-void tagclear(struct ___Object___ * obj,
- struct ___TagDescriptor___ * tagd) {
-#endif
- /* We'll assume that tag is alway there.
- Need to statically check for this of course. */
- struct ___Object___ * tagptr=obj->___tags___;
-
- if (tagptr->type==TAGTYPE) {
- if ((struct ___TagDescriptor___ *)tagptr==tagd)
- obj->___tags___=NULL;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- int i;
- for(i=0; i<ao->___cachedCode___; i++) {
- struct ___TagDescriptor___ * td=
- ARRAYGET(ao, struct ___TagDescriptor___ *, i);
- if (td==tagd) {
- ao->___cachedCode___--;
- if (i<ao->___cachedCode___)
- ARRAYSET(ao, struct ___TagDescriptor___ *, i,
- ARRAYGET(ao,struct ___TagDescriptor___*,ao->___cachedCode___));
- ARRAYSET(ao,struct ___TagDescriptor___ *,ao->___cachedCode___, NULL);
- if (ao->___cachedCode___==0)
- obj->___tags___=NULL;
- goto PROCESSCLEAR;
- }
- }
- }
-PROCESSCLEAR:
- {
- struct ___Object___ *tagset=tagd->flagptr;
- if (tagset->type!=OBJECTARRAYTYPE) {
- if (tagset==obj)
- tagd->flagptr=NULL;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagset;
- int i;
- for(i=0; i<ao->___cachedCode___; i++) {
- struct ___Object___ * tobj=ARRAYGET(ao, struct ___Object___ *, i);
- if (tobj==obj) {
- ao->___cachedCode___--;
- if (i<ao->___cachedCode___)
- ARRAYSET(ao, struct ___Object___ *, i,
- ARRAYGET(ao, struct ___Object___ *, ao->___cachedCode___));
- ARRAYSET(ao, struct ___Object___ *, ao->___cachedCode___, NULL);
- if (ao->___cachedCode___==0)
- tagd->flagptr=NULL;
- goto ENDCLEAR;
- }
- }
- }
- }
-ENDCLEAR:
- return;
-}
-
-/* This function allocates a new tag. */
-#ifdef MULTICORE_GC
-struct ___TagDescriptor___ * allocate_tag(void *ptr,
- int index) {
- struct ___TagDescriptor___ * v=
- (struct ___TagDescriptor___ *) FREEMALLOC((struct garbagelist *) ptr,
- classsize[TAGTYPE]);
-#else
-struct ___TagDescriptor___ * allocate_tag(int index) {
- struct ___TagDescriptor___ * v=FREEMALLOC(classsize[TAGTYPE]);
-#endif
- v->type=TAGTYPE;
- v->flag=index;
- return v;
-}
-
-
-
-/* This function updates the flag for object ptr. It or's the flag
- with the or mask and and's it with the andmask. */
-
-void flagbody(struct ___Object___ *ptr,
- int flag,
- struct parameterwrapper ** queues,
- int length,
- bool isnew);
-
-int flagcomp(const int *val1, const int *val2) {
- return (*val1)-(*val2);
-}
-
-void flagorand(void * ptr,
- int ormask,
- int andmask,
- struct parameterwrapper ** queues,
- int length) {
- {
- int oldflag=((int *)ptr)[1];
- int flag=ormask|oldflag;
- flag&=andmask;
- flagbody(ptr, flag, queues, length, false);
- }
-}
-
-bool intflagorand(void * ptr,
- int ormask,
- int andmask) {
- {
- int oldflag=((int *)ptr)[1];
- int flag=ormask|oldflag;
- flag&=andmask;
- if (flag==oldflag) /* Don't do anything */
- return false;
- else {
- flagbody(ptr, flag, NULL, 0, false);
- return true;
- }
- }
-}
-
-void flagorandinit(void * ptr,
- int ormask,
- int andmask) {
- int oldflag=((int *)ptr)[1];
- int flag=ormask|oldflag;
- flag&=andmask;
- flagbody(ptr,flag,NULL,0,true);
-}
-
-void flagbody(struct ___Object___ *ptr,
- int flag,
- struct parameterwrapper ** vqueues,
- int vlength,
- bool isnew) {
- struct parameterwrapper * flagptr = NULL;
- int i = 0;
- struct parameterwrapper ** queues = vqueues;
- int length = vlength;
- int next;
- int UNUSED, UNUSED2;
- int * enterflags = NULL;
- if((!isnew) && (queues == NULL)) {
- if(BAMBOO_NUM_OF_CORE < NUMCORESACTIVE) {
- queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
- length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
- } else {
- return;
- }
- }
- ptr->flag=flag;
-
- /*Remove object from all queues */
- for(i = 0; i < length; ++i) {
- flagptr = queues[i];
- ObjectHashget(flagptr->objectset, (int) ptr, (int *) &next,
- (int *) &enterflags, &UNUSED, &UNUSED2);
- ObjectHashremove(flagptr->objectset, (int)ptr);
- if (enterflags!=NULL)
- RUNFREE(enterflags);
- }
-}
-
-void enqueueObject(void * vptr,
- struct parameterwrapper ** vqueues,
- int vlength) {
- struct ___Object___ *ptr = (struct ___Object___ *)vptr;
-
- {
- //struct QueueItem *tmpptr;
- struct parameterwrapper * parameter=NULL;
- int j;
- int i;
- struct parameterwrapper * prevptr=NULL;
- struct ___Object___ *tagptr=NULL;
- struct parameterwrapper ** queues = vqueues;
- int length = vlength;
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
- return;
- }
- if(queues == NULL) {
- queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
- length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
- }
- tagptr=ptr->___tags___;
-
- /* Outer loop iterates through all parameter queues an object of
- this type could be in. */
- for(j = 0; j < length; ++j) {
- parameter = queues[j];
- /* Check tags */
- if (parameter->numbertags>0) {
- if (tagptr==NULL)
- goto nextloop; //that means the object has no tag
- //but that param needs tag
- else if(tagptr->type==TAGTYPE) { //one tag
- //struct ___TagDescriptor___ * tag=
- //(struct ___TagDescriptor___*) tagptr;
- for(i=0; i<parameter->numbertags; i++) {
- //slotid is parameter->tagarray[2*i];
- int tagid=parameter->tagarray[2*i+1];
- if (tagid!=tagptr->flag)
- goto nextloop; /*We don't have this tag */
- }
- } else { //multiple tags
- struct ArrayObject * ao=(struct ArrayObject *) tagptr;
- for(i=0; i<parameter->numbertags; i++) {
- //slotid is parameter->tagarray[2*i];
- int tagid=parameter->tagarray[2*i+1];
- int j;
- for(j=0; j<ao->___cachedCode___; j++) {
- if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
- goto foundtag;
- }
- goto nextloop;
-foundtag:
- ;
- }
- }
- }
-
- /* Check flags */
- for(i=0; i<parameter->numberofterms; i++) {
- int andmask=parameter->intarray[i*2];
- int checkmask=parameter->intarray[i*2+1];
- if ((ptr->flag&andmask)==checkmask) {
- enqueuetasks(parameter, prevptr, ptr, NULL, 0);
- prevptr=parameter;
- break;
- }
- }
-nextloop:
- ;
- }
- }
-}
-
-void enqueueObject_I(void * vptr,
- struct parameterwrapper ** vqueues,
- int vlength) {
- struct ___Object___ *ptr = (struct ___Object___ *)vptr;
-
- {
- //struct QueueItem *tmpptr;
- struct parameterwrapper * parameter=NULL;
- int j;
- int i;
- struct parameterwrapper * prevptr=NULL;
- struct ___Object___ *tagptr=NULL;
- struct parameterwrapper ** queues = vqueues;
- int length = vlength;
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
- return;
- }
- if(queues == NULL) {
- queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
- length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
- }
- tagptr=ptr->___tags___;
-
- /* Outer loop iterates through all parameter queues an object of
- this type could be in. */
- for(j = 0; j < length; ++j) {
- parameter = queues[j];
- /* Check tags */
- if (parameter->numbertags>0) {
- if (tagptr==NULL)
- goto nextloop; //that means the object has no tag
- //but that param needs tag
- else if(tagptr->type==TAGTYPE) { //one tag
- //struct ___TagDescriptor___*tag=(struct ___TagDescriptor___*)tagptr;
- for(i=0; i<parameter->numbertags; i++) {
- //slotid is parameter->tagarray[2*i];
- int tagid=parameter->tagarray[2*i+1];
- if (tagid!=tagptr->flag)
- goto nextloop; /*We don't have this tag */
- }
- } else { //multiple tags
- struct ArrayObject * ao=(struct ArrayObject *) tagptr;
- for(i=0; i<parameter->numbertags; i++) {
- //slotid is parameter->tagarray[2*i];
- int tagid=parameter->tagarray[2*i+1];
- int j;
- for(j=0; j<ao->___cachedCode___; j++) {
- if (tagid==ARRAYGET(ao, struct ___TagDescriptor___*, j)->flag)
- goto foundtag;
- }
- goto nextloop;
-foundtag:
- ;
- }
- }
- }
-
- /* Check flags */
- for(i=0; i<parameter->numberofterms; i++) {
- int andmask=parameter->intarray[i*2];
- int checkmask=parameter->intarray[i*2+1];
- if ((ptr->flag&andmask)==checkmask) {
- enqueuetasks_I(parameter, prevptr, ptr, NULL, 0);
- prevptr=parameter;
- break;
- }
- }
-nextloop:
- ;
- }
- }
-}
-
-
-int * getAliasLock(void ** ptrs,
- int length,
- struct RuntimeHash * tbl) {
- if(length == 0) {
- return (int*)(RUNMALLOC(sizeof(int)));
- } else {
- int i = 0;
- int locks[length];
- int locklen = 0;
- bool redirect = false;
- int redirectlock = 0;
- for(; i < length; i++) {
- struct ___Object___ * ptr = (struct ___Object___ *)(ptrs[i]);
- int lock = 0;
- int j = 0;
- if(ptr->lock == NULL) {
- lock = (int)(ptr);
- } else {
- lock = (int)(ptr->lock);
- }
- if(redirect) {
- if(lock != redirectlock) {
- RuntimeHashadd(tbl, lock, redirectlock);
- }
- } else {
- if(RuntimeHashcontainskey(tbl, lock)) {
- // already redirected
- redirect = true;
- RuntimeHashget(tbl, lock, &redirectlock);
- for(; j < locklen; j++) {
- if(locks[j] != redirectlock) {
- RuntimeHashadd(tbl, locks[j], redirectlock);
- }
- }
- } else {
- bool insert = true;
- for(j = 0; j < locklen; j++) {
- if(locks[j] == lock) {
- insert = false;
- break;
- } else if(locks[j] > lock) {
- break;
- }
- }
- if(insert) {
- int h = locklen;
- for(; h > j; h--) {
- locks[h] = locks[h-1];
- }
- locks[j] = lock;
- locklen++;
- }
- }
- }
- }
- if(redirect) {
- return (int *)redirectlock;
- } else {
- return (int *)(locks[0]);
- }
- }
-}
-
-void addAliasLock(void * ptr,
- int lock) {
- struct ___Object___ * obj = (struct ___Object___ *)ptr;
- if(((int)ptr != lock) && (obj->lock != (int*)lock)) {
- // originally no alias lock associated or have a different alias lock
- // flush it as the new one
- obj->lock = (int *)lock;
- }
-}
-
-#ifdef PROFILE
-inline void setTaskExitIndex(int index) {
- taskInfoArray[taskInfoIndex]->exitIndex = index;
-}
-
-inline void addNewObjInfo(void * nobj) {
- if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
- taskInfoArray[taskInfoIndex]->newObjs = createQueue();
- }
- addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
-}
-#endif
-
-#ifdef MULTICORE_GC
-// Only allocate local mem chunks to each core.
-// If a core has used up its local shared memory, start gc.
-void * localmalloc_I(int coren,
- int isize,
- int * allocsize) {
- void * mem = NULL;
- int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
- int i = 0;
- int j = 0;
- int tofindb = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
- int totest = tofindb;
- int bound = BAMBOO_SMEM_SIZE_L;
- int foundsmem = 0;
- int size = 0;
- do {
- bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- int nsize = bamboo_smemtbl[totest];
- bool islocal = true;
- if(nsize < bound) {
- bool tocheck = true;
- // have some space in the block
- if(totest == tofindb) {
- // the first partition
- size = bound - nsize;
- } else if(nsize == 0) {
- // an empty partition, can be appended
- size += bound;
- } else {
- // not an empty partition, can not be appended
- // the last continuous block is not big enough, go to check the next
- // local block
- islocal = true;
- tocheck = false;
- } // if(totest == tofindb) else if(nsize == 0) else ...
- if(tocheck) {
- if(size >= isize) {
- // have enough space in the block, malloc
- foundsmem = 1;
- break;
- } else {
- // no enough space yet, try to append next continuous block
- islocal = false;
- } // if(size > isize) else ...
- } // if(tocheck)
- } // if(nsize < bound)
- if(islocal) {
- // no space in the block, go to check the next block
- i++;
- if(2==i) {
- i = 0;
- j++;
- }
- tofindb = totest = gc_core2block[2*gccorenum+i]+(NUMCORES4GC*2)*j;
- } else {
- totest += 1;
- } // if(islocal) else ...
- if(totest > gcnumblock-1-bamboo_reserved_smem) {
- // no more local mem, do not find suitable block
- foundsmem = 2;
- break;
- } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
- } while(true);
-
- if(foundsmem == 1) {
- // find suitable block
- mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
- (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
- (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
- *allocsize = size;
- // set bamboo_smemtbl
- for(i = tofindb; i <= totest; i++) {
- bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
- }
- } else if(foundsmem == 2) {
- // no suitable block
- *allocsize = 0;
- }
-
- return mem;
-} // void * localmalloc_I(int, int, int *)
-
-#ifdef SMEMF
-// Allocate the local shared memory to each core with the highest priority,
-// if a core has used up its local shared memory, try to allocate the
-// shared memory that belong to its neighbours, if also failed, start gc.
-void * fixedmalloc_I(int coren,
- int isize,
- int * allocsize) {
- void * mem = NULL;
- int i = 0;
- int j = 0;
- int k = 0;
- int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
- int coords_x = bamboo_cpu2coords[gccorenum*2];
- int coords_y = bamboo_cpu2coords[gccorenum*2+1];
- int ii = 1;
- int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
- int totest = tofindb;
- int bound = BAMBOO_SMEM_SIZE_L;
- int foundsmem = 0;
- int size = 0;
- do {
- bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- int nsize = bamboo_smemtbl[totest];
- bool islocal = true;
- if(nsize < bound) {
- bool tocheck = true;
- // have some space in the block
- if(totest == tofindb) {
- // the first partition
- size = bound - nsize;
- } else if(nsize == 0) {
- // an empty partition, can be appended
- size += bound;
- } else {
- // not an empty partition, can not be appended
- // the last continuous block is not big enough, go to check the next
- // local block
- islocal = true;
- tocheck = false;
- } // if(totest == tofindb) else if(nsize == 0) else ...
- if(tocheck) {
- if(size >= isize) {
- // have enough space in the block, malloc
- foundsmem = 1;
- break;
- } else {
- // no enough space yet, try to append next continuous block
- // TODO may consider to go to next local block?
- islocal = false;
- } // if(size > isize) else ...
- } // if(tocheck)
- } // if(nsize < bound)
- if(islocal) {
- // no space in the block, go to check the next block
- i++;
- if(2==i) {
- i = 0;
- j++;
- }
- tofindb=totest=
- gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
- } else {
- totest += 1;
- } // if(islocal) else ...
- if(totest > gcnumblock-1-bamboo_reserved_smem) {
- // no more local mem, do not find suitable block on local mem
- // try to malloc shared memory assigned to the neighbour cores
- do{
- k++;
- if(k >= NUM_CORES2TEST) {
- // no more memory available on either coren or its neighbour cores
- foundsmem = 2;
- goto memsearchresult;
- }
- } while(core2test[gccorenum][k] == -1);
- i = 0;
- j = 0;
- tofindb=totest=
- gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
- } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
- } while(true);
-
-memsearchresult:
- if(foundsmem == 1) {
- // find suitable block
- mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
- (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
- (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
- *allocsize = size;
- // set bamboo_smemtbl
- for(i = tofindb; i <= totest; i++) {
- bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
- }
- } else if(foundsmem == 2) {
- // no suitable block
- *allocsize = 0;
- }
-
- return mem;
-} // void * fixedmalloc_I(int, int, int *)
-#endif // #ifdef SMEMF
-
-#ifdef SMEMM
-// Allocate the local shared memory to each core with the highest priority,
-// if a core has used up its local shared memory, try to allocate the
-// shared memory that belong to its neighbours first, if failed, check
-// current memory allocation rate, if it has already reached the threshold,
-// start gc, otherwise, allocate the shared memory globally. If all the
-// shared memory has been used up, start gc.
-void * mixedmalloc_I(int coren,
- int isize,
- int * allocsize) {
- void * mem = NULL;
- int i = 0;
- int j = 0;
- int k = 0;
- int gccorenum = (coren < NUMCORES4GC) ? (coren) : (coren % NUMCORES4GC);
- int ii = 1;
- int tofindb = gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
- int totest = tofindb;
- int bound = BAMBOO_SMEM_SIZE_L;
- int foundsmem = 0;
- int size = 0;
- do {
- bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- int nsize = bamboo_smemtbl[totest];
- bool islocal = true;
- if(nsize < bound) {
- bool tocheck = true;
- // have some space in the block
- if(totest == tofindb) {
- // the first partition
- size = bound - nsize;
- } else if(nsize == 0) {
- // an empty partition, can be appended
- size += bound;
- } else {
- // not an empty partition, can not be appended
- // the last continuous block is not big enough, go to check the next
- // local block
- islocal = true;
- tocheck = false;
- } // if(totest == tofindb) else if(nsize == 0) else ...
- if(tocheck) {
- if(size >= isize) {
- // have enough space in the block, malloc
- foundsmem = 1;
- break;
- } else {
- // no enough space yet, try to append next continuous block
- // TODO may consider to go to next local block?
- islocal = false;
- } // if(size > isize) else ...
- } // if(tocheck)
- } // if(nsize < bound)
- if(islocal) {
- // no space in the block, go to check the next block
- i++;
- if(2==i) {
- i = 0;
- j++;
- }
- tofindb=totest=
- gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
- } else {
- totest += 1;
- } // if(islocal) else ...
- if(totest > gcnumblock-1-bamboo_reserved_smem) {
- // no more local mem, do not find suitable block on local mem
- // try to malloc shared memory assigned to the neighbour cores
- do{
- k++;
- if(k >= NUM_CORES2TEST) {
- if(gcmem_mixed_usedmem >= gcmem_mixed_threshold) {
- // no more memory available on either coren or its neighbour cores
- foundsmem = 2;
- goto memmixedsearchresult;
- } else {
- // try allocate globally
- mem = globalmalloc_I(coren, isize, allocsize);
- return mem;
- }
- }
- } while(core2test[gccorenum][k] == -1);
- i = 0;
- j = 0;
- tofindb=totest=
- gc_core2block[2*core2test[gccorenum][k]+i]+(NUMCORES4GC*2)*j;
- } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
- } while(true);
-
-memmixedsearchresult:
- if(foundsmem == 1) {
- // find suitable block
- mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
- (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
- (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
- *allocsize = size;
- // set bamboo_smemtbl
- for(i = tofindb; i <= totest; i++) {
- bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
- }
- gcmem_mixed_usedmem += size;
- if(tofindb == bamboo_free_block) {
- bamboo_free_block = totest+1;
- }
- } else if(foundsmem == 2) {
- // no suitable block
- *allocsize = 0;
- }
-
- return mem;
-} // void * mixedmalloc_I(int, int, int *)
-#endif // #ifdef SMEMM
-
-// Allocate all the memory chunks globally, do not consider the host cores
-// When all the shared memory are used up, start gc.
-void * globalmalloc_I(int coren,
- int isize,
- int * allocsize) {
- void * mem = NULL;
- int tofindb = bamboo_free_block; //0;
- int totest = tofindb;
- int bound = BAMBOO_SMEM_SIZE_L;
- int foundsmem = 0;
- int size = 0;
- if(tofindb > gcnumblock-1-bamboo_reserved_smem) {
- // Out of shared memory
- *allocsize = 0;
- return NULL;
- }
- do {
- bound = (totest < NUMCORES4GC) ? BAMBOO_SMEM_SIZE_L : BAMBOO_SMEM_SIZE;
- int nsize = bamboo_smemtbl[totest];
- bool isnext = false;
- if(nsize < bound) {
- bool tocheck = true;
- // have some space in the block
- if(totest == tofindb) {
- // the first partition
- size = bound - nsize;
- } else if(nsize == 0) {
- // an empty partition, can be appended
- size += bound;
- } else {
- // not an empty partition, can not be appended
- // the last continuous block is not big enough, start another block
- isnext = true;
- tocheck = false;
- } // if(totest == tofindb) else if(nsize == 0) else ...
- if(tocheck) {
- if(size >= isize) {
- // have enough space in the block, malloc
- foundsmem = 1;
- break;
- } // if(size > isize)
- } // if(tocheck)
- } else {
- isnext = true;
- } // if(nsize < bound) else ...
- totest += 1;
- if(totest > gcnumblock-1-bamboo_reserved_smem) {
- // no more local mem, do not find suitable block
- foundsmem = 2;
- break;
- } // if(totest > gcnumblock-1-bamboo_reserved_smem) ...
- if(isnext) {
- // start another block
- tofindb = totest;
- } // if(islocal)
- } while(true);
-
- if(foundsmem == 1) {
- // find suitable block
- mem = gcbaseva+bamboo_smemtbl[tofindb]+((tofindb<NUMCORES4GC) ?
- (BAMBOO_SMEM_SIZE_L*tofindb) : (BAMBOO_LARGE_SMEM_BOUND+
- (tofindb-NUMCORES4GC)*BAMBOO_SMEM_SIZE));
- *allocsize = size;
- // set bamboo_smemtbl
- for(int i = tofindb; i <= totest; i++) {
- bamboo_smemtbl[i]=(i<NUMCORES4GC)?BAMBOO_SMEM_SIZE_L:BAMBOO_SMEM_SIZE;
- }
- if(tofindb == bamboo_free_block) {
- bamboo_free_block = totest+1;
- }
- } else if(foundsmem == 2) {
- // no suitable block
- *allocsize = 0;
- mem = NULL;
- }
-
- return mem;
-} // void * globalmalloc_I(int, int, int *)
-#endif // #ifdef MULTICORE_GC
-
-// malloc from the shared memory
-void * smemalloc_I(int coren,
- int size,
- int * allocsize) {
- void * mem = NULL;
-#ifdef MULTICORE_GC
- int isize = size+(BAMBOO_CACHE_LINE_SIZE);
-
- // go through the bamboo_smemtbl for suitable partitions
- switch(bamboo_smem_mode) {
- case SMEMLOCAL: {
- mem = localmalloc_I(coren, isize, allocsize);
- break;
- }
-
- case SMEMFIXED: {
-#ifdef SMEMF
- mem = fixedmalloc_I(coren, isize, allocsize);
-#else
- // not supported yet
- BAMBOO_EXIT(0xe001);
-#endif
- break;
- }
-
- case SMEMMIXED: {
-#ifdef SMEMM
- mem = mixedmalloc_I(coren, isize, allocsize);
-#else
- // not supported yet
- BAMBOO_EXIT(0xe002);
-#endif
- break;
- }
-
- case SMEMGLOBAL: {
- mem = globalmalloc_I(coren, isize, allocsize);
- break;
- }
-
- default:
- break;
- }
-
- if(mem == NULL) {
-#else
- int toallocate = (size>(BAMBOO_SMEM_SIZE)) ? (size) : (BAMBOO_SMEM_SIZE);
- if(toallocate > bamboo_free_smem_size) {
- // no enough mem
- mem = NULL;
- } else {
- mem = (void *)bamboo_free_smemp;
- bamboo_free_smemp = ((void*)bamboo_free_smemp) + toallocate;
- bamboo_free_smem_size -= toallocate;
- }
- *allocsize = toallocate;
- if(mem == NULL) {
-#endif // MULTICORE_GC
- // no enough shared global memory
- *allocsize = 0;
-#ifdef MULTICORE_GC
- if(!gcflag) {
- gcflag = true;
- // inform other cores to stop and wait for gc
- gcprecheck = true;
- for(int i = 0; i < NUMCORESACTIVE; i++) {
- // reuse the gcnumsendobjs & gcnumreceiveobjs
- gccorestatus[i] = 1;
- gcnumsendobjs[0][i] = 0;
- gcnumreceiveobjs[0][i] = 0;
- }
- for(int i = 0; i < NUMCORESACTIVE; i++) {
- if(i != BAMBOO_NUM_OF_CORE) {
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_1(i, GCSTARTPRE);
- } else {
- send_msg_1(i, GCSTARTPRE, true);
- }
- }
- }
- }
- return NULL;
-#else
- BAMBOO_DEBUGPRINT(0xa001);
- BAMBOO_EXIT(0xa001);
-#endif
- }
- return mem;
-} // void * smemalloc_I(int, int, int)
-
-INLINE int checkMsgLength_I(int size) {
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xcccc);
-#endif
-#endif
- int type = msgdata[msgdataindex];
- switch(type) {
- case STATUSCONFIRM:
- case TERMINATE:
-#ifdef MULTICORE_GC
- case GCSTARTPRE:
- case GCSTARTINIT:
- case GCSTART:
- case GCSTARTMAPINFO:
- case GCSTARTFLUSH:
- case GCFINISH:
- case GCMARKCONFIRM:
- case GCLOBJREQUEST:
-#ifdef GC_CACHE_ADAPT
- case GCSTARTPREF:
-#endif // GC_CACHE_ADAPT
-#endif // MULTICORE_GC
- {
- msglength = 1;
- break;
- }
-
- case PROFILEOUTPUT:
- case PROFILEFINISH:
-#ifdef MULTICORE_GC
- case GCSTARTCOMPACT:
- case GCMARKEDOBJ:
- case GCFINISHINIT:
- case GCFINISHMAPINFO:
- case GCFINISHFLUSH:
-#ifdef GC_CACHE_ADAPT
- case GCFINISHPREF:
-#endif // GC_CACHE_ADAPT
-#endif // MULTICORE_GC
- {
- msglength = 2;
- break;
- }
-
- case MEMREQUEST:
- case MEMRESPONSE:
-#ifdef MULTICORE_GC
- case GCMAPREQUEST:
- case GCMAPINFO:
- case GCMAPTBL:
- case GCLOBJMAPPING:
-#endif
- {
- msglength = 3;
- break;
- }
-
- case TRANSTALL:
- case LOCKGROUNT:
- case LOCKDENY:
- case LOCKRELEASE:
- case REDIRECTGROUNT:
- case REDIRECTDENY:
- case REDIRECTRELEASE:
-#ifdef MULTICORE_GC
- case GCFINISHPRE:
- case GCFINISHMARK:
- case GCMOVESTART:
-#ifdef GC_PROFILE
- case GCPROFILES:
-#endif
-#endif
- {
- msglength = 4;
- break;
- }
-
- case LOCKREQUEST:
- case STATUSREPORT:
-#ifdef MULTICORE_GC
- case GCFINISHCOMPACT:
- case GCMARKREPORT:
-#endif
- {
- msglength = 5;
- break;
- }
-
- case REDIRECTLOCK:
- {
- msglength = 6;
- break;
- }
-
- case TRANSOBJ: // nonfixed size
-#ifdef MULTICORE_GC
- case GCLOBJINFO:
-#endif
- { // nonfixed size
- if(size > 1) {
- msglength = msgdata[msgdataindex+1];
- } else {
- return -1;
- }
- break;
- }
-
- default:
- {
- BAMBOO_DEBUGPRINT_REG(type);
- BAMBOO_DEBUGPRINT_REG(size);
- BAMBOO_DEBUGPRINT_REG(msgdataindex);
- BAMBOO_DEBUGPRINT_REG(msgdatalast);
- BAMBOO_DEBUGPRINT_REG(msgdatafull);
- int i = 6;
- while(i-- > 0) {
- BAMBOO_DEBUGPRINT(msgdata[msgdataindex+i]);
- }
- BAMBOO_EXIT(0xd005);
- break;
- }
- }
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex]);
-#endif
-#endif
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xffff);
-#endif
-#endif
- return msglength;
-}
-
-INLINE void processmsg_transobj_I() {
-#ifdef PROFILE_INTERRUPT
- /*if(!interruptInfoOverflow) {
- InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
- interruptInfoArray[interruptInfoIndex] = intInfo;
- intInfo->startTime = BAMBOO_GET_EXE_TIME();
- intInfo->endTime = -1;
- }*/
-#endif
- MSG_INDEXINC_I();
- struct transObjInfo * transObj=RUNMALLOC_I(sizeof(struct transObjInfo));
- int k = 0;
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe880);
-#endif
-#endif
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
-#endif
- BAMBOO_EXIT(0xa002);
- }
- // store the object and its corresponding queue info, enqueue it later
- transObj->objptr = (void *)msgdata[msgdataindex]; //[2]
- MSG_INDEXINC_I();
- transObj->length = (msglength - 3) / 2;
- transObj->queues = RUNMALLOC_I(sizeof(int)*(msglength - 3));
- for(k = 0; k < transObj->length; ++k) {
- transObj->queues[2*k] = msgdata[msgdataindex]; //[3+2*k];
- MSG_INDEXINC_I();
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k]);
-#endif
-#endif
- transObj->queues[2*k+1] = msgdata[msgdataindex]; //[3+2*k+1];
- MSG_INDEXINC_I();
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- //BAMBOO_DEBUGPRINT_REG(transObj->queues[2*k+1]);
-#endif
-#endif
- }
- // check if there is an existing duplicate item
- {
- struct QueueItem * qitem = getHead(&objqueue);
- struct QueueItem * prev = NULL;
- while(qitem != NULL) {
- struct transObjInfo * tmpinfo =
- (struct transObjInfo *)(qitem->objectptr);
- if(tmpinfo->objptr == transObj->objptr) {
- // the same object, remove outdate one
- RUNFREE(tmpinfo->queues);
- RUNFREE(tmpinfo);
- removeItem(&objqueue, qitem);
- //break;
- } else {
- prev = qitem;
- }
- if(prev == NULL) {
- qitem = getHead(&objqueue);
- } else {
- qitem = getNextQueueItem(prev);
- }
- }
- addNewItem_I(&objqueue, (void *)transObj);
- }
- ++(self_numreceiveobjs);
-#ifdef MULTICORE_GC
- if(gcprocessing) {
- if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
- // set the gcprecheck to enable checking again
- gcprecheck = true;
- } else {
- // send a update pregc information msg to the master core
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs);
- } else {
- send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs, true);
- }
- }
- }
-#endif
-#ifdef PROFILE_INTERRUPT
- /*if(!interruptInfoOverflow) {
- interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
- interruptInfoIndex++;
- if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
- interruptInfoOverflow = true;
- }
- }*/
-#endif
-}
-
-INLINE void processmsg_transtall_I() {
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive stall msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
-#endif
- BAMBOO_EXIT(0xa003);
- }
- int num_core = msgdata[msgdataindex]; //[1]
- MSG_INDEXINC_I();
- if(num_core < NUMCORESACTIVE) {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe881);
-#endif
-#endif
- corestatus[num_core] = 0;
- numsendobjs[num_core] = msgdata[msgdataindex]; //[2];
- MSG_INDEXINC_I();
- numreceiveobjs[num_core] = msgdata[msgdataindex]; //[3];
- MSG_INDEXINC_I();
- }
-}
-
-#ifndef MULTICORE_GC
-INLINE void processmsg_lockrequest_I() {
- // check to see if there is a lock exist for the required obj
- // msgdata[1] -> lock type
- int locktype = msgdata[msgdataindex]; //[1];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex]; // obj pointer
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex]; // lock
- MSG_INDEXINC_I();
- int data4 = msgdata[msgdataindex]; // request core
- MSG_INDEXINC_I();
- // -1: redirected, 0: approved, 1: denied
- int deny=processlockrequest(locktype, data3, data2, data4, data4, true);
- if(deny == -1) {
- // this lock request is redirected
- return;
- } else {
- // send response msg
- // for 32 bit machine, the size is always 4 words, cache the msg first
- int tmp = deny==1 ? LOCKDENY : LOCKGROUNT;
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_4(data4, tmp, locktype, data2, data3);
- } else {
- send_msg_4(data4, tmp, locktype, data2, data3, true);
- }
- }
-}
-
-INLINE void processmsg_lockgrount_I() {
- MSG_INDEXINC_I();
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[2]*/);
-#endif
- BAMBOO_EXIT(0xa004);
- }
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- if((lockobj == data2) && (lock2require == data3)) {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe882);
-#endif
-#endif
- lockresult = 1;
- lockflag = true;
-#ifndef INTERRUPT
- reside = false;
-#endif
- } else {
- // conflicts on lockresults
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa005);
- }
-}
-
-INLINE void processmsg_lockdeny_I() {
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa006);
- }
- if((lockobj == data2) && (lock2require == data3)) {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe883);
-#endif
-#endif
- lockresult = 0;
- lockflag = true;
-#ifndef INTERRUPT
- reside = false;
-#endif
- } else {
- // conflicts on lockresults
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa007);
- }
-}
-
-INLINE void processmsg_lockrelease_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // receive lock release msg
- processlockrelease(data1, data2, 0, false);
-}
-
-INLINE void processmsg_redirectlock_I() {
- // check to see if there is a lock exist for the required obj
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[1]; // lock type
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[2]; // obj pointer
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[3]; // redirect lock
- int data4 = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[4]; // root request core
- int data5 = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[5]; // request core
- int deny = processlockrequest(data1, data3, data2, data5, data4, true);
- if(deny == -1) {
- // this lock request is redirected
- return;
- } else {
- // send response msg
- // for 32 bit machine, the size is always 4 words, cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_4(data4, deny==1 ? REDIRECTDENY : REDIRECTGROUNT,
- data1, data2, data3);
- } else {
- send_msg_4(data4, deny==1?REDIRECTDENY:REDIRECTGROUNT,
- data1, data2, data3, true);
- }
- }
-}
-
-INLINE void processmsg_redirectgrount_I() {
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa00a);
- }
- if(lockobj == data2) {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe891);
-#endif
-#endif
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- lockresult = 1;
- lockflag = true;
- RuntimeHashadd_I(objRedirectLockTbl, lockobj, data3);
-#ifndef INTERRUPT
- reside = false;
-#endif
- } else {
- // conflicts on lockresults
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa00b);
- }
-}
-
-INLINE void processmsg_redirectdeny_I() {
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa00c);
- }
- if(lockobj == data2) {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe892);
-#endif
-#endif
- lockresult = 0;
- lockflag = true;
-#ifndef INTERRUPT
- reside = false;
-#endif
- } else {
- // conflicts on lockresults
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa00d);
- }
-}
-
-INLINE void processmsg_redirectrelease_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- processlockrelease(data1, data2, data3, true);
-}
-#endif // #ifndef MULTICORE_GC
-
-#ifdef PROFILE
-INLINE void processmsg_profileoutput_I() {
- if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
- // startup core can not receive profile output finish msg
- BAMBOO_EXIT(0xa008);
- }
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe885);
-#endif
-#endif
- stall = true;
- totalexetime = msgdata[msgdataindex]; //[1]
- MSG_INDEXINC_I();
-#ifdef RT_TEST
- BAMBOO_DEBUGPRINT_REG(dot_num);
-#else
- outputProfileData();
-#endif
- // cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE);
- } else {
- send_msg_2(STARTUPCORE, PROFILEFINISH, BAMBOO_NUM_OF_CORE, true);
- }
-}
-
-INLINE void processmsg_profilefinish_I() {
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive profile output finish msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex /*1*/]);
-#endif
- BAMBOO_EXIT(0xa009);
- }
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe886);
-#endif
-#endif
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- profilestatus[data1] = 0;
-}
-#endif // #ifdef PROFILE
-
-INLINE void processmsg_statusconfirm_I() {
- if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
- || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
- // wrong core to receive such msg
- BAMBOO_EXIT(0xa00e);
- } else {
- // send response msg
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe887);
-#endif
-#endif
- // cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_5(STARTUPCORE, STATUSREPORT,
- 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, true);
- }
- }
-}
-
-INLINE void processmsg_statusreport_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data4 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // receive a status confirm info
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // wrong core to receive such msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa00f);
- } else {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe888);
-#endif
-#endif
- if(waitconfirm) {
- numconfirm--;
- }
- corestatus[data2] = data1;
- numsendobjs[data2] = data3;
- numreceiveobjs[data2] = data4;
- }
-}
-
-INLINE void processmsg_terminate_I() {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe889);
-#endif
-#endif
- disruntimedata();
-#ifdef MULTICORE_GC
-#ifdef GC_CACHE_ADAPT
- bamboo_mask_timer_intr(); // disable the TILE_TIMER interrupt
-#endif // GC_CACHE_ADAPT
-#endif // MULTICORE_GC
- BAMBOO_EXIT_APP(0);
-}
-
-INLINE void processmsg_memrequest_I() {
-#ifdef PROFILE_INTERRUPT
- /*if(!interruptInfoOverflow) {
- InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
- interruptInfoArray[interruptInfoIndex] = intInfo;
- intInfo->startTime = BAMBOO_GET_EXE_TIME();
- intInfo->endTime = -1;
- }*/
-#endif
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // receive a shared memory request msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // wrong core to receive such msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xa010);
- } else {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe88a);
-#endif
-#endif
- int allocsize = 0;
- void * mem = NULL;
-#ifdef MULTICORE_GC
- if(gcprocessing) {
- // is currently doing gc, dump this msg
- if(INITPHASE == gcphase) {
- // if still in the initphase of gc, send a startinit msg again,
- // cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_1(data2, GCSTARTINIT);
- } else {
- send_msg_1(data2, GCSTARTINIT, true);
- }
- }
- } else {
-#endif
- mem = smemalloc_I(data2, data1, &allocsize);
- if(mem != NULL) {
- // send the start_va to request core, cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_3(data2, MEMRESPONSE, mem, allocsize);
- } else {
- send_msg_3(data2, MEMRESPONSE, mem, allocsize, true);
- }
- } //else
- // if mem == NULL, the gcflag of the startup core has been set
- // and all the other cores have been informed to start gc
-#ifdef MULTICORE_GC
- }
-#endif
- }
-#ifdef PROFILE_INTERRUPT
- /*if(!interruptInfoOverflow) {
- interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
- interruptInfoIndex++;
- if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
- interruptInfoOverflow = true;
- }
- }*/
-#endif
-}
-
-INLINE void processmsg_memresponse_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // receive a shared memory response msg
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe88b);
-#endif
-#endif
-#ifdef MULTICORE_GC
- // if is currently doing gc, dump this msg
- if(!gcprocessing) {
-#endif
- if(data2 == 0) {
- bamboo_smem_size = 0;
- bamboo_cur_msp = 0;
-#ifdef MULTICORE_GC
- bamboo_smem_zero_top = 0;
-#endif
- } else {
-#ifdef MULTICORE_GC
- // fill header to store the size of this mem block
- BAMBOO_MEMSET_WH(data1, '\0', BAMBOO_CACHE_LINE_SIZE);
- //memset(data1, 0, BAMBOO_CACHE_LINE_SIZE);
- (*((int*)data1)) = data2;
- bamboo_smem_size = data2 - BAMBOO_CACHE_LINE_SIZE;
- bamboo_cur_msp = data1 + BAMBOO_CACHE_LINE_SIZE;
- bamboo_smem_zero_top = bamboo_cur_msp;
-#else
- bamboo_smem_size = data2;
- bamboo_cur_msp =(void*)(data1);
-#endif
- }
- smemflag = true;
-#ifdef MULTICORE_GC
-}
-#endif
-}
-
-#ifdef MULTICORE_GC
-INLINE void processmsg_gcstartpre_I() {
- if(gcprocessing) {
- // already stall for gc
- // send a update pregc information msg to the master core
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs);
- } else {
- send_msg_4(STARTUPCORE, GCFINISHPRE, BAMBOO_NUM_OF_CORE,
- self_numsendobjs, self_numreceiveobjs, true);
- }
- } else {
- // the first time to be informed to start gc
- gcflag = true;
- if(!smemflag) {
- // is waiting for response of mem request
- // let it return NULL and start gc
- bamboo_smem_size = 0;
- bamboo_cur_msp = NULL;
- smemflag = true;
- bamboo_smem_zero_top = NULL;
- }
- }
-}
-
-INLINE void processmsg_gcstartinit_I() {
- gcphase = INITPHASE;
-}
-
-INLINE void processmsg_gcstart_I() {
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe88c);
-#endif
-#endif
- // set the GC flag
- gcphase = MARKPHASE;
-}
-
-INLINE void processmsg_gcstartcompact_I() {
- gcblock2fill = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[1];
- gcphase = COMPACTPHASE;
-}
-
-INLINE void processmsg_gcstartmapinfo_I() {
- gcphase = MAPPHASE;
-}
-
-INLINE void processmsg_gcstartflush_I() {
- gcphase = FLUSHPHASE;
-}
-
-INLINE void processmsg_gcfinishpre_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a init phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb000);
- }
- // All cores should do init GC
- if(!gcprecheck) {
- gcprecheck = true;
- }
- gccorestatus[data1] = 0;
- gcnumsendobjs[0][data1] = data2;
- gcnumreceiveobjs[0][data1] = data3;
-}
-
-INLINE void processmsg_gcfinishinit_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a init phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb001);
- }
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe88c);
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- // All cores should do init GC
- if(data1 < NUMCORESACTIVE) {
- gccorestatus[data1] = 0;
- }
-}
-
-INLINE void processmsg_gcfinishmark_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a mark phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb002);
- }
- // all cores should do mark
- if(data1 < NUMCORESACTIVE) {
- gccorestatus[data1] = 0;
- int entry_index = 0;
- if(waitconfirm) {
- // phase 2
- entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
- } else {
- // phase 1
- entry_index = gcnumsrobjs_index;
- }
- gcnumsendobjs[entry_index][data1] = data2;
- gcnumreceiveobjs[entry_index][data1] = data3;
- }
-}
-
-INLINE void processmsg_gcfinishcompact_I() {
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
- // return -1
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(msgdata[msgdataindex] /*[1]*/);
-#endif
- BAMBOO_EXIT(0xb003);
- }
- int cnum = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[1];
- int filledblocks = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[2];
- int heaptop = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[3];
- int data4 = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[4];
- // only gc cores need to do compact
- if(cnum < NUMCORES4GC) {
- if(COMPACTPHASE == gcphase) {
- gcfilledblocks[cnum] = filledblocks;
- gcloads[cnum] = heaptop;
- }
- if(data4 > 0) {
- // ask for more mem
- int startaddr = 0;
- int tomove = 0;
- int dstcore = 0;
- if(gcfindSpareMem_I(&startaddr, &tomove, &dstcore, data4, cnum)) {
- // cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove);
- } else {
- send_msg_4(cnum, GCMOVESTART, dstcore, startaddr, tomove, true);
- }
- }
- } else {
- gccorestatus[cnum] = 0;
- } // if(data4>0)
- } // if(cnum < NUMCORES4GC)
-}
-
-INLINE void processmsg_gcfinishmapinfo_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a map phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb004);
- }
- // all cores should do flush
- if(data1 < NUMCORES4GC) {
- gccorestatus[data1] = 0;
- }
-}
-
-
-INLINE void processmsg_gcfinishflush_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a flush phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb005);
- }
- // all cores should do flush
- if(data1 < NUMCORESACTIVE) {
- gccorestatus[data1] = 0;
- }
-}
-
-INLINE void processmsg_gcmarkconfirm_I() {
- if((BAMBOO_NUM_OF_CORE == STARTUPCORE)
- || (BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1)) {
- // wrong core to receive such msg
- BAMBOO_EXIT(0xb006);
- } else {
- // send response msg, cahce the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
- gcbusystatus, gcself_numsendobjs,
- gcself_numreceiveobjs);
- } else {
- send_msg_5(STARTUPCORE, GCMARKREPORT, BAMBOO_NUM_OF_CORE,
- gcbusystatus, gcself_numsendobjs,
- gcself_numreceiveobjs, true);
- }
- }
-}
-
-INLINE void processmsg_gcmarkreport_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data4 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a marked phase finish confirm response msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // wrong core to receive such msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xb007);
- } else {
- int entry_index = 0;
- if(waitconfirm) {
- // phse 2
- numconfirm--;
- entry_index = (gcnumsrobjs_index == 0) ? 1 : 0;
- } else {
- // can never reach here
- // phase 1
- entry_index = gcnumsrobjs_index;
- }
- gccorestatus[data1] = data2;
- gcnumsendobjs[entry_index][data1] = data3;
- gcnumreceiveobjs[entry_index][data1] = data4;
- }
-}
-
-INLINE void processmsg_gcmarkedobj_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a markedObj msg
- if(((int *)data1)[6] == INIT) {
- // this is the first time that this object is discovered,
- // set the flag as DISCOVERED
- ((int *)data1)[6] = DISCOVERED;
- gc_enqueue_I(data1);
- }
- // set the remote flag
- ((int *)data1)[6] |= REMOTEM;
- gcself_numreceiveobjs++;
- gcbusystatus = true;
-}
-
-INLINE void processmsg_gcmovestart_I() {
- gctomove = true;
- gcdstcore = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[1];
- gcmovestartaddr = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[2];
- gcblock2fill = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[3];
-}
-
-INLINE void processmsg_gcmaprequest_I() {
-#ifdef GC_PROFILE
- //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
-#endif
- void * dstptr = NULL;
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
-#ifdef GC_PROFILE
- // TODO unsigned long long ttime = BAMBOO_GET_EXE_TIME();
-#endif
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashget(gcpointertbl, data1, &dstptr);
-#else
- dstptr = mgchashSearch(gcpointertbl, data1);
-#endif
- //MGCHashget(gcpointertbl, data1, &dstptr);
-#ifdef GC_PROFILE
- // TODO flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
-#endif
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
-#ifdef GC_PROFILE
- // TODO unsigned long long ttimei = BAMBOO_GET_EXE_TIME();
-#endif
- if(NULL == dstptr) {
- // no such pointer in this core, something is wrong
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(data1);
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xb008);
- //assume that the object was not moved, use the original address
- /*if(isMsgSending) {
- cache_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
- } else {
- send_msg_3(msgdata[2], GCMAPINFO, msgdata[1], msgdata[1]);
- }*/
- } else {
- // send back the mapping info, cache the msg first
- if(BAMBOO_CHECK_SEND_MODE()) {
- cache_msg_3(data2, GCMAPINFO, data1, (int)dstptr);
- } else {
- send_msg_3(data2, GCMAPINFO, data1, (int)dstptr, true);
- }
- }
-#ifdef GC_PROFILE
- // TODO flushstalltime_i += BAMBOO_GET_EXE_TIME()-ttimei;
- //num_mapinforequest_i++;
-#endif
-}
-
-INLINE void processmsg_gcmapinfo_I() {
-#ifdef GC_PROFILE
- //unsigned long long ttime = BAMBOO_GET_EXE_TIME();
-#endif
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- gcmappedobj = msgdata[msgdataindex]; // [2]
- MSG_INDEXINC_I();
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashadd_I(gcpointertbl, data1, gcmappedobj);
-#else
- mgchashInsert_I(gcpointertbl, data1, gcmappedobj);
-#endif
- //MGCHashadd_I(gcpointertbl, data1, gcmappedobj);
- if(data1 == gcobj2map) {
- gcismapped = true;
- }
-#ifdef GC_PROFILE
- //flushstalltime += BAMBOO_GET_EXE_TIME() - ttime;
-#endif
-}
-
-INLINE void processmsg_gcmaptbl_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- gcrpointertbls[data2] = (mgcsharedhashtbl_t *)data1; //(struct GCSharedHash *)data1;
-}
-
-INLINE void processmsg_gclobjinfo_I() {
- numconfirm--;
-
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- if(BAMBOO_NUM_OF_CORE > NUMCORES4GC - 1) {
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data2);
-#endif
- BAMBOO_EXIT(0xb009);
- }
- // store the mark result info
- int cnum = data2;
- gcloads[cnum] = msgdata[msgdataindex];
- MSG_INDEXINC_I(); // msgdata[3];
- int data4 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- if(gcheaptop < data4) {
- gcheaptop = data4;
- }
- // large obj info here
- for(int k = 5; k < data1; ) {
- int lobj = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[k++];
- int length = msgdata[msgdataindex];
- MSG_INDEXINC_I(); //msgdata[k++];
- gc_lobjenqueue_I(lobj, length, cnum);
- gcnumlobjs++;
- } // for(int k = 5; k < msgdata[1];)
-}
-
-INLINE void processmsg_gclobjmapping_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
-#ifdef LOCALHASHTBL_TEST
- RuntimeHashadd_I(gcpointertbl, data1, data2);
-#else
- mgchashInsert_I(gcpointertbl, data1, data2);
-#endif
- //MGCHashadd_I(gcpointertbl, data1, data2);
- mgcsharedhashInsert_I(gcsharedptbl, data1, data2);
-}
-
-#ifdef GC_PROFILE
-INLINE void processmsg_gcprofiles_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data2 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- int data3 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- gc_num_obj += data1;
- gc_num_liveobj += data2;
- gc_num_forwardobj += data3;
- gc_num_profiles--;
-}
-#endif // GC_PROFILE
-
-#ifdef GC_CACHE_ADAPT
-INLINE void processmsg_gcstartpref_I() {
- gcphase = PREFINISHPHASE;
-}
-
-INLINE void processmsg_gcfinishpref_I() {
- int data1 = msgdata[msgdataindex];
- MSG_INDEXINC_I();
- // received a flush phase finish msg
- if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
- // non startup core can not receive this msg
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT_REG(data1);
-#endif
- BAMBOO_EXIT(0xb00a);
- }
- // all cores should do flush
- if(data1 < NUMCORESACTIVE) {
- gccorestatus[data1] = 0;
- }
-}
-#endif // GC_CACHE_ADAPT
-#endif // #ifdef MULTICORE_GC
-
-// receive object transferred from other cores
-// or the terminate message from other cores
-// Should be invoked in critical sections!!
-// NOTICE: following format is for threadsimulate version only
-// RAW version please see previous description
-// format: type + object
-// type: -1--stall msg
-// !-1--object
-// return value: 0--received an object
-// 1--received nothing
-// 2--received a Stall Msg
-// 3--received a lock Msg
-// RAW version: -1 -- received nothing
-// otherwise -- received msg type
-int receiveObject(int send_port_pending) {
-#ifdef PROFILE_INTERRUPT
- if(!interruptInfoOverflow) {
- InterruptInfo* intInfo = RUNMALLOC_I(sizeof(struct interrupt_info));
- interruptInfoArray[interruptInfoIndex] = intInfo;
- intInfo->startTime = BAMBOO_GET_EXE_TIME();
- intInfo->endTime = -1;
- }
-#endif
-msg:
- // get the incoming msgs
- if(receiveMsg(send_port_pending) == -1) {
- return -1;
- }
-processmsg:
- // processing received msgs
- int size = 0;
- MSG_REMAINSIZE_I(&size);
- if((size == 0) || (checkMsgLength_I(size) == -1)) {
- // not a whole msg
- // have new coming msg
- if((BAMBOO_MSG_AVAIL() != 0) && !msgdatafull) {
- goto msg;
- } else {
- return -1;
- }
- }
-
- if(msglength <= size) {
- // have some whole msg
- MSGTYPE type;
- type = msgdata[msgdataindex]; //[0]
- MSG_INDEXINC_I();
- msgdatafull = false;
- // TODO
- //tprintf("msg type: %x\n", type);
- switch(type) {
- case TRANSOBJ: {
- // receive a object transfer msg
- processmsg_transobj_I();
- break;
- } // case TRANSOBJ
-
- case TRANSTALL: {
- // receive a stall msg
- processmsg_transtall_I();
- break;
- } // case TRANSTALL
-
-// GC version have no lock msgs
-#ifndef MULTICORE_GC
- case LOCKREQUEST: {
- // receive lock request msg, handle it right now
- processmsg_lockrequest_I();
- break;
- } // case LOCKREQUEST
-
- case LOCKGROUNT: {
- // receive lock grount msg
- processmsg_lockgrount_I();
- break;
- } // case LOCKGROUNT
-
- case LOCKDENY: {
- // receive lock deny msg
- processmsg_lockdeny_I();
- break;
- } // case LOCKDENY
-
- case LOCKRELEASE: {
- processmsg_lockrelease_I();
- break;
- } // case LOCKRELEASE
-#endif // #ifndef MULTICORE_GC
-
-#ifdef PROFILE
- case PROFILEOUTPUT: {
- // receive an output profile data request msg
- processmsg_profileoutput_I();
- break;
- } // case PROFILEOUTPUT
-
- case PROFILEFINISH: {
- // receive a profile output finish msg
- processmsg_profilefinish_I();
- break;
- } // case PROFILEFINISH
-#endif // #ifdef PROFILE
-
-// GC version has no lock msgs
-#ifndef MULTICORE_GC
- case REDIRECTLOCK: {
- // receive a redirect lock request msg, handle it right now
- processmsg_redirectlock_I();
- break;
- } // case REDIRECTLOCK
-
- case REDIRECTGROUNT: {
- // receive a lock grant msg with redirect info
- processmsg_redirectgrount_I();
- break;
- } // case REDIRECTGROUNT
-
- case REDIRECTDENY: {
- // receive a lock deny msg with redirect info
- processmsg_redirectdeny_I();
- break;
- } // case REDIRECTDENY
-
- case REDIRECTRELEASE: {
- // receive a lock release msg with redirect info
- processmsg_redirectrelease_I();
- break;
- } // case REDIRECTRELEASE
-#endif // #ifndef MULTICORE_GC
-
- case STATUSCONFIRM: {
- // receive a status confirm info
- processmsg_statusconfirm_I();
- break;
- } // case STATUSCONFIRM
-
- case STATUSREPORT: {
- processmsg_statusreport_I();
- break;
- } // case STATUSREPORT
-
- case TERMINATE: {
- // receive a terminate msg
- processmsg_terminate_I();
- break;
- } // case TERMINATE
-
- case MEMREQUEST: {
- processmsg_memrequest_I();
- break;
- } // case MEMREQUEST
-
- case MEMRESPONSE: {
- processmsg_memresponse_I();
- break;
- } // case MEMRESPONSE
-
-#ifdef MULTICORE_GC
- // GC msgs
- case GCSTARTPRE: {
- processmsg_gcstartpre_I();
- break;
- } // case GCSTARTPRE
-
- case GCSTARTINIT: {
- processmsg_gcstartinit_I();
- break;
- } // case GCSTARTINIT
-
- case GCSTART: {
- // receive a start GC msg
- processmsg_gcstart_I();
- break;
- } // case GCSTART
-
- case GCSTARTCOMPACT: {
- // a compact phase start msg
- processmsg_gcstartcompact_I();
- break;
- } // case GCSTARTCOMPACT
-
- case GCSTARTMAPINFO: {
- // received a flush phase start msg
- processmsg_gcstartmapinfo_I();
- break;
- } // case GCSTARTFLUSH
-
- case GCSTARTFLUSH: {
- // received a flush phase start msg
- processmsg_gcstartflush_I();
- break;
- } // case GCSTARTFLUSH
-
- case GCFINISHPRE: {
- processmsg_gcfinishpre_I();
- break;
- } // case GCFINISHPRE
-
- case GCFINISHINIT: {
- processmsg_gcfinishinit_I();
- break;
- } // case GCFINISHINIT
-
- case GCFINISHMARK: {
- processmsg_gcfinishmark_I();
- break;
- } // case GCFINISHMARK
-
- case GCFINISHCOMPACT: {
- // received a compact phase finish msg
- processmsg_gcfinishcompact_I();
- break;
- } // case GCFINISHCOMPACT
-
- case GCFINISHMAPINFO: {
- processmsg_gcfinishmapinfo_I();
- break;
- } // case GCFINISHMAPINFO
-
- case GCFINISHFLUSH: {
- processmsg_gcfinishflush_I();
- break;
- } // case GCFINISHFLUSH
-
- case GCFINISH: {
- // received a GC finish msg
- gcphase = FINISHPHASE;
- break;
- } // case GCFINISH
-
- case GCMARKCONFIRM: {
- // received a marked phase finish confirm request msg
- // all cores should do mark
- processmsg_gcmarkconfirm_I();
- break;
- } // case GCMARKCONFIRM
-
- case GCMARKREPORT: {
- processmsg_gcmarkreport_I();
- break;
- } // case GCMARKREPORT
-
- case GCMARKEDOBJ: {
- processmsg_gcmarkedobj_I();
- break;
- } // case GCMARKEDOBJ
-
- case GCMOVESTART: {
- // received a start moving objs msg
- processmsg_gcmovestart_I();
- break;
- } // case GCMOVESTART
-
- case GCMAPREQUEST: {
- // received a mapping info request msg
- processmsg_gcmaprequest_I();
- break;
- } // case GCMAPREQUEST
-
- case GCMAPINFO: {
- // received a mapping info response msg
- processmsg_gcmapinfo_I();
- break;
- } // case GCMAPINFO
-
- case GCMAPTBL: {
- // received a mapping tbl response msg
- processmsg_gcmaptbl_I();
- break;
- } // case GCMAPTBL
-
- case GCLOBJREQUEST: {
- // received a large objs info request msg
- transferMarkResults_I();
- break;
- } // case GCLOBJREQUEST
-
- case GCLOBJINFO: {
- // received a large objs info response msg
- processmsg_gclobjinfo_I();
- break;
- } // case GCLOBJINFO
-
- case GCLOBJMAPPING: {
- // received a large obj mapping info msg
- processmsg_gclobjmapping_I();
- break;
- } // case GCLOBJMAPPING
-
-#ifdef GC_PROFILE
- case GCPROFILES: {
- // received a gcprofiles msg
- processmsg_gcprofiles_I();
- break;
- }
-#endif // GC_PROFILE
-
-#ifdef GC_CACHE_ADAPT
- case GCSTARTPREF: {
- // received a gcstartpref msg
- processmsg_gcstartpref_I();
- break;
- }
-
- case GCFINISHPREF: {
- // received a gcfinishpref msg
- processmsg_gcfinishpref_I();
- break;
- }
-#endif // GC_CACHE_ADAPT
-#endif // #ifdef MULTICORE_GC
-
- default:
- break;
- } // switch(type)
- msglength = BAMBOO_MSG_BUF_LENGTH;
- // TODO
- //printf("++ msg: %x \n", type);
-
- if(msgdataindex != msgdatalast) {
- // still have available msg
- goto processmsg;
- }
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe88d);
-#endif
-#endif
-
- // have new coming msg
- if(BAMBOO_MSG_AVAIL() != 0) {
- goto msg;
- } // TODO
-
-#ifdef PROFILE_INTERRUPT
- if(!interruptInfoOverflow) {
- interruptInfoArray[interruptInfoIndex]->endTime=BAMBOO_GET_EXE_TIME();
- interruptInfoIndex++;
- if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
- interruptInfoOverflow = true;
- }
- }
-#endif
- return (int)type;
- } else {
- // not a whole msg
-#ifdef DEBUG
-#ifndef CLOSE_PRINT
- BAMBOO_DEBUGPRINT(0xe88e);
-#endif
-#endif
- return -2;
- }
-}
-
-int enqueuetasks(struct parameterwrapper *parameter,
- struct parameterwrapper *prevptr,
- struct ___Object___ *ptr,
- int * enterflags,
- int numenterflags) {
- void * taskpointerarray[MAXTASKPARAMS];
- int j;
- //int numparams=parameter->task->numParameters;
- int numiterators=parameter->task->numTotal-1;
- int retval=1;
-
- struct taskdescriptor * task=parameter->task;
-
- //this add the object to parameterwrapper
- ObjectHashadd(parameter->objectset, (int) ptr, 0, (int) enterflags,
- numenterflags, enterflags==NULL);
-
- /* Add enqueued object to parameter vector */
- taskpointerarray[parameter->slot]=ptr;
-
- /* Reset iterators */
- for(j=0; j<numiterators; j++) {
- toiReset(¶meter->iterators[j]);
- }
-
- /* Find initial state */
- for(j=0; j<numiterators; j++) {
-backtrackinit:
- if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
- toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
- else if (j>0) {
- /* Need to backtrack */
- toiReset(¶meter->iterators[j]);
- j--;
- goto backtrackinit;
- } else {
- /* Nothing to enqueue */
- return retval;
- }
- }
-
- while(1) {
- /* Enqueue current state */
- //int launch = 0;
- struct taskparamdescriptor *tpd=
- RUNMALLOC(sizeof(struct taskparamdescriptor));
- tpd->task=task;
- tpd->numParameters=numiterators+1;
- tpd->parameterArray=RUNMALLOC(sizeof(void *)*(numiterators+1));
-
- for(j=0; j<=numiterators; j++) {
- //store the actual parameters
- tpd->parameterArray[j]=taskpointerarray[j];
- }
- /* Enqueue task */
- if (( /*!gencontains(failedtasks, tpd)&&*/
- !gencontains(activetasks,tpd))) {
- genputtable(activetasks, tpd, tpd);
- } else {
- RUNFREE(tpd->parameterArray);
- RUNFREE(tpd);
- }
-
- /* This loop iterates to the next parameter combination */
- if (numiterators==0)
- return retval;
-
- for(j=numiterators-1; j<numiterators; j++) {
-backtrackinc:
- if(toiHasNext(
- ¶meter->iterators[j],taskpointerarray OPTARG(failed)))
- toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
- else if (j>0) {
- /* Need to backtrack */
- toiReset(¶meter->iterators[j]);
- j--;
- goto backtrackinc;
- } else {
- /* Nothing more to enqueue */
- return retval;
- }
- }
- }
- return retval;
-}
-
-int enqueuetasks_I(struct parameterwrapper *parameter,
- struct parameterwrapper *prevptr,
- struct ___Object___ *ptr,
- int * enterflags,
- int numenterflags) {
- void * taskpointerarray[MAXTASKPARAMS];
- int j;
- //int numparams=parameter->task->numParameters;
- int numiterators=parameter->task->numTotal-1;
- int retval=1;
- //int addnormal=1;
- //int adderror=1;
-
- struct taskdescriptor * task=parameter->task;
-
- //this add the object to parameterwrapper
- ObjectHashadd_I(parameter->objectset, (int) ptr, 0, (int) enterflags,
- numenterflags, enterflags==NULL);
-
- /* Add enqueued object to parameter vector */
- taskpointerarray[parameter->slot]=ptr;
-
- /* Reset iterators */
- for(j=0; j<numiterators; j++) {
- toiReset(¶meter->iterators[j]);
- }
-
- /* Find initial state */
- for(j=0; j<numiterators; j++) {
-backtrackinit:
- if(toiHasNext(¶meter->iterators[j],taskpointerarray OPTARG(failed)))
- toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
- else if (j>0) {
- /* Need to backtrack */
- toiReset(¶meter->iterators[j]);
- j--;
- goto backtrackinit;
- } else {
- /* Nothing to enqueue */
- return retval;
- }
- }
-
- while(1) {
- /* Enqueue current state */
- //int launch = 0;
- struct taskparamdescriptor *tpd=
- RUNMALLOC_I(sizeof(struct taskparamdescriptor));
- tpd->task=task;
- tpd->numParameters=numiterators+1;
- tpd->parameterArray=RUNMALLOC_I(sizeof(void *)*(numiterators+1));
-
- for(j=0; j<=numiterators; j++) {
- //store the actual parameters
- tpd->parameterArray[j]=taskpointerarray[j];
- }
- /* Enqueue task */
- if (( /*!gencontains(failedtasks, tpd)&&*/
- !gencontains(activetasks,tpd))) {
- genputtable_I(activetasks, tpd, tpd);
- } else {
- RUNFREE(tpd->parameterArray);
- RUNFREE(tpd);
- }
-
- /* This loop iterates to the next parameter combination */
- if (numiterators==0)
- return retval;
-
- for(j=numiterators-1; j<numiterators; j++) {
-backtrackinc:
- if(toiHasNext(
- ¶meter->iterators[j], taskpointerarray OPTARG(failed)))
- toiNext(¶meter->iterators[j], taskpointerarray OPTARG(failed));
- else if (j>0) {
- /* Need to backtrack */
- toiReset(¶meter->iterators[j]);
- j--;
- goto backtrackinc;
- } else {
- /* Nothing more to enqueue */
- return retval;
- }
- }
- }
- return retval;
-}
-
-#ifdef MULTICORE_GC
-#define OFFSET 2
-#else
-#define OFFSET 0
-#endif
-
-int containstag(struct ___Object___ *ptr,
- struct ___TagDescriptor___ *tag);
-
-#ifndef MULTICORE_GC
-void releasewritelock_r(void * lock, void * redirectlock) {
- int targetcore = 0;
- int reallock = (int)lock;
- targetcore = (reallock >> 5) % NUMCORES;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe671);
- BAMBOO_DEBUGPRINT_REG((int)lock);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == BAMBOO_NUM_OF_CORE) {
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- // reside on this core
- if(!RuntimeHashcontainskey(locktbl, reallock)) {
- // no locks for this object, something is wrong
- BAMBOO_EXIT(0xa00b);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe672);
-#endif
- RuntimeHashget(locktbl, reallock, &rwlock_obj);
- lockvalue = (struct LockValue *)rwlock_obj;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
- lockvalue->value++;
- lockvalue->redirectlock = (int)redirectlock;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
- }
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
- return;
- } 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, false);
- }
-}
-#endif
-
-void executetasks() {
- void * taskpointerarray[MAXTASKPARAMS+OFFSET];
- int numparams=0;
- int numtotal=0;
- struct ___Object___ * tmpparam = NULL;
- struct parameterdescriptor * pd=NULL;
- struct parameterwrapper *pw=NULL;
- int j = 0;
- int x = 0;
- bool islock = true;
-
- int grount = 0;
- int andmask=0;
- int checkmask=0;
-
-newtask:
- while(hashsize(activetasks)>0) {
-#ifdef MULTICORE_GC
-//#ifdef GC_CACHE_ADAPT
- // do dtlb sampling if necessary
-// bamboo_dtlb_sampling_process();
-//#endif // GC_CACHE_ADAPT
- if(gcflag) gc(NULL);
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe990);
-#endif
-
- /* See if there are any active tasks */
- //if (hashsize(activetasks)>0) {
- int i;
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- profileTaskStart("tpd checking");
-#endif
-#endif
- //long clock1;
- //clock1 = BAMBOO_GET_EXE_TIME();
-
- busystatus = true;
- currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
- genfreekey(activetasks, currtpd);
-
- numparams=currtpd->task->numParameters;
- numtotal=currtpd->task->numTotal;
-
- // clear the lockRedirectTbl
- // (TODO, this table should be empty after all locks are released)
- // reset all locks
- /*for(j = 0; j < MAXTASKPARAMS; j++) {
- runtime_locks[j].redirectlock = 0;
- runtime_locks[j].value = 0;
- }*/
- // get all required locks
- runtime_locklen = 0;
- // check which locks are needed
- for(i = 0; i < numparams; i++) {
- void * param = currtpd->parameterArray[i];
- int tmplock = 0;
- int j = 0;
- bool insert = true;
- if(((struct ___Object___ *)param)->type == STARTUPTYPE) {
- islock = false;
- taskpointerarray[i+OFFSET]=param;
- goto execute;
- }
- if(((struct ___Object___ *)param)->lock == NULL) {
- tmplock = (int)param;
- } else {
- tmplock = (int)(((struct ___Object___ *)param)->lock);
- }
- // insert into the locks array
- for(j = 0; j < runtime_locklen; j++) {
- if(runtime_locks[j].value == tmplock) {
- insert = false;
- break;
- } else if(runtime_locks[j].value > tmplock) {
- break;
- }
- }
- if(insert) {
- int h = runtime_locklen;
- for(; h > j; h--) {
- runtime_locks[h].redirectlock = runtime_locks[h-1].redirectlock;
- runtime_locks[h].value = runtime_locks[h-1].value;
- }
- runtime_locks[j].value = tmplock;
- runtime_locks[j].redirectlock = (int)param;
- runtime_locklen++;
- }
- } // line 2713: for(i = 0; i < numparams; i++)
- // grab these required locks
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe991);
-#endif
- //long clock2;
- //clock2 = BAMBOO_GET_EXE_TIME();
-
- for(i = 0; i < runtime_locklen; i++) {
- int * lock = (int *)(runtime_locks[i].redirectlock);
- islock = true;
- // require locks for this parameter if it is not a startup object
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG((int)lock);
- BAMBOO_DEBUGPRINT_REG((int)(runtime_locks[i].value));
-#endif
- getwritelock(lock);
- BAMBOO_ENTER_RUNTIME_MODE_FROM_CLIENT();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
-#ifdef PROFILE
- //isInterrupt = false;
-#endif
- while(!lockflag) {
- BAMBOO_WAITING_FOR_LOCK(0);
- }
-#ifndef INTERRUPT
- if(reside) {
- while(BAMBOO_WAITING_FOR_LOCK(0) != -1) {
- }
- }
-#endif
- grount = lockresult;
-
- lockresult = 0;
- lockobj = 0;
- lock2require = 0;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
-#ifdef PROFILE
- //isInterrupt = true;
-#endif
- BAMBOO_ENTER_CLIENT_MODE_FROM_RUNTIME();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf000);
-#endif
-
- if(grount == 0) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe992);
- BAMBOO_DEBUGPRINT_REG(lock);
-#endif
- // check if has the lock already
- // can not get the lock, try later
- // release all grabbed locks for previous parameters
- for(j = 0; j < i; ++j) {
- lock = (int*)(runtime_locks[j].redirectlock);
- releasewritelock(lock);
- }
- genputtable(activetasks, currtpd, currtpd);
- if(hashsize(activetasks) == 1) {
- // only one task right now, wait a little while before next try
- int halt = 10000;
- while(halt--) {
- }
- }
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- // fail, set the end of the checkTaskInfo
- profileTaskEnd();
-#endif
-#endif
- goto newtask;
- //}
- }
- } // line 2752: for(i = 0; i < runtime_locklen; i++)
-
- /*long clock3;
- clock3 = BAMBOO_GET_EXE_TIME();
- //tprintf("sort: %d, grab: %d \n", clock2-clock1, clock3-clock2);*/
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe993);
-#endif
- /* Make sure that the parameters are still in the queues */
- for(i=0; i<numparams; i++) {
- void * parameter=currtpd->parameterArray[i];
-
- // flush the object
-#ifdef CACHEFLUSH
- BAMBOO_CACHE_FLUSH_RANGE((int)parameter,
- classsize[((struct ___Object___ *)parameter)->type]);
-#endif
- tmpparam = (struct ___Object___ *)parameter;
- pd=currtpd->task->descriptorarray[i];
- pw=(struct parameterwrapper *) pd->queue;
- /* Check that object is still in queue */
- {
- if (!ObjectHashcontainskey(pw->objectset, (int) parameter)) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe994);
- BAMBOO_DEBUGPRINT_REG(parameter);
-#endif
- // release grabbed locks
- for(j = 0; j < runtime_locklen; ++j) {
- int * lock = (int *)(runtime_locks[j].redirectlock);
- releasewritelock(lock);
- }
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- currtpd = NULL;
- goto newtask;
- }
- } // line2865
- /* Check if the object's flags still meets requirements */
- {
- int tmpi = 0;
- bool ismet = false;
- for(tmpi = 0; tmpi < pw->numberofterms; ++tmpi) {
- andmask=pw->intarray[tmpi*2];
- checkmask=pw->intarray[tmpi*2+1];
- if((((struct ___Object___ *)parameter)->flag&andmask)==checkmask) {
- ismet = true;
- break;
- }
- }
- if (!ismet) {
- // flags are never suitable
- // remove this obj from the queue
- int next;
- int UNUSED, UNUSED2;
- int * enterflags;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe995);
- BAMBOO_DEBUGPRINT_REG(parameter);
-#endif
- ObjectHashget(pw->objectset, (int) parameter, (int *) &next,
- (int *) &enterflags, &UNUSED, &UNUSED2);
- ObjectHashremove(pw->objectset, (int)parameter);
- if (enterflags!=NULL)
- RUNFREE(enterflags);
- // release grabbed locks
- for(j = 0; j < runtime_locklen; ++j) {
- int * lock = (int *)(runtime_locks[j].redirectlock);
- releasewritelock(lock);
- }
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- currtpd = NULL;
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- // fail, set the end of the checkTaskInfo
- profileTaskEnd();
-#endif
-#endif
- goto newtask;
- } // line 2878: if (!ismet)
- } // line 2867
-parameterpresent:
- ;
- /* Check that object still has necessary tags */
- for(j=0; j<pd->numbertags; j++) {
- int slotid=pd->tagarray[2*j]+numparams;
- struct ___TagDescriptor___ *tagd=currtpd->parameterArray[slotid];
- if (!containstag(parameter, tagd)) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe996);
-#endif
- {
- // release grabbed locks
- int tmpj = 0;
- for(tmpj = 0; tmpj < runtime_locklen; ++tmpj) {
- int * lock = (int *)(runtime_locks[tmpj].redirectlock);
- releasewritelock(lock);
- }
- }
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- currtpd = NULL;
- goto newtask;
- } // line2911: if (!containstag(parameter, tagd))
- } // line 2808: for(j=0; j<pd->numbertags; j++)
-
- taskpointerarray[i+OFFSET]=parameter;
- } // line 2824: for(i=0; i<numparams; i++)
- /* Copy the tags */
- for(; i<numtotal; i++) {
- taskpointerarray[i+OFFSET]=currtpd->parameterArray[i];
- }
-
- {
-execute:
- /* Actually call task */
-#ifdef MULTICORE_GC
- ((int *)taskpointerarray)[0]=currtpd->numParameters;
- taskpointerarray[1]=NULL;
-#endif
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- // check finish, set the end of the checkTaskInfo
- profileTaskEnd();
-#endif
- profileTaskStart(currtpd->task->name);
-#endif
- // TODO
- //long clock4;
- //clock4 = BAMBOO_GET_EXE_TIME();
- //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe997);
-#endif
- ((void (*)(void **))currtpd->task->taskptr)(taskpointerarray);
- // TODO
- //long clock5;
- //clock5 = BAMBOO_GET_EXE_TIME();
- // tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
-
-#ifdef PROFILE
-#ifdef ACCURATEPROFILE
- // task finish, set the end of the checkTaskInfo
- profileTaskEnd();
- // new a PostTaskInfo for the post-task execution
- profileTaskStart("post task execution");
-#endif
-#endif
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe998);
- BAMBOO_DEBUGPRINT_REG(islock);
-#endif
-
- if(islock) {
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe999);
-#endif
- for(i = 0; i < runtime_locklen; ++i) {
- void * ptr = (void *)(runtime_locks[i].redirectlock);
- int * lock = (int *)(runtime_locks[i].value);
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT_REG((int)ptr);
- BAMBOO_DEBUGPRINT_REG((int)lock);
- BAMBOO_DEBUGPRINT_REG(*((int*)lock+5));
-#endif
-#ifndef MULTICORE_GC
- if(RuntimeHashcontainskey(lockRedirectTbl, (int)lock)) {
- int redirectlock;
- RuntimeHashget(lockRedirectTbl, (int)lock, &redirectlock);
- RuntimeHashremovekey(lockRedirectTbl, (int)lock);
- releasewritelock_r(lock, (int *)redirectlock);
- } else {
-#else
- {
-#endif
- releasewritelock(ptr);
- }
- }
- } // line 3015: if(islock)
-
- //long clock6;
- //clock6 = BAMBOO_GET_EXE_TIME();
- //tprintf("sort: %d, grab: %d, check: %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3));
-
-#ifdef PROFILE
- // post task execution finish, set the end of the postTaskInfo
- profileTaskEnd();
-#endif
-
- // Free up task parameter descriptor
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- currtpd = NULL;
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe99a);
-#endif
- //long clock7;
- //clock7 = BAMBOO_GET_EXE_TIME();
- //tprintf("sort: %d, grab: %d, check: %d, release: %d, other %d \n", (int)(clock2-clock1), (int)(clock3-clock2), (int)(clock4-clock3), (int)(clock6-clock5), (int)(clock7-clock6));
-
- } //
- //} // if (hashsize(activetasks)>0)
- } // while(hashsize(activetasks)>0)
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe99b);
-#endif
-}
-
-/* This function processes an objects tags */
-void processtags(struct parameterdescriptor *pd,
- int index,
- struct parameterwrapper *parameter,
- int * iteratorcount,
- int *statusarray,
- int numparams) {
- int i;
-
- for(i=0; i<pd->numbertags; i++) {
- int slotid=pd->tagarray[2*i];
- int tagid=pd->tagarray[2*i+1];
-
- if (statusarray[slotid+numparams]==0) {
- parameter->iterators[*iteratorcount].istag=1;
- parameter->iterators[*iteratorcount].tagid=tagid;
- parameter->iterators[*iteratorcount].slot=slotid+numparams;
- parameter->iterators[*iteratorcount].tagobjectslot=index;
- statusarray[slotid+numparams]=1;
- (*iteratorcount)++;
- }
- }
-}
-
-
-void processobject(struct parameterwrapper *parameter,
- int index,
- struct parameterdescriptor *pd,
- int *iteratorcount,
- int * statusarray,
- int numparams) {
- int i;
- int tagcount=0;
- struct ObjectHash * objectset=
- ((struct parameterwrapper *)pd->queue)->objectset;
-
- parameter->iterators[*iteratorcount].istag=0;
- parameter->iterators[*iteratorcount].slot=index;
- parameter->iterators[*iteratorcount].objectset=objectset;
- statusarray[index]=1;
-
- for(i=0; i<pd->numbertags; i++) {
- int slotid=pd->tagarray[2*i];
- //int tagid=pd->tagarray[2*i+1];
- if (statusarray[slotid+numparams]!=0) {
- /* This tag has already been enqueued, use it to narrow search */
- parameter->iterators[*iteratorcount].tagbindings[tagcount]=
- slotid+numparams;
- tagcount++;
- }
- }
- parameter->iterators[*iteratorcount].numtags=tagcount;
-
- (*iteratorcount)++;
-}
-
-/* This function builds the iterators for a task & parameter */
-
-void builditerators(struct taskdescriptor * task,
- int index,
- struct parameterwrapper * parameter) {
- int statusarray[MAXTASKPARAMS];
- int i;
- int numparams=task->numParameters;
- int iteratorcount=0;
- for(i=0; i<MAXTASKPARAMS; i++) statusarray[i]=0;
-
- statusarray[index]=1; /* Initial parameter */
- /* Process tags for initial iterator */
-
- processtags(task->descriptorarray[index], index, parameter,
- &iteratorcount, statusarray, numparams);
-
- while(1) {
-loopstart:
- /* Check for objects with existing tags */
- for(i=0; i<numparams; i++) {
- if (statusarray[i]==0) {
- struct parameterdescriptor *pd=task->descriptorarray[i];
- int j;
- for(j=0; j<pd->numbertags; j++) {
- int slotid=pd->tagarray[2*j];
- if(statusarray[slotid+numparams]!=0) {
- processobject(parameter,i,pd,&iteratorcount,
- statusarray,numparams);
- processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
- goto loopstart;
- }
- }
- }
- }
-
- /* Next do objects w/ unbound tags*/
-
- for(i=0; i<numparams; i++) {
- if (statusarray[i]==0) {
- struct parameterdescriptor *pd=task->descriptorarray[i];
- if (pd->numbertags>0) {
- processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
- processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
- goto loopstart;
- }
- }
- }
-
- /* Nothing with a tag enqueued */
-
- for(i=0; i<numparams; i++) {
- if (statusarray[i]==0) {
- struct parameterdescriptor *pd=task->descriptorarray[i];
- processobject(parameter,i,pd,&iteratorcount,statusarray,numparams);
- processtags(pd,i,parameter,&iteratorcount,statusarray,numparams);
- goto loopstart;
- }
- }
-
- /* Nothing left */
- return;
- }
-}
-
-void printdebug() {
- int i;
- int j;
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
- return;
- }
- for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
- struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
-#ifndef RAW
- printf("%s\n", task->name);
-#endif
- for(j=0; j<task->numParameters; j++) {
- struct parameterdescriptor *param=task->descriptorarray[j];
- struct parameterwrapper *parameter=param->queue;
- struct ObjectHash * set=parameter->objectset;
- struct ObjectIterator objit;
-#ifndef RAW
- printf(" Parameter %d\n", j);
-#endif
- ObjectHashiterator(set, &objit);
- while(ObjhasNext(&objit)) {
- struct ___Object___ * obj=(struct ___Object___ *)Objkey(&objit);
- struct ___Object___ * tagptr=obj->___tags___;
- int nonfailed=Objdata4(&objit);
- int numflags=Objdata3(&objit);
- int flags=Objdata2(&objit);
- Objnext(&objit);
-#ifndef RAW
- printf(" Contains %lx\n", obj);
- printf(" flag=%d\n", obj->flag);
-#endif
- if (tagptr==NULL) {
- } else if (tagptr->type==TAGTYPE) {
-#ifndef RAW
- printf(" tag=%lx\n",tagptr);
-#else
- ;
-#endif
- } else {
- int tagindex=0;
- struct ArrayObject *ao=(struct ArrayObject *)tagptr;
- for(; tagindex<ao->___cachedCode___; tagindex++) {
-#ifndef RAW
- printf(" tag=%lx\n",ARRAYGET(ao,struct ___TagDescriptor___*,
- tagindex));
-#else
- ;
-#endif
- }
- }
- }
- }
- }
-}
-
-
-/* This function processes the task information to create queues for
- each parameter type. */
-
-void processtasks() {
- int i;
- if(BAMBOO_NUM_OF_CORE > NUMCORESACTIVE - 1) {
- return;
- }
- for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
- struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
- int j;
-
- /* Build objectsets */
- for(j=0; j<task->numParameters; j++) {
- struct parameterdescriptor *param=task->descriptorarray[j];
- struct parameterwrapper *parameter=param->queue;
- parameter->objectset=allocateObjectHash(10);
- parameter->task=task;
- }
-
- /* Build iterators for parameters */
- for(j=0; j<task->numParameters; j++) {
- struct parameterdescriptor *param=task->descriptorarray[j];
- struct parameterwrapper *parameter=param->queue;
- builditerators(task, j, parameter);
- }
- }
-}
-
-void toiReset(struct tagobjectiterator * it) {
- if (it->istag) {
- it->tagobjindex=0;
- } else if (it->numtags>0) {
- it->tagobjindex=0;
- } else {
- ObjectHashiterator(it->objectset, &it->it);
- }
-}
-
-int toiHasNext(struct tagobjectiterator *it,
- void ** objectarray OPTARG(int * failed)) {
- if (it->istag) {
- /* Iterate tag */
- /* Get object with tags */
- struct ___Object___ *obj=objectarray[it->tagobjectslot];
- struct ___Object___ *tagptr=obj->___tags___;
- if (tagptr->type==TAGTYPE) {
- if ((it->tagobjindex==0)&& /* First object */
- (it->tagid==((struct ___TagDescriptor___ *)tagptr)->flag)) /* Right tag type */
- return 1;
- else
- return 0;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- int tagindex=it->tagobjindex;
- for(; tagindex<ao->___cachedCode___; tagindex++) {
- struct ___TagDescriptor___ *td=
- ARRAYGET(ao, struct ___TagDescriptor___ *, tagindex);
- if (td->flag==it->tagid) {
- it->tagobjindex=tagindex; /* Found right type of tag */
- return 1;
- }
- }
- return 0;
- }
- } else if (it->numtags>0) {
- /* Use tags to locate appropriate objects */
- struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
- struct ___Object___ *objptr=tag->flagptr;
- int i;
- if (objptr->type!=OBJECTARRAYTYPE) {
- if (it->tagobjindex>0)
- return 0;
- if (!ObjectHashcontainskey(it->objectset, (int) objptr))
- return 0;
- for(i=1; i<it->numtags; i++) {
- struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
- if (!containstag(objptr,tag2))
- return 0;
- }
- return 1;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) objptr;
- int tagindex;
- int i;
- for(tagindex=it->tagobjindex;tagindex<ao->___cachedCode___;tagindex++){
- struct ___Object___ *objptr=
- ARRAYGET(ao,struct ___Object___*,tagindex);
- if (!ObjectHashcontainskey(it->objectset, (int) objptr))
- continue;
- for(i=1; i<it->numtags; i++) {
- struct ___TagDescriptor___ *tag2=objectarray[it->tagbindings[i]];
- if (!containstag(objptr,tag2))
- goto nexttag;
- }
- it->tagobjindex=tagindex;
- return 1;
-nexttag:
- ;
- }
- it->tagobjindex=tagindex;
- return 0;
- }
- } else {
- return ObjhasNext(&it->it);
- }
-}
-
-int containstag(struct ___Object___ *ptr,
- struct ___TagDescriptor___ *tag) {
- int j;
- struct ___Object___ * objptr=tag->flagptr;
- if (objptr->type==OBJECTARRAYTYPE) {
- struct ArrayObject *ao=(struct ArrayObject *)objptr;
- for(j=0; j<ao->___cachedCode___; j++) {
- if (ptr==ARRAYGET(ao, struct ___Object___*, j)) {
- return 1;
- }
- }
- return 0;
- } else {
- return objptr==ptr;
- }
-}
-
-void toiNext(struct tagobjectiterator *it,
- void ** objectarray OPTARG(int * failed)) {
- /* hasNext has all of the intelligence */
- if(it->istag) {
- /* Iterate tag */
- /* Get object with tags */
- struct ___Object___ *obj=objectarray[it->tagobjectslot];
- struct ___Object___ *tagptr=obj->___tags___;
- if (tagptr->type==TAGTYPE) {
- it->tagobjindex++;
- objectarray[it->slot]=tagptr;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) tagptr;
- objectarray[it->slot]=
- ARRAYGET(ao, struct ___TagDescriptor___ *, it->tagobjindex++);
- }
- } else if (it->numtags>0) {
- /* Use tags to locate appropriate objects */
- struct ___TagDescriptor___ *tag=objectarray[it->tagbindings[0]];
- struct ___Object___ *objptr=tag->flagptr;
- if (objptr->type!=OBJECTARRAYTYPE) {
- it->tagobjindex++;
- objectarray[it->slot]=objptr;
- } else {
- struct ArrayObject *ao=(struct ArrayObject *) objptr;
- objectarray[it->slot]=
- ARRAYGET(ao, struct ___Object___ *, it->tagobjindex++);
- }
- } else {
- /* Iterate object */
- objectarray[it->slot]=(void *)Objkey(&it->it);
- Objnext(&it->it);
- }
-}
-
-#ifdef PROFILE
-inline void profileTaskStart(char * taskname) {
- if(!taskInfoOverflow) {
- TaskInfo* taskInfo = RUNMALLOC(sizeof(struct task_info));
- taskInfoArray[taskInfoIndex] = taskInfo;
- taskInfo->taskName = taskname;
- taskInfo->startTime = BAMBOO_GET_EXE_TIME();
- taskInfo->endTime = -1;
- taskInfo->exitIndex = -1;
- taskInfo->newObjs = NULL;
- }
-}
-
-inline void profileTaskEnd() {
- if(!taskInfoOverflow) {
- taskInfoArray[taskInfoIndex]->endTime = BAMBOO_GET_EXE_TIME();
- taskInfoIndex++;
- if(taskInfoIndex == TASKINFOLENGTH) {
- taskInfoOverflow = true;
- //taskInfoIndex = 0;
- }
- }
-}
-
-// output the profiling data
-void outputProfileData() {
-#ifdef USEIO
- int i;
- unsigned long long totaltasktime = 0;
- unsigned long long preprocessingtime = 0;
- unsigned long long objqueuecheckingtime = 0;
- unsigned long long postprocessingtime = 0;
- //int interruptiontime = 0;
- unsigned long long other = 0;
- unsigned long long averagetasktime = 0;
- int tasknum = 0;
-
- printf("Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
- // output task related info
- for(i = 0; i < taskInfoIndex; i++) {
- TaskInfo* tmpTInfo = taskInfoArray[i];
- unsigned long long duration = tmpTInfo->endTime - tmpTInfo->startTime;
- printf("%s, %lld, %lld, %lld, %lld",
- tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime,
- duration, tmpTInfo->exitIndex);
- // summarize new obj info
- if(tmpTInfo->newObjs != NULL) {
- struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
- struct RuntimeIterator * iter = NULL;
- while(0 == isEmpty(tmpTInfo->newObjs)) {
- char * objtype = (char *)(getItem(tmpTInfo->newObjs));
- if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
- int num = 0;
- RuntimeHashget(nobjtbl, (int)objtype, &num);
- RuntimeHashremovekey(nobjtbl, (int)objtype);
- num++;
- RuntimeHashadd(nobjtbl, (int)objtype, num);
- } else {
- RuntimeHashadd(nobjtbl, (int)objtype, 1);
- }
- //printf(stderr, "new obj!\n");
- }
-
- // output all new obj info
- iter = RuntimeHashcreateiterator(nobjtbl);
- while(RunhasNext(iter)) {
- char * objtype = (char *)Runkey(iter);
- int num = Runnext(iter);
- printf(", %s, %d", objtype, num);
- }
- }
- printf("\n");
- if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
- preprocessingtime += duration;
- } else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
- postprocessingtime += duration;
- } else if(strcmp(tmpTInfo->taskName, "objqueue checking") == 0) {
- objqueuecheckingtime += duration;
- } else {
- totaltasktime += duration;
- averagetasktime += duration;
- tasknum++;
- }
- }
-
- if(taskInfoOverflow) {
- printf("Caution: task info overflow!\n");
- }
-
- other = totalexetime-totaltasktime-preprocessingtime-postprocessingtime;
- averagetasktime /= tasknum;
-
- printf("\nTotal time: %lld\n", totalexetime);
- printf("Total task execution time: %lld (%d%%)\n", totaltasktime,
- (int)(((double)totaltasktime/(double)totalexetime)*100));
- printf("Total objqueue checking time: %lld (%d%%)\n",
- objqueuecheckingtime,
- (int)(((double)objqueuecheckingtime/(double)totalexetime)*100));
- printf("Total pre-processing time: %lld (%d%%)\n", preprocessingtime,
- (int)(((double)preprocessingtime/(double)totalexetime)*100));
- printf("Total post-processing time: %lld (%d%%)\n", postprocessingtime,
- (int)(((double)postprocessingtime/(double)totalexetime)*100));
- printf("Other time: %lld (%d%%)\n", other,
- (int)(((double)other/(double)totalexetime)*100));
-
-
- printf("\nAverage task execution time: %lld\n", averagetasktime);
-
- //printf("\nTotal time spent for interruptions: %lld\n", interrupttime);
-#else
- int i = 0;
- int j = 0;
-
- BAMBOO_DEBUGPRINT(0xdddd);
- // output task related info
- for(i= 0; i < taskInfoIndex; i++) {
- TaskInfo* tmpTInfo = taskInfoArray[i];
- char* tmpName = tmpTInfo->taskName;
- int nameLen = strlen(tmpName);
- BAMBOO_DEBUGPRINT(0xddda);
- for(j = 0; j < nameLen; j++) {
- BAMBOO_DEBUGPRINT_REG(tmpName[j]);
- }
- BAMBOO_DEBUGPRINT(0xdddb);
- BAMBOO_DEBUGPRINT_REG(tmpTInfo->startTime);
- BAMBOO_DEBUGPRINT_REG(tmpTInfo->endTime);
- BAMBOO_DEBUGPRINT_REG(tmpTInfo->exitIndex);
- if(tmpTInfo->newObjs != NULL) {
- struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
- struct RuntimeIterator * iter = NULL;
- while(0 == isEmpty(tmpTInfo->newObjs)) {
- char * objtype = (char *)(getItem(tmpTInfo->newObjs));
- if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
- int num = 0;
- RuntimeHashget(nobjtbl, (int)objtype, &num);
- RuntimeHashremovekey(nobjtbl, (int)objtype);
- num++;
- RuntimeHashadd(nobjtbl, (int)objtype, num);
- } else {
- RuntimeHashadd(nobjtbl, (int)objtype, 1);
- }
- }
-
- // ouput all new obj info
- iter = RuntimeHashcreateiterator(nobjtbl);
- while(RunhasNext(iter)) {
- char * objtype = (char *)Runkey(iter);
- int num = Runnext(iter);
- int nameLen = strlen(objtype);
- BAMBOO_DEBUGPRINT(0xddda);
- for(j = 0; j < nameLen; j++) {
- BAMBOO_DEBUGPRINT_REG(objtype[j]);
- }
- BAMBOO_DEBUGPRINT(0xdddb);
- BAMBOO_DEBUGPRINT_REG(num);
- }
- }
- BAMBOO_DEBUGPRINT(0xdddc);
- }
-
- if(taskInfoOverflow) {
- BAMBOO_DEBUGPRINT(0xefee);
- }
-
-#ifdef PROFILE_INTERRUPT
- // output interrupt related info
- for(i = 0; i < interruptInfoIndex; i++) {
- InterruptInfo* tmpIInfo = interruptInfoArray[i];
- BAMBOO_DEBUGPRINT(0xddde);
- BAMBOO_DEBUGPRINT_REG(tmpIInfo->startTime);
- BAMBOO_DEBUGPRINT_REG(tmpIInfo->endTime);
- BAMBOO_DEBUGPRINT(0xdddf);
- }
-
- if(interruptInfoOverflow) {
- BAMBOO_DEBUGPRINT(0xefef);
- }
-#endif // PROFILE_INTERRUPT
-
- BAMBOO_DEBUGPRINT(0xeeee);
-#endif
-}
-#endif // #ifdef PROFILE
-
-#endif
BUILDDIR="$CURDIR/$tmpbuilddirectory"
+BAMBOORUNTIME=$ROBUSTROOT/Runtime/bamboo
+
cd $1
cd $CURDIR
shift
MAKEFILE="$MAKEFILE.$RAWCONFIG"
fi #useio version
-cp $ROBUSTROOT/Runtime/RAW/$MAKEFILE ./Makefile
+cp $BAMBOORUNTIME/RAW/$MAKEFILE ./Makefile
cp ../Runtime/*.c ./
cp ../Runtime/*.h ./
cp ../Runtime/*.S ./
cp ../Runtime/*.s ./
-cp ../Runtime/RAW/*.c ./
-cp ../Runtime/RAW/*.h ./
-cp ../Runtime/RAW/*.S ./
-cp ../Runtime/RAW/*.s ./
+cp $BAMBOORUNTIME/RAW/*.c ./
+cp $BAMBOORUNTIME/RAW/*.h ./
+cp $BAMBOORUNTIME/RAW/*.S ./
+cp $BAMBOORUNTIME/RAW/*.s ./
cp ../$tmpbuilddirectory/*.c ./
cp ../$tmpbuilddirectory/*.h ./
cp $ROBUSTROOT/Tilera/Runtime/$TILERA_INDIR/bamboo-vmlinux-pci.hvc ./bamboo-vmlinux-pci.hvc
fi
fi
-cp ../Runtime/multicoretask.c ./
-cp ../Runtime/multicoreruntime.c ./
cp ../Runtime/Queue.c ./
cp ../Runtime/file.c ./
cp ../Runtime/math.c ./
cp ../Runtime/object.c ./
cp ../Runtime/GenericHashtable.c ./
cp ../Runtime/SimpleHash.c ./
-cp ../Runtime/GCSharedHash.c ./
cp ../Runtime/ObjectHash.c ./
cp ../Runtime/socket.c ./
cp ../Runtime/mem.c ./
-cp ../Runtime/multicoregarbage.c ./
-cp ../Runtime/MGCHash.c ./
cp ../Runtime/GenericHashtable.h ./
cp ../Runtime/mem.h ./
-cp ../Runtime/multicoreruntime.h ./
cp ../Runtime/object.h ./
cp ../Runtime/ObjectHash.h ./
cp ../Runtime/Queue.h ./
cp ../Runtime/runtime.h ./
cp ../Runtime/SimpleHash.h ./
-cp ../Runtime/GCSharedHash.h ./
-cp ../Runtime/multicoregc.h ./
-cp ../Runtime/multicoregarbage.h ./
-cp ../Runtime/multicorehelper.h ./
-cp ../Runtime/MGCHash.h ./
+cp $BAMBOORUNTIME/multicoretask.c ./
+cp $BAMBOORUNTIME/multicoreruntime.c ./
+cp $BAMBOORUNTIME/GCSharedHash.c ./
+cp $BAMBOORUNTIME/multicoregarbage.c ./
+cp $BAMBOORUNTIME/MGCHash.c ./
+cp $BAMBOORUNTIME/multicoreruntime.h ./
+cp $BAMBOORUNTIME/GCSharedHash.h ./
+cp $BAMBOORUNTIME/multicoregc.h ./
+cp $BAMBOORUNTIME/multicoregarbage.h ./
+cp $BAMBOORUNTIME/multicorehelper.h ./
+cp $BAMBOORUNTIME/MGCHash.h ./
cp ../Tilera/Runtime/*.c ./
cp ../Tilera/Runtime/*.h ./
cp ../Tilera/Runtime/$TILERA_INDIR/*.c ./
if $MULTICOREFLAG
then
-RUNTIMEFILE="$ROBUSTROOT/Runtime/multicoreruntime.c $ROBUSTROOT/Runtime/multicoretask.c"
+RUNTIMEFILE="$BAMBOORUNTIME/multicoreruntime.c $BAMBOORUNTIME/multicoretask.c"
+INCLUDES="$INCLUDES -I$BAMBOORUNTIME"
else
RUNTIMEFILE="$ROBUSTROOT/Runtime/runtime.c $ROBUSTROOT/Runtime/task.c"
fi