int corestatus[NUMCORES]; // records status of each core
// 1: running tasks
-// 0: stall
+ // 0: stall
int numsendobjs[NUMCORES]; // records how many objects a core has sent out
int numreceiveobjs[NUMCORES]; // records how many objects a core has received
#ifdef RAW
// profiling mode of RAW version
#ifdef RAWPROFILE
-#define TASKINFOLENGTH 150
+#define TASKINFOLENGTH 10000
//#define INTERRUPTINFOLENGTH 500
bool stall;
char* taskName;
int startTime;
int endTime;
+ int exitIndex;
+ struct Queue * newObjs;
} TaskInfo;
/*typedef struct interrupt_info {
- int startTime;
- int endTime;
-} InterruptInfo;*/
+ int startTime;
+ int endTime;
+ } InterruptInfo;*/
TaskInfo * taskInfoArray[TASKINFOLENGTH];
int taskInfoIndex;
bool taskInfoOverflow;
/*InterruptInfo * interruptInfoArray[INTERRUPTINFOLENGTH];
-int interruptInfoIndex;
-bool interruptInfoOverflow;*/
+ int interruptInfoIndex;
+ bool interruptInfoOverflow;*/
int profilestatus[NUMCORES]; // records status of each core
// 1: running tasks
-// 0: stall
+ // 0: stall
bool transProfileRequestMsg(int targetcore);
void outputProfileData();
#endif
#ifdef RAW
-//#ifdef RAWPROFILE
#ifdef RAWUSEIO
int main(void) {
#else
for(i = 0; i < 30; ++i) {
msgdata[i] = -1;
}
- //msgdata = NULL;
msgtype = -1;
msgdataindex = 0;
msglength = 30;
totalexetime = -1;
taskInfoIndex = 0;
/*interruptInfoIndex = 0;
- taskInfoOverflow = false;
- interruptInfoOverflow = false;*/
+ taskInfoOverflow = false;
+ interruptInfoOverflow = false;*/
#endif
#ifdef INTERRUPT
}
}
- //pthread_exit(NULL);
while(true) {
}
}
#endif
while(true) {
-/*#ifndef INTERRUPT
- while(receiveObject() != -1) {
- }
- #endif*/
-
// check if there are new active tasks can be executed
executetasks();
taskInfo->taskName = "objqueue checking";
taskInfo->startTime = raw_get_cycle();
taskInfo->endTime = -1;
+ taskInfo->exitIndex = -1;
+ taskInfo->newObjs = NULL;
}
isChecking = true;
}
#endif
while(!isEmpty(&objqueue)) {
void * obj = NULL;
+ int * locks = NULL;
+ int numlocks = 0;
#ifdef INTERRUPT
raw_user_interrupts_off();
#endif
sendStall = false;
tocontinue = true;
objitem = getTail(&objqueue);
- //obj = objitem->objectptr;
objInfo = (struct transObjInfo *)objitem->objectptr;
obj = objInfo->objptr;
#ifdef RAWDEBUG
raw_test_pass_reg((int)obj);
#endif
// grab lock and flush the obj
- getreadlock_I(obj);
- while(!lockflag) {
- receiveObject();
+ grount = 0;
+ if(((struct ___Object___ *)obj)->numlocks == 0) {
+ locks = obj;
+ numlocks = 1;
+ } else {
+ locks = ((struct ___Object___ *)obj)->locks;
+ numlocks = ((struct ___Object___ *)obj)->numlocks;
}
- grount = lockresult;
+ for(; numlocks > 0; numlocks--) {
+ getreadlock_I(locks);
+ while(!lockflag) {
+ receiveObject();
+ }
+ grount = grount || lockresult;
#ifdef RAWDEBUG
- raw_test_pass_reg(grount);
+ raw_test_pass_reg(grount);
#endif
- lockresult = 0;
- lockobj = 0;
- lockflag = false;
+ lockresult = 0;
+ lockobj = 0;
+ lockflag = false;
#ifndef INTERRUPT
- reside = false;
+ reside = false;
#endif
+ if(grount == 0) {
+ goto grablockfail;
+ }
+
+ locks = (int*)(*locks);
+ }
+
if(grount == 1) {
int k = 0;
+ // flush the object
raw_invalidate_cache_range((int)obj, classsize[((struct ___Object___ *)obj)->type]);
- // flush the obj
- /*for(k = 0; k < classsize[((struct ___Object___ *)obj)->type]; ++k) {
- invalidateAddr(obj + k);
- }*/
// enqueue the object
for(k = 0; k < objInfo->length; ++k) {
int taskindex = objInfo->queues[2 * k];
enqueueObject_I(obj, queues, 1);
}
removeItem(&objqueue, objitem);
- releasereadlock_I(obj);
+ if(((struct ___Object___ *)obj)->numlocks == 0) {
+ locks = obj;
+ numlocks = 1;
+ } else {
+ locks = ((struct ___Object___ *)obj)->locks;
+ numlocks = ((struct ___Object___ *)obj)->numlocks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasereadlock_I(locks);
+ locks = (int *)(*locks);
+ }
RUNFREE(objInfo->queues);
RUNFREE(objInfo);
- /*enqueueObject_I(obj, NULL, 0);
- removeItem(&objqueue, objitem);
- releasereadlock_I(obj);*/
} else {
+grablockfail:
// can not get lock
// put it at the end of the queue
// and try to execute active tasks already enqueued first
removeItem(&objqueue, objitem);
addNewItem_I(&objqueue, objInfo);
+ if(((struct ___Object___ *)obj)->numlocks > 0) {
+ //release grabbed locks
+ numlocks = ((struct ___Object___ *)obj)->numlocks - numlocks;
+ locks = ((struct ___Object___ *)obj)->locks;
+ for(; numlocks > 0; numlocks--) {
+ releasereadlock_I(locks);
+ locks = (int *)(*locks);
+ }
+ }
#ifdef RAWPROFILE
//isInterrupt = true;
#endif
#ifdef RAWDEBUG
raw_test_pass(0xee11);
#endif
-//#ifdef RAWPROFILE
#ifdef RAWUSEIO
totalexetime = raw_get_cycle();
#else
while(true) {
switch(receiveObject()) {
case 0: {
- printf("[run, %d] receive an object\n", numofcore);
+ //printf("[run, %d] receive an object\n", numofcore);
sendStall = false;
// received an object
// check if there are new active tasks can be executed
break;
}
- /* case 3: {
- printf("[run, %d] receive a terminate msg\n", numofcore);
- // receive a terminate Msg
- assert(STARTUPCORE != corenum); // only non-startup core can receive such msg
- mq_close(mqd[corenum]);
- fflush(stdout);
- exit(0);
- break;
- }*/
default: {
printf("[run, %d] Error: invalid message type.\n", numofcore);
fflush(stdout);
startupobject->isolate = 1;
startupobject->version = 0;
+ startupobject->numlocks = 0;
+ startupobject->locks = NULL;
/* Set initialized flag for startup object */
flagorandinit(startupobject,1,0xFFFFFFFF);
enqueueObject(startupobject, NULL, 0);
#ifdef RAW
- //flushAll();
raw_flush_entire_cache();
#endif
}
}
#endif
+void addAliasLock(void * ptr, int lock) {
+ struct ___Object___ * obj = (struct ___Object___ *)ptr;
+ if(obj->numlocks == 0) {
+ // originally no alias locks associated
+ obj->locks = (int *)lock;
+ *(obj->locks) = 0;
+ obj->numlocks++;
+ } else {
+ // already have some alias locks
+ // insert the new lock into the sorted lock linklist
+ int prev, next;
+ prev = next = (int)obj->locks;
+ while(next != 0) {
+ if(next < lock) {
+ // next is less than lock, move to next node
+ prev = next;
+ next = *((int *)next);
+ } else if(next == lock) {
+ // already have this lock, do nothing
+ return;
+ } else {
+ // insert the lock between prev and next
+ break;
+ }
+ }
+ *(int *)prev = lock;
+ *(int *)lock = next;
+ obj->numlocks++;
+ }
+}
+
/* Message format for RAW version:
* type + Msgbody
* type: 0 -- transfer object
* 4 -- lock deny
* 5 -- lock release
* 6 -- transfer profile output msg
- * 7 -- transfer profile ouput finish msg
+ * 7 -- transfer profile output finish msg
*
* ObjMsg: 0 + size of msg + obj's address + (task index + param index)+
* StallMsg: 1 + corenum + sendobjs + receiveobjs (size is always 4 * sizeof(int))
int type=((int *)obj)[0];
int size=classsize[type];
int targetcore = transObj->targetcore;
- //assert(type < NUMCLASSES); // can only transfer normal object
#ifdef RAW
unsigned msgHdr;
int self_y, self_x, target_y, target_x;
- //int isshared = 0;
// for 32 bit machine, the size of fixed part is always 3 words
- //int msgsize = sizeof(int) * 2 + sizeof(void *);
int msgsize = 3 + transObj->length * 2;
int i = 0;
struct ___Object___ * newobj = (struct ___Object___ *)obj;
- /*if(0 == newobj->isolate) {
- isshared = 1;
- }*/
calCoords(corenum, &self_y, &self_x);
calCoords(targetcore, &target_y, &target_x);
#ifdef RAWDEBUG
raw_test_pass_reg(msgsize);
#endif
- gdn_send(obj);
+ gdn_send((int)obj);
#ifdef RAWDEBUG
raw_test_pass_reg(obj);
#endif
fflush(stdout);
exit(-1);
}
- /*struct ___Object___ * newobj = (struct ___Object___ *)obj;
- if(0 == newobj->isolate) {
- newobj = RUNMALLOC(size);
- memcpy(newobj, obj, size);
- newobj->original=obj;
- }*/
struct transObjInfo * tmptransObj = RUNMALLOC(sizeof(struct transObjInfo));
memcpy(tmptransObj, transObj, sizeof(struct transObjInfo));
int * tmpqueue = RUNMALLOC(sizeof(int)*2*tmptransObj->length);
unsigned msgHdr;
int self_y, self_x, target_y, target_x;
// for 32 bit machine, the size is always 4 words
- //int msgsize = sizeof(int) * 4;
int msgsize = 2;
calCoords(corenum, &self_y, &self_x);
if((fp = fopen(fn, "w+")) == NULL) {
fprintf(stderr, "fopen error\n");
- return -1;
+ return;
}
- fprintf(fp, "Task Name, Start Time, End Time, Duration\n");
+ fprintf(fp, "Task Name, Start Time, End Time, Duration, Exit Index(, NewObj Name, Num)+\n");
// output task related info
for(i = 0; i < taskInfoIndex; i++) {
TaskInfo* tmpTInfo = taskInfoArray[i];
int duration = tmpTInfo->endTime - tmpTInfo->startTime;
- fprintf(fp, "%s, %d, %d, %d\n", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration);
+ fprintf(fp, "%s, %d, %d, %d, %d", tmpTInfo->taskName, tmpTInfo->startTime, tmpTInfo->endTime, duration, tmpTInfo->exitIndex);
+ // summarize new obj info
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ //fprintf(stderr, "new obj!\n");
+ }
+
+ // output all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ fprintf(fp, ", %s, %d", objtype, num);
+ }
+ }
+ fprintf(fp, "\n");
if(strcmp(tmpTInfo->taskName, "tpd checking") == 0) {
preprocessingtime += duration;
} else if(strcmp(tmpTInfo->taskName, "post task execution") == 0) {
fclose(fp);
#else
- int i = 0;
- int j = 0;
-
- raw_test_pass(0xdddd);
- // output task related info
- for(i= 0; i < taskInfoIndex; i++) {
- TaskInfo* tmpTInfo = taskInfoArray[i];
- char* tmpName = tmpTInfo->taskName;
- int nameLen = strlen(tmpName);
- raw_test_pass(0xddda);
- for(j = 0; j < nameLen; j++) {
- raw_test_pass_reg(tmpName[j]);
- }
- raw_test_pass(0xdddb);
- raw_test_pass_reg(tmpTInfo->startTime);
- raw_test_pass_reg(tmpTInfo->endTime);
- raw_test_pass(0xdddc);
- }
+ int i = 0;
+ int j = 0;
- if(taskInfoOverflow) {
- raw_test_pass(0xefee);
- }
+ raw_test_pass(0xdddd);
+ // output task related info
+ for(i= 0; i < taskInfoIndex; i++) {
+ TaskInfo* tmpTInfo = taskInfoArray[i];
+ char* tmpName = tmpTInfo->taskName;
+ int nameLen = strlen(tmpName);
+ raw_test_pass(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ raw_test_pass_reg(tmpName[j]);
+ }
+ raw_test_pass(0xdddb);
+ raw_test_pass_reg(tmpTInfo->startTime);
+ raw_test_pass_reg(tmpTInfo->endTime);
+ raw_test_pass_reg(tmpTInfo->exitIndex);
+ if(tmpTInfo->newObjs != NULL) {
+ struct RuntimeHash * nobjtbl = allocateRuntimeHash(5);
+ struct RuntimeIterator * iter = NULL;
+ while(0 == isEmpty(tmpTInfo->newObjs)) {
+ char * objtype = (char *)(getItem(tmpTInfo->newObjs));
+ if(RuntimeHashcontainskey(nobjtbl, (int)(objtype))) {
+ int num = 0;
+ RuntimeHashget(nobjtbl, (int)objtype, &num);
+ RuntimeHashremovekey(nobjtbl, (int)objtype);
+ num++;
+ RuntimeHashadd(nobjtbl, (int)objtype, num);
+ } else {
+ RuntimeHashadd(nobjtbl, (int)objtype, 1);
+ }
+ }
+
+ // ouput all new obj info
+ iter = RuntimeHashcreateiterator(nobjtbl);
+ while(RunhasNext(iter)) {
+ char * objtype = (char *)Runkey(iter);
+ int num = Runnext(iter);
+ int nameLen = strlen(objtype);
+ raw_test_pass(0xddda);
+ for(j = 0; j < nameLen; j++) {
+ raw_test_pass_reg(objtype[j]);
+ }
+ raw_test_pass(0xdddb);
+ raw_test_pass_reg(num);
+ }
+ }
+ raw_test_pass(0xdddc);
+ }
- // output interrupt related info
- /*for(i = 0; i < interruptInfoIndex; i++) {
- InterruptInfo* tmpIInfo = interruptInfoArray[i];
- raw_test_pass(0xddde);
- raw_test_pass_reg(tmpIInfo->startTime);
- raw_test_pass_reg(tmpIInfo->endTime);
- raw_test_pass(0xdddf);
+ if(taskInfoOverflow) {
+ raw_test_pass(0xefee);
+ }
+
+ // output interrupt related info
+ /*for(i = 0; i < interruptInfoIndex; i++) {
+ InterruptInfo* tmpIInfo = interruptInfoArray[i];
+ raw_test_pass(0xddde);
+ raw_test_pass_reg(tmpIInfo->startTime);
+ raw_test_pass_reg(tmpIInfo->endTime);
+ raw_test_pass(0xdddf);
}
if(interruptInfoOverflow) {
- raw_test_pass(0xefef);
+ raw_test_pass(0xefef);
}*/
- raw_test_pass(0xeeee);
+ raw_test_pass(0xeeee);
#endif
}
+
+inline void setTaskExitIndex(int index) {
+ taskInfoArray[taskInfoIndex]->exitIndex = index;
+}
+
+inline void addNewObjInfo(void * nobj) {
+ if(taskInfoArray[taskInfoIndex]->newObjs == NULL) {
+ taskInfoArray[taskInfoIndex]->newObjs = createQueue();
+ }
+ addNewItem(taskInfoArray[taskInfoIndex]->newObjs, nobj);
+}
#endif
// receive object transferred from other cores
}
#ifdef RAWPROFILE
/*if(isInterrupt && (!interruptInfoOverflow)) {
- // raw_test_pass(0xffff);
- interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
- interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
- interruptInfoArray[interruptInfoIndex]->endTime = -1;
- }*/
+ // raw_test_pass(0xffff);
+ interruptInfoArray[interruptInfoIndex] = RUNMALLOC_I(sizeof(struct interrupt_info));
+ interruptInfoArray[interruptInfoIndex]->startTime = raw_get_cycle();
+ interruptInfoArray[interruptInfoIndex]->endTime = -1;
+ }*/
#endif
msg:
#ifdef RAWDEBUG
raw_test_pass_reg(msgdata[msgdataindex]);
#endif
msgdataindex++;
-
- /*if(msgdataindex == 0) {
- // type
- msgtype = gdn_receive();
- if(msgtype > 2) {
- msglength = 3;
- } else {
- msglength = 4;
- }
- if(msgtype != 0) {
- msgdata = (int *)RUNMALLOC_I(msglength * sizeof(int));
- msgdata[msgdataindex] = msgtype;
- }
- #ifdef RAWDEBUG
- raw_test_pass_reg(msgtype);
- #endif
- } else if((msgdataindex == 1) && (msgtype == 0)) {
- // object transfer msg
- msglength = gdn_receive();
- msgdata = (int *)RUNMALLOC_I(msglength * sizeof(int));
- msgdata[0] = msgtype;
- msgdata[msgdataindex] = msglength;
- #ifdef RAWDEBUG
- raw_test_pass_reg(msgdata[msgdataindex]);
- #endif
- } else {
- msgdata[msgdataindex] = gdn_receive();
- #ifdef RAWDEBUG
- raw_test_pass_reg(msgdata[msgdataindex]);
- #endif
- }
- msgdataindex++;*/
}
#ifdef RAWDEBUG
raw_test_pass(0xffff);
if(prev == NULL) {
qitem = getTail(&objqueue);
} else {
- qitem = getNext(prev);
+ qitem = getNextQueueItem(prev);
}
}
- //memcpy(transObj->queues, msgdata[3], sizeof(int)*(msglength - 3));
addNewItem_I(&objqueue, (void *)transObj);
}
++(self_numreceiveobjs);
#ifdef RAWDEBUG
raw_test_pass(0xe881);
#endif
- /*
- addNewItem_I(&objqueue, (void *)data2);
- ++(self_numreceiveobjs);
- #ifdef RAWDEBUG
- raw_test_pass(0xe881);
- #endif
- */
break;
}
// receive lock release msg
if(!RuntimeHashcontainskey(locktbl, data2)) {
// no locks for this object, something is wrong
+ //raw_test_pass_reg(data2);
raw_test_done(0xa004);
} else {
int rwlock_obj = 0;
// receive an output request msg
if(corenum == STARTUPCORE) {
// startup core can not receive profile output finish msg
- // return -1
raw_test_done(0xa00a);
}
{
// receive a profile output finish msg
if(corenum != STARTUPCORE) {
// non startup core can not receive profile output finish msg
- // return -1
raw_test_done(0xa00b);
}
profilestatus[data1] = 0;
default:
break;
}
- //RUNFREE(msgdata);
- //msgdata = NULL;
for(msgdataindex--; msgdataindex > 0; --msgdataindex) {
msgdata[msgdataindex] = -1;
}
msgtype = -1;
- //msgdataindex = 0;
msglength = 30;
#ifdef RAWDEBUG
raw_test_pass(0xe888);
interruptInfoArray[interruptInfoIndex]->endTime = raw_get_cycle();
interruptInfoIndex++;
if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
- interruptInfoOverflow = true;
+ interruptInfoOverflow = true;
}
}*/
#endif
interruptInfoArray[interruptInfoIndex]->endTime = raw_get_cycle();
interruptInfoIndex++;
if(interruptInfoIndex == INTERRUPTINFOLENGTH) {
- interruptInfoOverflow = true;
+ interruptInfoOverflow = true;
}
}*/
#endif
printf("<receiveObject> index: %d, sendobjs: %d, reveiveobjs: %d\n", index, numsendobjs[index], numreceiveobjs[index]);
free(msgptr);
return 2;
- } /*else if(((int*)msgptr)[0] == -2) {
- // terminate msg
- return 3;
- } */
- else {
+ } else {
// an object
if(numofcore == STARTUPCORE) {
++(numreceiveobjs[numofcore]);
int self_y, self_x, target_y, target_x;
int targetcore = 0; //((int)ptr >> 5) % TOTALCORE;
// for 32 bit machine, the size is always 4 words
- //int msgsize = sizeof(int) * 4;
int msgsize = 4;
int tc = TOTALCORE;
#ifdef INTERRUPT
#ifdef RAWDEBUG
raw_test_pass(0);
#endif
- gdn_send(ptr);
+ gdn_send((int)ptr);
#ifdef RAWDEBUG
raw_test_pass_reg(ptr);
#endif
int self_y, self_x, target_y, target_x;
int targetcore = 0; //((int)ptr >> 5) % TOTALCORE;
// for 32 bit machine, the size is always 3 words
- //int msgsize = sizeof(int) * 3;
int msgsize = 3;
int tc = TOTALCORE;
#ifdef INTERRUPT
#ifdef RAWDEBUG
raw_test_pass(0);
#endif
- gdn_send(ptr);
+ gdn_send((int)ptr);
#ifdef RAWDEBUG
raw_test_pass_reg(ptr);
raw_test_pass(0xffff);
int self_y, self_x, target_y, target_x;
int targetcore = ((int)ptr >> 5) % TOTALCORE;
// for 32 bit machine, the size is always 4 words
- //int msgsize = sizeof(int) * 4;
int msgsize = 4;
lockobj = (int)ptr;
#ifdef RAWDEBUG
raw_test_pass(0);
#endif
- gdn_send(ptr);
+ gdn_send((int)ptr);
#ifdef RAWDEBUG
raw_test_pass_reg(ptr);
#endif
int self_y, self_x, target_y, target_x;
int targetcore = ((int)ptr >> 5) % TOTALCORE;
// for 32 bit machine, the size is always 3 words
- //int msgsize = sizeof(int) * 3;
int msgsize = 3;
if(targetcore == corenum) {
#ifdef RAWDEBUG
raw_test_pass(0);
#endif
- gdn_send(ptr);
+ gdn_send((int)ptr);
#ifdef RAWDEBUG
raw_test_pass_reg(ptr);
raw_test_pass(0xffff);
int self_y, self_x, target_y, target_x;
int targetcore = 0; //((int)ptr >> 5) % TOTALCORE;
// for 32 bit machine, the size is always 4 words
- //int msgsize = sizeof(int) * 4;
int msgsize= 4;
int tc = TOTALCORE;
#ifdef INTERRUPT
#ifdef RAWDEBUG
raw_test_pass(1);
#endif
- gdn_send(ptr);
+ gdn_send((int)ptr);
#ifdef RAWDEBUG
raw_test_pass_reg(ptr);
#endif
int self_y, self_x, target_y, target_x;
int targetcore = 0; //((int)ptr >> 5) % TOTALCORE;
// for 32 bit machine, the size is always 3 words
- //int msgsize = sizeof(int) * 3;
int msgsize = 3;
int tc = TOTALCORE;
#ifdef INTERRUPT
#ifdef RAWDEBUG
raw_test_pass(1);
#endif
- gdn_send(ptr);
+ gdn_send((int)ptr);
#ifdef RAWDEBUG
raw_test_pass_reg(ptr);
raw_test_pass(0xffff);
checkTaskInfo->taskName = "tpd checking";
checkTaskInfo->startTime = raw_get_cycle();
checkTaskInfo->endTime = -1;
+ checkTaskInfo->exitIndex = -1;
+ checkTaskInfo->newObjs = NULL;
}
#endif
currtpd=(struct taskparamdescriptor *) getfirstkey(activetasks);
genfreekey(activetasks, currtpd);
- /* Check if this task has failed, allow a task that contains optional objects to fire */
- /*if (gencontains(failedtasks, currtpd)) {
- // Free up task parameter descriptor
- RUNFREE(currtpd->parameterArray);
- RUNFREE(currtpd);
- goto newtask;
- }*/
numparams=currtpd->task->numParameters;
numtotal=currtpd->task->numTotal;
/* Make sure that the parameters are still in the queues */
for(i=0; i<numparams; i++) {
void * parameter=currtpd->parameterArray[i];
+ int * locks;
+ int numlocks;
#ifdef RAW
#ifdef RAWDEBUG
raw_test_pass(0xe993);
}
lock = true;
// require locks for this parameter if it is not a startup object
- getwritelock(parameter);
+ if(((struct ___Object___ *)parameter)->numlocks == 0) {
+ numlocks = 1;
+ locks = parameter;
+ } else {
+ numlocks = ((struct ___Object___ *)parameter)->numlocks;
+ locks = ((struct ___Object___ *)parameter)->locks;
+ }
+
grount = 0;
+ for(; numlocks > 0; numlocks--) {
+ getwritelock(locks);
#ifdef INTERRUPT
- raw_user_interrupts_off();
+ raw_user_interrupts_off();
#endif
#ifdef RAWPROFILE
- //isInterrupt = false;
+ //isInterrupt = false;
#endif
- while(!lockflag) {
- receiveObject();
- }
+ while(!lockflag) {
+ receiveObject();
+ }
#ifndef INTERRUPT
- if(reside) {
- while(receiveObject() != -1) {
+ if(reside) {
+ while(receiveObject() != -1) {
+ }
}
- }
#endif
- grount = lockresult;
+ grount = grount || lockresult;
- lockresult = 0;
- lockobj = 0;
- lockflag = false;
+ lockresult = 0;
+ lockobj = 0;
+ lockflag = false;
#ifndef INTERRUPT
- reside = false;
+ reside = false;
#endif
#ifdef RAWPROFILE
- //isInterrupt = true;
+ //isInterrupt = true;
#endif
#ifdef INTERRUPT
- raw_user_interrupts_on();
+ raw_user_interrupts_on();
#endif
+ if(grount == 0) {
+ goto grablock_fail;
+ }
+ locks = (int *)(*locks);
+ }
+
if(grount == 0) {
+grablock_fail:
#ifdef RAWDEBUG
raw_test_pass(0xe994);
#endif
// can not get the lock, try later
+ // first release all grabbed locks for this parameter
+ numlocks = ((struct ___Object___ *)parameter)->numlocks - numlocks;
+ locks = ((struct ___Object___ *)parameter)->locks;
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
+ }
+ // then releas all grabbed locks for previous parameters
for(j = 0; j < i; ++j) {
- releasewritelock(taskpointerarray[j+OFFSET]);
+ if(((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks == 0) {
+ locks = taskpointerarray[j+OFFSET];
+ numlocks = 1;
+ } else {
+ locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+ numlocks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
+ }
}
genputtable(activetasks, currtpd, currtpd);
if(hashsize(activetasks) == 1) {
// flush the object
{
raw_invalidate_cache_range((int)parameter, classsize[((struct ___Object___ *)parameter)->type]);
- /*int tmp = 0;
- for(tmp = 0; tmp < classsize[((struct ___Object___ *)parameter)->type]; ++tmp) {
- invalidateAddr(parameter + tmp);
- }*/
}
#endif
tmpparam = (struct ___Object___ *)parameter;
if(0 == tmpparam->isolate) {
isolateflags[i] = 0;
// shared object, need to flush with current value
- //if(!getreadlock(tmpparam->original)) {
- // // fail to get read lock of the original object, try this task later
+ // TODO: need modification according to added alias locks
if(!getwritelock(tmpparam->original)) {
// fail to get write lock, release all obtained locks and try this task later
int j = 0;
goto newtask;
}
if(tmpparam->version != tmpparam->original->version) {
- // some task on another core has changed this object
- // flush this object
- //memcpy(tmpparam, tmpparam->original, classsize[tmpparam->type]);
// release all obtained locks
int j = 0;
for(j = 0; j < i; ++j) {
free(enterflags);
}
}
- // try to enqueue it again to check if it feeds other tasks;
- //enqueueObject(tmpparam, NULL, 0);
// Free up task parameter descriptor
RUNFREE(currtpd->parameterArray);
RUNFREE(currtpd);
#endif
// release grabbed locks
for(j = 0; j < i; ++j) {
- releasewritelock(taskpointerarray[j+OFFSET]);
+ if(((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks == 0) {
+ numlocks = 1;
+ locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+ } else {
+ numlocks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks;
+ locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
+ }
+ }
+ if(((struct ___Object___ *)parameter)->numlocks == 0) {
+ numlocks = 1;
+ locks = parameter;
+ } else {
+ numlocks = ((struct ___Object___ *)parameter)->numlocks;
+ locks = ((struct ___Object___ *)parameter)->locks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
}
- releasewritelock(parameter);
RUNFREE(currtpd->parameterArray);
RUNFREE(currtpd);
goto newtask;
free(enterflags);
// release grabbed locks
for(j = 0; j < i; ++j) {
- releasewritelock(taskpointerarray[j+OFFSET]);
+ if(((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks == 0) {
+ numlocks = 1;
+ locks = taskpointerarray[j+OFFSET];
+ } else {
+ numlocks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->numlocks;
+ locks = ((struct ___Object___ *)taskpointerarray[j+OFFSET])->locks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
+ }
+ }
+ if(((struct ___Object___ *)parameter)->numlocks == 0) {
+ numlocks = 1;
+ locks = parameter;
+ } else {
+ numlocks = ((struct ___Object___ *)parameter)->numlocks;
+ locks = ((struct ___Object___ *)parameter)->locks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
}
- releasewritelock(parameter);
RUNFREE(currtpd->parameterArray);
RUNFREE(currtpd);
#ifdef RAWPROFILE
#ifdef RAWDEBUG
raw_test_pass_reg(x);
#endif
+ raw_test_pass_reg(x);
raw_test_done(0xa009);
#else
exit(-1);
}*/
/* Actually call task */
#ifdef PRECISE_GC
- ((int *)taskpointerarray)[0]=currtpd->numParameters;
+ ((int *)taskpointerarray)[0]=currtpd->numParameters;
taskpointerarray[1]=NULL;
#endif
execute:
taskInfo->taskName = currtpd->task->name;
taskInfo->startTime = raw_get_cycle();
taskInfo->endTime = -1;
+ taskInfo->exitIndex = -1;
+ taskInfo->newObjs = NULL;
}
#endif
postTaskInfo->taskName = "post task execution";
postTaskInfo->startTime = raw_get_cycle();
postTaskInfo->endTime = -1;
+ postTaskInfo->exitIndex = -1;
+ postTaskInfo->newObjs = NULL;
}
#endif
#ifdef RAWDEBUG
for(i = 0; i < numparams; ++i) {
int j = 0;
struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
+ int numlocks;
+ int * locks;
#ifdef RAWDEBUG
raw_test_pass(0xe999);
raw_test_pass(0xdd100000 + tmpparam->flag);
#endif
- releasewritelock(tmpparam);
+ if(tmpparam->numlocks == 0) {
+ numlocks = 1;
+ locks = (int*)tmpparam;
+ } else {
+ numlocks = tmpparam->numlocks;
+ locks = tmpparam->locks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
+ }
}
#elif defined THREADSIMULATE
for(i = 0; i < numparams; ++i) {
if(0 == isolateflags[i]) {
struct ___Object___ * tmpparam = (struct ___Object___ *)taskpointerarray[i+OFFSET];
- releasewritelock(tmpparam);
+ if(tmpparam->numlocks == 0) {
+ numlocks = 1;
+ locks = (int*)tmpparam;
+ } else {
+ numlocks = tmpparam->numlocks;
+ locks = tmpparam->locks;
+ }
+ for(; numlocks > 0; numlocks--) {
+ releasewritelock(locks);
+ locks = (int *)(*locks);
+ }
}
}
#endif