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 +