if(!state.MULTICORE) {
outclassdefs.println(" void * flagptr;");
} else {
- outclassdefs.println(" int version;");
- outclassdefs.println(" struct ___Object___ * original;");
- //outclassdefs.println(" int numlocks;"); // array for locks
- outclassdefs.println(" int * lock;");
+ if(state.MULTICOREGC) {
+ outclassdefs.println(" int marked;");
+ }
+ outclassdefs.println(" int version;");
+ outclassdefs.println(" int * lock;"); // lock entry for this obj
+ outclassdefs.println(" void * mutex;");
+ outclassdefs.println(" int lockcount;");
}
if(state.OPTIONAL) {
outclassdefs.println(" int numfses;");
if((!state.MULTICORE) || (cn.getSymbol().equals("TagDescriptor"))) {
classdefout.println(" void * flagptr;");
} else if (state.MULTICORE) {
+ if(state.MULTICOREGC) {
+ classdefout.println(" int marked;");
+ }
classdefout.println(" int version;");
- classdefout.println(" struct ___Object___ * original;");
- //classdefout.println(" int numlocks;"); // array for locks
- classdefout.println(" int * lock;");
+ classdefout.println(" int * lock;"); // lock entry for this obj
+ classdefout.println(" void * mutex;");
+ classdefout.println(" int lockcount;");
}
if (state.OPTIONAL) {
classdefout.println(" int numfses;");
/* This method outputs code for each task. */
private void outputTaskCode(PrintWriter outtaskdefs,
- PrintWriter outmethod,
- PrintWriter outtask,
- Iterator[] taskits,
- int[] numtasks,
+ PrintWriter outmethod,
+ PrintWriter outtask,
+ Iterator[] taskits,
+ int[] numtasks,
int[][] numqueues) {
/* Compile task based program */
outtaskdefs.println("#include \"task.h\"");
}
private void generateTaskMethod(FlatMethod fm,
- LocalityBinding lb,
- PrintWriter output) {
+ LocalityBinding lb,
+ PrintWriter output) {
/*if (State.PRINTFLAT)
System.out.println(fm.printMethod());*/
TaskDescriptor task=fm.getTask();
isolate = (this.currentSchedule.getAllyCoreTable().get(tmpFState) == null) ||
(this.currentSchedule.getAllyCoreTable().get(tmpFState).size() == 0);
}
- /* no longler use the isolate flag in object structure
- if(!isolate) {
- // indentify this object as a shared object
- // isolate flag is initially set as 1, once this flag is set as 0, it is never reset to 1, i.e. once an object
- // is shared, it maybe shared all the time afterwards
- output.println("if(" + super.generateTemp(fm, temp, lb) + "->isolate == 1) {");
- output.println(" " + super.generateTemp(fm, temp, lb) + "->isolate = 0;");
- output.println(" " + super.generateTemp(fm, temp, lb) + "->original = (struct ___Object___ *)" + super.generateTemp(fm, temp, lb) + ";");
- output.println("}");
- }
- */
Vector<Integer> sendto = new Vector<Integer>();
Queue<Integer> queue = null;
}
protected void outputAliasLockCode(FlatMethod fm,
- LocalityBinding lb,
- PrintWriter output) {
+ LocalityBinding lb,
+ PrintWriter output) {
if(this.m_oa == null) {
return;
}
public boolean FLATIRGRAPHUSERMETHODS=false;
public boolean FLATIRGRAPHLIBMETHODS=false;
public boolean MULTICORE=false;
+ public boolean MULTICOREGC=false;
public boolean OWNERSHIP=false;
public int OWNERSHIPALLOCDEPTH=3;
public boolean OWNERSHIPWRITEDOTS=false;
state.FLATIRGRAPHLIBMETHODS=true;
} else if (option.equals("-multicore"))
state.MULTICORE=true;
+ else if (option.equals("-multicoregc"))
+ state.MULTICOREGC=true;
else if (option.equals("-ownership"))
state.OWNERSHIP=true;
else if (option.equals("-ownallocdepth")) {
#include "multicoreruntime.h"
#include "runtime_arch.h"
+// data structures for locking
+struct RuntimeHash locktable;
+static struct RuntimeHash* locktbl = &locktable;
+struct LockValue {
+ int redirectlock;
+ int value;
+};
+
__attribute__((always_inline)) inline void initialization() {
} // initialization()
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) % BAMBOO_TOTALCORE;
+ 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(false, targetcore, 2, 0, (int)ptr, lock2require, BAMBOO_NUM_OF_CORE);
+ }
+ return true;
+}
+
+void releasewritelock_r(void * lock, void * redirectlock);
+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) % BAMBOO_TOTALCORE;
+
+ 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(false, targetcore, 5, 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) % BAMBOO_TOTALCORE;
+
+ 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(false, core, deny==1?0xa:9, 0, (int)ptr, (int)redirectlock);
+ } else {
+ cache_msg_4(false, core, deny==1?0xa:9, 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(false, targetcore, 8, 0, (int)ptr, lock2require, core, BAMBOO_NUM_OF_CORE);
+ } else {
+ cache_msg_6(false, targetcore, 8, 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) % BAMBOO_TOTALCORE;
+ 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(false, targetcore, 2, 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) % BAMBOO_TOTALCORE;
+
+#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(false,targetcore, 5, 1, (int)ptr, reallock);
+ }
+}
+
+void releasewritelock_r(void * lock, void * redirectlock) {
+ int targetcore = 0;
+ int reallock = (int)lock;
+ targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+#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_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(0xa01d);
+ } 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_CLOSE_CRITICAL_SECTION_LOCK();
+#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(false, targetcore, 0xb, 1, (int)lock, (int)redirectlock);
+ }
+}
+
+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) % BAMBOO_TOTALCORE;
+ 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(false, targetcore, 2, 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) % BAMBOO_TOTALCORE;
+
+#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(false, core, deny==1?0xa:9, 1, (int)ptr, (int)redirectlock);
+ } else {
+ cache_msg_4(false, core, deny==1?0xa:9, 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(false, targetcore, 8, 1, (int)ptr, (int)redirectlock, core, BAMBOO_NUM_OF_CORE);
+ } else {
+ cache_msg_6(false, targetcore, 8, 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) % BAMBOO_TOTALCORE;
+
+#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(false, targetcore, 5, 1, (int)ptr, reallock);
+ }
+}
+
+void releasewritelock_I_r(void * lock, void * redirectlock) {
+ int targetcore = 0;
+ int reallock = (int)lock;
+ targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
+
+#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(false, targetcore, 0xb, 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) % BAMBOO_TOTALCORE) != 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) {
--- /dev/null
+#ifdef MULTICORE_GC
+#include "multicoregarbage.h"
+#include "multicoreruntime.h"
+#include "runtime_arch.h"
+#include "SimpleHash.h"
+#include "GenericHashtable.h"
+
+extern struct genhashtable * activetasks;
+extern struct parameterwrapper ** objectqueues[][NUMCLASSES];
+extern struct taskparamdescriptor *currtpd;
+//extern struct RuntimeHash *fdtoobject;
+
+struct largeObjList lObjList;
+struct markedObjList mObjList;
+INTPTR curr_heaptop = 0;
+
+struct markedObjList {
+ struct markedObjItem * head;
+ struct markedObjItem * tail;
+};
+
+struct largeObjList {
+ struct largeObjItem * head;
+ struct largeObjItem * tail;
+};
+
+bool isLarge(void * ptr, int * ttype, int * tsize) {
+ // check if a pointer is referring to a large object
+ 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;
+ }
+ *ttype = type;
+ *tsize = size;
+ return(!isLocal(ptr + size));
+}
+
+int hostcore(void * ptr) {
+ // check the host core of ptr
+ int host = 0;
+ int x = 0;
+ int y = 0;
+ RESIDECORE(ptr, &x, &y);
+ host = (x == 0)?(x * bamboo_height + y) : (x * bamboo_height + y - 2);
+ return host;
+}
+
+bool isLocal(void * ptr) {
+ // check if a pointer is in shared heap on this core
+ return hostcore(ptr) == BAMBOO_NUM_OF_CORE;
+}
+
+void insertMarkedObj(struct markedObjList * list, struct markedObjItem * toinsert) {
+ // insert a markedObjItem
+ struct markedObjItem * tmp = list->head;
+ if(tmp == NULL) {
+ list->head = toinsert;
+ list->tail = toinsert;
+ } else if(tmp->orig > toinsert->orig) {
+ // insert into the head of the list
+ toinsert->next = tmp;
+ list->head = toinsert;
+ } else {
+ struct markedObjItem * next = tmp->next;
+ while(next != NULL) {
+ if(next->orig < toinsert->orig) {
+ tmp = next;
+ next = tmp->next;
+ } else if((next->orig == toinsert->orig) || (tmp->orig == toinsert->orig)) {
+ // has been inserted
+ RUNFREE(toinsert);
+ toinsert = NULL;
+ break;
+ } else {
+ // insert after tmp
+ toinsert->next = next;
+ tmp->next = tmp;
+ break;
+ }
+ } // while(next != NULL)
+ if(next == NULL) {
+ if(tmp->orig == toinsert->orig) {
+ RUNFREE(toinsert);
+ toinsert = NULL;
+ } else {
+ // insert to the tail of the list
+ tmp->next = toinsert;
+ list->tail = toinsert;
+ }
+ } // if(next == NULL)
+ }
+}
+
+struct markedObjItem * getStartItem(struct markedObjItem * moi, INTPTR start) {
+ // find the markedobj whose start address is start
+ struct markedObjItem * tostart = moi;
+ while(tostart->orig < start) {
+ tostart = tostart->next;
+ }
+ return tostart;
+}
+
+void transferMarkResults() {
+ // TODO, need distiguish between send and cache
+ // invoked inside interruptiong handler
+}
+
+void gc() {
+ // core coordinator routine
+ if(0 == BAMBOO_NUM_OF_CORE) {
+ // change to UDN1
+ bme_install_interrupt_handler(INT_UDN_AVAIL, gc_msghandler);
+#ifdef DEBUG
+ tprintf("Process %x(%d): change udn interrupt handler\n", BAMBOO_NUM_OF_CORE,
+ BAMBOO_NUM_OF_CORE);
+#endif
+ __insn_mtspr(SPR_UDN_TAG_1, UDN1_DEMUX_TAG);
+ // enable udn interrupts
+ //__insn_mtspr(SPR_INTERRUPT_MASK_RESET_2_1, INT_MASK_HI(INT_UDN_AVAIL));
+ __insn_mtspr(SPR_UDN_AVAIL_EN, (1<<1));
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+
+ int i = 0;
+ gcwaitconfirm = false;
+ gcwaitconfirm = 0;
+ gcphase = 0;
+ for(i = 1; i < NUMCORES - 1; i++) {
+ // send GC start messages to all cores
+ send_msg_1(true, i, 0x11);
+ }
+ bool isfirst = true;
+ lObjList.head = NULL;
+ lObjList.tail = NULL;
+ mObjList.head = NULL;
+ mObjList.tail = NULL;
+
+ // mark phase
+ while(gcphase == 0) {
+ mark(isfirst);
+ if(isfirst) {
+ isfirst = false;
+ }
+
+ bool allStall = false;
+ // check gcstatus
+ if((!gcwaitconfirm) ||
+ (gcwaitconfirm && (gcnumconfirm == 0))) {
+ BAMBOO_START_CRITICAL_SECTION_STATUS();
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ gcnumsendobjs[BAMBOO_NUM_OF_CORE] = gcself_numsendobjs;
+ gcnumreceiveobjs[BAMBOO_NUM_OF_CORE] = gcself_numreceiveobjs;
+ // check the status of all cores
+ allStall = true;
+ for(i = 0; i < NUMCORES; ++i) {
+ if(gccorestatus[i] != 0) {
+ allStall = false;
+ break;
+ }
+ }
+ 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
+ int sumsendobj = 0;
+ for(i = 0; i < NUMCORES; ++i) {
+ sumsendobj += gcnumsendobjs[i];
+ }
+ for(i = 0; i < NUMCORES; ++i) {
+ sumsendobj -= gcnumreceiveobjs[i];
+ }
+ if(0 == sumsendobj) {
+ if(!gcwaitconfirm) {
+ // 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;
+ gcwaitconfirm = true;
+ gcnumconfirm = NUMCORES - 1;
+ for(i = 1; i < NUMCORES; ++i) {
+ gccorestatus[i] = 1;
+ // send mark phase finish confirm request msg to core i
+ send_msg_1(true, i, 0x18);
+ }
+ } else {
+ // all the core status info are the latest
+ // stop mark phase
+ gcphase = 1;
+ for(i = 0; i < NUMCORES; ++i) {
+ gccorestatus[i] = 1;
+ }
+ } // if(!gcwautconfirm) else()
+ } // if(0 == sumsendobj)
+ } // if(allStall)
+ BAMBOO_CLOSE_CRITICAL_SECTION_STATUS();
+ } // if((!gcwaitconfirm)...
+ } // while(gcphase == 0)
+ // send msgs to all cores requiring large objs info
+ gcnumconfirm = NUMCORES - 1;
+ for(i = 1; i < NUMCORES; ++i) {
+ send_msg_1(true, i, 0x1e);
+ }
+ while(gcnumconfirm != 0) {} // wait for responses
+ // TODO compute load balance
+
+ // TODO cache all large objects
+ for(i = 1; i < NUMCORES; ++i) {
+ //TODO send start compact messages to all cores
+
+ }
+
+ // compact phase
+ compact();
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ while(gcphase == 1) {
+ // check the status of all cores
+ allStall = true;
+ for(i = 0; i < NUMCORES; ++i) {
+ if(gccorestatus[i] != 0) {
+ allStall = false;
+ break;
+ }
+ }
+ if(allStall) {
+ for(i = 0; i < NUMCORES; ++i) {
+ gccorestatus[i] = 1;
+ }
+ break;
+ }
+ } // while(gcphase == 1)
+ // TODO merge all mapping information
+ gcphase = 2;
+ for(i = 1; i < NUMCORES; ++i) {
+ // send start flush messages to all cores
+ send_msg_1(true, i, 0x13);
+ }
+
+ // flush phase
+ flush();
+ gccorestatus[BAMBOO_NUM_OF_CORE] = 0;
+ while(gcphase == 2) {
+ // check the status of all cores
+ allStall = true;
+ for(i = 0; i < NUMCORES; ++i) {
+ if(gccorestatus[i] != 0) {
+ allStall = false;
+ break;
+ }
+ }
+ if(allStall) {
+ break;
+ }
+ } // while(gcphase == 2)
+ // TODO merge all mapping information
+ gcphase = 3;
+ for(i = 1; i < NUMCORES; ++i) {
+ // send gc finish messages to all cores
+ send_msg_1(true, i, 0x17);
+ }
+
+ // change to UDN0
+ bme_install_interrupt_handler(INT_UDN_AVAIL, udn_inter_handle);
+#ifdef DEBUG
+ tprintf("Process %x(%d): change back udn interrupt handler\n", BAMBOO_NUM_OF_CORE,
+ BAMBOO_NUM_OF_CORE);
+#endif
+ __insn_mtspr(SPR_UDN_TAG_0, UDN0_DEMUX_TAG);
+ // enable udn interrupts
+ //__insn_mtspr(SPR_INTERRUPT_MASK_RESET_2_1, INT_MASK_HI(INT_UDN_AVAIL));
+ __insn_mtspr(SPR_UDN_AVAIL_EN, (1<<0));
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+
+ return;
+ } else {
+ BAMBOO_EXIT(0xb001);
+ }
+}
+
+void mark(bool isfirst) {
+ if(isfirst) {
+ if(gcphase != 0) {
+ BAMBOO_EXIT(0xb002);
+ }
+ gcbusystatus = 1;
+ // initialize gctomark queue
+ while(!isEmpty(gctomark)) {
+ getItem(gctomark);
+ }
+ // enqueue current stack TODO
+
+ // enqueue objectsets
+ int i;
+ 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 *orig=(void *)ptr->key;
+ addNewItem(gctomark, orig);
+ ptr=ptr->lnext;
+ }
+ }
+ }
+ // euqueue current task descriptor
+ for(i=0; i<currtpd->numParameters; i++) {
+ void *orig=currtpd->parameterArray[i];
+ addNewItem(gctomark, orig);
+ }
+ // euqueue active tasks
+ struct genpointerlist * ptr=activetasks->list;
+ while(ptr!=NULL) {
+ struct taskparamdescriptor *tpd=ptr->src;
+ int i;
+ for(i=0; i<tpd->numParameters; i++) {
+ void * orig=tpd->parameterArray[i];
+ addNewItem(gctomark, orig);
+ }
+ ptr=ptr->inext;
+ }
+ }
+
+ // mark phase
+ while(gcphase == 0) {
+ while(!isEmpty(gctomark)) {
+ voit * ptr = getItem(gctomark);
+ int size = 0;
+ int type = 0;
+ if(isLarge(ptr, &type, &size)) {
+ // ptr is a large object
+ struct largeObjItem * loi =
+ (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem));
+ loi->orig = (INTPTR)ptr;
+ loi->dst = (INTPTR)0;
+ loi->length = size;
+ if(lObjList.head == NULL) {
+ lObjList.head = lObjList.tail = loi;
+ } else {
+ lObjList.tail->next = loi;
+ lObjList.tail = loi;
+ }
+ } else if (isLocal(ptr)) {
+ // ptr is an active object on this core
+ if(type == -1) {
+ // nothing to do
+ }
+ curr_heaptop += size;
+ struct markedObjItem * moi =
+ (struct markedObjItem *)RUNMALLOC(sizeof(struct markedObjItem));
+ moi->orig = (INTPTR)ptr;
+ moi->dst = (INTPTR)0;
+ insertMarkedObj(&mObjList, moi);
+ }
+ // 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];
+ int host = hostcore(objptr);
+ if(BAMBOO_NUM_OF_CORE == host) {
+ // on this core
+ addNewItem(gctomark, objptr);
+ } else {
+ // send a msg to host informing that objptr is active
+ send_msg_2(true, host, 0x1a, objptr);
+ gcself_numsendobjs++;
+ }
+ }
+ } else {
+ INTPTR size=pointer[0];
+ int i;
+ for(i=1; i<=size; i++) {
+ unsigned int offset=pointer[i];
+ void * objptr=*((void **)(((char *)ptr)+offset));
+ int host = hostcore(objptr);
+ if(BAMBOO_NUM_OF_CORE == host) {
+ // on this core
+ addNewItem(gctomark, objptr);
+ } else {
+ // send a msg to host informing that objptr is active
+ send_msg_2(true, host, 0x1a, objptr);
+ gcself_numsendobjs++;
+ }
+ }
+ }
+ } // while(!isEmpty(gctomark))
+ gcbusystatus = false;
+ // send mark finish msg to core coordinator
+ send_msg_4(true, STARTUPCORE, 0x14, BAMBOO_NUM_OF_CORE, gcself_numsendobjs, gcself_numreceiveobjs);
+
+ if(BAMBOO_NUM_OF_CORE == 0) {
+ return;
+ }
+ } // while(gcphase == 0)
+} // mark()
+
+void compact() {
+ if(gcphase != 1) {
+ BAMBOO_EXIT(0xb003);
+ }
+ curr_heaptop = 0;
+ struct markedObjItem * moi = mObjList.head;
+ bool iscopy = true;
+ while(moi != NULL) {
+ if((cinstruction == NULL) || (cinstruction->tomoveobjs == NULL)
+ || (curr_heaptop < cinstruction->tomoveobjs->starts[0])) {
+ // objs to compact
+ int type = ((int *)(moi->orig))[0];
+ int size = 0;
+ if(type == -1) {
+ // do nothing
+ }
+ if(type < NUMCLASSES) {
+ // a normal object
+ size = classsize[type];
+ moi->dst = curr_heaptop;
+ curr_heaptop += size;
+ if(iscopy) {
+ memcpy(moi->dst, moi->orig, size);
+ genputtable(pointertbl, moi->orig, moi->dst);
+ }
+ } else {
+ // an array
+ struct ArrayObject *ao=(struct ArrayObject *)ptr;
+ int elementsize=classsize[type];
+ int length=ao->___length___;
+ size=sizeof(struct ArrayObject)+length*elementsize;
+ moi->dst = curr_heaptop;
+ curr_heaptop += size;
+ if(iscopy) {
+ memcpy(moi->dst, moi->orig, size);
+ genputtable(pointertbl, moi->orig, moi->dst);
+ }
+ }
+ } else {
+ iscopy = false;;
+ }
+ moi = moi->next;
+ } // while(moi != NULL)
+ if(moi == NULL) {
+ if(cinstruction->incomingobjs != NULL) {
+ for(int j = 0; j < cinstruction->incomingobjs->length; j++) {
+ // send messages to corresponding cores to start moving
+ send_msg_2(true, cinstruction->incomingobjs->dsts[j], 0x1b, BAMBOO_NUM_OF_CORE);
+ }
+ }
+ } else {
+ int num_dsts = cinstruction->tomoveobjs->length;
+ while(num_dsts > 0) {
+ while(!gctomove) {}
+ // start moving objects to other cores
+ gctomove = 0;
+ while(!isEmpty(gcdsts)) {
+ int dst = (int)(getItem(gcdsts));
+ num_dsts--;
+ int j = 0;
+ for(j = 0; j < cinstruction->tomoveobjs->length; j++) {
+ if(dst == cinstruction->tomoveobjs->dsts[j]) {
+ break;
+ }
+ }
+ INTPTR top = cinstruction->tomoveobjs->dststarts[j];
+ INTPTR start = cinstruction->tomoveobjs->starts[j];
+ INTPTR end = cinstruction->tomoveobjs->ends[j];
+ struct markedObjItem * tomove = getStartItem(moi, start);
+ do {
+ int type = ((int *)(tomove->orig))[0];
+ int size = 0;
+ if(type == -1) {
+ // do nothing
+ }
+ if(type < NUMCLASSES) {
+ // a normal object
+ size = classsize[type];
+ moi->dst = top;
+ top += size;
+ memcpy(moi->dst, moi->orig, size);
+ genputtable(pointertbl, moi->orig, moi->dst);
+ } else {
+ // an array
+ struct ArrayObject *ao=(struct ArrayObject *)ptr;
+ int elementsize=classsize[type];
+ int length=ao->___length___;
+ size=sizeof(struct ArrayObject)+length*elementsize;
+ moi->dst = top;
+ top += size;
+ memcpy(moi->dst, moi->orig, size);
+ genputtable(pointertbl, moi->orig, moi->dst);
+ }
+ tomove = tomove->next;
+ } while(tomove->orig < end);
+ } // while(!isEmpty(gcdsts))
+ } // while(num_dsts > 0)
+ } // if(moi == NULL) else()
+ if((cinstruction != NULL) && (cinstruction->largeobjs != NULL)) {
+ // move all large objects
+ do {
+ // dequeue the first large obj
+ struct largeObjItem * loi = cinstruction->largeobjs;
+ cinstruction->largeobjs = loi->next;
+ // move this large obj
+ memcpy(loi->dst, loi->orig, loi->length);
+ genputtable(pointertbl, loi->orig, loi->dst);
+ RUNFREE(loi);
+ }while(cinstruction->largeobjs != NULL);
+ }
+ // send compact finish message to core coordinator
+ send_msg_2(true, STARTUPCORE, 0x15, BAMBOO_NUM_OF_CORE);
+
+} // compact()
+
+void flush() {
+ struct markedObjItem * moi = mObjList.head;
+ while(moi != NULL) {
+ void * ptr = moi->dst;
+ int type = ((int *)(ptr))[0];
+ // 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];
+ // change to new address
+ void *dstptr = gengettable(pointertbl, objptr);
+ if(NULL == dstptr) {
+ // send msg to host core for the mapping info
+ obj2map = (int)objptr;
+ ismapped = false;
+ mappedobj = NULL;
+ send_msg_3(true, hostcore(objptr), 0x1c, (int)objptr, BAMBOO_NUM_OF_CORE);
+ while(!ismapped) {}
+ dstptr = mappedobj;
+ }
+ ((void **)(((char *)&ao->___length___)+sizeof(int)))[j] = dstptr;
+ }
+ } else {
+ INTPTR size=pointer[0];
+ int i;
+ for(i=1; i<=size; i++) {
+ unsigned int offset=pointer[i];
+ void * objptr=*((void **)(((char *)ptr)+offset));
+ // change to new address
+ void *dstptr = gengettable(pointertbl, objptr);
+ if(NULL == dstptr) {
+ // send msg to host core for the mapping info
+ obj2map = (int)objptr;
+ ismapped = false;
+ mappedobj = NULL;
+ send_msg_3(true, hostcore(objptr), 0x1c, (int)objptr, BAMBOO_NUM_OF_CORE);
+ while(!ismapped) {}
+ dstptr = mappedobj;
+ }
+ *((void **)(((char *)ptr)+offset)) = dstptr;
+ }
+ }
+ moi = moi->next;
+ } // while(moi != NULL)
+ // send flush finish message to core coordinator
+ send_msg_2(true, STARTUPCORE, 0x16, BAMBOO_NUM_OF_CORE);
+
+} // flush()
+
+void collect() {
+ // core collector routine
+ // change to UDN1
+ bme_install_interrupt_handler(INT_UDN_AVAIL, gc_msghandler);
+#ifdef DEBUG
+ tprintf("Process %x(%d): change udn interrupt handler\n", BAMBOO_NUM_OF_CORE,
+ BAMBOO_NUM_OF_CORE);
+#endif
+ __insn_mtspr(SPR_UDN_TAG_1, UDN1_DEMUX_TAG);
+ // enable udn interrupts
+ //__insn_mtspr(SPR_INTERRUPT_MASK_RESET_2_1, INT_MASK_HI(INT_UDN_AVAIL));
+ __insn_mtspr(SPR_UDN_AVAIL_EN, (1<<1));
+ BAMBOO_CLOSE_CRITICAL_SECTION_MSG();
+
+ lObjList.head = NULL;
+ lObjList.tail = NULL;
+ mObjList.head = NULL;
+ mObjList.tail = NULL;
+ mark(true);
+ compact();
+ while(gcphase != 2) {}
+ flush();
+
+ while(true) {
+ if(gcphase == 3) {
+ // change to UDN0
+ bme_install_interrupt_handler(INT_UDN_AVAIL, udn_inter_handle);
+#ifdef DEBUG
+ tprintf("Process %x(%d): change back udn interrupt handler\n", BAMBOO_NUM_OF_CORE,
+ BAMBOO_NUM_OF_CORE);
+#endif
+ __insn_mtspr(SPR_UDN_TAG_0, UDN0_DEMUX_TAG);
+ // enable udn interrupts
+ //__insn_mtspr(SPR_INTERRUPT_MASK_RESET_2_1, INT_MASK_HI(INT_UDN_AVAIL));
+ __insn_mtspr(SPR_UDN_AVAIL_EN, (1<<0));
+ BAMBOO_START_CRITICAL_SECTION_MSG();
+
+ return;
+ }
+ }
+}
+
+/* Message format:
+ * type + Msgbody
+ * type:11 -- GC start
+ * 12 -- compact phase start
+ * 13 -- flush phase start
+ * 14 -- mark phase finish
+ * 15 -- compact phase finish
+ * 16 -- flush phase finish
+ * 17 -- GC finish
+ * 18 -- marked phase finish confirm request
+ * 19 -- marked phase finish confirm response
+ * 1a -- markedObj msg
+ * 1b -- start moving objs msg
+ * 1c -- ask for mapping info of a markedObj
+ * 1d -- mapping info of a markedObj
+ * 1e -- large objs info request
+ * 1f -- large objs info response
+ *
+ * GCMsg: 11 (size is always 1 * sizeof(int))
+ * 12 + 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)+)?
+ * 13 (size is always 1 * sizeof(int))
+ * 14 + corenum + gcsendobjs + gcreceiveobjs (size if always 4 * sizeof(int))
+ * 15/16 + corenum (size is always 2 * sizeof(int))
+ * 17 (size is always 1 * sizeof(int))
+ * 18 (size if always 1 * sizeof(int))
+ * 19 + size of msg + corenum + gcsendobjs + gcreceiveobjs (size is always 5 * sizeof(int))
+ * 1a + obj's address (size is always 2 * sizeof(int))
+ * 1b + corenum ( size is always 2 * sizeof(int))
+ * 1c + obj's address + corenum (size is always 3 * sizeof(int))
+ * 1d + obj's address + dst address (size if always 3 * sizeof(int))
+ * 1e (size is always 1 * sizeof(int))
+ * 1f + size of msg + corenum + (num of large obj lists + (start address + length)+)?
+ *
+ * NOTE: for Tilera, all GCMsgs except the GC start msg should be processed with a different net/port with other msgs
+ */
+
+
+int gc_msghandler() {
+ int deny = 0;
+ int i = 0;
+
+gcmsg:
+ if(receiveGCMsg() == -1) {
+ return -1;
+ }
+
+ if(gcmsgdataindex == gcmsglength) {
+ // received a whole msg
+ int type, data1; // will receive at least 2 words including type
+ type = gcmsgdata[0];
+ data1 = gcmsgdata[1];
+ switch(gctype) {
+ case 0x12: {
+ // a compact phase start msg
+ if(cinstruction == NULL) {
+ cinstruction = (struct compactInstr *)RUNMALLOC(sizeof(struct compactInstr));
+ } else {
+ // clean up out of data info
+ if(cinstruction->tomoveobjs != NULL) {
+ RUNFREE(cinstruction->tomoveobjs->starts);
+ RUNFREE(cinstruction->tomoveobjs->ends);
+ RUNFREE(cinstruction->tomoveobjs->dststarts);
+ RUNFREE(cinstruction->tomoveobjs->dsts);
+ RUNFREE(cinstruction->tomoveobjs);
+ cinstruction->tomoveobjs = NULL;
+ }
+ if(cinstruction->incomingobjs != NULL) {
+ RUNFREE();
+ RUNFREE(cinstruction->incomingobjs->starts);
+ RUNFREE(cinstruction->incomingobjs->dsts);
+ RUNFREE(cinstruction->incomingobjs);
+ cinstruction->incomingobjs = NULL;
+ }
+ // largeobj items should have been freed when processed
+ if(cinstruction->largeobjs != NULL) {
+ BAMBOO_EXIT(0xb005);
+ }
+ }
+ if(data1 > 2) {
+ // have objs to move etc.
+ int startindex = 2;
+ // process objs to move
+ int num = gcmsgdata[startindex++];
+ if(num > 0) {
+ cinstruction->tomoveobjs = (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
+ cinstruction->tomoveobjs->length = num;
+ cinstruction->tomoveobjs->starts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+ cinstruction->tomoveobjs->ends = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+ cinstruction->tomoveobjs->dststarts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+ cinstruction->tomoveobjs->dsts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+ for(i = 0; i < num; i++) {
+ cinstruction->tomoveobjs->starts[i] = gcmsgdata[startindex++];
+ cinstruction->tomoveobjs->ends[i] = gcmsgdata[startindex++];
+ cinstruction->tomoveobjs->dsts[i] = gcmsgdata[startindex++];
+ cinstruction->tomoveobjs->dststarts[i] = gcmsgdata[startindex++];
+ }
+ }
+ // process incoming objs
+ num = gcmsgdata[startindex++];
+ if(num > 0) {
+ cinstruction->incomingobjs = (struct moveObj *)RUNMALLOC(sizeof(struct moveObj));
+ cinstruction->incomingobjs->length = num;
+ cinstruction->incomingobjs->starts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+ cinstruction->incomingobjs->dsts = (INTPTR *)RUNMALLOC(num * sizeof(INTPTR));
+ for(i = 0; i < num; i++) {
+ cinstruction->incomingobjs->starts[i] = gcmsgdata[startindex++];
+ cinstruction->incomingobjs->dsts[i] = gcmsgdata[startindex++];
+ }
+ }
+ // process large objs
+ num = gcmsgdata[startindex++];
+ for(i = 0; i < num; i++) {
+ struct largeObjItem * loi = (struct largeObjItem *)RUNMALLOC(sizeof(struct largeObjItem ));
+ loi->orig = gcmsgdata[startindex++];
+ loi->length = gcmsgdata[startindex++];
+ loi->dst = gcmsgdata[startindex++];
+ loi->next = NULL;
+ if(i > 0) {
+ cinstruction->largeobjs->next = loi;
+ }
+ cinstruction->largeobjs = loi;
+ }
+ }
+ gcphase = 1;
+ break;
+ }
+
+ case 0x13: {
+ // received a flush phase start msg
+ gcphase = 2;
+ break;
+ }
+
+ case 0x14: {
+ // received a mark phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+ // return -1
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb006);
+ }
+ if(data1 < NUMCORES) {
+ gccorestatus[data1] = 0;
+ gcnumsendobjs[data1] = gcmsgdata[2];
+ gcnumreceiveobjs[data1] = gcmsgdata[3];
+ }
+ break;
+ }
+
+ case 0x15: {
+ // received a compact phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+ // return -1
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb006);
+ }
+ if(data1 < NUMCORES) {
+ gccorestatus[data1] = 0;
+ }
+ break;
+ }
+
+ case 0x16: {
+ // received a flush phase finish msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // non startup core can not receive this msg
+ // return -1
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(data1);
+#endif
+ BAMBOO_EXIT(0xb006);
+ }
+ if(data1 < NUMCORES) {
+ gccorestatus[data1] = 0;
+ }
+ break;
+ }
+
+ case 0x17: {
+ // received a GC finish msg
+ gcphase = 3;
+ break;
+ }
+
+ case 0x18: {
+ // received a marked phase finish confirm request msg
+ if((BAMBOO_NUM_OF_CORE == STARTUPCORE) || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
+ // wrong core to receive such msg
+ BAMBOO_EXIT(0xa013);
+ } else {
+ // send response msg
+ if(gcisMsgSending) {
+ cache_msg_5(true, STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
+ } else {
+ send_msg_5(true, STARTUPCORE, 0x19, BAMBOO_NUM_OF_CORE, gcbusystatus, gcself_numsendobjs, gcself_numreceiveobjs);
+ }
+ }
+ break;
+ }
+
+ case 0x19: {
+ // received a marked phase finish confirm response msg
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
+ // wrong core to receive such msg
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT_REG(gcmsgdata[2]);
+#endif
+ BAMBOO_EXIT(0xb014);
+ } else {
+ if(gcwaitconfirm) {
+ gcnumconfirm--;
+ }
+ gccorestatus[data1] = gcmsgdata[2];
+ gcnumsendobjs[data1] = gcmsgdata[3];
+ gcnumreceiveobjs[data1] = gcmsgdata[4];
+ }
+ break;
+ }
+
+ case 0x1a: {
+ // received a markedObj msg
+ addNewItem(gctomark, data1);
+ gcself_numreceiveobjs++;
+ gcbusystatus = true;
+ break;
+ }
+
+ case 0x1b: {
+ // received a start moving objs msg
+ addNewItem_I(gcdsts, data1);
+ tomove = true;
+ break;
+ }
+
+ case 0x1c: {
+ // received a mapping info request msg
+ void * dstptr = gengettable(pointertbl, data1);
+ if(NULL == dstptr) {
+ // no such pointer in this core, something is wrong
+ BAMBOO_EXIT(0xb008);
+ } else {
+ // send back the mapping info
+ if(gcisMsgSending) {
+ cache_msg_3(true, gcmsgdata[2], 0x1d, data1, dstptr);
+ } else {
+ send_msg_3(true, gcmsgdata[2], 0x1d, data1, dstptr);
+ }
+ }
+ break;
+ }
+
+ case 0x1d: {
+ // received a mapping info response msg
+ if(data1 != obj2map) {
+ // obj not matched, something is wrong
+ BAMBOO_EXIT(0xb009);
+ } else {
+ mappedobj = gcmsgdata[2];
+ genputtable(pointertbl, obj2map, mappedobj);
+ }
+ ismapped = true;
+ break;
+ }
+
+ case 0x1e: {
+ // received a large objs info request msg
+ transferMarkResults();
+ break;
+ }
+
+ case 0x1f: {
+ // received a large objs info response msg
+ // TODO
+ gcwaitconfirm--;
+ break;
+ }
+
+ default:
+ break;
+ }
+ for(gcmsgdataindex--; gcmsgdataindex > 0; --gcmsgdataindex) {
+ gcmsgdata[gcmsgdataindex] = -1;
+ }
+ gcmsgtype = -1;
+ gcmsglength = 30;
+
+ if(BAMBOO_GCMSG_AVAIL() != 0) {
+ goto gcmsg;
+ }
+#ifdef PROFILE
+ /*if(isInterrupt) {
+ profileTaskEnd();
+ }*/
+#endif
+ return type;
+ } else {
+ // not a whole msg
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xe88d);
+#endif
+#endif
+ return -2;
+ }
+}
+#endif
--- /dev/null
+#ifndef MULTICORE_GARBAGE_H
+#define MULTICORE_GARBAGE_H
+#include "Queue.h"
+
+// data structures for GC
+#define BAMBOO_NUM_PAGES 1024 * 512
+#define BAMBOO_PAGE_SIZE 4096
+#define BAMBOO_SHARED_MEM_SIZE BAMBOO_PAGE_SIZE * BAMBOO_PAGE_SIZE
+#define BAMBOO_BASE_VA 0xd000000
+#define BAMBOO_SMEM_SIZE 16 * BAMBOO_PAGE_SIZE
+#define BAMBOO_SMEM_SIZE_L 512 * BAMBOO_PAGE_SIZE
+#define BAMBOO_LARGE_SMEM_BOUND BAMBOO_SMEM_SIZE_L * NUMCORES // NUMCORES = 62
+
+// for GC msgs
+int gcmsgdata[100];
+int gcmsgtype;
+int gcmsgdataindex;
+int gcmsglength;
+#define BAMBOO_OUT_BUF_LENGTH_GC 100
+int gcoutmsgdata[BAMBOO_OUT_BUF_LENGTH_GC];
+int gcoutmsgindex;
+int gcoutmsglast;
+int gcoutmsgleft;
+bool gcisMsgHanging;
+volatile bool gcisMsgSending;
+
+struct markedObjItem {
+ INTPTR orig;
+ INTPTR dst;
+ struct markedObjItem * next;
+};
+
+struct largeObjItem {
+ INTPTR orig;
+ INTPTR dst;
+ int length;
+ struct largeObjItem * next;
+};
+
+struct moveObj {
+ INTPTR * starts;
+ INTPTR * ends;
+ INTPTR * dststarts;
+ int * dsts;
+ int length;
+};
+
+struct compactInstr {
+ struct moveObj * tomoveobjs;
+ struct moveObj * incomingobjs;
+ struct largeObjItem * largeobjs;
+};
+
+int gcphase; // indicating GC phase
+bool gctomove; // flag indicating if can start moving objects to other cores
+struct Queue * gcdsts;
+struct Queue gctomark; // global queue of objects to mark
+// for mark phase termination
+int gccorestatus[NUMCORES]; // records status of each core
+ // 1: running gc
+ // 0: stall
+int gcnumsendobjs[NUMCORES]; // records how many objects a core has sent out
+int gcnumreceiveobjs[NUMCORES]; // records how many objects a core has received
+int gcnumconfirm;
+bool gcwaitconfirm;
+bool gcbusystatus;
+int gcself_numsendobjs;
+int gcself_numreceiveobjs;
+// compact instruction
+struct compactInstr * cinstruction;
+// mapping of old address to new address
+struct genhashtable * pointertbl;
+int obj2map;
+int mappedobj;
+bool ismapped;
+
+#define BLOCKNUM(p, b) \
+ if((p) < BAMBOO_LARGE_SMEM_BOUND) { \
+ (*((int*)b)) = (p) / BAMBOO_SMEM_SIZE_L; \
+ } else { \
+ (*((int*)b)) = NUMCORES + ((p) - BAMBOO_LARGE_SMEM_BOUND) / BAMBOO_SMEM_SIZE; \
+ }
+
+#define RESIDECORE(p, x, y) \
+ int b; \
+ BLOCKNUM((p), &b); \
+ bool reverse = (b / NUMCORES) % 2; \
+ int l = b % NUMCORES; \
+ if(reverse) { \
+ if(l < 16) { \
+ l += 1; \
+ } else { \
+ l += 2; \
+ } \
+ (*((int*)y)) = 7 - l / 8; \
+ } else { \
+ if(l > 54) { \
+ l += 2; \
+ } else if(l > 47) {\
+ l += 1; \
+ } \
+ (*((int*)y)) = l / 8; \
+ } \
+ if((l/8)%2) { \
+ (*((int*)x)) = 1 - l % 8; \
+ } else { \
+ (*((int*)x)) = l % 8; \
+ }
+
+void gc(); // core coordinator routine
+void collect(); // core collector routine
+int gc_msghandler(); // interruption handler for GC msgs
+
+#endif
+
int self_numreceiveobjs;
// data structures for locking
-struct RuntimeHash locktable;
-static struct RuntimeHash* locktbl = &locktable;
-struct LockValue {
- int redirectlock;
- int value;
-};
struct RuntimeHash * objRedirectLockTbl;
int lockobj;
int lock2require;
struct Queue objqueue;
// data structures for shared memory allocation
+#ifdef MULTICORE_GC
+#include "multicoregarbage.h"
+#else
#define BAMBOO_NUM_PAGES 1024 * 512
#define BAMBOO_PAGE_SIZE 4096
#define BAMBOO_SHARED_MEM_SIZE BAMBOO_PAGE_SIZE * BAMBOO_PAGE_SIZE
mspace bamboo_free_msp;
mspace bamboo_cur_msp;
int bamboo_smem_size;
+#endif
// for test TODO
int total_num_t6;
inline void fakeExecution(void) __attribute__((always_inline));
inline void terminate(void) __attribute__((always_inline));
+// 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);
+/* 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) __attribute_((always_inline));
+inline void processlockrelease(int locktype, int lock, int redirectlock, bool isredirect) __attribute_((always_inline));
+
+// msg related functions
inline void send_msg_1(int targetcore, unsigned long n0) __attribute__((always_inline));
inline void send_msg_2(int targetcore, unsigned long n0, unsigned long n1) __attribute__((always_inline));
inline void send_msg_3(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2) __attribute__((always_inline));
inline void cache_msg_2(int targetcore, unsigned long n0, unsigned long n1) __attribute__((always_inline));
inline void cache_msg_3(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2) __attribute__((always_inline));
inline void cache_msg_4(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2, unsigned long n3) __attribute__((always_inline));
+inline void cache_msg_5(int targetcore, unsigned long n0, unsigned long n1, unsigned long n2, unsigned long n3, unsigned long n4) __attribute__((always_inline));
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) __attribute__((always_inline));
inline void transferObject(struct transObjInfo * transObj);
inline int receiveMsg(void) __attribute__((always_inline));
+inline int receiveGCMsg(void) __attribute__((always_inline));
#ifdef PROFILE
inline void profileTaskStart(char * taskname) __attribute__((always_inline));
// BAMBOO_CACHE_FLUSH_ALL(): flush the whole cache of a core if necessary //
// BAMBOO_EXIT(x): exit routine //
// BAMBOO_MSG_AVAIL(): checking if there are msgs coming in //
+// BAMBOO_GCMSG_AVAIL(): checking if there are gcmsgs coming in //
// BAMBOO_GET_EXE_TIME(): rountine to get current clock cycle number //
/////////////////////////////////////////////////////////////////////////////////////
#include "multicoreruntime.h"
#include "runtime_arch.h"
#include "GenericHashtable.h"
+#if 0
/*
extern int injectfailures;
extern float failurechance;
void * curr_heapbase=0;
void * curr_heaptop=0;
-#if 0
#ifdef CONSCHECK
#include "instrument.h"
#endif
// data structures for task invocation
struct genhashtable * activetasks;
-struct genhashtable * failedtasks;
+//struct genhashtable * failedtasks; // for recovery
struct taskparamdescriptor * currtpd;
#if 0
struct RuntimeHash * forward;
struct RuntimeHash * reverse;
#endif // if 0: for recovery
-bool getreadlock(void* ptr);
-void releasereadlock(void* ptr);
-bool getwritelock(void* ptr);
-void releasewritelock(void* ptr);
-void releasewritelock_r(void * lock, void * redirectlock);
-
// 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);
-bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache);
-bool getwritelock_I(void* ptr);
-bool getwritelock_I_r(void* lock, void* redirectlock, int core, bool cache);
-void releasewritelock_I(void * ptr);
// main function for each core
inline void run(void * arg) {
#endif
// initialize the arrays
- if(STARTUPCORE == corenum) {
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
// startup core to initialize corestatus[]
for(i = 0; i < NUMCORES; ++i) {
corestatus[i] = 1;
initializeexithandler();
// main process of the execution module
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
// non-executing cores, only processing communications
- failedtasks = NULL;
+ //failedtasks = NULL;
activetasks = NULL;
/*#ifdef PROFILE
BAMBOO_DEBUGPRINT(0xee01);
failedtasks=genallocatehashtable((unsigned int (*)(void *)) &hashCodetpd,
(int (*)(void *,void *)) &comparetpd);
#endif // #if 0: for recovery
- failedtasks = NULL;
/* Create queue of active tasks */
activetasks=genallocatehashtable((unsigned int(*) (void *)) &hashCodetpd,
(int(*) (void *,void *)) &comparetpd);
/* Process task information */
processtasks();
- if(STARTUPCORE == corenum) {
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
/* Create startup object */
createstartupobject(argc, argv);
}
for(k = 0; k < objInfo->length; ++k) {
int taskindex = objInfo->queues[2 * k];
int paramindex = objInfo->queues[2 * k + 1];
- struct parameterwrapper ** queues = &(paramqueues[corenum][taskindex][paramindex]);
+ 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", corenum, corenum, (int)obj, (long)obj, tmpptr->flag);
+ 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
if(!tocontinue) {
// check if stop
- if(STARTUPCORE == corenum) {
+ if(STARTUPCORE == BAMBOO_NUM_OF_CORE) {
if(isfirst) {
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xee03);
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xf001);
#endif
- corestatus[corenum] = 0;
- numsendobjs[corenum] = self_numsendobjs;
- numreceiveobjs[corenum] = self_numreceiveobjs;
+ 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
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xee05);
#endif
- corestatus[corenum] = 1;
+ corestatus[BAMBOO_NUM_OF_CORE] = 1;
for(i = 1; i < NUMCORES; ++i) {
corestatus[i] = 1;
// send status confirm msg to core i
- send_msg_1(i, 0xc);
+ send_msg_1(false, i, 0xc);
}
waitconfirm = true;
numconfirm = NUMCORES - 1;
#endif
for(i = 1; i < NUMCORES; ++i) {
// send profile request msg to core i
- send_msg_2(i, 6, totalexetime);
+ send_msg_2(false, i, 6, totalexetime);
}
// pour profiling data on startup core
outputProfileData();
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xf001);
#endif
- profilestatus[corenum] = 0;
+ profilestatus[BAMBOO_NUM_OF_CORE] = 0;
// check the status of all cores
allStall = true;
#ifdef DEBUG
BAMBOO_DEBUGPRINT(0xee0b);
#endif
// send stall msg
- send_msg_4(STARTUPCORE, 1, corenum, self_numsendobjs, self_numreceiveobjs);
+ send_msg_4(false, STARTUPCORE, 1, BAMBOO_NUM_OF_CORE, self_numsendobjs, self_numreceiveobjs);
sendStall = true;
isfirst = true;
busystatus = false;
BAMBOO_DEBUGPRINT(0xee0c);
#endif
} // if-else of line 464: if(!sendStall)
- } // if-else of line 313: if(STARTUPCORE == corenum)
+ } // if-else of line 313: if(STARTUPCORE == BAMBOO_NUM_OF_CORE)
} // if-else of line 311: if(!tocontinue)
} // line 193: while(true)
- } // right-bracket for if-else of line 153: if(corenum > NUMCORES - 1)
+ } // right-bracket for if-else of line 153: if(BAMBOO_NUM_OF_CORE > NUMCORES - 1)
} // run()
int UNUSED, UNUSED2;
int * enterflags = NULL;
if((!isnew) && (queues == NULL)) {
- if(corenum < NUMCORES) {
+ if(BAMBOO_NUM_OF_CORE < NUMCORES) {
queues = objectqueues[BAMBOO_NUM_OF_CORE][ptr->type];
length = numqueues[BAMBOO_NUM_OF_CORE][ptr->type];
} else {
struct ___Object___ *tagptr=NULL;
struct parameterwrapper ** queues = vqueues;
int length = vlength;
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
return;
}
if(queues == NULL) {
struct ___Object___ *tagptr=NULL;
struct parameterwrapper ** queues = vqueues;
int length = vlength;
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
return;
}
if(queues == NULL) {
* e -- terminate
* f -- requiring for new memory
* 10 -- response for new memory request
+ * 11 -- GC start
+ * 12 -- compact phase start
+ * 13 -- flush phase start
+ * 14 -- mark phase finish
+ * 15 -- compact phase finish
+ * 16 -- flush phase finish
+ * 17 -- GC finish
+ * 18 -- marked phase finish confirm request
+ * 19 -- marked phase finish confirm response
+ * 1a -- markedObj msg
+ * 1b -- start moving objs msg
+ * 1c -- ask for mapping info of a markedObj
+ * 1d -- mapping info of a markedObj
+ * 1e -- large objs info request
+ * 1f -- large objs info response
*
* ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
* StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
* TerminateMsg: e (size is always 1 * sizeof(int)
* MemoryMsg: f + size + corenum (size is always 3 * sizeof(int))
* 10 + base_va + size (size is always 3 * sizeof(int))
+ * GCMsg: 11 (size is always 1 * sizeof(int))
+ * 12 + 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)+)?
+ * 13 (size is always 1 * sizeof(int))
+ * 14 + corenum + gcsendobjs + gcreceiveobjs (size if always 4 * sizeof(int))
+ * 15/16 + corenum (size is always 2 * sizeof(int))
+ * 17 (size is always 1 * sizeof(int))
+ * 18 (size if always 1 * sizeof(int))
+ * 19 + size of msg + corenum + gcsendobjs + gcreceiveobjs (size is always 5 * sizeof(int))
+ * 1a + obj's address (size is always 2 * sizeof(int))
+ * 1b + corenum ( size is always 2 * sizeof(int))
+ * 1c + obj's address + corenum (size is always 3 * sizeof(int))
+ * 1d + obj's address + dst address (size if always 3 * sizeof(int))
+ * 1e (size is always 1 * sizeof(int))
+ * 1f + size of msg + corenum + (num of large obj lists + (start address + length)+)?
+ *
+ * NOTE: for Tilera, all GCMsgs except the GC start msg should be processed with a different net/port with other msgs
*/
-/* 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
-int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache);
-
// receive object transferred from other cores
// or the terminate message from other cores
// Should be invoked in critical sections!!
// otherwise -- received msg type
int receiveObject() {
int deny = 0;
- //int targetcore = 0;
msg:
if(receiveMsg() == -1) {
BAMBOO_DEBUGPRINT(0xe880);
#endif
#endif
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
#endif
BAMBOO_EXIT(0xa005);
- } /*else if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
+ }
// store the object and its corresponding queue info, enqueue it later
transObj->objptr = (void *)msgdata[2]; // data1 is now size of the msg
transObj->length = (msglength - 3) / 2;
case 1: {
// receive a stall msg
- if(corenum != STARTUPCORE) {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
// non startup core can not receive stall msg
// return -1
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(data1);
#endif
BAMBOO_EXIT(0xa006);
- } /*else if(waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
+ }
if(data1 < NUMCORES) {
#ifdef DEBUG
#ifndef TILERA
case 2: {
// receive lock request msg, handle it right now
- // check to see if there is a lock exist in locktbl for the required obj
+ // check to see if there is a lock exist for the required obj
// data1 -> lock type
int data2 = msgdata[2]; // obj pointer
int data3 = msgdata[3]; // lock
// for 32 bit machine, the size is always 4 words
int tmp = deny==1?4:3;
if(isMsgSending) {
- cache_msg_4(data4, tmp, data1, data2, data3);
+ cache_msg_4(false, data4, tmp, data1, data2, data3);
} else {
- send_msg_4(data4, tmp, data1, data2, data3);
+ send_msg_4(false, data4, tmp, data1, data2, data3);
}
}
break;
case 3: {
// receive lock grount msg
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
#endif
BAMBOO_EXIT(0xa007);
- } /*else if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
+ }
if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
#ifdef DEBUG
#ifndef TILERA
}
case 4: {
- // receive lock grount/deny msg
- if(corenum > NUMCORES - 1) {
+ // receive lock deny msg
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
#endif
BAMBOO_EXIT(0xa009);
- } /*else if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
+ }
if((lockobj == msgdata[2]) && (lock2require == msgdata[3])) {
#ifdef DEBUG
#ifndef TILERA
case 5: {
// receive lock release msg
- /*if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
- if(!RuntimeHashcontainskey(locktbl, msgdata[3])) {
- // no locks for this object, something is wrong
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(msgdata[3]);
-#endif
- BAMBOO_EXIT(0xa00b);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
- RuntimeHashget(locktbl, msgdata[3], &rwlock_obj);
- lockvalue = (struct LockValue*)(rwlock_obj);
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe884);
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
- if(data1 == 0) {
- lockvalue->value--;
- } else {
- lockvalue->value++;
- }
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
- }
+ processlockrelease(data1, msgdata[2], 0, false);
break;
}
#ifdef PROFILE
case 6: {
// receive an output profile data request msg
- if(corenum == STARTUPCORE) {
+ if(BAMBOO_NUM_OF_CORE == STARTUPCORE) {
// startup core can not receive profile output finish msg
BAMBOO_EXIT(0xa00c);
}
totalexetime = data1;
outputProfileData();
if(isMsgSending) {
- cache_msg_2(STARTUPCORE, 7, corenum);
+ cache_msg_2(false, STARTUPCORE, 7, BAMBOO_NUM_OF_CORE);
} else {
- send_msg_2(STARTUPCORE, 7, corenum);
+ send_msg_2(false, STARTUPCORE, 7, BAMBOO_NUM_OF_CORE);
}
break;
}
case 7: {
// receive a profile output finish msg
- if(corenum != STARTUPCORE) {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
// non startup core can not receive profile output finish msg
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(data1);
case 8: {
// receive a redirect lock request msg, handle it right now
- // check to see if there is a lock exist in locktbl for the required obj
+ // check to see if there is a lock exist for the required obj
// data1 -> lock type
int data2 = msgdata[2]; // obj pointer
int data3 = msgdata[3]; // redirect lock
// send response msg
// for 32 bit machine, the size is always 4 words
if(isMsgSending) {
- cache_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
+ cache_msg_4(false, data4, deny==1?0xa:9, data1, data2, data3);
} else {
- send_msg_4(data4, deny==1?0xa:9, data1, data2, data3);
+ send_msg_4(false, data4, deny==1?0xa:9, data1, data2, data3);
}
}
break;
case 9: {
// receive a lock grant msg with redirect info
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
#endif
BAMBOO_EXIT(0xa00e);
- }/* else if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
+ }
if(lockobj == msgdata[2]) {
#ifdef DEBUG
#ifndef TILERA
case 0xa: {
// receive a lock deny msg with redirect info
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
#endif
BAMBOO_EXIT(0xa010);
- }/* else if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
+ }
if(lockobj == msgdata[2]) {
#ifdef DEBUG
#ifndef TILERA
#endif
lockresult = 0;
lockflag = true;
- //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]);
#ifndef INTERRUPT
reside = false;
#endif
case 0xb: {
// receive a lock release msg with redirect info
- /*if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
- if(!RuntimeHashcontainskey(locktbl, msgdata[2])) {
- // no locks for this object, something is wrong
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(msgdata[2]);
-#endif
- BAMBOO_EXIT(0xa012);
- } else {
- int rwlock_obj = 0;
- struct LockValue * lockvalue = NULL;
- RuntimeHashget(locktbl, msgdata[2], &rwlock_obj);
- lockvalue = (struct LockValue*)(rwlock_obj);
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe893);
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
- if(data1 == 0) {
- lockvalue->value--;
- } else {
- lockvalue->value++;
- }
-#ifdef DEBUG
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(lockvalue->value);
-#endif
-#endif
- lockvalue->redirectlock = msgdata[3];
- }
- break;
+ processlockrelease(data1, msgdata[2], msgdata[3], true);
+ break;
}
case 0xc: {
// receive a status confirm info
- if((corenum == STARTUPCORE) || (corenum > NUMCORES - 1)) {
+ if((BAMBOO_NUM_OF_CORE == STARTUPCORE) || (BAMBOO_NUM_OF_CORE > NUMCORES - 1)) {
// wrong core to receive such msg
BAMBOO_EXIT(0xa013);
} else {
#endif
#endif
if(isMsgSending) {
- cache_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
+ cache_msg_3(false, STARTUPCORE, 0xd, busystatus?1:0, BAMBOO_NUM_OF_CORE);
} else {
- send_msg_3(STARTUPCORE, 0xd, busystatus?1:0, corenum);
+ send_msg_3(false, STARTUPCORE, 0xd, busystatus?1:0, BAMBOO_NUM_OF_CORE);
}
}
break;
case 0xd: {
// receive a status confirm info
- if(corenum != STARTUPCORE) {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
// wrong core to receive such msg
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
case 0xf: {
// receive a shared memory request msg
- if(corenum != STARTUPCORE) {
+ if(BAMBOO_NUM_OF_CORE != STARTUPCORE) {
// wrong core to receive such msg
#ifndef TILERA
BAMBOO_DEBUGPRINT_REG(msgdata[2]);
BAMBOO_DEBUGPRINT(0xe88a);
#endif
#endif
+ // TODO change for GC
void * mem = mspace_calloc(bamboo_free_msp, 1, msgdata[1]);
if(mem == NULL) {
BAMBOO_DEBUGPRINT(0xa016);
}
// send the start_va to request core
if(isMsgSending) {
- cache_msg_3(msgdata[2], 0x10, mem, msgdata[1]);
+ cache_msg_3(false, msgdata[2], 0x10, mem, msgdata[1]);
} else {
- send_msg_3(msgdata[2], 0x10, mem, msgdata[1]);
+ send_msg_3(false, msgdata[2], 0x10, mem, msgdata[1]);
}
}
break;
smemflag = true;
break;
}
+
+ case 0x11: {
+ // receive a start GC msg
+#ifdef DEBUG
+#ifndef TILERA
+ BAMBOO_DEBUGPRINT(0xe88c);
+#endif
+#endif
+ collect();
+ break;
+ }
default:
break;
msglength = 30;
#ifdef DEBUG
#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe88c);
+ BAMBOO_DEBUGPRINT(0xe88d);
#endif
#endif
// not a whole msg
#ifdef DEBUG
#ifndef TILERA
- BAMBOO_DEBUGPRINT(0xe88d);
+ BAMBOO_DEBUGPRINT(0xe88e);
#endif
#endif
#ifdef PROFILE
}
}
-/* 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
-int processlockrequest(int locktype, int lock, int obj, int requestcore, int rootrequestcore, bool cache) {
- int deny = 0;
- if( ((lock >> 5) % BAMBOO_TOTALCORE) != corenum ) {
- // the lock should not be on this core
-#ifndef TILERA
- BAMBOO_DEBUGPRINT_REG(requestcore);
- BAMBOO_DEBUGPRINT_REG(lock);
- BAMBOO_DEBUGPRINT_REG(corenum);
-#endif
- BAMBOO_EXIT(0xa017);
- }
- /*if((corenum == STARTUPCORE) && waitconfirm) {
- waitconfirm = false;
- numconfirm = 0;
- }*/
- 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;
-}
-
-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) % BAMBOO_TOTALCORE;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
-
- if(targetcore == corenum) {
- // reside on this core
- int deny = 0;
- BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- deny = processlockrequest(0, lock2require, (int)ptr, corenum, corenum, 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, 2, 0, (int)ptr, lock2require, corenum);
- }
- return true;
-}
-
-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) % BAMBOO_TOTALCORE;
-
- if(targetcore == corenum) {
- 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, 5, 0, (int)ptr, reallock);
- }
-}
-
-// redirected lock request
-bool getreadlock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
- int targetcore = 0;
-
- if(core == corenum) {
- lockobj = (int)ptr;
- lock2require = (int)redirectlock;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
- }
- targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
-
- if(targetcore == corenum) {
- // reside on this core
- int deny = processlockrequest(0, (int)redirectlock, (int)ptr, corenum, core, cache);
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(core == corenum) {
- 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?0xa:9, 0, (int)ptr, (int)redirectlock);
- } else {
- cache_msg_4(core, deny==1?0xa:9, 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, 8, 0, (int)ptr, lock2require, core, corenum);
- } else {
- cache_msg_6(targetcore, 8, 0, (int)ptr, lock2require, core, corenum);
- }
- }
- 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) % BAMBOO_TOTALCORE;
- 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 == corenum) {
- // reside on this core
- int deny = 0;
- BAMBOO_START_CRITICAL_SECTION_LOCK();
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xf001);
-#endif
- deny = processlockrequest(1, lock2require, (int)ptr, corenum, corenum, 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, 2, 1, (int)ptr, lock2require, corenum);
- }
- 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) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe661);
- BAMBOO_DEBUGPRINT_REG((int)ptr);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == corenum) {
- 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, 5, 1, (int)ptr, reallock);
- }
-}
-
-void releasewritelock_r(void * lock, void * redirectlock) {
- int targetcore = 0;
- int reallock = (int)lock;
- targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe671);
- BAMBOO_DEBUGPRINT_REG((int)lock);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == corenum) {
- 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(0xa01d);
- } 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_CLOSE_CRITICAL_SECTION_LOCK();
-#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, 0xb, 1, (int)lock, (int)redirectlock);
- }
-}
-
-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) % BAMBOO_TOTALCORE;
- 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 == corenum) {
- // reside on this core
- int deny = processlockrequest(1, (int)lock2require, (int)ptr, corenum, corenum, 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, 2, 1, (int)ptr, lock2require, corenum);
- }
- return true;
-}
-
-// redirected lock request
-bool getwritelock_I_r(void * ptr, void * redirectlock, int core, bool cache) {
- int targetcore = 0;
-
- if(core == corenum) {
- lockobj = (int)ptr;
- lock2require = (int)redirectlock;
- lockflag = false;
-#ifndef INTERRUPT
- reside = false;
-#endif
- lockresult = 0;
- }
- targetcore = ((int)redirectlock >> 5) % BAMBOO_TOTALCORE;
-
-#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 == corenum) {
- // reside on this core
- int deny = processlockrequest(1, (int)redirectlock, (int)ptr, corenum, core, cache);
- if(deny == -1) {
- // redirected
- return true;
- } else {
- if(core == corenum) {
- 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?0xa:9, 1, (int)ptr, (int)redirectlock);
- } else {
- cache_msg_4(core, deny==1?0xa:9, 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, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
- } else {
- cache_msg_6(targetcore, 8, 1, (int)ptr, (int)redirectlock, core, corenum);
- }
- }
- 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) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe681);
- BAMBOO_DEBUGPRINT_REG((int)ptr);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == corenum) {
- // 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, 5, 1, (int)ptr, reallock);
- }
-}
-
-void releasewritelock_I_r(void * lock, void * redirectlock) {
- int targetcore = 0;
- int reallock = (int)lock;
- targetcore = (reallock >> 5) % BAMBOO_TOTALCORE;
-
-#ifdef DEBUG
- BAMBOO_DEBUGPRINT(0xe691);
- BAMBOO_DEBUGPRINT_REG((int)lock);
- BAMBOO_DEBUGPRINT_REG(reallock);
- BAMBOO_DEBUGPRINT_REG(targetcore);
-#endif
-
- if(targetcore == corenum) {
- // 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, 0xb, 1, (int)lock, (int)redirectlock);
- }
-}
-int enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
+ent enqueuetasks(struct parameterwrapper *parameter, struct parameterwrapper *prevptr, struct ___Object___ *ptr, int * enterflags, int numenterflags) {
void * taskpointerarray[MAXTASKPARAMS];
int j;
//int numparams=parameter->task->numParameters;
void printdebug() {
int i;
int j;
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
return;
}
- for(i=0; i<numtasks[corenum]; i++) {
+ for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
#ifndef MULTICORE
printf("%s\n", task->name);
void processtasks() {
int i;
- if(corenum > NUMCORES - 1) {
+ if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) {
return;
}
- for(i=0; i<numtasks[corenum]; i++) {
+ for(i=0; i<numtasks[BAMBOO_NUM_OF_CORE]; i++) {
struct taskdescriptor * task=taskarray[BAMBOO_NUM_OF_CORE][i];
int j;