Mercurial > cgi-bin > hgwebdir.cgi > PR > PR_Implementations > PR__ML_sharedMem > VReo_impls > VReo__ML_sharedMem_impl__MC_shared
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 +