Mercurial > cgi-bin > hgwebdir.cgi > VMS > VMS_Implementations > VSs_impls > VSs__MC_shared_impl
changeset 18:c9606ea7abc8 dev_expl_VP_and_DKU
add interface for Tamer's nexus board
author | Nina Engelhardt <nengel@mailbox.tu-berlin.de> |
---|---|
date | Tue, 11 Sep 2012 17:51:05 +0200 |
parents | f83fff8bd4b2 |
children | 58a71af04cd1 |
files | VSs.c VSs.h VSs_PluginFns.c VSs_Request_Handlers.c VSs_nexus_support.c VSs_nexus_support.h |
diffstat | 6 files changed, 282 insertions(+), 15 deletions(-) [+] |
line diff
1.1 --- a/VSs.c Fri Aug 31 18:24:03 2012 +0200 1.2 +++ b/VSs.c Tue Sep 11 17:51:05 2012 +0200 1.3 @@ -240,7 +240,9 @@ 1.4 1.5 semanticEnv->nextCoreToGetNewSlv = 0; 1.6 1.7 - 1.8 +#ifdef EXTERNAL_SCHEDULER 1.9 + VSs__init_ext_scheduler(); 1.10 +#endif 1.11 //TODO: bug -- turn these arrays into dyn arrays to eliminate limit 1.12 //semanticEnv->singletonHasBeenExecutedFlags = makeDynArrayInfo( ); 1.13 //semanticEnv->transactionStrucs = makeDynArrayInfo( ); 1.14 @@ -279,12 +281,11 @@ 1.15 { VSsSemEnv *semanticEnv; 1.16 1.17 semanticEnv = _VMSMasterEnv->semanticEnv; 1.18 - 1.19 - #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 1.20 - //UCC 1.21 FILE* output; 1.22 int n; 1.23 - char filename[255]; 1.24 + char filename[255]; 1.25 + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 1.26 + //UCC 1.27 for(n=0;n<255;n++) 1.28 { 1.29 sprintf(filename, "./counters/UCC.%d",n);
2.1 --- a/VSs.h Fri Aug 31 18:24:03 2012 +0200 2.2 +++ b/VSs.h Tue Sep 11 17:51:05 2012 +0200 2.3 @@ -14,6 +14,13 @@ 2.4 #include "VMS_impl/VMS.h" 2.5 #include "Measurement/dependency.h" 2.6 2.7 +/* Switch for Nexus support 2.8 + * Note: nexus incompatible with holistic recording (constraints not accessible) 2.9 + * But counter recording still functional, can build constraintless display 2.10 + * with wallclock time 2.11 + */ 2.12 +//#define EXTERNAL_SCHEDULER 2.13 +//#define SIMULATE_EXTERNAL_SCHEDULER 2.14 2.15 //=========================================================================== 2.16 #define NUM_STRUCS_IN_SEM_ENV 1000
3.1 --- a/VSs_PluginFns.c Fri Aug 31 18:24:03 2012 +0200 3.2 +++ b/VSs_PluginFns.c Tue Sep 11 17:51:05 2012 +0200 3.3 @@ -11,6 +11,10 @@ 3.4 #include "VSs.h" 3.5 #include "VSs_Request_Handlers.h" 3.6 3.7 +#ifdef EXTERNAL_SCHEDULER 3.8 + #include "VSs_nexus_support.h" 3.9 +#endif 3.10 + 3.11 //=========================== Local Fn Prototypes =========================== 3.12 void 3.13 resume_slaveVP(SlaveVP *slave, VSsSemEnv *semEnv); 3.14 @@ -74,6 +78,9 @@ 3.15 goto ReturnTheSlv; 3.16 } 3.17 3.18 +#ifdef EXTERNAL_SCHEDULER 3.19 + VSs__get_ready_tasks_from_ext(semEnv->taskReadyQ); 3.20 +#endif 3.21 //If none, speculate will have a task, so get the slot slave 3.22 //TODO: false sharing ? (think not bad cause mostly read..) 3.23 returnSlv = semEnv->slotTaskSlvs[coreNum][slotNum];
4.1 --- a/VSs_Request_Handlers.c Fri Aug 31 18:24:03 2012 +0200 4.2 +++ b/VSs_Request_Handlers.c Tue Sep 11 17:51:05 2012 +0200 4.3 @@ -14,6 +14,9 @@ 4.4 #include "VSs_Request_Handlers.h" 4.5 4.6 4.7 +#ifdef EXTERNAL_SCHEDULER 4.8 +#include "VSs_nexus_support.h" 4.9 +#endif 4.10 4.11 4.12 //=========================== Local Fn Prototypes =========================== 4.13 @@ -63,11 +66,10 @@ 4.14 return entry; 4.15 } 4.16 4.17 -inline VSsPointerEntry * 4.18 -create_pointer_entry() { 4.19 - VSsPointerEntry *newEntry; 4.20 +VSsPointerEntry* create_pointer_entry() { 4.21 + VSsPointerEntry* newEntry; 4.22 4.23 - newEntry = VMS_PI__malloc(sizeof (VSsPointerEntry)); 4.24 + newEntry = (VSsPointerEntry*) VMS_PI__malloc(sizeof (VSsPointerEntry)); 4.25 newEntry->hasEnabledNonFinishedWriter = FALSE; 4.26 newEntry->numEnabledNonDoneReaders = 0; 4.27 newEntry->waitersQ = makePrivQ(); 4.28 @@ -262,6 +264,10 @@ 4.29 //DEBUG__printf3(dbgRqstHdlr,"Submit req from slaveID: %d, from task: %d, for task: %d", semReq->callingSlv->slaveID, parentSemData->taskStub->taskID[1], taskStub->taskID[1]) 4.30 if(semReq->taskID) { DEBUG__printf2(dbgRqstHdlr,"Submit req from slaveID: %d, for task: %d", semReq->callingSlv->slaveID, taskStub->taskID[1]) } 4.31 else { DEBUG__printf1(dbgRqstHdlr,"Submit req from slaveID: %d, for anonymous task", semReq->callingSlv->slaveID) } 4.32 +#ifdef EXTERNAL_SCHEDULER 4.33 + //send task descriptor 4.34 + VSs__submit_task_to_ext(taskStub, semEnv); 4.35 +#else 4.36 /*The controlled arguments are then processed one by one. 4.37 *Processing an argument means getting the hash of the pointer. Then, 4.38 * looking up the hash entry. (If none, create one). 4.39 @@ -326,7 +332,7 @@ 4.40 } 4.41 } 4.42 } //for argNum 4.43 - 4.44 +#endif 4.45 4.46 resume_slaveVP(semReq->callingSlv, semEnv); 4.47 4.48 @@ -413,7 +419,10 @@ 4.49 VMS_PI__free(parent); 4.50 } 4.51 4.52 - 4.53 +#ifdef EXTERNAL_SCHEDULER 4.54 + //send task end notification 4.55 + VSs__end_task_to_ext(endingTaskStub, semEnv); 4.56 +#else 4.57 //Now, update state of dependents and start ready tasks 4.58 /*The task's controlled arguments are processed one by one. 4.59 *Processing an argument means getting arg-pointer's entry. 4.60 @@ -441,7 +450,7 @@ 4.61 if (endingTaskType->argTypes[argNum] == READER) { /*then decrement the enabled and non-finished reader-count in 4.62 * the hash-entry. */ 4.63 ptrEntry->numEnabledNonDoneReaders -= 1; 4.64 -#ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 4.65 + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 4.66 Unit u; 4.67 u.vp = semReq->callingSlv->slaveID; 4.68 u.task=semReq->callingSlv->assignCount; 4.69 @@ -454,7 +463,7 @@ 4.70 newd.to_task = semReq->callingSlv->assignCount; 4.71 addToListOfArrays(Dependency, newd, semEnv->dataDependenciesList); 4.72 } 4.73 -#endif 4.74 + #endif 4.75 /*If the count becomes zero, then take the next entry from the Q. 4.76 *It should be a writer, or else there's a bug in this algorithm.*/ 4.77 if (ptrEntry->numEnabledNonDoneReaders == 0) { 4.78 @@ -480,7 +489,7 @@ 4.79 } 4.80 } else /*the ending task is a writer of this arg*/ { /*clear the enabled non-finished writer flag of the hash-entry.*/ 4.81 ptrEntry->hasEnabledNonFinishedWriter = FALSE; 4.82 -#ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 4.83 + #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC 4.84 { 4.85 int n,i; 4.86 int num_full = ptrEntry->readersSinceLastWriter->next_free_index / ptrEntry->readersSinceLastWriter->num_entries_per_fragment; //!\\ != list->dim1info->numInArray-1 4.87 @@ -552,7 +561,8 @@ 4.88 }//if-else, first waiting task is a reader 4.89 }//if-else, check of ending task, whether writer or reader 4.90 }//for argnum in ending task 4.91 - 4.92 +#endif 4.93 + 4.94 4.95 //done ending the task, now free the stub + args copy 4.96 // if still has live children, then keep stub around
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/VSs_nexus_support.c Tue Sep 11 17:51:05 2012 +0200 5.3 @@ -0,0 +1,217 @@ 5.4 +#include "VSs_nexus_support.h" 5.5 + 5.6 + 5.7 +//prototypes of functions internal to VSs_Request_Handlers.c 5.8 +#ifdef SIMULATE_EXTERNAL_SCHEDULER 5.9 +VSsPointerEntry* create_pointer_entry(); 5.10 +VSsTaskStubCarrier * 5.11 +create_task_carrier(VSsTaskStub *taskStub, int32 argNum, int32 rdOrWrite); 5.12 +#endif 5.13 + 5.14 +void VSs__init_ext_scheduler(){ 5.15 + 5.16 +#ifdef SIMULATE_EXTERNAL_SCHEDULER 5.17 + simQ = makeVMSQ(); 5.18 +#endif 5.19 +} 5.20 + 5.21 + 5.22 +void VSs__submit_task_to_ext(VSsTaskStub* taskStub, VSsSemEnv *semEnv){ 5.23 + //save correspondence of task ID and taskStub 5.24 + 5.25 + 5.26 +#ifdef SIMULATE_EXTERNAL_SCHEDULER 5.27 + uint32 key[3]; 5.28 + VSsTaskType *taskType; 5.29 + HashEntry *rawHashEntry; //has char *, but use with uint32 * 5.30 + VSsPointerEntry* ptrEntry; //contents of hash table entry for an arg pointer 5.31 + void **args; 5.32 + VSsTaskStubCarrier *taskCarrier; 5.33 + 5.34 + HashTable* argPtrHashTbl = semEnv->argPtrHashTbl; 5.35 + 5.36 + taskType = taskStub->taskType; 5.37 + args = taskStub->args; 5.38 + 5.39 + /*The controlled arguments are then processed one by one. 5.40 + *Processing an argument means getting the hash of the pointer. Then, 5.41 + * looking up the hash entry. (If none, create one). 5.42 + */ 5.43 + int32 argNum; 5.44 + for (argNum = 0; argNum < taskType->numCtldArgs; argNum++) { 5.45 + key[0] = 2; //two 32b values in key 5.46 + *((uint64*) & key[1]) = (uint64) args[argNum]; //write 64b into two 32b 5.47 + 5.48 + /*If the hash entry was chained, put it at the 5.49 + * start of the chain. (Means no-longer-used pointers accumulate 5.50 + * at end of chain, decide garbage collection later) */ 5.51 + rawHashEntry = getEntryFromTable32(key, argPtrHashTbl); 5.52 + if (rawHashEntry == NULL) { //adding a value auto-creates the hash-entry 5.53 + ptrEntry = create_pointer_entry(); 5.54 + rawHashEntry = addValueIntoTable32(key, ptrEntry, argPtrHashTbl); 5.55 + } else { 5.56 + ptrEntry = (VSsPointerEntry *) rawHashEntry->content; 5.57 + if (ptrEntry == NULL) { 5.58 + ptrEntry = create_pointer_entry(); 5.59 + rawHashEntry = addValueIntoTable32(key, ptrEntry, argPtrHashTbl); 5.60 + } 5.61 + } 5.62 + taskStub->ptrEntries[argNum] = ptrEntry; 5.63 + 5.64 + /*Have the hash entry. 5.65 + *If the arg is a reader and the entry does not have an enabled 5.66 + * non-finished writer, and the queue is empty. */ 5.67 + if (taskType->argTypes[argNum] == READER) { 5.68 + if (!ptrEntry->hasEnabledNonFinishedWriter && 5.69 + isEmptyPrivQ(ptrEntry->waitersQ)) { /*The reader is free. So, decrement the blocking-propendent 5.70 + * count in the task-stub. If the count is zero, then put the 5.71 + * task-stub into the readyQ. At the same time, increment 5.72 + * the hash-entry's count of enabled and non-finished readers.*/ 5.73 + taskStub->numBlockingProp -= 1; 5.74 + if (taskStub->numBlockingProp == 0) { 5.75 + writePrivQ(taskStub, simQ); 5.76 + } 5.77 + ptrEntry->numEnabledNonDoneReaders += 1; 5.78 + } else { /*Otherwise, the reader is put into the hash-entry's Q of 5.79 + * waiters*/ 5.80 + taskCarrier = create_task_carrier(taskStub, argNum, READER); 5.81 + writePrivQ(taskCarrier, ptrEntry->waitersQ); 5.82 + } 5.83 + } else //arg is a writer 5.84 + { /*the arg is a writer, plus the entry does not have a current 5.85 + * writer, plus the number of enabled non-finished readers is 5.86 + * zero, (the Q must be empty, else bug!) then the writer is free*/ 5.87 + if (!ptrEntry->hasEnabledNonFinishedWriter && 5.88 + ptrEntry->numEnabledNonDoneReaders == 0) { /*Mark the entry has having a enabled and non-finished writer. 5.89 + * Decrement the blocking-propenden count in the writer's 5.90 + * task-stub. If the count is zero, then put the task-stub 5.91 + * into the readyQ.*/ 5.92 + taskStub->numBlockingProp -= 1; 5.93 + if (taskStub->numBlockingProp == 0) { 5.94 + writePrivQ(taskStub, simQ); 5.95 + } 5.96 + ptrEntry->hasEnabledNonFinishedWriter = TRUE; 5.97 + } else {/*Otherwise, put the writer into the entry's Q of waiters.*/ 5.98 + taskCarrier = create_task_carrier(taskStub, argNum, WRITER); 5.99 + writePrivQ(taskCarrier, ptrEntry->waitersQ); 5.100 + } 5.101 + } 5.102 + } //for argNum 5.103 +#endif 5.104 +} 5.105 + 5.106 +void VSs__end_task_to_ext(VSsTaskStub* endingTaskStub, VSsSemEnv *semEnv){ 5.107 + VSsPointerEntry *ptrEntry; //contents of hash table entry for an arg pointer 5.108 + VSsTaskStub *waitingTaskStub; 5.109 + VSsTaskType *endingTaskType; 5.110 + VSsTaskStubCarrier *waitingTaskCarrier; 5.111 + VSsPointerEntry **ptrEntries; 5.112 + 5.113 + endingTaskType = endingTaskStub->taskType; 5.114 + ptrEntries = endingTaskStub->ptrEntries; 5.115 + 5.116 +#ifdef SIMULATE_EXTERNAL_SCHEDULER 5.117 + //Now, update state of dependents and start ready tasks 5.118 + /*The task's controlled arguments are processed one by one. 5.119 + *Processing an argument means getting arg-pointer's entry. 5.120 + */ 5.121 + int32 argNum; 5.122 + for (argNum = 0; argNum < endingTaskType->numCtldArgs; argNum++) { 5.123 + /* commented out 'cause remembering entry ptr when create stub 5.124 + key[0] = 2; //says are 2 32b values in key 5.125 + *( (uint64*)&key[1] ) = args[argNum]; //write 64b ptr into two 32b 5.126 + 5.127 + /*If the hash entry was chained, put it at the 5.128 + * start of the chain. (Means no-longer-used pointers accumulate 5.129 + * at end of chain, decide garbage collection later) 5.130 + */ 5.131 + /*NOTE: don't do hash lookups here, instead, have a pointer to the 5.132 + * hash entry inside task-stub, put there during task creation. 5.133 + rawHashEntry = getEntryFromTable32( key, ptrHashTbl ); 5.134 + ptrEntry = (VSsPointerEntry *)rawHashEntry->content; 5.135 + if( ptrEntry == NULL ) 5.136 + VMS_App__throw_exception("hash entry NULL", NULL, NULL); 5.137 + */ 5.138 + 5.139 + ptrEntry = ptrEntries[argNum]; 5.140 + /*check if the ending task was reader of this arg*/ 5.141 + if (endingTaskType->argTypes[argNum] == READER) { /*then decrement the enabled and non-finished reader-count in 5.142 + * the hash-entry. */ 5.143 + ptrEntry->numEnabledNonDoneReaders -= 1; 5.144 + 5.145 + /*If the count becomes zero, then take the next entry from the Q. 5.146 + *It should be a writer, or else there's a bug in this algorithm.*/ 5.147 + if (ptrEntry->numEnabledNonDoneReaders == 0) { 5.148 + waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ); 5.149 + if (waitingTaskCarrier == NULL) { //TODO: looks safe to delete the ptr entry at this point 5.150 + continue; //next iter of loop 5.151 + } 5.152 + if (waitingTaskCarrier->isReader) 5.153 + VMS_App__throw_exception("READER waiting", NULL, NULL); 5.154 + 5.155 + waitingTaskStub = waitingTaskCarrier->taskStub; 5.156 + 5.157 + /*Set the hash-entry to have an enabled non-finished writer.*/ 5.158 + ptrEntry->hasEnabledNonFinishedWriter = TRUE; 5.159 + 5.160 + /* Decrement the blocking-propendent-count of the writer's 5.161 + * task-stub. If the count has reached zero, then put the 5.162 + * task-stub into the readyQ.*/ 5.163 + waitingTaskStub->numBlockingProp -= 1; 5.164 + if (waitingTaskStub->numBlockingProp == 0) { 5.165 + writePrivQ(waitingTaskStub, simQ); 5.166 + } 5.167 + } 5.168 + } else /*the ending task is a writer of this arg*/ { /*clear the enabled non-finished writer flag of the hash-entry.*/ 5.169 + ptrEntry->hasEnabledNonFinishedWriter = FALSE; 5.170 + 5.171 + /*Take the next waiter from the hash-entry's Q.*/ 5.172 + waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ); 5.173 + if (waitingTaskCarrier == NULL) { //TODO: looks safe to delete ptr entry at this point 5.174 + continue; //go to next iter of loop, done here. 5.175 + } 5.176 + waitingTaskStub = waitingTaskCarrier->taskStub; 5.177 + 5.178 + /*If task is a writer of this hash-entry's pointer*/ 5.179 + if (!waitingTaskCarrier->isReader) { /* then turn the flag back on.*/ 5.180 + ptrEntry->hasEnabledNonFinishedWriter = TRUE; 5.181 + /*Decrement the writer's blocking-propendent-count in task-stub 5.182 + * If it becomes zero, then put the task-stub into the readyQ.*/ 5.183 + waitingTaskStub->numBlockingProp -= 1; 5.184 + if (waitingTaskStub->numBlockingProp == 0) { 5.185 + writePrivQ(waitingTaskStub, simQ); 5.186 + } 5.187 + } else { /*Waiting task is a reader, so do a loop, of all waiting readers 5.188 + * until encounter a writer or waitersQ is empty*/ 5.189 + while (TRUE) /*The checks guarantee have a waiting reader*/ { /*Increment the hash-entry's count of enabled non-finished 5.190 + * readers.*/ 5.191 + ptrEntry->numEnabledNonDoneReaders += 1; 5.192 + 5.193 + /*Decrement the blocking propendents count of the reader's 5.194 + * task-stub. If it reaches zero, then put the task-stub 5.195 + * into the readyQ.*/ 5.196 + waitingTaskStub->numBlockingProp -= 1; 5.197 + if (waitingTaskStub->numBlockingProp == 0) { 5.198 + writePrivQ(waitingTaskStub, simQ); 5.199 + } 5.200 + /*Get next waiting task*/ 5.201 + waitingTaskCarrier = peekPrivQ(ptrEntry->waitersQ); 5.202 + if (waitingTaskCarrier == NULL) break; 5.203 + if (!waitingTaskCarrier->isReader) break; 5.204 + waitingTaskCarrier = readPrivQ(ptrEntry->waitersQ); 5.205 + waitingTaskStub = waitingTaskCarrier->taskStub; 5.206 + }//while waiter is a reader 5.207 + }//if-else, first waiting task is a reader 5.208 + }//if-else, check of ending task, whether writer or reader 5.209 + }//for argnum in ending task 5.210 +#endif 5.211 +} 5.212 + 5.213 +void VSs__get_ready_tasks_from_ext(PrivQueueStruc* taskReadyQ){ 5.214 +#ifdef SIMULATE_EXTERNAL_SCHEDULER 5.215 + void* taskStub; 5.216 + while(taskStub=readPrivQ(simQ)){ 5.217 + writePrivQ(taskStub,taskReadyQ); 5.218 + } 5.219 +#endif 5.220 +} 5.221 \ No newline at end of file
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/VSs_nexus_support.h Tue Sep 11 17:51:05 2012 +0200 6.3 @@ -0,0 +1,25 @@ 6.4 +/* 6.5 + * File: VSs_nexus_support.h 6.6 + * Author: nengel 6.7 + * 6.8 + * Created on September 10, 2012, 5:35 PM 6.9 + */ 6.10 + 6.11 +#ifndef VSS_NEXUS_SUPPORT_H 6.12 +#define VSS_NEXUS_SUPPORT_H 6.13 +#include "VSs.h" 6.14 + 6.15 +#ifdef SIMULATE_EXTERNAL_SCHEDULER 6.16 +PrivQueueStruc* simQ; 6.17 +#endif 6.18 + 6.19 +void VSs__init_ext_scheduler(); 6.20 + 6.21 +void VSs__submit_task_to_ext(VSsTaskStub* taskStub, VSsSemEnv *semEnv); 6.22 + 6.23 +void VSs__end_task_to_ext(VSsTaskStub* taskStub, VSsSemEnv *semEnv); 6.24 + 6.25 +void VSs__get_ready_tasks_from_ext(PrivQueueStruc* taskReadyQ); 6.26 + 6.27 +#endif /* VSS_NEXUS_SUPPORT_H */ 6.28 +