# HG changeset patch # User Nina Engelhardt # Date 1347378665 -7200 # Node ID c9606ea7abc860746ec7bb508a42c8d7ffc9d807 # Parent f83fff8bd4b2c0331e775c3df4ac8b44fac0a87c add interface for Tamer's nexus board diff -r f83fff8bd4b2 -r c9606ea7abc8 VSs.c --- a/VSs.c Fri Aug 31 18:24:03 2012 +0200 +++ b/VSs.c Tue Sep 11 17:51:05 2012 +0200 @@ -240,7 +240,9 @@ semanticEnv->nextCoreToGetNewSlv = 0; - +#ifdef EXTERNAL_SCHEDULER + VSs__init_ext_scheduler(); +#endif //TODO: bug -- turn these arrays into dyn arrays to eliminate limit //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); //semanticEnv->transactionStrucs = makeDynArrayInfo( ); @@ -279,12 +281,11 @@ { VSsSemEnv *semanticEnv; semanticEnv = _VMSMasterEnv->semanticEnv; - - #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC - //UCC FILE* output; int n; - char filename[255]; + char filename[255]; + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC + //UCC for(n=0;n<255;n++) { sprintf(filename, "./counters/UCC.%d",n); diff -r f83fff8bd4b2 -r c9606ea7abc8 VSs.h --- a/VSs.h Fri Aug 31 18:24:03 2012 +0200 +++ b/VSs.h Tue Sep 11 17:51:05 2012 +0200 @@ -14,6 +14,13 @@ #include "VMS_impl/VMS.h" #include "Measurement/dependency.h" +/* Switch for Nexus support + * Note: nexus incompatible with holistic recording (constraints not accessible) + * But counter recording still functional, can build constraintless display + * with wallclock time + */ +//#define EXTERNAL_SCHEDULER +//#define SIMULATE_EXTERNAL_SCHEDULER //=========================================================================== #define NUM_STRUCS_IN_SEM_ENV 1000 diff -r f83fff8bd4b2 -r c9606ea7abc8 VSs_PluginFns.c --- a/VSs_PluginFns.c Fri Aug 31 18:24:03 2012 +0200 +++ b/VSs_PluginFns.c Tue Sep 11 17:51:05 2012 +0200 @@ -11,6 +11,10 @@ #include "VSs.h" #include "VSs_Request_Handlers.h" +#ifdef EXTERNAL_SCHEDULER + #include "VSs_nexus_support.h" +#endif + //=========================== Local Fn Prototypes =========================== void resume_slaveVP(SlaveVP *slave, VSsSemEnv *semEnv); @@ -74,6 +78,9 @@ goto ReturnTheSlv; } +#ifdef EXTERNAL_SCHEDULER + VSs__get_ready_tasks_from_ext(semEnv->taskReadyQ); +#endif //If none, speculate will have a task, so get the slot slave //TODO: false sharing ? (think not bad cause mostly read..) returnSlv = semEnv->slotTaskSlvs[coreNum][slotNum]; diff -r f83fff8bd4b2 -r c9606ea7abc8 VSs_Request_Handlers.c --- a/VSs_Request_Handlers.c Fri Aug 31 18:24:03 2012 +0200 +++ b/VSs_Request_Handlers.c Tue Sep 11 17:51:05 2012 +0200 @@ -14,6 +14,9 @@ #include "VSs_Request_Handlers.h" +#ifdef EXTERNAL_SCHEDULER +#include "VSs_nexus_support.h" +#endif //=========================== Local Fn Prototypes =========================== @@ -63,11 +66,10 @@ return entry; } -inline VSsPointerEntry * -create_pointer_entry() { - VSsPointerEntry *newEntry; +VSsPointerEntry* create_pointer_entry() { + VSsPointerEntry* newEntry; - newEntry = VMS_PI__malloc(sizeof (VSsPointerEntry)); + newEntry = (VSsPointerEntry*) VMS_PI__malloc(sizeof (VSsPointerEntry)); newEntry->hasEnabledNonFinishedWriter = FALSE; newEntry->numEnabledNonDoneReaders = 0; newEntry->waitersQ = makePrivQ(); @@ -262,6 +264,10 @@ //DEBUG__printf3(dbgRqstHdlr,"Submit req from slaveID: %d, from task: %d, for task: %d", semReq->callingSlv->slaveID, parentSemData->taskStub->taskID[1], taskStub->taskID[1]) if(semReq->taskID) { DEBUG__printf2(dbgRqstHdlr,"Submit req from slaveID: %d, for task: %d", semReq->callingSlv->slaveID, taskStub->taskID[1]) } else { DEBUG__printf1(dbgRqstHdlr,"Submit req from slaveID: %d, for anonymous task", semReq->callingSlv->slaveID) } +#ifdef EXTERNAL_SCHEDULER + //send task descriptor + VSs__submit_task_to_ext(taskStub, semEnv); +#else /*The controlled arguments are then processed one by one. *Processing an argument means getting the hash of the pointer. Then, * looking up the hash entry. (If none, create one). @@ -326,7 +332,7 @@ } } } //for argNum - +#endif resume_slaveVP(semReq->callingSlv, semEnv); @@ -413,7 +419,10 @@ VMS_PI__free(parent); } - +#ifdef EXTERNAL_SCHEDULER + //send task end notification + VSs__end_task_to_ext(endingTaskStub, semEnv); +#else //Now, update state of dependents and start ready tasks /*The task's controlled arguments are processed one by one. *Processing an argument means getting arg-pointer's entry. @@ -441,7 +450,7 @@ if (endingTaskType->argTypes[argNum] == READER) { /*then decrement the enabled and non-finished reader-count in * the hash-entry. */ ptrEntry->numEnabledNonDoneReaders -= 1; -#ifdef HOLISTIC__TURN_ON_OBSERVE_UCC + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC Unit u; u.vp = semReq->callingSlv->slaveID; u.task=semReq->callingSlv->assignCount; @@ -454,7 +463,7 @@ newd.to_task = semReq->callingSlv->assignCount; addToListOfArrays(Dependency, newd, semEnv->dataDependenciesList); } -#endif + #endif /*If the count becomes zero, then take the next entry from the Q. *It should be a writer, or else there's a bug in this algorithm.*/ if (ptrEntry->numEnabledNonDoneReaders == 0) { @@ -480,7 +489,7 @@ } } else /*the ending task is a writer of this arg*/ { /*clear the enabled non-finished writer flag of the hash-entry.*/ ptrEntry->hasEnabledNonFinishedWriter = FALSE; -#ifdef HOLISTIC__TURN_ON_OBSERVE_UCC + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC { int n,i; int num_full = ptrEntry->readersSinceLastWriter->next_free_index / ptrEntry->readersSinceLastWriter->num_entries_per_fragment; //!\\ != list->dim1info->numInArray-1 @@ -552,7 +561,8 @@ }//if-else, first waiting task is a reader }//if-else, check of ending task, whether writer or reader }//for argnum in ending task - +#endif + //done ending the task, now free the stub + args copy // if still has live children, then keep stub around diff -r f83fff8bd4b2 -r c9606ea7abc8 VSs_nexus_support.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VSs_nexus_support.c Tue Sep 11 17:51:05 2012 +0200 @@ -0,0 +1,217 @@ +#include "VSs_nexus_support.h" + + +//prototypes of functions internal to VSs_Request_Handlers.c +#ifdef SIMULATE_EXTERNAL_SCHEDULER +VSsPointerEntry* create_pointer_entry(); +VSsTaskStubCarrier * +create_task_carrier(VSsTaskStub *taskStub, int32 argNum, int32 rdOrWrite); +#endif + +void VSs__init_ext_scheduler(){ + +#ifdef SIMULATE_EXTERNAL_SCHEDULER + simQ = makeVMSQ(); +#endif +} + + +void VSs__submit_task_to_ext(VSsTaskStub* taskStub, VSsSemEnv *semEnv){ + //save correspondence of task ID and taskStub + + +#ifdef SIMULATE_EXTERNAL_SCHEDULER + uint32 key[3]; + VSsTaskType *taskType; + HashEntry *rawHashEntry; //has char *, but use with uint32 * + VSsPointerEntry* ptrEntry; //contents of hash table entry for an arg pointer + void **args; + VSsTaskStubCarrier *taskCarrier; + + HashTable* argPtrHashTbl = semEnv->argPtrHashTbl; + + taskType = taskStub->taskType; + args = taskStub->args; + + /*The controlled arguments are then processed one by one. + *Processing an argument means getting the hash of the pointer. Then, + * looking up the hash entry. (If none, create one). + */ + int32 argNum; + for (argNum = 0; argNum < taskType->numCtldArgs; argNum++) { + key[0] = 2; //two 32b values in key + *((uint64*) & key[1]) = (uint64) args[argNum]; //write 64b into two 32b + + /*If the hash entry was chained, put it at the + * start of the chain. (Means no-longer-used pointers accumulate + * at end of chain, decide garbage collection later) */ + rawHashEntry = getEntryFromTable32(key, argPtrHashTbl); + if (rawHashEntry == NULL) { //adding a value auto-creates the hash-entry + ptrEntry = create_pointer_entry(); + rawHashEntry = addValueIntoTable32(key, ptrEntry, argPtrHashTbl); + } else { + ptrEntry = (VSsPointerEntry *) rawHashEntry->content; + if (ptrEntry == NULL) { + ptrEntry = create_pointer_entry(); + rawHashEntry = addValueIntoTable32(key, ptrEntry, argPtrHashTbl); + } + } + taskStub->ptrEntries[argNum] = ptrEntry; + + /*Have the hash entry. + *If the arg is a reader and the entry does not have an enabled + * non-finished writer, and the queue is empty. */ + if (taskType->argTypes[argNum] == READER) { + if (!ptrEntry->hasEnabledNonFinishedWriter && + isEmptyPrivQ(ptrEntry->waitersQ)) { /*The reader is free. So, decrement the blocking-propendent + * count in the task-stub. If the count is zero, then put the + * task-stub into the readyQ. At the same time, increment + * the hash-entry's count of enabled and non-finished readers.*/ + taskStub->numBlockingProp -= 1; + if (taskStub->numBlockingProp == 0) { + writePrivQ(taskStub, simQ); + } + ptrEntry->numEnabledNonDoneReaders += 1; + } else { /*Otherwise, the reader is put into the hash-entry's Q of + * waiters*/ + taskCarrier = create_task_carrier(taskStub, argNum, READER); + writePrivQ(taskCarrier, ptrEntry->waitersQ); + } + } else //arg is a writer + { /*the arg is a writer, plus the entry does not have a current + * writer, plus the number of enabled non-finished readers is + * zero, (the Q must be empty, else bug!) then the writer is free*/ + if (!ptrEntry->hasEnabledNonFinishedWriter && + ptrEntry->numEnabledNonDoneReaders == 0) { /*Mark the entry has having a enabled and non-finished writer. + * Decrement the blocking-propenden count in the writer's + * task-stub. If the count is zero, then put the task-stub + * into the readyQ.*/ + taskStub->numBlockingProp -= 1; + if (taskStub->numBlockingProp == 0) { + writePrivQ(taskStub, simQ); + } + ptrEntry->hasEnabledNonFinishedWriter = TRUE; + } else {/*Otherwise, put the writer into the entry's Q of waiters.*/ + taskCarrier = create_task_carrier(taskStub, argNum, WRITER); + writePrivQ(taskCarrier, ptrEntry->waitersQ); + } + } + } //for argNum +#endif +} + +void VSs__end_task_to_ext(VSsTaskStub* endingTaskStub, VSsSemEnv *semEnv){ + VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer + VSsTaskStub *waitingTaskStub; + VSsTaskType *endingTaskType; + VSsTaskStubCarrier *waitingTaskCarrier; + VSsPointerEntry **ptrEntries; + + endingTaskType = endingTaskStub->taskType; + ptrEntries = endingTaskStub->ptrEntries; + +#ifdef SIMULATE_EXTERNAL_SCHEDULER + //Now, update state of dependents and start ready tasks + /*The task's controlled arguments are processed one by one. + *Processing an argument means getting arg-pointer's entry. + */ + int32 argNum; + for (argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++) { + /* commented out 'cause remembering entry ptr when create stub + key[0] = 2; //says are 2 32b values in key + *( (uint64*)&key[1] ) = args[argNum]; //write 64b ptr into two 32b + + /*If the hash entry was chained, put it at the + * start of the chain. (Means no-longer-used pointers accumulate + * at end of chain, decide garbage collection later) + */ + /*NOTE: don't do hash lookups here, instead, have a pointer to the + * hash entry inside task-stub, put there during task creation. + rawHashEntry = getEntryFromTable32( key, ptrHashTbl ); + ptrEntry = (VSsPointerEntry *)rawHashEntry->content; + if( ptrEntry == NULL ) + VMS_App__throw_exception("hash entry NULL", NULL, NULL); + */ + + ptrEntry = ptrEntries[argNum]; + /*check if the ending task was reader of this arg*/ + if (endingTaskType->argTypes[argNum] == READER) { /*then decrement the enabled and non-finished reader-count in + * the hash-entry. */ + ptrEntry->numEnabledNonDoneReaders -= 1; + + /*If the count becomes zero, then take the next entry from the Q. + *It should be a writer, or else there's a bug in this algorithm.*/ + if (ptrEntry->numEnabledNonDoneReaders == 0) { + waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ); + if (waitingTaskCarrier == NULL) { //TODO: looks safe to delete the ptr entry at this point + continue; //next iter of loop + } + if (waitingTaskCarrier->isReader) + VMS_App__throw_exception("READER waiting", NULL, NULL); + + waitingTaskStub = waitingTaskCarrier->taskStub; + + /*Set the hash-entry to have an enabled non-finished writer.*/ + ptrEntry->hasEnabledNonFinishedWriter = TRUE; + + /* Decrement the blocking-propendent-count of the writer's + * task-stub. If the count has reached zero, then put the + * task-stub into the readyQ.*/ + waitingTaskStub->numBlockingProp -= 1; + if (waitingTaskStub->numBlockingProp == 0) { + writePrivQ(waitingTaskStub, simQ); + } + } + } else /*the ending task is a writer of this arg*/ { /*clear the enabled non-finished writer flag of the hash-entry.*/ + ptrEntry->hasEnabledNonFinishedWriter = FALSE; + + /*Take the next waiter from the hash-entry's Q.*/ + waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ); + if (waitingTaskCarrier == NULL) { //TODO: looks safe to delete ptr entry at this point + continue; //go to next iter of loop, done here. + } + waitingTaskStub = waitingTaskCarrier->taskStub; + + /*If task is a writer of this hash-entry's pointer*/ + if (!waitingTaskCarrier->isReader) { /* then turn the flag back on.*/ + ptrEntry->hasEnabledNonFinishedWriter = TRUE; + /*Decrement the writer's blocking-propendent-count in task-stub + * If it becomes zero, then put the task-stub into the readyQ.*/ + waitingTaskStub->numBlockingProp -= 1; + if (waitingTaskStub->numBlockingProp == 0) { + writePrivQ(waitingTaskStub, simQ); + } + } else { /*Waiting task is a reader, so do a loop, of all waiting readers + * until encounter a writer or waitersQ is empty*/ + while (TRUE) /*The checks guarantee have a waiting reader*/ { /*Increment the hash-entry's count of enabled non-finished + * readers.*/ + ptrEntry->numEnabledNonDoneReaders += 1; + + /*Decrement the blocking propendents count of the reader's + * task-stub. If it reaches zero, then put the task-stub + * into the readyQ.*/ + waitingTaskStub->numBlockingProp -= 1; + if (waitingTaskStub->numBlockingProp == 0) { + writePrivQ(waitingTaskStub, simQ); + } + /*Get next waiting task*/ + waitingTaskCarrier = peekPrivQ(ptrEntry->waitersQ); + if (waitingTaskCarrier == NULL) break; + if (!waitingTaskCarrier->isReader) break; + waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ); + waitingTaskStub = waitingTaskCarrier->taskStub; + }//while waiter is a reader + }//if-else, first waiting task is a reader + }//if-else, check of ending task, whether writer or reader + }//for argnum in ending task +#endif +} + +void VSs__get_ready_tasks_from_ext(PrivQueueStruc* taskReadyQ){ +#ifdef SIMULATE_EXTERNAL_SCHEDULER + void* taskStub; + while(taskStub=readPrivQ(simQ)){ + writePrivQ(taskStub,taskReadyQ); + } +#endif +} \ No newline at end of file diff -r f83fff8bd4b2 -r c9606ea7abc8 VSs_nexus_support.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VSs_nexus_support.h Tue Sep 11 17:51:05 2012 +0200 @@ -0,0 +1,25 @@ +/* + * File: VSs_nexus_support.h + * Author: nengel + * + * Created on September 10, 2012, 5:35 PM + */ + +#ifndef VSS_NEXUS_SUPPORT_H +#define VSS_NEXUS_SUPPORT_H +#include "VSs.h" + +#ifdef SIMULATE_EXTERNAL_SCHEDULER +PrivQueueStruc* simQ; +#endif + +void VSs__init_ext_scheduler(); + +void VSs__submit_task_to_ext(VSsTaskStub* taskStub, VSsSemEnv *semEnv); + +void VSs__end_task_to_ext(VSsTaskStub* taskStub, VSsSemEnv *semEnv); + +void VSs__get_ready_tasks_from_ext(PrivQueueStruc* taskReadyQ); + +#endif /* VSS_NEXUS_SUPPORT_H */ +