From 81520bb20d5e1ceb2bb7037da6a4cb6a9c9eb033 Mon Sep 17 00:00:00 2001 From: jzhou Date: Fri, 31 Jul 2009 00:37:36 +0000 Subject: [PATCH] initial multicore gargbage collection, not finish yet --- Robust/src/IR/Flat/BuildCode.java | 20 +- Robust/src/IR/Flat/BuildCodeMultiCore.java | 27 +- Robust/src/IR/State.java | 1 + Robust/src/Main/Main.java | 2 + Robust/src/Runtime/RAW/task_arch.c | 662 +++++++++++++++ Robust/src/Runtime/multicoregarbage.c | 938 +++++++++++++++++++++ Robust/src/Runtime/multicoregarbage.h | 115 +++ Robust/src/Runtime/multicoreruntime.h | 29 +- Robust/src/Runtime/multicoretask.c | 890 +++---------------- 9 files changed, 1867 insertions(+), 817 deletions(-) create mode 100644 Robust/src/Runtime/multicoregarbage.c create mode 100644 Robust/src/Runtime/multicoregarbage.h diff --git a/Robust/src/IR/Flat/BuildCode.java b/Robust/src/IR/Flat/BuildCode.java index b25311c6..ed217a47 100644 --- a/Robust/src/IR/Flat/BuildCode.java +++ b/Robust/src/IR/Flat/BuildCode.java @@ -592,10 +592,13 @@ public class BuildCode { 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;"); @@ -1300,10 +1303,13 @@ public class BuildCode { 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;"); diff --git a/Robust/src/IR/Flat/BuildCodeMultiCore.java b/Robust/src/IR/Flat/BuildCodeMultiCore.java index 8e7061c6..4e2a8f72 100644 --- a/Robust/src/IR/Flat/BuildCodeMultiCore.java +++ b/Robust/src/IR/Flat/BuildCodeMultiCore.java @@ -391,10 +391,10 @@ public class BuildCodeMultiCore extends BuildCode { /* 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\""); @@ -577,8 +577,8 @@ public class BuildCodeMultiCore extends BuildCode { } 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(); @@ -1042,17 +1042,6 @@ public class BuildCodeMultiCore extends BuildCode { 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 sendto = new Vector(); Queue queue = null; @@ -1332,8 +1321,8 @@ public class BuildCodeMultiCore extends BuildCode { } protected void outputAliasLockCode(FlatMethod fm, - LocalityBinding lb, - PrintWriter output) { + LocalityBinding lb, + PrintWriter output) { if(this.m_oa == null) { return; } diff --git a/Robust/src/IR/State.java b/Robust/src/IR/State.java index 81a463d6..b835f102 100644 --- a/Robust/src/IR/State.java +++ b/Robust/src/IR/State.java @@ -60,6 +60,7 @@ public class State { 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; diff --git a/Robust/src/Main/Main.java b/Robust/src/Main/Main.java index 14642866..56800060 100644 --- a/Robust/src/Main/Main.java +++ b/Robust/src/Main/Main.java @@ -126,6 +126,8 @@ public class Main { 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")) { diff --git a/Robust/src/Runtime/RAW/task_arch.c b/Robust/src/Runtime/RAW/task_arch.c index 0b0e6b20..d9746f70 100644 --- a/Robust/src/Runtime/RAW/task_arch.c +++ b/Robust/src/Runtime/RAW/task_arch.c @@ -3,6 +3,14 @@ #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() @@ -723,6 +731,660 @@ __attribute__((always_inline)) inline int receiveMsg() { 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) { diff --git a/Robust/src/Runtime/multicoregarbage.c b/Robust/src/Runtime/multicoregarbage.c new file mode 100644 index 00000000..50836edb --- /dev/null +++ b/Robust/src/Runtime/multicoregarbage.c @@ -0,0 +1,938 @@ +#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; iobjectset; + 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; inumParameters; 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; inumParameters; 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___)+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___)+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 diff --git a/Robust/src/Runtime/multicoregarbage.h b/Robust/src/Runtime/multicoregarbage.h new file mode 100644 index 00000000..8a6283d1 --- /dev/null +++ b/Robust/src/Runtime/multicoregarbage.h @@ -0,0 +1,115 @@ +#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 + diff --git a/Robust/src/Runtime/multicoreruntime.h b/Robust/src/Runtime/multicoreruntime.h index 80108f3c..fe9f4ed2 100644 --- a/Robust/src/Runtime/multicoreruntime.h +++ b/Robust/src/Runtime/multicoreruntime.h @@ -31,12 +31,6 @@ int self_numsendobjs; 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; @@ -47,6 +41,9 @@ bool lockflag; 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 @@ -57,6 +54,7 @@ bool smemflag; mspace bamboo_free_msp; mspace bamboo_cur_msp; int bamboo_smem_size; +#endif // for test TODO int total_num_t6; @@ -111,6 +109,22 @@ inline void initCommunication(void) __attribute__((always_inline)); 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)); @@ -120,9 +134,11 @@ inline void send_msg_6(int targetcore, unsigned long n0, unsigned long n1, unsig 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)); @@ -168,6 +184,7 @@ void outputProfileData(); // 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 // ///////////////////////////////////////////////////////////////////////////////////// diff --git a/Robust/src/Runtime/multicoretask.c b/Robust/src/Runtime/multicoretask.c index f5ed2cc9..fc5da71d 100644 --- a/Robust/src/Runtime/multicoretask.c +++ b/Robust/src/Runtime/multicoretask.c @@ -3,6 +3,7 @@ #include "multicoreruntime.h" #include "runtime_arch.h" #include "GenericHashtable.h" +#if 0 /* extern int injectfailures; extern float failurechance; @@ -13,7 +14,6 @@ extern int instaccum; void * curr_heapbase=0; void * curr_heaptop=0; -#if 0 #ifdef CONSCHECK #include "instrument.h" #endif @@ -21,26 +21,16 @@ void * curr_heaptop=0; // 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) { @@ -63,7 +53,7 @@ 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; @@ -151,9 +141,9 @@ inline void run(void * arg) { 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); @@ -172,7 +162,6 @@ inline void run(void * arg) { 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); @@ -180,7 +169,7 @@ inline void run(void * arg) { /* Process task information */ processtasks(); - if(STARTUPCORE == corenum) { + if(STARTUPCORE == BAMBOO_NUM_OF_CORE) { /* Create startup object */ createstartupobject(argc, argv); } @@ -263,12 +252,12 @@ inline void run(void * arg) { 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 @@ -327,7 +316,7 @@ objqueuebreak: if(!tocontinue) { // check if stop - if(STARTUPCORE == corenum) { + if(STARTUPCORE == BAMBOO_NUM_OF_CORE) { if(isfirst) { #ifdef DEBUG BAMBOO_DEBUGPRINT(0xee03); @@ -344,9 +333,9 @@ objqueuebreak: #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 @@ -385,11 +374,11 @@ objqueuebreak: #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; @@ -417,7 +406,7 @@ objqueuebreak: #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(); @@ -426,7 +415,7 @@ objqueuebreak: #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 @@ -501,7 +490,7 @@ objqueuebreak: 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; @@ -516,10 +505,10 @@ objqueuebreak: 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() @@ -849,7 +838,7 @@ void flagbody(struct ___Object___ *ptr, int flag, struct parameterwrapper ** vqu 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 { @@ -880,7 +869,7 @@ void enqueueObject(void * vptr, struct parameterwrapper ** vqueues, int vlength) 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) { @@ -950,7 +939,7 @@ void enqueueObject_I(void * vptr, struct parameterwrapper ** vqueues, int vlengt 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) { @@ -1113,6 +1102,21 @@ inline void addNewObjInfo(void * nobj) { * 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)) @@ -1130,15 +1134,24 @@ inline void addNewObjInfo(void * nobj) { * 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!! @@ -1155,7 +1168,6 @@ int processlockrequest(int locktype, int lock, int obj, int requestcore, int roo // otherwise -- received msg type int receiveObject() { int deny = 0; - //int targetcore = 0; msg: if(receiveMsg() == -1) { @@ -1177,15 +1189,12 @@ msg: 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; @@ -1231,17 +1240,14 @@ msg: 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 @@ -1257,7 +1263,7 @@ msg: 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 @@ -1271,9 +1277,9 @@ msg: // 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; @@ -1281,15 +1287,12 @@ msg: 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 @@ -1312,16 +1315,13 @@ msg: } 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 @@ -1345,45 +1345,14 @@ msg: 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); } @@ -1396,16 +1365,16 @@ msg: 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); @@ -1424,7 +1393,7 @@ msg: 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 @@ -1438,9 +1407,9 @@ msg: // 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; @@ -1448,15 +1417,12 @@ msg: 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 @@ -1481,15 +1447,12 @@ msg: 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 @@ -1498,7 +1461,6 @@ msg: #endif lockresult = 0; lockflag = true; - //RuntimeHashadd_I(objRedirectLockTbl, lockobj, msgdata[3]); #ifndef INTERRUPT reside = false; #endif @@ -1514,45 +1476,13 @@ msg: 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 { @@ -1563,9 +1493,9 @@ msg: #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; @@ -1573,7 +1503,7 @@ msg: 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]); @@ -1606,7 +1536,7 @@ msg: 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]); @@ -1618,6 +1548,7 @@ msg: 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); @@ -1625,9 +1556,9 @@ msg: } // 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; @@ -1650,6 +1581,17 @@ msg: smemflag = true; break; } + + case 0x11: { + // receive a start GC msg +#ifdef DEBUG +#ifndef TILERA + BAMBOO_DEBUGPRINT(0xe88c); +#endif +#endif + collect(); + break; + } default: break; @@ -1661,7 +1603,7 @@ msg: msglength = 30; #ifdef DEBUG #ifndef TILERA - BAMBOO_DEBUGPRINT(0xe88c); + BAMBOO_DEBUGPRINT(0xe88d); #endif #endif @@ -1678,7 +1620,7 @@ msg: // not a whole msg #ifdef DEBUG #ifndef TILERA - BAMBOO_DEBUGPRINT(0xe88d); + BAMBOO_DEBUGPRINT(0xe88e); #endif #endif #ifdef PROFILE @@ -1690,630 +1632,8 @@ msg: } } -/* 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; @@ -3096,10 +2416,10 @@ loopstart: void printdebug() { int i; int j; - if(corenum > NUMCORES - 1) { + if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) { return; } - for(i=0; iname); @@ -3153,10 +2473,10 @@ void printdebug() { void processtasks() { int i; - if(corenum > NUMCORES - 1) { + if(BAMBOO_NUM_OF_CORE > NUMCORES - 1) { return; } - for(i=0; i