changeset 0:35ca0c795e3d

Initial add -- fully working
author Sean Halle <seanhalle@yahoo.com>
date Wed, 12 Jun 2013 15:20:03 -0700
parents
children 78fadd8da8c0
files .hgeol .hgignore Measurement/VReo_Measurement.h Measurement/dependency.c Measurement/dependency.h VReo.c VReo.h VReo_Assigner.c VReo_Request_Handlers.c VReo_Request_Handlers.h VReo_SS.c __brch__ML_dev
diffstat 12 files changed, 1593 insertions(+), 0 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgeol	Wed Jun 12 15:20:03 2013 -0700
     1.3 @@ -0,0 +1,12 @@
     1.4 +
     1.5 +[patterns]
     1.6 +**.py = native
     1.7 +**.txt = native
     1.8 +**.c = native
     1.9 +**.h = native
    1.10 +**.cpp = native
    1.11 +**.java = native
    1.12 +**.sh = native
    1.13 +**.pl = native
    1.14 +**.jpg = bin
    1.15 +**.gif = bin
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/.hgignore	Wed Jun 12 15:20:03 2013 -0700
     2.3 @@ -0,0 +1,3 @@
     2.4 +syntax: glob
     2.5 +
     2.6 +*.o
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Measurement/VReo_Measurement.h	Wed Jun 12 15:20:03 2013 -0700
     3.3 @@ -0,0 +1,93 @@
     3.4 +/*
     3.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
     3.6 + *  Licensed under GNU General Public License version 2
     3.7 + *
     3.8 + * Author: seanhalle@yahoo.com
     3.9 + *
    3.10 + */
    3.11 +
    3.12 +#ifndef _VReo_MEAS_H
    3.13 +#define	_VReo_MEAS_H
    3.14 +
    3.15 +
    3.16 +#ifdef MEAS__TURN_ON_LANG_MEAS
    3.17 +
    3.18 +   //PR defines this as empty, by default, so undefine it here, then define below
    3.19 +   #ifdef MEAS__Make_Meas_Hists_for_VReo
    3.20 +   #undef MEAS__Make_Meas_Hists_for_VReo
    3.21 +   #endif
    3.22 +
    3.23 +
    3.24 +//===================  Language-specific Measurement Stuff ===================
    3.25 +//
    3.26 +//
    3.27 +   #define SendFromToHistIdx      1 //note: starts at 1
    3.28 +   #define SendOfTypeHistIdx      2
    3.29 +   #define ReceiveFromToHistIdx   3
    3.30 +   #define ReceiveOfTypeHistIdx   4
    3.31 +
    3.32 +   #define MEAS__Make_Meas_Hists_for_VReo( slave, magicNum ) \
    3.33 +    do \
    3.34 +    { VCilkLangEnv * \
    3.35 +      protoLangEnv = PR_PI__get_proto_lang_env_from_slave( slave, magicNum ); \
    3.36 +      protoLangEnv->measHistsInfo = \
    3.37 +             makePrivDynArrayOfSize( (void***)&(protoLangEnv->measHists), 200); \
    3.38 +      histInfo = protoLangEnv->measHistsInfo;
    3.39 +      makeAMeasHist( SendFromToHistIdx,   "SendFromTo",    50, 0, 100 ) \
    3.40 +      makeAMeasHist( SendOfTypeHistIdx,   "SendOfType",    50, 0, 100 ) \
    3.41 +      makeAMeasHist( ReceiveFromToHistIdx,"ReceiveFromTo", 50, 0, 100 ) \
    3.42 +      makeAMeasHist( ReceiveOfTypeHistIdx,"ReceiveOfType", 50, 0, 100 ) \
    3.43 + }while(FALSE); /* macro magic to protect local vars from name collision */
    3.44 +
    3.45 +   #define Meas_startSendFromTo \
    3.46 +       int32 startStamp, endStamp; \
    3.47 +       saveLowTimeStampCountInto( startStamp ); 
    3.48 +
    3.49 +   #define Meas_endSendFromTo \
    3.50 +       saveLowTimeStampCountInto( endStamp ); \
    3.51 +       addIntervalToHist( startStamp, endStamp, \
    3.52 +                                _PRTopEnv->measHists[ SendFromToHistIdx ] );
    3.53 +
    3.54 +   #define Meas_startSendOfType \
    3.55 +       int32 startStamp, endStamp; \
    3.56 +       saveLowTimeStampCountInto( startStamp ); \
    3.57 +
    3.58 +   #define Meas_endSendOfType \
    3.59 +       saveLowTimeStampCountInto( endStamp ); \
    3.60 +       addIntervalToHist( startStamp, endStamp, \
    3.61 +                                _PRTopEnv->measHists[ SendOfTypeHistIdx ] );
    3.62 +
    3.63 +   #define Meas_startReceiveFromTo \
    3.64 +       int32 startStamp, endStamp; \
    3.65 +       saveLowTimeStampCountInto( startStamp ); \
    3.66 +
    3.67 +   #define Meas_endReceiveFromTo \
    3.68 +       saveLowTimeStampCountInto( endStamp ); \
    3.69 +       addIntervalToHist( startStamp, endStamp, \
    3.70 +                                _PRTopEnv->measHists[ ReceiveFromToHistIdx ] );
    3.71 +
    3.72 +   #define Meas_startReceiveOfType \
    3.73 +       int32 startStamp, endStamp; \
    3.74 +       saveLowTimeStampCountInto( startStamp ); \
    3.75 +
    3.76 +   #define Meas_endReceiveOfType \
    3.77 +       saveLowTimeStampCountInto( endStamp ); \
    3.78 +       addIntervalToHist( startStamp, endStamp, \
    3.79 +                                _PRTopEnv->measHists[ReceiveOfTypeHistIdx ] );
    3.80 +
    3.81 +#else //===================== turned off ==========================
    3.82 +
    3.83 +   #define MEAS__Make_Meas_Hists_for_VReo( slave, magicNum )
    3.84 +   #define Meas_startSendFromTo
    3.85 +   #define Meas_endSendFromTo
    3.86 +   #define Meas_startSendOfType
    3.87 +   #define Meas_endSendOfType
    3.88 +   #define Meas_startReceiveFromTo
    3.89 +   #define Meas_endReceiveFromTo
    3.90 +   #define Meas_startReceiveOfType
    3.91 +   #define Meas_endReceiveOfType
    3.92 +
    3.93 +#endif  /* MEAS__TURN_ON_LANG_MEAS */
    3.94 +
    3.95 +#endif	/*  */
    3.96 +
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/Measurement/dependency.c	Wed Jun 12 15:20:03 2013 -0700
     4.3 @@ -0,0 +1,78 @@
     4.4 +#include "dependency.h"
     4.5 +#include "PR_impl/PR.h"
     4.6 +
     4.7 +Dependency* new_dependency(int from_vp, int from_task, int to_vp, int to_task){
     4.8 +    Dependency* newDep = (Dependency*) PR_int__malloc(sizeof(Dependency));
     4.9 +    if (newDep!=NULL){
    4.10 +        newDep->from_vp = from_vp;
    4.11 +        newDep->from_task = from_task;
    4.12 +        newDep->to_vp = to_vp;
    4.13 +        newDep->to_task = to_task;
    4.14 +    }
    4.15 +    return newDep;
    4.16 +}
    4.17 +
    4.18 +NtoN* new_NtoN(int id){
    4.19 +    NtoN* newn = (NtoN*) PR_int__malloc(sizeof(NtoN));
    4.20 +    newn->id = id;
    4.21 +    newn->senders = makeListOfArrays(sizeof(Unit), 64);
    4.22 +    newn->receivers = makeListOfArrays(sizeof(Unit), 64);
    4.23 +    return newn;
    4.24 +}
    4.25 +
    4.26 +int set_dependency_file(FILE* file){
    4.27 +    dependency_file = file;
    4.28 +}
    4.29 +
    4.30 +void print_ctl_dependency_to_file(void* _dep){
    4.31 +    Dependency* dep = (Dependency*) _dep;
    4.32 +    if(!dep) return;
    4.33 +    fprintf(dependency_file,"ctlDep,%d,%d,%d,%d\n",dep->from_vp,dep->from_task,dep->to_vp,dep->to_task);
    4.34 +}
    4.35 +
    4.36 +void print_comm_dependency_to_file(void* _dep){
    4.37 +    Dependency* dep = (Dependency*) _dep;
    4.38 +    if(!dep) return;
    4.39 +    fprintf(dependency_file,"commDep,%d,%d,%d,%d\n",dep->from_vp,dep->from_task,dep->to_vp,dep->to_task);
    4.40 +}
    4.41 +
    4.42 +void print_dyn_dependency_to_file(void* _dep){
    4.43 +    Dependency* dep = (Dependency*) _dep;
    4.44 +    if(!dep) return;
    4.45 +    fprintf(dependency_file,"dynDep,%d,%d,%d,%d\n",dep->from_vp,dep->from_task,dep->to_vp,dep->to_task);
    4.46 +}
    4.47 +
    4.48 +void print_hw_dependency_to_file(void* _dep){
    4.49 +    Dependency* dep = (Dependency*) _dep;
    4.50 +    if(!dep) return;
    4.51 +    fprintf(dependency_file,"hwDep,%d,%d,%d,%d\n",dep->from_vp,dep->from_task,dep->to_vp,dep->to_task);
    4.52 +}
    4.53 +
    4.54 +void print_dependency_to_file(void* _dep){
    4.55 +    Dependency* dep = (Dependency*) _dep;
    4.56 +    if(!dep) return;
    4.57 +    fprintf(dependency_file,"VP_%d_%d -> VP_%d_%d;\n",dep->from_vp,dep->from_task,dep->to_vp,dep->to_task);
    4.58 +}
    4.59 +
    4.60 +void print_unit_to_file(void* _unit){
    4.61 +    Unit* unit = (Unit*) _unit;
    4.62 +    if(!unit) return;
    4.63 +    fprintf(dependency_file,"unit,%d,%d\n",unit->vp,unit->task);
    4.64 +}
    4.65 +
    4.66 +void print_nton_set_helper(void* _u){
    4.67 +    Unit* u = (Unit*) _u;
    4.68 +    if(!u) return;
    4.69 +    fprintf(dependency_file,",%d,%d",u->vp,u->task);
    4.70 +}
    4.71 +
    4.72 +void print_nton_to_file(void* _nton){
    4.73 +    NtoN* nton = (NtoN*) _nton;
    4.74 +    if(!nton) return;
    4.75 +    //assert(nton->senders->next_free_index==nton->receivers->next_free_index);
    4.76 +    int numInSet = nton->senders->next_free_index;
    4.77 +    fprintf(dependency_file,"NtoN,%d",numInSet);
    4.78 +    forAllInListOfArraysDo(nton->senders,&print_nton_set_helper);
    4.79 +    forAllInListOfArraysDo(nton->receivers,&print_nton_set_helper);
    4.80 +    fprintf(dependency_file,"\n");
    4.81 +}
    4.82 \ No newline at end of file
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/Measurement/dependency.h	Wed Jun 12 15:20:03 2013 -0700
     5.3 @@ -0,0 +1,56 @@
     5.4 +/* 
     5.5 + * File:   dependency.h
     5.6 + * Author: Nina Engelhardt
     5.7 + *
     5.8 + * Created on 29. August 2011, 17:41
     5.9 + */
    5.10 +
    5.11 +#ifndef  _DEPENDENCY_H
    5.12 +#define	_DEPENDENCY_H
    5.13 +
    5.14 +
    5.15 +#include <stdio.h>
    5.16 +#include "ListOfArrays/ListOfArrays.h"
    5.17 +
    5.18 +typedef struct {
    5.19 +    int vp;
    5.20 +    int task;
    5.21 +} Unit;
    5.22 +
    5.23 +typedef struct {
    5.24 +    int from_vp;
    5.25 +    int from_task;
    5.26 +    int to_vp;
    5.27 +    int to_task;
    5.28 +} Dependency; 
    5.29 +
    5.30 +typedef struct {
    5.31 +    int32 id;
    5.32 +    ListOfArrays* senders;
    5.33 +    ListOfArrays* receivers;
    5.34 +} NtoN;
    5.35 +
    5.36 +FILE* dependency_file;
    5.37 +
    5.38 +Dependency* new_dependency(int from_vp, int from_task, int to_vp, int to_task);
    5.39 +
    5.40 +NtoN* new_NtoN(int id);
    5.41 +
    5.42 +int set_dependency_file(FILE* file);
    5.43 +
    5.44 +void print_ctl_dependency_to_file(void* _dep);
    5.45 +
    5.46 +void print_comm_dependency_to_file(void* _dep);
    5.47 +
    5.48 +void print_dyn_dependency_to_file(void* _dep);
    5.49 +
    5.50 +void print_hw_dependency_to_file(void* _dep);
    5.51 +
    5.52 +void print_dependency_to_file(void* dep);
    5.53 +
    5.54 +void print_unit_to_file(void* unit);
    5.55 +
    5.56 +void print_nton_to_file(void* _nton);
    5.57 +
    5.58 +#endif	/* DEPENDENCY_H */
    5.59 +
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/VReo.c	Wed Jun 12 15:20:03 2013 -0700
     6.3 @@ -0,0 +1,143 @@
     6.4 +/*
     6.5 + * Copyright 2010  OpenSourceCodeStewardshipFoundation
     6.6 + *
     6.7 + * Licensed under BSD
     6.8 + */
     6.9 +
    6.10 +#include <stdio.h>
    6.11 +#include <stdlib.h>
    6.12 +#include <malloc.h>
    6.13 +
    6.14 +#include "Queue_impl/PrivateQueue.h"
    6.15 +#include "Hash_impl/PrivateHash.h"
    6.16 +
    6.17 +#include "VReo.h"
    6.18 +//#include "PR_impl/Services_Offered_by_PR/Measurement_and_Stats/MEAS__Counter_Recording.h"
    6.19 +//==========================================================================
    6.20 +
    6.21 +
    6.22 +
    6.23 +//===========================================================================
    6.24 +
    6.25 +
    6.26 +
    6.27 +//===========================================================================
    6.28 +
    6.29 +/*Put onto port blocks until the circuit accepts the item being put.
    6.30 + * 
    6.31 + *The port index is an index into the circuit's array of ports.  It is given
    6.32 + * to the VP when the VP is created.
    6.33 + */
    6.34 +void
    6.35 +VReo__put_into_port( void *itemToPut,VReoPort *port, SlaveVP *callingVP )
    6.36 + { VReoLangReq reqData;
    6.37 +   
    6.38 +      //lang request data is on stack: disappears when this call returns.
    6.39 +   reqData.port          = port;
    6.40 +   reqData.itemToPut     = itemToPut;
    6.41 +   
    6.42 +   PR_WL__send_lang_request( &reqData, (RequestHandler)&VReo__handlePutIntoPort, 
    6.43 +                             callingVP, VReo_MAGIC_NUMBER );
    6.44 + }
    6.45 +
    6.46 +/*Get from port blocks until the circuit provides an item.
    6.47 + * 
    6.48 + *The port index is an index into the circuit's array of ports.  It is given
    6.49 + * to the VP when the VP is created.
    6.50 + */
    6.51 +void *
    6.52 +VReo__get_from_port( VReoPort *port, SlaveVP *callingVP )
    6.53 + { VReoLangReq reqData;
    6.54 +   
    6.55 +      //lang request data is on stack: disappears when this call returns.
    6.56 +   reqData.port          = port;
    6.57 +   
    6.58 +   PR_WL__send_lang_request( &reqData, (RequestHandler)&VReo__handleGetFromPort, 
    6.59 +                             callingVP, VReo_MAGIC_NUMBER );
    6.60 +   return callingVP->dataRetFromReq;
    6.61 + }
    6.62 +
    6.63 +
    6.64 +//===========================================================================
    6.65 +
    6.66 +SlaveVP *
    6.67 +VReo__create_VP( BirthFnPtr fnPtr, void *_params, 
    6.68 +                           VReoCircuit *circuit, SlaveVP *creatingVP )
    6.69 + { VReoLangReq reqData;
    6.70 +   VReoBirthParams *birthParams = (VReoBirthParams *)_params;
    6.71 + 
    6.72 +   birthParams->circuit = circuit;
    6.73 +   
    6.74 +      //the lang request data is on the stack and disappears when this
    6.75 +      // call returns -- it's guaranteed to remain in the VP's stack for as
    6.76 +      // long as the VP is suspended.
    6.77 +   reqData.fnPtr            = fnPtr;
    6.78 +   reqData.initData         = birthParams;
    6.79 +   reqData.circuit          = circuit; //VPs are linked to circuit when created
    6.80 +                            //They're born suspended, then started all together
    6.81 +   
    6.82 +   PR_WL__send_create_slaveVP_req( &reqData, NO_ID,  
    6.83 +      (CreateHandler)&VReo__handleCreateVP, creatingVP, VReo_MAGIC_NUMBER );
    6.84 +   return (SlaveVP *)creatingVP->dataRetFromReq;
    6.85 + }
    6.86 +
    6.87 +/*This is always the last thing done in the code animated by a VP.
    6.88 + * Normally, this would be the last line of the VP's top level function.
    6.89 + * But, if the VP exits from any point, it has to do so by calling
    6.90 + * this.
    6.91 + *
    6.92 + *It simply sends a dissipate request, which handles all the state cleanup.
    6.93 + */
    6.94 +void
    6.95 +VReo__end_VP( SlaveVP *VPToEnd )
    6.96 + {    
    6.97 +   //PR will free the lang datas from the slave, which will free the params
    6.98 +   PR_WL__send_end_slave_req( NULL, (RequestHandler)&VReo__handleEndVP, VPToEnd, 
    6.99 +                              VReo_MAGIC_NUMBER );
   6.100 + }
   6.101 +
   6.102 +
   6.103 +void
   6.104 +VReo__start_circuit( VReoCircuit *circuit, SlaveVP *animVP )
   6.105 + { VReoLangReq reqData;
   6.106 +    
   6.107 +      //the lang request data is on the stack and disappears when this
   6.108 +      // call returns -- it's guaranteed to remain in the VP's stack for as
   6.109 +      // long as the VP is suspended.
   6.110 +   reqData.circuit = circuit;
   6.111 +   
   6.112 +   PR_WL__send_lang_request( &reqData, 
   6.113 +        (RequestHandler)&VReo__handleStartCircuit, animVP, VReo_MAGIC_NUMBER );
   6.114 + }
   6.115 +
   6.116 +
   6.117 +//===========================================================================
   6.118 +
   6.119 +
   6.120 +void
   6.121 +VReo__wait_for_all_VReo_created_work_to_end( SlaveVP *seedVP )
   6.122 + {
   6.123 +    VReoLangReq  reqData;
   6.124 +
   6.125 +   reqData.callingVP   = seedVP;
   6.126 +   
   6.127 +   PR_WL__send_lang_request( &reqData, (RequestHandler)&VReo__handleWaitForVReoWorkToEnd, seedVP,
   6.128 +                             VReo_MAGIC_NUMBER );   
   6.129 + }
   6.130 +
   6.131 +
   6.132 +
   6.133 +/*This is called by the application -- normally the seed slave.  It causes a
   6.134 + * request to be sent that frees the VSs lang env and all its contents.
   6.135 + *The seed slave resumes from the built-in PRServ langlet's environment.  It
   6.136 + * will be PRServ that causes return from this call.
   6.137 + */
   6.138 +void
   6.139 +VReo__shutdown( SlaveVP *seedVP )
   6.140 + {
   6.141 +   PR_WL__send_lang_shutdown_request( seedVP, VReo_MAGIC_NUMBER );   
   6.142 + }
   6.143 +
   6.144 +
   6.145 +
   6.146 +
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/VReo.h	Wed Jun 12 15:20:03 2013 -0700
     7.3 @@ -0,0 +1,245 @@
     7.4 +/*
     7.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
     7.6 + *  Licensed under GNU General Public License version 2
     7.7 + *
     7.8 + * Author: seanhalle@yahoo.com
     7.9 + *
    7.10 + */
    7.11 +
    7.12 +#ifndef _VReo_H
    7.13 +#define	_VReo_H
    7.14 +
    7.15 +#include "Queue_impl/PrivateQueue.h"
    7.16 +#include "Hash_impl/PrivateHash.h"
    7.17 +#include "PR_impl/PR.h"
    7.18 +#include "Measurement/dependency.h"
    7.19 +
    7.20 +
    7.21 +//===========================================================================
    7.22 +   //uniquely identifies VSs -- should be a jenkins char-hash of "VSs" to int32
    7.23 +#define VReo_MAGIC_NUMBER 0000000003
    7.24 +
    7.25 +#define NUM_STRUCS_IN_LANG_ENV 1000
    7.26 +
    7.27 +   //This is hardware dependent -- it's the number of cycles of scheduling
    7.28 +   // overhead -- if a work unit is fewer than this, it is better being
    7.29 +   // combined sequentially with other work
    7.30 +   //This value depends on both PR overhead and VSs's plugin.  At some point
    7.31 +   // it will be derived by perf-counter measurements during init of VSs
    7.32 +#define MIN_WORK_UNIT_CYCLES 20000
    7.33 +
    7.34 +//===========================================================================
    7.35 +/*This header defines everything specific to the VReo semantic plug-in
    7.36 + */
    7.37 +typedef struct _VReoIsland VReoIsland;
    7.38 +
    7.39 +typedef struct _VReoLangReq   VReoLangReq;
    7.40 +typedef struct _VReoTaskStub  VReoTaskStub;
    7.41 +typedef void   (*VReoTaskFnPtr ) ( void *, SlaveVP *);
    7.42 +typedef bool32 (*VReoCheckerFn ) ( VReoIsland * );
    7.43 +typedef void   (*VReoDoerFn )    ( VReoIsland * );
    7.44 +//===========================================================================
    7.45 +
    7.46 +#define IS_A_VP NULL
    7.47 +#define IS_ENDED    NULL
    7.48 +#define SEED_SLV    NULL
    7.49 +
    7.50 +#define NO_ID       NULL
    7.51 +#define ANY_CORE    -1
    7.52 +
    7.53 +//===========================================================================
    7.54 +
    7.55 +typedef struct
    7.56 + {
    7.57 +   void          *buffer;
    7.58 +   bool32         portIsFull;
    7.59 +   SlaveVP       *waitingReaderVP;   //doubles as flag
    7.60 +   SlaveVP       *waitingWriterVP;
    7.61 +   
    7.62 +   void          *reader;  //either island or VP
    7.63 +   void          *writer;  //either island or VP
    7.64 + }
    7.65 +VReoPort;
    7.66 +
    7.67 +struct _VReoIsland
    7.68 + {
    7.69 +   int32          numPorts;
    7.70 +   VReoPort     **ports;          //array of pointers to port structs
    7.71 +   
    7.72 +   int32          numCheckerFns;
    7.73 +   VReoCheckerFn *checkerFns;     //checkers triggered when state changes
    7.74 +   VReoDoerFn    *doerFns;        //corresponding doer functions   
    7.75 +   
    7.76 +   int32          lastCheckerToSucceed;
    7.77 + };
    7.78 +//VReoIsland
    7.79 +
    7.80 +typedef struct _VReoListElem VReoListElem;
    7.81 + 
    7.82 +struct _VReoListElem
    7.83 + {
    7.84 +   void *payload;
    7.85 +   VReoListElem *next;
    7.86 + };
    7.87 +//VReoListElem
    7.88 + 
    7.89 +typedef struct
    7.90 + {
    7.91 +   int32        numPorts; //
    7.92 +   VReoPort    *ports;    //array of port structs
    7.93 +   VReoPort   **boundaryPorts;
    7.94 +   
    7.95 +   int32        numIslands;
    7.96 +   VReoIsland  *islands;  //array of island structs -- no pointers
    7.97 +   
    7.98 +   int32        numVPs;
    7.99 +   VReoListElem *VPs;
   7.100 +   
   7.101 +   int32        suspendScope; //given to PR -- VPs created suspended 
   7.102 + }
   7.103 +VReoCircuit;
   7.104 +
   7.105 +//Every application-defined birth param struct must have a pointer to a
   7.106 +// circuit as its first field.  An instance of one of those app-defined 
   7.107 +// structs is then cast to be a VReoBirthParams, in order for VReo to 
   7.108 +// access the circuit field without knowing anything about the app-specific
   7.109 +// part of the structure
   7.110 +typedef struct
   7.111 + {
   7.112 +   VReoCircuit *circuit; 
   7.113 + }
   7.114 +VReoBirthParams;
   7.115 +
   7.116 +/*This is VReo's "lang meta task"
   7.117 + *See the proto-runtime wiki entry to learn about "lang meta task"
   7.118 + *In essence, this holds all the meta information that VReo needs about a task
   7.119 + */
   7.120 +struct _VReoTaskStub
   7.121 + {   
   7.122 +   VReoTaskStub *parentTaskStub; //for liveness, for the wait construct
   7.123 +   int32         numLiveChildTasks;
   7.124 +   int32         numLiveChildVPs;
   7.125 +   bool32        isWaitingForChildTasksToEnd;
   7.126 +   bool32        isWaitingForChildVPsToEnd;
   7.127 +   bool32        isEnded;
   7.128 + };
   7.129 +
   7.130 +
   7.131 +
   7.132 +/*Semantic-layer-specific data sent inside a request from lib call in app
   7.133 + * to request handler called in AnimationMaster
   7.134 + */
   7.135 +
   7.136 +struct _VReoLangReq
   7.137 + { 
   7.138 +   SlaveVP           *callingVP;
   7.139 +      
   7.140 +   BirthFnPtr      fnPtr;
   7.141 +   void              *initData;
   7.142 +   int32              coreToAssignOnto;
   7.143 +   int32              createSuspendedGroup;
   7.144 +   
   7.145 +   VReoCircuit       *circuit;
   7.146 +   VReoPort          *port;
   7.147 +   void              *itemToPut;
   7.148 + }
   7.149 +/* VReoLangReq */;
   7.150 +
   7.151 +
   7.152 +typedef struct
   7.153 + { 
   7.154 +   PrivQueueStruc  *slaveReadyQ; //Shared (slaves not pinned)
   7.155 +   PrivQueueStruc  *taskReadyQ;  //Shared (tasks not pinned)
   7.156 +   
   7.157 +   int32            nextCoreToGetNewSlv;
   7.158 +   int32            primitiveStartTime;
   7.159 +   
   7.160 +   VReoCircuit     *circuit; //used during debugging, to get access when no work
   7.161 +   
   7.162 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   7.163 +   ListOfArrays* unitList;
   7.164 +   ListOfArrays* ctlDependenciesList;
   7.165 +   ListOfArrays* commDependenciesList;
   7.166 +   NtoN** ntonGroups;
   7.167 +   PrivDynArrayInfo* ntonGroupsInfo;
   7.168 +   ListOfArrays* dynDependenciesList;
   7.169 +   Unit last_in_slot[NUM_CORES * NUM_ANIM_SLOTS];
   7.170 +   ListOfArrays* hwArcs;
   7.171 +   #endif
   7.172 +
   7.173 +   #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
   7.174 +   ListOfArrays* counterList[NUM_CORES];
   7.175 +   #endif
   7.176 + }
   7.177 +VReoLangEnv;
   7.178 +
   7.179 +typedef struct
   7.180 + {
   7.181 +   VReoCircuit *circuit;
   7.182 +   int32  numPorts;
   7.183 +   int32 *ports;
   7.184 + }
   7.185 +VReoVPParams;
   7.186 + 
   7.187 +typedef struct
   7.188 + {
   7.189 +   VReoVPParams *params; //keep here, so can free when end VP
   7.190 + }
   7.191 +VReoLangData;
   7.192 + 
   7.193 +//===========================================================================
   7.194 +
   7.195 +//=======================
   7.196 +
   7.197 +void
   7.198 +VReo__start( SlaveVP *seedVP );
   7.199 +
   7.200 +void
   7.201 +VReo__shutdown( SlaveVP *seedVP );
   7.202 +
   7.203 +void
   7.204 +VReo__wait_for_all_VReo_created_work_to_end( SlaveVP *seedVP );
   7.205 +
   7.206 +//=======================
   7.207 +
   7.208 +void
   7.209 +VReo__put_into_port( void *itemToPut, VReoPort *port, SlaveVP *callingVP );
   7.210 +
   7.211 +void *
   7.212 +VReo__get_from_port( VReoPort *port, SlaveVP *callingVP );
   7.213 +
   7.214 +
   7.215 +
   7.216 +SlaveVP *
   7.217 +VReo__create_VP( BirthFnPtr fnPtr, void *_params, 
   7.218 +                           VReoCircuit *circuit, SlaveVP *creatingVP );
   7.219 +
   7.220 +void
   7.221 +VReo__end_VP( SlaveVP *VPToEnd );
   7.222 +
   7.223 +
   7.224 +//=======================
   7.225 +
   7.226 +
   7.227 +//=========================  Internal use only  =============================
   7.228 +
   7.229 +bool32
   7.230 +VReo__assign_work_to_slot( void *_langEnv, AnimSlot *slot );
   7.231 +
   7.232 +SlaveVP *
   7.233 +VReo__create_slave_with_affinity( BirthFnPtr fnPtr,    void *initData,
   7.234 +                            SlaveVP *creatingSlv, int32 coreToAssignOnto);
   7.235 +
   7.236 +void
   7.237 +VReo__cleanup_after_shutdown();
   7.238 +
   7.239 +//=====================    =====================
   7.240 +
   7.241 +#include "VReo_Request_Handlers.h"
   7.242 +
   7.243 +//=====================  Measurement of Lang Overheads  =====================
   7.244 +#include "Measurement/VReo_Measurement.h"
   7.245 +
   7.246 +//===========================================================================
   7.247 +#endif	/* _VReo_H */
   7.248 +
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/VReo_Assigner.c	Wed Jun 12 15:20:03 2013 -0700
     8.3 @@ -0,0 +1,166 @@
     8.4 +/*
     8.5 + * Copyright 2010  OpenSourceCodeStewardshipFoundation
     8.6 + *
     8.7 + * Licensed under BSD
     8.8 + */
     8.9 +
    8.10 +#include <stdio.h>
    8.11 +#include <stdlib.h>
    8.12 +
    8.13 +#include "Queue_impl/PrivateQueue.h"
    8.14 +#include "VReo.h"
    8.15 +#include "VReo_Request_Handlers.h"
    8.16 +
    8.17 +//=========================== Local Fn Prototypes ===========================
    8.18 +
    8.19 +//============================== Assigner ==================================
    8.20 +//
    8.21 +/*The assigner is complicated by having both tasks and explicitly created
    8.22 + * VPs, and by tasks being able to suspend.
    8.23 + *It can't use an explicit slave to animate a task because of stack
    8.24 + * pollution. So, it has to keep the two kinds separate.
    8.25 + * 
    8.26 + *Q: one assigner for both tasks and slaves, or separate?
    8.27 + * 
    8.28 + *Simplest way for the assigner logic is with a Q for extra empty task
    8.29 + * slaves, and another Q for slaves of both types that are ready to resume.
    8.30 + *
    8.31 + *Keep a current task slave for each anim slot. The request handler manages
    8.32 + * it by pulling from the extraTaskSlvQ when a task suspends, or else
    8.33 + * creating a new task slave if taskSlvQ empty. 
    8.34 + *Assigner only assigns a task to the current task slave for the slot.
    8.35 + *If no more tasks, then takes a ready to resume slave, if also none of them
    8.36 + * then dissipates extra task slaves (one per invocation).
    8.37 + *Shutdown condition is: must have no suspended tasks, and no suspended
    8.38 + * explicit slaves and no more tasks in taskQ.  Will only have the masters
    8.39 + * plus a current task slave for each slot.. detects this condition. 
    8.40 + * 
    8.41 + *Having the two types of slave is part of having communications directly
    8.42 + * between tasks, and tasks to explicit slaves, which requires the ability
    8.43 + * to suspend both kinds, but also to keep explicit slave stacks clean from
    8.44 + * the junk tasks are allowed to leave behind.
    8.45 + */
    8.46 +bool32
    8.47 +VReo__assign_work_to_slot( void *_langEnv, AnimSlot *slot )
    8.48 + { SlaveVP     *returnSlv;
    8.49 +   VReoLangEnv  *langEnv;
    8.50 +   int32        coreNum, slotNum;
    8.51 +   VReoTaskStub *newTaskStub;
    8.52 +  
    8.53 +   coreNum = slot->coreSlotIsOn;
    8.54 +   slotNum = slot->slotIdx;
    8.55 +   
    8.56 +   langEnv = (VReoLangEnv *)_langEnv;
    8.57 +   
    8.58 +      //Check for suspended slaves that are ready to resume
    8.59 +   returnSlv = readPrivQ( langEnv->slaveReadyQ );
    8.60 +   if( returnSlv != NULL )  //Yes, have a slave, so return it.
    8.61 +    { returnSlv->coreAnimatedBy   = coreNum;
    8.62 +      
    8.63 +      PR_PI__put_slave_into_slot( returnSlv, slot );
    8.64 +         //Note: PR uses the return boolean to track how much ready work the
    8.65 +         // lang env has in it..
    8.66 +      goto Success;
    8.67 +    }
    8.68 +   
    8.69 +      //No ready slaves, so check for ready tasks
    8.70 +   newTaskStub = readPrivQ( langEnv->taskReadyQ );
    8.71 +   if( newTaskStub != NULL )
    8.72 +    { 
    8.73 +      PR_int__put_task_into_slot( newTaskStub, slot );   
    8.74 +      goto Success;
    8.75 +    }
    8.76 +   
    8.77 +   //If here, didn't assign any work
    8.78 + Fail:
    8.79 +   return FALSE; //figure out what to do -- go through holistic code still?
    8.80 +
    8.81 + Success:  //doing gotos to here should help with holistic..
    8.82 +
    8.83 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
    8.84 +   //This no longer works -- should be moved into PR in master
    8.85 +   //This assumes the task has already been assigned to a slave, which happens
    8.86 +   // inside Master..
    8.87 +   if( returnMetaTask == NULL )
    8.88 +    { returnSlv = langEnv->process->idleSlv[coreNum][slotNum]; 
    8.89 +    
    8.90 +         //things that would normally happen in resume(), but these VPs
    8.91 +         // never go there
    8.92 +      returnSlv->numTimesAssignedToASlot++;
    8.93 +      Unit newU;
    8.94 +      newU.vp = returnSlv->slaveNum;
    8.95 +      newU.task = returnSlv->numTimesAssignedToASlot;
    8.96 +      addToListOfArrays(Unit,newU,langEnv->unitList);
    8.97 +
    8.98 +      if (returnSlv->numTimesAssignedToASlot > 1)
    8.99 +       { Dependency newD;
   8.100 +         newD.from_vp = returnSlv->slaveNum;
   8.101 +         newD.from_task = returnSlv->numTimesAssignedToASlot - 1;
   8.102 +         newD.to_vp = returnSlv->slaveNum;
   8.103 +         newD.to_task = returnSlv->numTimesAssignedToASlot;
   8.104 +         addToListOfArrays(Dependency, newD, langEnv->ctlDependenciesList);  
   8.105 +       }
   8.106 +      returnMetaTask = returnSlv->metaTasks;
   8.107 +    }
   8.108 +   else //returnSlv != NULL
   8.109 +    { //assignSlv->numTimesAssigned++;
   8.110 +      Unit prev_in_slot = 
   8.111 +         langEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum];
   8.112 +      if(prev_in_slot.vp != 0)
   8.113 +       { Dependency newD;
   8.114 +         newD.from_vp = prev_in_slot.vp;
   8.115 +         newD.from_task = prev_in_slot.task;
   8.116 +         newD.to_vp = returnSlv->slaveNum;
   8.117 +         newD.to_task = returnSlv->numTimesAssignedToASlot;
   8.118 +         addToListOfArrays(Dependency,newD,langEnv->hwArcs);   
   8.119 +       }
   8.120 +      prev_in_slot.vp = returnSlv->slaveNum;
   8.121 +      prev_in_slot.task = returnSlv->numTimesAssignedToASlot;
   8.122 +      langEnv->last_in_slot[coreNum * NUM_ANIM_SLOTS + slotNum] =
   8.123 +         prev_in_slot;        
   8.124 +    }
   8.125 +   #endif
   8.126 +/* PR handles work available in lang env and in process..
   8.127 +   if( isEmptyPrivQ(langEnv->slaveReadyQ) &&
   8.128 +       isEmptyPrivQ(langEnv->taskReadyQ) ) 
   8.129 +      PR_int__clear_work_in_lang_env(langEnv);
   8.130 + */
   8.131 + 
   8.132 +   return TRUE;
   8.133 + }
   8.134 +
   8.135 +
   8.136 +
   8.137 +//=========================== Helper ==============================
   8.138 +void
   8.139 +VReo__resume_slave( SlaveVP *slave, void *_langEnv )
   8.140 + { VReoLangEnv *langEnv = (VReoLangEnv *)_langEnv;
   8.141 + 
   8.142 +      //both suspended tasks and suspended explicit slaves resumed with this
   8.143 +   writePrivQ( slave, langEnv->slaveReadyQ );
   8.144 +//PR handles this..   PR_int__set_work_in_lang_env(langEnv);
   8.145 +   
   8.146 +   #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
   8.147 +/*
   8.148 +   int lastRecordIdx = slave->counter_history_array_info->numInArray -1;
   8.149 +   CounterRecord* lastRecord = slave->counter_history[lastRecordIdx];
   8.150 +   saveLowTimeStampCountInto(lastRecord->unblocked_timestamp);
   8.151 +*/
   8.152 +   #endif
   8.153 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   8.154 +   slave->numTimesAssignedToASlot++; //Somewhere here!
   8.155 +   Unit newU;
   8.156 +   newU.vp = slave->slaveNum;
   8.157 +   newU.task = slave->numTimesAssignedToASlot;
   8.158 +   addToListOfArrays(Unit,newU,langEnv->unitList);
   8.159 +   
   8.160 +   if (slave->numTimesAssignedToASlot > 1)
   8.161 +    { Dependency newD;
   8.162 +      newD.from_vp = slave->slaveNum;
   8.163 +      newD.from_task = slave->numTimesAssignedToASlot - 1;
   8.164 +      newD.to_vp = slave->slaveNum;
   8.165 +      newD.to_task = slave->numTimesAssignedToASlot;
   8.166 +      addToListOfArrays(Dependency, newD ,langEnv->ctlDependenciesList);  
   8.167 +    }
   8.168 +   #endif
   8.169 + }
     9.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.2 +++ b/VReo_Request_Handlers.c	Wed Jun 12 15:20:03 2013 -0700
     9.3 @@ -0,0 +1,479 @@
     9.4 +/*
     9.5 + * Copyright 2010  OpenSourceCodeStewardshipFoundation
     9.6 + *
     9.7 + * Licensed under BSD
     9.8 + */
     9.9 +
    9.10 +#include <stdio.h>
    9.11 +#include <stdlib.h>
    9.12 +
    9.13 +#include "PR_impl/PR.h"
    9.14 +#include "Queue_impl/PrivateQueue.h"
    9.15 +#include "Hash_impl/PrivateHash.h"
    9.16 +#include "VReo.h"
    9.17 +#include "VReo_Request_Handlers.h"
    9.18 +
    9.19 +
    9.20 +
    9.21 +
    9.22 +//=========================== Local Fn Prototypes ===========================
    9.23 +
    9.24 +//==========================================================================
    9.25 +//                           Helpers
    9.26 +//
    9.27 +
    9.28 +/*Only clone the elements of req used in these reqst handlers
    9.29 + */
    9.30 +VReoLangReq *
    9.31 +cloneReq( VReoLangReq *langReq )
    9.32 + { VReoLangReq *clonedReq;
    9.33 +
    9.34 +   clonedReq             = PR_PI__malloc( sizeof(VReoLangReq) );
    9.35 +   
    9.36 +   return clonedReq;
    9.37 + }
    9.38 +
    9.39 +
    9.40 +
    9.41 +/*malloc's space and initializes fields -- and COPIES the arg values
    9.42 + * to new space
    9.43 + */
    9.44 +inline 
    9.45 +VReoTaskStub *
    9.46 +create_task_stub( void **args )
    9.47 + { void **newArgs;
    9.48 +   VReoTaskStub* newStub;
    9.49 +   
    9.50 +      //Create a new task stub, with enough room at end to copy args there
    9.51 +   newStub = (VReoTaskStub *)PR_int__create_lang_meta_task( 
    9.52 +    sizeof(VReoTaskStub), &VReo__lang_meta_task_freer, VReo_MAGIC_NUMBER );
    9.53 +   
    9.54 +   
    9.55 +      //Skip over the task stub, to get ptr to space alloc'd for args copy
    9.56 +   newArgs = (void **)( (uint8 *)newStub + sizeof(VReoTaskStub) );
    9.57 +   newStub->numLiveChildTasks   = 0;
    9.58 +   newStub->numLiveChildVPs = 0;
    9.59 +   newStub->isEnded             = FALSE;
    9.60 +      
    9.61 +   return newStub;
    9.62 + }
    9.63 +
    9.64 +void
    9.65 +VReo__lang_meta_task_freer( void *_langMetaTask )
    9.66 + { //no malloc'd structs inside task stub, so nothing to do
    9.67 + }
    9.68 +
    9.69 +void * 
    9.70 +VReo__create_empty_lang_meta_task_in_slave( SlaveVP *slave )
    9.71 + { 
    9.72 +   return (void *)VReo__create_generic_slave_task_stub_in_slave( slave );
    9.73 + }
    9.74 +
    9.75 +
    9.76 +VReoTaskStub *
    9.77 +VReo__create_generic_slave_task_stub_in_slave( SlaveVP *slave )
    9.78 + { VReoTaskStub *newStub;
    9.79 + 
    9.80 +   newStub = (VReoTaskStub *)PR_int__create_lang_meta_task_in_slave( 
    9.81 +      sizeof(VReoTaskStub), &VReo__lang_meta_task_freer, slave, VReo_MAGIC_NUMBER );
    9.82 +   newStub->numLiveChildTasks   = 0;
    9.83 +   newStub->numLiveChildVPs = 0;
    9.84 +   newStub->isEnded             = FALSE;   
    9.85 +
    9.86 +   return newStub;
    9.87 + }
    9.88 +
    9.89 +/*This has a fixed prototype defined by PR
    9.90 + * Initialize semantic data struct..  this initializer doesn't need any input,
    9.91 + * but some languages may need something from inside the request that was sent
    9.92 + * to create a slave..  in that case, just make initializer do the malloc then
    9.93 + * use the PR_PI__give_lang_data  inside the create handler, and fill in the
    9.94 + * langData values there.
    9.95 + */
    9.96 +void * 
    9.97 +VReo__create_lang_data_in_slave( SlaveVP *slave )
    9.98 + { VReoLangData *langData;
    9.99 +
   9.100 + 
   9.101 +   langData = PR_PI__create_lang_data_in_slave( sizeof(VReoLangData), 
   9.102 +                                 &VReo__langDataFreer, slave, VReo_MAGIC_NUMBER );
   9.103 +   
   9.104 +   return langData;
   9.105 + }
   9.106 +
   9.107 +void
   9.108 +VReo__langDataFreer( void *_langData )
   9.109 + { //free the params here, which were malloc'd when created the VP
   9.110 +   VReoLangData *langData = (VReoLangData *) _langData;
   9.111 +   
   9.112 +   if( langData->params != NULL )
   9.113 +      PR_WL__free(langData->params);
   9.114 + }
   9.115 +
   9.116 +
   9.117 +
   9.118 +//===========================  ==============================
   9.119 +
   9.120 +//
   9.121 +//NOTE ON DOER FUNCTIONS:
   9.122 +//
   9.123 +/*A doer function is what makes a FSM state transition take place.  It 
   9.124 + * modifies the states of ports, and triggers checks for consequent
   9.125 + * transitions.
   9.126 + * 
   9.127 + *A doer function must run atomicly together with the checker function that
   9.128 + * triggered it -- if those don't run as an isolated pair, then two different
   9.129 + * checkers on two different cores could both fire doers based upon current
   9.130 + * state that both see, before either doer has executed.  The first doer
   9.131 + * to complete then changes the state, into something that the checker for
   9.132 + * the second doer would fail!  Hence, that second doer should not run, but
   9.133 + * it still does..
   9.134 + * 
   9.135 + *A doer function changes states of ports in an island, and for each
   9.136 + * change can either go ahead and check transitions in the island on the
   9.137 + * other end of that port..  or else it can generate a task that will
   9.138 + * perform the checks.  (That task must run the checker and doer together
   9.139 + * atomically in isolation from other tasks dealing with the same island).
   9.140 + */
   9.141 +
   9.142 +
   9.143 +
   9.144 +/*The Put into Port request handler does:
   9.145 + * Copies data into the port's buffer, to indicate it is full.
   9.146 + * (A pointer to the VP is permanently stored in the port, so no need to set
   9.147 + *  it)
   9.148 + * Then this invokes the island checker on the island attached to the port.
   9.149 + * Then it returns.
   9.150 + * The callingVP remains suspended unless the island checker matches and
   9.151 + *  calls a doer function that resumes it.
   9.152 + */
   9.153 +void
   9.154 +VReo__handlePutIntoPort( VReoLangReq *langReq, SlaveVP *callingVP,
   9.155 +                         VReoLangEnv *langEnv )
   9.156 + { int32 numCheckerFns;
   9.157 +   VReoIsland    *island;
   9.158 +   VReoCheckerFn *checkerFns;
   9.159 +   VReoDoerFn    *doerFns;
   9.160 +   VReoPort      *port;
   9.161 +   
   9.162 +   
   9.163 +   port = langReq->port;
   9.164 +   
   9.165 +   port->buffer = langReq->itemToPut;
   9.166 +   port->waitingWriterVP = callingVP; //Doer has to set to NULL when takes
   9.167 +   port->portIsFull = TRUE;
   9.168 +   
   9.169 +   island = port->reader;
   9.170 +   
   9.171 +   numCheckerFns = island->numCheckerFns;
   9.172 +   checkerFns = island->checkerFns;
   9.173 +   doerFns = island->doerFns;
   9.174 +   
   9.175 +   VReo__check_an_island( island, numCheckerFns, checkerFns, doerFns );
   9.176 + }
   9.177 +
   9.178 +/*Get From Port -- sets the waitingVP
   9.179 + *A Doer function has to set the buffer in the port to NULL when it reads
   9.180 + * from the buffer.  Does same whether buffer is in a port attached to a
   9.181 + * VP on the other side, or another island.
   9.182 + */
   9.183 +void
   9.184 +VReo__handleGetFromPort( VReoLangReq *langReq, SlaveVP *callingVP,
   9.185 +                         VReoLangEnv *langEnv )
   9.186 + { int32 numCheckerFns;
   9.187 +   VReoIsland *island;
   9.188 +   VReoCheckerFn *checkerFns;
   9.189 +   VReoDoerFn *doerFns;
   9.190 +   VReoPort *port;
   9.191 +   
   9.192 +   
   9.193 +   port = langReq->port;
   9.194 +   port->waitingReaderVP = callingVP;  //Doer has to set to NULL when resumes it
   9.195 +   
   9.196 +   //Doer Fn is what puts the datum into the VP, just before resuming it
   9.197 +   //callingVP->dataRetFromReq = port->buffer;
   9.198 +   
   9.199 +   island = port->writer; //island on other side of the port from VP
   9.200 +   
   9.201 +   numCheckerFns = island->numCheckerFns;
   9.202 +   checkerFns = island->checkerFns;
   9.203 +   doerFns = island->doerFns;
   9.204 +   
   9.205 +   VReo__check_an_island( island, numCheckerFns, checkerFns, doerFns );
   9.206 + }
   9.207 +
   9.208 +/*Check an island is called from two places: from the request handler that
   9.209 + * handles a put or get, and from a Doer function that is triggered by a
   9.210 + * checker being satisfied.
   9.211 + * 
   9.212 + *This function loops through all the checker Fns in the island, and each
   9.213 + * tests whether the conditions are met for one of the transitions of the
   9.214 + * circuit's Finite State Machine.
   9.215 + *It starts with the checker function just past the last checker to be
   9.216 + * satisfied in the past of the Master timeline.
   9.217 + * 
   9.218 + *The params passed in are the island being checked for satisfied 
   9.219 + * transitions, the number of checker functions that exist for that island,
   9.220 + * the array of pointers to checker functions, and the array of corresponding
   9.221 + * doer functions.
   9.222 + *Could just get the num checkers and array of checkers and doers from the
   9.223 + * island, but want to make the form capable of letting each port have its
   9.224 + * own list of checker and doer functions, for each island it connects.
   9.225 + */
   9.226 +void
   9.227 +VReo__check_an_island( VReoIsland *island, int32 numCheckerFns, 
   9.228 +                 VReoCheckerFn *checkerFns, VReoDoerFn *doerFns )
   9.229 + { int32 idxOfCheckerToRun, numChecked;
   9.230 +   bool32        satisfies;
   9.231 +   VReoCheckerFn checkerFnPtr;
   9.232 +   VReoDoerFn    doerFnPtr;
   9.233 +
   9.234 +   //Loops through the checker functions for the island.  
   9.235 +   //Looping starts just past the last checker to succeed.
   9.236 +   idxOfCheckerToRun = island->lastCheckerToSucceed + 1;
   9.237 +   for( numChecked = 0; numChecked < numCheckerFns; numChecked++ )
   9.238 +    { if( idxOfCheckerToRun >= numCheckerFns ) idxOfCheckerToRun = 0;
   9.239 +      checkerFnPtr = checkerFns[idxOfCheckerToRun];
   9.240 +      satisfies    = (*checkerFnPtr)( island );
   9.241 +      if( satisfies ) //call corresponding Doer, which executes state chgs
   9.242 +       { island->lastCheckerToSucceed = idxOfCheckerToRun; //set first, just
   9.243 +         // in case the doer Fns wrap all the way back around to this island
   9.244 +         doerFnPtr = (doerFns)[idxOfCheckerToRun];
   9.245 +         (*doerFnPtr)( island );
   9.246 +         break; //escape from FOR loop
   9.247 +       }
   9.248 +      idxOfCheckerToRun += 1;
   9.249 +    }
   9.250 + }
   9.251 +   
   9.252 +void
   9.253 +VReo__add_new_VP_to_circuit( SlaveVP *newSlv, VReoCircuit *circuit )
   9.254 + { VReoListElem *newElem = PR_PI__malloc( sizeof(VReoListElem) );
   9.255 +   newElem->next = circuit->VPs;
   9.256 +   newElem->payload = newSlv;
   9.257 +   circuit->VPs = newElem;
   9.258 + }
   9.259 +
   9.260 +/*Handle create VP
   9.261 + *Application invokes this via wrapper library, when it explicitly creates a
   9.262 + * VP with the "VSs__create_VP()" command.
   9.263 + * 
   9.264 + *Slave creation is a special form, so PR does handling before calling this.
   9.265 + * It does creation of the new slave, and hands it to this handler.  
   9.266 + *This handler is registered with PR during VSs__start().
   9.267 + * 
   9.268 + *So, here, create a task Stub that contains a marker stating this is a VP. 
   9.269 + * Then, attach the task stub to the slave's meta Task via a PR command.
   9.270 + * 
   9.271 + *When slave dissipates, PR will call the registered recycler for the task stub.
   9.272 + */
   9.273 +//inline 
   9.274 +SlaveVP *
   9.275 +VReo__handleCreateVP( void *_langReq, SlaveVP *requestingSlv, void *_langEnv )
   9.276 + { VReoLangReq  *langReq;
   9.277 +   VReoTaskStub *taskStub, *parentTaskStub;
   9.278 +   SlaveVP      *newSlv;
   9.279 +   VReoLangEnv  *langEnv;
   9.280 +   VReoLangData *langData;
   9.281 +
   9.282 +   langReq = (VReoLangReq *) _langReq;
   9.283 +   langEnv = (VReoLangEnv *) _langEnv;
   9.284 +   
   9.285 +   newSlv  = PR_PI__create_slaveVP( langReq->fnPtr, langReq->initData );
   9.286 +   
   9.287 +   langData = 
   9.288 +    VReo__create_lang_data_in_slave( newSlv );
   9.289 +   langData->params = langReq->initData;
   9.290 +   
   9.291 +   parentTaskStub = PR_PI__give_lang_meta_task_from_slave( requestingSlv, VReo_MAGIC_NUMBER );
   9.292 +   parentTaskStub->numLiveChildVPs += 1;
   9.293 +   
   9.294 +   taskStub = VReo__create_generic_slave_task_stub_in_slave(newSlv); //used for wait info
   9.295 +   taskStub->parentTaskStub = parentTaskStub;
   9.296 +   
   9.297 +   //================= Assign the new VP to a core ===================
   9.298 +      //Assigning slave to core..
   9.299 +   newSlv->coreAnimatedBy = langEnv->nextCoreToGetNewSlv;
   9.300 +
   9.301 +   if( langEnv->nextCoreToGetNewSlv >= NUM_CORES - 1 )
   9.302 +      langEnv->nextCoreToGetNewSlv  = 0;
   9.303 +   else
   9.304 +      langEnv->nextCoreToGetNewSlv += 1;
   9.305 +   //========================================================================
   9.306 +   
   9.307 +   
   9.308 +
   9.309 +         DEBUG__printf2(dbgRqstHdlr,"Create from: %d, new VP: %d",
   9.310 +                                    requestingSlv->slaveNum, newSlv->slaveNum)
   9.311 +
   9.312 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   9.313 +   Dependency newD;
   9.314 +   newD.from_vp = requestingSlv->slaveNum;
   9.315 +   newD.from_task = requestingSlv->numTimesAssignedToASlot;
   9.316 +   newD.to_vp = newSlv->slaveNum;
   9.317 +   newD.to_task = 1;
   9.318 +   addToListOfArrays(Dependency,newD,langEnv->commDependenciesList);   
   9.319 +   #endif
   9.320 +
   9.321 +      //For VReo, caller needs ptr to created VP returned to it
   9.322 +   requestingSlv->dataRetFromReq = newSlv;
   9.323 +   PR_PI__make_slave_ready(requestingSlv , langEnv );
   9.324 +   
   9.325 +   VReo__add_new_VP_to_circuit( newSlv, langReq->circuit );
   9.326 +   
   9.327 +   return newSlv;
   9.328 + }
   9.329 +
   9.330 +/*Handle start circuit
   9.331 + *Called once the entire circuit has been created and all the pieces connected.
   9.332 + * The VPs were all born suspended, so this goes through and starts all the VPs.
   9.333 + */
   9.334 +void
   9.335 +VReo__handleStartCircuit( void *_langReq, SlaveVP *requestingSlv, void *_langEnv )
   9.336 + { VReoCircuit *circuit;
   9.337 +   VReoLangReq *langReq = (VReoLangReq *)_langReq;
   9.338 +   VReoListElem *currElem;
   9.339 +   
   9.340 +   circuit = langReq->circuit;
   9.341 +   currElem = circuit->VPs;
   9.342 +   
   9.343 +   VReoLangEnv *langEnv = (VReoLangEnv *)_langEnv;
   9.344 +   langEnv->circuit = circuit; //for debugging -- gives a handle, when no work
   9.345 +   
   9.346 +   while( currElem != NULL )
   9.347 +    { PR_PI__make_slave_ready( (SlaveVP *)(currElem->payload), _langEnv );
   9.348 +      currElem = currElem->next;
   9.349 +    }
   9.350 +   PR_PI__make_slave_ready(requestingSlv, _langEnv);
   9.351 + }
   9.352 +
   9.353 +
   9.354 +/*SlaveVP dissipate -- this is NOT task-end!, only call this to end explicitly
   9.355 + * created VPs
   9.356 + */
   9.357 +//inline
   9.358 +void
   9.359 +VReo__handleEndVP( void *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv )
   9.360 + { 
   9.361 +   VReoTaskStub  *parentTaskStub, *ownTaskStub;
   9.362 + 
   9.363 +         DEBUG__printf1(dbgRqstHdlr,"Dissipate request from processor %d",
   9.364 +                                                     requestingSlv->slaveNum)
   9.365 +             
   9.366 +   ownTaskStub    = PR_PI__give_lang_meta_task_from_slave( requestingSlv, VReo_MAGIC_NUMBER );
   9.367 +   parentTaskStub = ownTaskStub->parentTaskStub;
   9.368 +   parentTaskStub->numLiveChildVPs -= 1;  //parent wasn't freed, even if ended
   9.369 +      
   9.370 +      //if children still live, keep stub around, and last child will free it (below)
   9.371 +   if( ownTaskStub->numLiveChildTasks   != 0 ||
   9.372 +       ownTaskStub->numLiveChildVPs != 0 )
   9.373 +    {
   9.374 +      PR_PI__set_no_del_flag_in_lang_meta_task( ownTaskStub );
   9.375 +      ownTaskStub->isEnded = TRUE; //for children to see, when they end
   9.376 +    }
   9.377 +   
   9.378 +      //check if this is last child of ended parent (note, not possible to
   9.379 +      // have more than one level of ancestor *waiting to be freed*)
   9.380 +   if( parentTaskStub->isEnded &&
   9.381 +       parentTaskStub->numLiveChildTasks   == 0 && 
   9.382 +       parentTaskStub->numLiveChildVPs == 0 )
   9.383 +    { PR_PI__free_lang_meta_task( parentTaskStub ); //free whole meta-task
   9.384 +    }
   9.385 +   
   9.386 +      //Now, check on parents waiting on child VPs to end
   9.387 +   if( parentTaskStub->isWaitingForChildVPsToEnd &&
   9.388 +       parentTaskStub->numLiveChildVPs == 0 )
   9.389 +    { parentTaskStub->isWaitingForChildVPsToEnd = FALSE;
   9.390 +      if( parentTaskStub->isWaitingForChildTasksToEnd )
   9.391 +        return; //still waiting on tasks (should be impossible)
   9.392 +      else //parent free to resume
   9.393 +        PR_PI__make_slave_ready( PR_PI__give_slave_lang_meta_task_is_assigned_to(parentTaskStub), langEnv );
   9.394 +    }
   9.395 +   
   9.396 +
   9.397 + FreeSlaveStateAndReturn:
   9.398 +      //PR frees slave's base state, and also the meta-tasks and lang data,
   9.399 +      // except ones have "don't delete" flag set
   9.400 +   return; 
   9.401 + }
   9.402 +
   9.403 +
   9.404 +
   9.405 +//==========================================================================
   9.406 +//
   9.407 +
   9.408 +
   9.409 +
   9.410 +
   9.411 +
   9.412 +//==========================================================================
   9.413 +//
   9.414 +
   9.415 +
   9.416 +
   9.417 +/*Frees only the langlet's portion of the meta task.
   9.418 + *This is given to PR when a meta task is created.  It is also used by the
   9.419 + * end task handler, which may choose to keep the meta task info far past the
   9.420 + * end of the task's existence..
   9.421 + */
   9.422 +//inline 
   9.423 +void
   9.424 +VReo__free_langlet_part_of_lang_meta_task( VReoTaskStub *stubToFree )
   9.425 + { 
   9.426 + }
   9.427 +
   9.428 +//========================== Task Comm handlers ===========================
   9.429 +
   9.430 +
   9.431 +
   9.432 +/*Waits for all tasks that are direct children to end, then resumes calling
   9.433 + * task or VP
   9.434 + */
   9.435 +//inline 
   9.436 +void
   9.437 +VReo__handleTaskwait( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv)
   9.438 + { VReoTaskStub* taskStub;
   9.439 + 
   9.440 +            DEBUG__printf1(dbgRqstHdlr,"Taskwait request from processor %d",
   9.441 +                                                      requestingSlv->slaveNum)
   9.442 +    
   9.443 +   taskStub = (VReoTaskStub *)PR_PI__give_lang_meta_task_from_slave( requestingSlv, VReo_MAGIC_NUMBER);
   9.444 +   
   9.445 +   if( taskStub->numLiveChildTasks == 0 )
   9.446 +    {    //nobody to wait for, resume
   9.447 +      PR_PI__make_slave_ready( requestingSlv, langEnv );
   9.448 +    }
   9.449 +   else  //have to wait, mark waiting
   9.450 +    {        
   9.451 +      taskStub->isWaitingForChildTasksToEnd = TRUE;
   9.452 +    }    
   9.453 + }
   9.454 +
   9.455 +void
   9.456 +VReo__handleWaitForVReoWorkToEnd( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv)
   9.457 + {
   9.458 +   PR_PI__handle_wait_for_langlets_work_to_end( requestingSlv, langEnv );
   9.459 + }
   9.460 +
   9.461 +void
   9.462 +VReo__handleWaitThenShutdown( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv )
   9.463 + {
   9.464 +   implement_me();
   9.465 + }
   9.466 +
   9.467 +void
   9.468 +VReo__make_task_ready( void *taskStub, void *_langEnv )
   9.469 + {
   9.470 +   writePrivQ( taskStub, ((VReoLangEnv*)_langEnv)->taskReadyQ );
   9.471 + }
   9.472 +
   9.473 +/*This is called during shutdown, to delete a task that is sitting in the
   9.474 + * taskReadyQ
   9.475 + */
   9.476 +//inline 
   9.477 +void
   9.478 +VReo__free_waiting_task( void *langMetaTask )
   9.479 + { 
   9.480 +   PR_PI__free(langMetaTask);
   9.481 + }
   9.482 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/VReo_Request_Handlers.h	Wed Jun 12 15:20:03 2013 -0700
    10.3 @@ -0,0 +1,71 @@
    10.4 +/*
    10.5 + *  Copyright 2009 OpenSourceResearchInstitute.org
    10.6 + *  Licensed under GNU General Public License version 2
    10.7 + *
    10.8 + * Author: seanhalle@yahoo.com
    10.9 + *
   10.10 + */
   10.11 +
   10.12 +#ifndef _VReo_REQ_H
   10.13 +#define	_VReo_REQ_H
   10.14 +
   10.15 +#include "VReo.h"
   10.16 +
   10.17 +/*This header defines everything specific to the VReo semantic plug-in
   10.18 + */
   10.19 +
   10.20 +void
   10.21 +VReo__handlePutIntoPort( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv );
   10.22 +void
   10.23 +VReo__handleGetFromPort( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv );
   10.24 +
   10.25 +SlaveVP *
   10.26 +VReo__handleCreateVP( void *_langReq, SlaveVP *requestingSlv, void *_langEnv );
   10.27 +void
   10.28 +VReo__handleStartCircuit( void *_langReq, SlaveVP *requestingSlv, void *_langEnv );
   10.29 +void
   10.30 +VReo__handleEndVP( void *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv );
   10.31 +
   10.32 +void
   10.33 +VReo__handleEndTask( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv );
   10.34 +
   10.35 +void
   10.36 +VReo__handleTaskwait(VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv);
   10.37 +
   10.38 +//====================================
   10.39 +void
   10.40 +VReo__lang_meta_task_freer( void *_langMetaTask );
   10.41 +
   10.42 +inline 
   10.43 +void
   10.44 +VReo__free_langlet_part_of_lang_meta_task( VReoTaskStub *stubToFree );
   10.45 +
   10.46 +void
   10.47 +VReo__langDataFreer( void *_langData );
   10.48 +
   10.49 +VReoTaskStub *
   10.50 +VReo__create_generic_slave_task_stub_in_slave( SlaveVP *slave );
   10.51 +
   10.52 +void
   10.53 +VReo__handle_shutdown( void *_langEnv );
   10.54 +void * 
   10.55 +VReo__create_lang_data_in_slave( SlaveVP *slave );
   10.56 +void * 
   10.57 +VReo__create_empty_lang_meta_task_in_slave( SlaveVP *slave );
   10.58 +
   10.59 +void
   10.60 +VReo__check_an_island( VReoIsland *island, int32 numCheckerFns, 
   10.61 +                 VReoCheckerFn *checkerFns, VReoDoerFn *doerFns );
   10.62 +
   10.63 +void
   10.64 +VReo__handleWaitForVReoWorkToEnd( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv);
   10.65 +void
   10.66 +VReo__handleWaitThenShutdown( VReoLangReq *langReq, SlaveVP *requestingSlv, VReoLangEnv *langEnv);
   10.67 +
   10.68 +void
   10.69 +VReo__resume_slave( SlaveVP *slave, void *_langEnv );
   10.70 +void
   10.71 +VReo__make_task_ready( void *taskStub, void *_langEnv );
   10.72 +
   10.73 +#endif	/* _VReo_REQ_H */
   10.74 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/VReo_SS.c	Wed Jun 12 15:20:03 2013 -0700
    11.3 @@ -0,0 +1,245 @@
    11.4 +/*
    11.5 + * Copyright 2010  OpenSourceCodeStewardshipFoundation
    11.6 + *
    11.7 + * Licensed under BSD
    11.8 + */
    11.9 +
   11.10 +#include <stdio.h>
   11.11 +#include <stdlib.h>
   11.12 +#include <malloc.h>
   11.13 +
   11.14 +#include "Queue_impl/PrivateQueue.h"
   11.15 +#include "Hash_impl/PrivateHash.h"
   11.16 +
   11.17 +#include "VReo.h"
   11.18 +//#include "PR_impl/Services_Offered_by_PR/Measurement_and_Stats/MEAS__Counter_Recording.h"
   11.19 +
   11.20 +//==========================================================================
   11.21 +
   11.22 +
   11.23 +
   11.24 +//===========================================================================
   11.25 +
   11.26 +/*
   11.27 + */
   11.28 +void
   11.29 +VReo__start( SlaveVP *seedSlv )
   11.30 + { VReoLangEnv       *langEnv;
   11.31 +   int32             i;
   11.32 +   VReoLangData      *langData;
   11.33 +   VReoTaskStub      *VPTaskStub, *parentTaskStub;
   11.34 +   
   11.35 +   langEnv = 
   11.36 +      (VReoLangEnv *)PR_SS__create_lang_env( sizeof(VReoLangEnv), seedSlv, VReo_MAGIC_NUMBER);
   11.37 +   
   11.38 +      //seed slave is a VP slave, so make a VP's task stub for it
   11.39 +      // and then make another to stand for the seed's parent task.  Make
   11.40 +      // the parent be already ended, and have one child (the seed).  This
   11.41 +      // will make the dissipate handler do the right thing when the seed
   11.42 +      // is dissipated.
   11.43 +   VPTaskStub = 
   11.44 +    PR_int__create_lang_meta_task_in_slave( sizeof(VReoTaskStub), &VReo__lang_meta_task_freer, seedSlv, VReo_MAGIC_NUMBER );
   11.45 +
   11.46 +   VPTaskStub->isEnded = FALSE;
   11.47 +   VPTaskStub->isWaitingForChildTasksToEnd = FALSE;
   11.48 +   
   11.49 +   parentTaskStub =
   11.50 +    PR_int__create_lang_meta_task(sizeof(VReoTaskStub), &VReo__lang_meta_task_freer, VReo_MAGIC_NUMBER);
   11.51 +   
   11.52 +   parentTaskStub->isEnded = TRUE;
   11.53 +   parentTaskStub->numLiveChildVPs = 1; //so dissipate works for seed
   11.54 +   VPTaskStub->parentTaskStub = parentTaskStub;
   11.55 +      //Note: VPTaskStub and parentTaskStub freed when dissipate seedSlv 
   11.56 +   
   11.57 +      //register the langlet's handlers with PR
   11.58 +   PR_SS__register_assigner(                &VReo__assign_work_to_slot, seedSlv, VReo_MAGIC_NUMBER );
   11.59 +   PR_SS__register_lang_shutdown_handler(   &VReo__handle_shutdown, seedSlv, VReo_MAGIC_NUMBER );
   11.60 +   PR_SS__register_lang_data_creator(       &VReo__create_lang_data_in_slave, seedSlv, VReo_MAGIC_NUMBER );
   11.61 +   PR_SS__register_lang_meta_task_creator(  &VReo__create_empty_lang_meta_task_in_slave, seedSlv, VReo_MAGIC_NUMBER );
   11.62 +   PR_SS__register_make_slave_ready_fn(     &VReo__resume_slave, seedSlv, VReo_MAGIC_NUMBER );
   11.63 +   PR_SS__register_make_task_ready_fn(      &VReo__make_task_ready, seedSlv, VReo_MAGIC_NUMBER );
   11.64 +
   11.65 +   #ifdef HOLISTIC__TURN_ON_PERF_COUNTERS
   11.66 +   _PRTopEnv->counterHandler = &PR_MEAS__counter_handler;
   11.67 +   PR_MEAS__init_counter_data_structs_for_lang( seedSlv, VReo_MAGIC_NUMBER );
   11.68 +   #endif
   11.69 +
   11.70 +
   11.71 +      //create the ready queues, hash tables used for matching and so forth
   11.72 +   langEnv->slaveReadyQ    = makePRQ();
   11.73 +   langEnv->taskReadyQ     = makePRQ();
   11.74 +      
   11.75 +   langEnv->nextCoreToGetNewSlv = 0;
   11.76 +   
   11.77 +
   11.78 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
   11.79 +   langEnv->unitList = makeListOfArrays(sizeof(Unit),128);
   11.80 +   langEnv->ctlDependenciesList = makeListOfArrays(sizeof(Dependency),128);
   11.81 +   langEnv->commDependenciesList = makeListOfArrays(sizeof(Dependency),128);
   11.82 +   langEnv->dynDependenciesList = makeListOfArrays(sizeof(Dependency),128);
   11.83 +   langEnv->ntonGroupsInfo = makePrivDynArrayOfSize((void***)&(langEnv->ntonGroups),8);
   11.84 +   
   11.85 +   langEnv->hwArcs = makeListOfArrays(sizeof(Dependency),128);
   11.86 +   memset(langEnv->last_in_slot,0,sizeof(NUM_CORES * NUM_ANIM_SLOTS * sizeof(Unit)));
   11.87 +   #endif
   11.88 +
   11.89 +   MEAS__Make_Meas_Hists_for_VReo(seedSlv, VReo_MAGIC_NUMBER);
   11.90 + }
   11.91 +
   11.92 +
   11.93 +
   11.94 +/*This runs inside the MasterVP.
   11.95 + *It shuts down the langlet
   11.96 + * Frees any memory allocated by VReo__init() and deletes any slaves or tasks
   11.97 + * still in ready Qs.
   11.98 + * 
   11.99 + *Note: it needs the special lang-shutdown-request-handler prototype
  11.100 + */
  11.101 +void
  11.102 +VReo__handle_shutdown( void *_langEnv )
  11.103 + { VReoLangEnv *langEnv = (VReoLangEnv *)_langEnv;
  11.104 +   
  11.105 +   #ifdef HOLISTIC__TURN_ON_OBSERVE_UCC
  11.106 +   //UCC
  11.107 +   FILE* output;
  11.108 +   int n;
  11.109 +   char filename[255];    
  11.110 +    for(n=0;n<255;n++)
  11.111 +    {
  11.112 +        sprintf(filename, "./counters/UCC.%d",n);
  11.113 +        output = fopen(filename,"r");
  11.114 +        if(output)
  11.115 +        {
  11.116 +            fclose(output);
  11.117 +        }else{
  11.118 +            break;
  11.119 +        }
  11.120 +    }
  11.121 +   if(n<255){
  11.122 +    printf("Saving UCC to File: %s ...\n", filename);
  11.123 +    output = fopen(filename,"w+");
  11.124 +    if(output!=NULL){
  11.125 +        set_dependency_file(output);
  11.126 +        //fprintf(output,"digraph Dependencies {\n");
  11.127 +        //set_dot_file(output);
  11.128 +        //FIXME:  first line still depends on counters being enabled, replace w/ unit struct!
  11.129 +        //forAllInDynArrayDo(_PRTopEnv->counter_history_array_info, &print_dot_node_info );
  11.130 +        forAllInListOfArraysDo(langEnv->unitList, &print_unit_to_file);
  11.131 +        forAllInListOfArraysDo( langEnv->commDependenciesList, &print_comm_dependency_to_file );
  11.132 +        forAllInListOfArraysDo( langEnv->ctlDependenciesList, &print_ctl_dependency_to_file );
  11.133 +        forAllInDynArrayDo(langEnv->ntonGroupsInfo,&print_nton_to_file);
  11.134 +        //fprintf(output,"}\n");
  11.135 +        fflush(output);
  11.136 +
  11.137 +    } else
  11.138 +        printf("Opening UCC file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n");
  11.139 +   } else {
  11.140 +       printf("Could not open UCC file, please clean \"counters\" folder. (Must contain less than 255 files.)\n");
  11.141 +   }
  11.142 +   //Loop Graph
  11.143 +   for(n=0;n<255;n++)
  11.144 +    {
  11.145 +        sprintf(filename, "./counters/LoopGraph.%d",n);
  11.146 +        output = fopen(filename,"r");
  11.147 +        if(output)
  11.148 +        {
  11.149 +            fclose(output);
  11.150 +        }else{
  11.151 +            break;
  11.152 +        }
  11.153 +    }
  11.154 +   if(n<255){
  11.155 +    printf("Saving LoopGraph to File: %s ...\n", filename);
  11.156 +    output = fopen(filename,"w+");
  11.157 +    if(output!=NULL){
  11.158 +        set_dependency_file(output);
  11.159 +        //fprintf(output,"digraph Dependencies {\n");
  11.160 +        //set_dot_file(output);
  11.161 +        //FIXME:  first line still depends on counters being enabled, replace w/ unit struct!
  11.162 +        //forAllInDynArrayDo(_PRTopEnv->counter_history_array_info, &print_dot_node_info );
  11.163 +        forAllInListOfArraysDo( langEnv->unitList, &print_unit_to_file );
  11.164 +        forAllInListOfArraysDo( langEnv->commDependenciesList, &print_comm_dependency_to_file );
  11.165 +        forAllInListOfArraysDo( langEnv->ctlDependenciesList, &print_ctl_dependency_to_file );
  11.166 +        forAllInListOfArraysDo( langEnv->dynDependenciesList, &print_dyn_dependency_to_file );
  11.167 +        forAllInListOfArraysDo( langEnv->hwArcs, &print_hw_dependency_to_file );
  11.168 +        //fprintf(output,"}\n");
  11.169 +        fflush(output);
  11.170 +
  11.171 +    } else
  11.172 +        printf("Opening LoopGraph file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n");
  11.173 +   } else {
  11.174 +       printf("Could not open LoopGraph file, please clean \"counters\" folder. (Must contain less than 255 files.)\n");
  11.175 +   }
  11.176 +   
  11.177 +   
  11.178 +   freeListOfArrays(langEnv->unitList);
  11.179 +   freeListOfArrays(langEnv->commDependenciesList);
  11.180 +   freeListOfArrays(langEnv->ctlDependenciesList);
  11.181 +   freeListOfArrays(langEnv->dynDependenciesList);
  11.182 +   
  11.183 +   #endif
  11.184 +#ifdef HOLISTIC__TURN_ON_PERF_COUNTERS    
  11.185 +    for(n=0;n<255;n++)
  11.186 +    {
  11.187 +        sprintf(filename, "./counters/Counters.%d.csv",n);
  11.188 +        output = fopen(filename,"r");
  11.189 +        if(output)
  11.190 +        {
  11.191 +            fclose(output);
  11.192 +        }else{
  11.193 +            break;
  11.194 +        }
  11.195 +    }
  11.196 +    if(n<255){
  11.197 +    printf("Saving Counter measurements to File: %s ...\n", filename);
  11.198 +    output = fopen(filename,"w+");
  11.199 +    if(output!=NULL){
  11.200 +        int i;
  11.201 +        set_counter_file(output);
  11.202 +        for( i=0; i<NUM_CORES; i++ )
  11.203 +         {
  11.204 +           forAllInListOfArraysDo( langEnv->counterList[i], &PR_MEAS__print_counter_event_to_file );
  11.205 +           fflush(output);
  11.206 +         }
  11.207 +
  11.208 +    } else
  11.209 +        printf("Opening UCC file failed. Please check that folder \"counters\" exists in run directory and has write permission.\n");
  11.210 +   } else {
  11.211 +       printf("Could not open UCC file, please clean \"counters\" folder. (Must contain less than 255 files.)\n");
  11.212 +   }
  11.213 +    
  11.214 +#endif
  11.215 +   
  11.216 +   //Things to free:
  11.217 +   // tasks and slaves in ready Qs
  11.218 +   // ready Qs
  11.219 +   // tasks and slaves in the comm hash table
  11.220 +   // comm hash table
  11.221 +   // tasks in the argPtrHashTbl
  11.222 +   // the argPtrHashTbl
  11.223 +   PrivQueueStruc *queue;
  11.224 +   SlaveVP *slave;
  11.225 +   VReoTaskStub *task;
  11.226 +   
  11.227 +   //Not clear what to do with ready slaves still in readyQ.. reasonable to
  11.228 +   // end them..  also reasonable to send them over to PRServ.
  11.229 +   //Decided to send ready slaves over to PRServ
  11.230 +   queue = langEnv->slaveReadyQ;
  11.231 +   slave = readPrivQ( queue );
  11.232 +   while( slave != NULL )
  11.233 +    { PR_PI__resume_slave_in_PRServ( slave ); //recycler is for all of PR
  11.234 +      slave = readPrivQ( queue );
  11.235 +    }
  11.236 +   freePrivQ( queue );
  11.237 +   
  11.238 +   //delete any tasks in the readyQ
  11.239 +   queue = langEnv->taskReadyQ;
  11.240 +   task = readPrivQ( queue );
  11.241 +   while( task != NULL )
  11.242 +    { VReo__free_waiting_task( task );
  11.243 +      task = readPrivQ( queue );
  11.244 +    }
  11.245 +   freePrivQ( queue );   
  11.246 + }
  11.247 +
  11.248 +
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/__brch__ML_dev	Wed Jun 12 15:20:03 2013 -0700
    12.3 @@ -0,0 +1,2 @@
    12.4 +This branch is being used to develop a new structure for VMS, where there are langlets that each have their own semantic env, but share slaves among them..  so, any construct from any langlet can be mixed in with constructs from any others..
    12.5 +