# HG changeset patch # User Sean Halle # Date 1371075214 25200 # Node ID 5b757d5a70444d335a5e5401e1415c20b0063ae4 Initial add -- fully working diff -r 000000000000 -r 5b757d5a7044 .hgeol --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgeol Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,14 @@ + +[patterns] +**.py = native +**.txt = native +**.c = native +**.h = native +**.cpp = native +**.java = native +**.class = bin +**.jar = bin +**.sh = native +**.pl = native +**.jpg = bin +**.gif = bin diff -r 000000000000 -r 5b757d5a7044 .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,12 @@ +nbproject +Makefile +build +dist +src/Default +src/.settings +src/.cproject +src/.project +.dep.inc +glob:.cproject +glob:.project +glob:Debug diff -r 000000000000 -r 5b757d5a7044 Design_Notes.txt --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Design_Notes.txt Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,29 @@ + +This test app is for VReo development.. first version replicates a program +from the paper. It has two producers and one consumer. The circuit causes +the producers to take turns providing the next input that the consumer takes. + +The circuit is in the paper.. + +The way the code works, the circuit is supplied separately. A function is +generated by a tool, which creates the circuit data structs. Those structs +contain pointers to the functions that check transitions and then perform +transitions. + +So, the seed first starts up VReo, then it calls the create circuit Fn, +which returns a pointer to the circuit, then it calls create_VP three +times. The first, it hands it the pointer to the producer Fn, along with +a pointer to the circuit and an integer that indicates that it connects to +port 1 of the circuit. Second, it creates another producer, but connected +to port 2, then it creates a consumer connected to port 3. + +Then, it waits for the computation to end. + +A producer puts out 5 items, doing a print for each. The consumer consumes +10 items, doing a print for each. + +Then each of them call "end_VP". + +That ends the computation, and the seed comes back, and calls "end_seed_VP" + + diff -r 000000000000 -r 5b757d5a7044 VReo__Test_App/Circuit.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VReo__Test_App/Circuit.c Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,380 @@ +/* + * Copyright 2009 OpenSourceResearchInstitute.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + + +#include +#include +#include "VReo__Test_App.h" + +#include "Circuit.h" + +/*Create Circuit for Application + *This is called by the seedVP to create the circuit structs, + * which include port structs and island structs + * + *This circuit has two islands. + *First island has a port A written by VP A, a port B written by VP B, and a + * port C that is a FIFO it writes. + * + *Second island has a FIFO port Cp that it reads, and a VP port D that it + * writes + * + * + *Circuit code is written separately from the application + *It creates the island structures and the port structures + *Returns an array of pointer to the ports on the boundary + */ +VReoCircuit * +create_circuit__Test_App( SlaveVP *animVP ) + { VReoCircuit *circuit; + VReoPort *port, *ports, **boundaryPorts; + VReoIsland *islands, *island; + + //create uninitialized port structs, by allocating space in array + ports = PR_WL__malloc( NUM_PORTS * sizeof(VReoPort) ); + + //create uninitialized islands, by allocating space in array + islands = PR_WL__malloc( NUM_ISLANDS * sizeof(VReoIsland) ); + + //======================= Set up Islands ======================== + //== + //set up first island + island = &( islands[CKT_I1] ); //easier to work with a pointer + + //fill in pointers to checker functions + island->numCheckerFns = 2; + island->checkerFns = + PR_WL__malloc( island->numCheckerFns * sizeof(VReoCheckerFn) ); + island->checkerFns[0] = &Checker_1__I1; + island->checkerFns[1] = &Checker_2__I1; + + //fill in pointers to doer functions + island->doerFns = + PR_WL__malloc( island->numCheckerFns * sizeof(VReoDoerFn) ); + island->doerFns[0] = &Doer_1__I1; + island->doerFns[1] = &Doer_2__I1; + + //create space for pointers to ports + island->numPorts = 3; + island->ports = PR_WL__malloc( island->numPorts * sizeof(VReoPort *) ); + + //connect ports to island + island->ports[I1_PORT_Ar] = &(ports[CKT_PORT_A]); + island->ports[I1_PORT_Br] = &(ports[CKT_PORT_B]); + island->ports[I1_PORT_Cw] = &(ports[CKT_PORT_C]); + + //== + //set up second island + island = &( islands[CKT_I2] ); //easier to work with a pointer + + //fill in pointers to checker functions + island->numCheckerFns = 1; + island->checkerFns = + PR_WL__malloc( island->numCheckerFns * sizeof(VReoCheckerFn) ); + island->checkerFns[0] = &Checker_1__I2; + + //fill in pointers to doer functions + island->doerFns = + PR_WL__malloc( island->numCheckerFns * sizeof(VReoDoerFn) ); + island->doerFns[0] = &Doer_1__I2; + + //create space for pointers to ports + island->numPorts = 2; + island->ports = PR_WL__malloc( island->numPorts * sizeof(VReoPort *) ); + + //connect ports to island + island->ports[I2_PORT_Cr] = &(ports[CKT_PORT_C]); + island->ports[I2_PORT_Dw] = &(ports[CKT_PORT_D]); + + //========================= Connect ports ========================= + //== + //Connect port 1 to islands and/or VPs + port = &(ports[CKT_PORT_A]); + port->reader = &(islands[CKT_I1]); + + //initialize port + port->buffer = NULL; + port->portIsFull = FALSE; + port->waitingReaderVP = NULL; + port->waitingWriterVP = NULL; + + + //Connect port 2 to islands and/or VPs + port = &(ports[CKT_PORT_B]); + port->reader = &(islands[CKT_I1]); + + //initialize port + port->buffer = NULL; + port->portIsFull = FALSE; + port->waitingReaderVP = NULL; + port->waitingWriterVP = NULL; + + + //Connect port 3 to islands and/or VPs + port = &(ports[CKT_PORT_C]); + port->writer = &(islands[CKT_I1]); + port->reader = &(islands[CKT_I2]); + + //initialize port + port->buffer = NULL; + port->portIsFull = FALSE; + port->waitingReaderVP = NULL; + port->waitingWriterVP = NULL; + + + //Connect port 4 to islands and/or VPs + port = &(ports[CKT_PORT_D]); + port->writer = &(islands[CKT_I2]); + + //initialize port + port->buffer = NULL; + port->portIsFull = FALSE; + port->waitingReaderVP = NULL; + port->waitingWriterVP = NULL; + + + + + //======================= Set up Circuit ======================== + //== + circuit = (VReoCircuit *)PR_WL__malloc( sizeof(VReoCircuit) ); + + circuit->numIslands = NUM_ISLANDS; + circuit->islands = islands; + + circuit->numPorts = NUM_PORTS; + circuit->ports = ports; + + //populate the array of ports that are on the boundary of the + //Note: it is up to the "user" of the circuit to know the order of the + // ports, and whether a particular one is input vs output + boundaryPorts = PR_WL__malloc( NUM_BOUNDARY_PORTS * sizeof(VReoPort*) ); + boundaryPorts[0] = &(ports[CKT_PORT_A]); + boundaryPorts[1] = &(ports[CKT_PORT_B]); + boundaryPorts[2] = &(ports[CKT_PORT_D]); + + circuit->boundaryPorts = boundaryPorts; + + circuit->VPs = NULL; //must initialize, 'cause used to detect end of list + + return(circuit); + } + + + +/*The Connections between the virtual processors and the circuit + * are defined as part of the application development + *A connection correlates a port accessed inside application code + * to a port on the boundary of a circuit. + *The connection is represented by a pointer to a particular port + * being placed into a particular index in a virtual processor's + * array of ports. + *This function both creates the connection-arrays for a given + * VP instance, then it makes that VP instance, passing it the + * connection-array. + */ +void +create_VPs_and_connect__Test_App( VReoCircuit *circuit, SlaveVP *animVP ) + { VReoPort **boundaryPorts; + + TestAppProducerParams *prodParams; + TestAppConsumerParams *consParams; + + boundaryPorts = circuit->boundaryPorts; + + //====================== Create VPs ====================== + //== + //when create a VP, pass it an array of pointers to ports. + //VP keeps the array + //VP function has hard-coded into it which port idx it puts to or gets + // from + VReoPort **portsForVP; //array of pointers + SlaveVP **VPs; //array of pointers + + VPs = PR_WL__malloc( NUM_VPs * sizeof(SlaveVP *) ); + + //array of pointers to ports, that is given to VP + portsForVP = PR_WL__malloc( 1 * sizeof(VReoPort *) ); + //connect VP's 0th input port to the circuit's 0th boundary port + portsForVP[0] = boundaryPorts[0]; + prodParams = PR_WL__malloc( sizeof(TestAppProducerParams) ); + prodParams->inPorts = NULL; + prodParams->outPorts = portsForVP; + VPs[CKT_VP1] = VReo__create_VP( &producer_Fn, prodParams, circuit, animVP ); + boundaryPorts[0]->writer = VPs[CKT_VP1]; +// PRServ__pass_mem_ownership_of_to( portsForVP, VPs[0] ); + + portsForVP = PR_WL__malloc( 1 * sizeof(VReoPort *) ); + //connect VP's 0th input port to the circuit's 1-idx boundary port + portsForVP[0] = boundaryPorts[1]; + prodParams = PR_WL__malloc( sizeof(TestAppProducerParams) ); + prodParams->inPorts = NULL; + prodParams->outPorts = portsForVP; + VPs[CKT_VP2] = VReo__create_VP( &producer_Fn, prodParams, circuit, animVP ); + boundaryPorts[1]->writer = VPs[CKT_VP2]; +// PRServ__pass_mem_ownership_of_to( portsForVP, VPs[1] ); + + portsForVP = PR_WL__malloc( 1 * sizeof(VReoPort *) ); + //connect VP's 0th output port to the circuit's 2-idx boundary port + portsForVP[0] = boundaryPorts[2]; //connects circuit boundary port to VP port + consParams = PR_WL__malloc( sizeof(TestAppConsumerParams) ); + consParams->inPorts = portsForVP; + consParams->outPorts = NULL; + VPs[CKT_VP3] = VReo__create_VP( &consumer_Fn, consParams, circuit, animVP ); + boundaryPorts[2]->reader = VPs[CKT_VP3]; +// PRServ__pass_mem_ownership_of_to( portsForVP, VPs[2] ); + + //Now that all the connections in circuit are complete, can start it + VReo__start_circuit( circuit, animVP ); + } + + +/*A Checker function is one-to-one with a transition of the state machine. + * It takes as input an Island data-struct, and proceeds to check the states + * of each port that it cares about. It accesses the ports through the + * island struct. + */ + +/*Island 1 + *Checkers: + * 1) A offering and C empty + * 2) B offering and C empty + *Note: C is a FIFO port, so don't need to check for VP waiting to accept. + */ +bool32 +Checker_1__I1( VReoIsland *island ) + { VReoPort *portA, *portC; + bool32 satisfied; + + portA = (island->ports)[I1_PORT_Ar]; + portC = (island->ports)[I1_PORT_Cw]; + satisfied = portA->portIsFull && ! portC->portIsFull; + return satisfied; + } +bool32 +Checker_2__I1( VReoIsland *island ) + { VReoPort *portB, *portC; + bool32 satisfied; + + portB = (island->ports)[I1_PORT_Br]; + portC = (island->ports)[I1_PORT_Cw]; + satisfied = portB->portIsFull && ! portC->portIsFull; + return satisfied; + } + +/*Island 1 + *Doers: + * 1) take from A, put into C, resume A + * 2) take from B, put into C, resume B + *Note: C is a FIFO port, so no VP on C to resume + *Hard-code that C is a FIFO port because generated this from circuit + */ +void +Doer_1__I1( VReoIsland *island ) + { VReoPort *portA, *portC; + VReoIsland *islandOnOtherSide; + void *temp; + + portA = (island->ports)[I1_PORT_Ar]; + portC = (island->ports)[I1_PORT_Cw]; + temp = portA->buffer; + portA->portIsFull = FALSE; + portC->buffer = temp; + portC->portIsFull = TRUE; + + //Just wrote into C, which has an island on the other side, so check it + //Note, may have been that island that caused THIS check.. but check it + // anyway, this second go will not satisfy any checkers.. later do an + // optimization that remembers what triggered, to avoid this redundancy + islandOnOtherSide = (VReoIsland *)portC->reader; + VReo__check_an_island( islandOnOtherSide, islandOnOtherSide->numCheckerFns, + islandOnOtherSide->checkerFns, islandOnOtherSide->doerFns ); + + //A was made full by the request handler, which wrote buffer and flags + //A was full, so guaranteed to have a VP waiting to resume + PR_PI__make_slave_ready_for_lang( portA->waitingWriterVP, VReo_MAGIC_NUMBER); + portA->waitingWriterVP = NULL; + } +void +Doer_2__I1( VReoIsland *island ) + { VReoPort *portB, *portC; + VReoIsland *islandOnOtherSide; + void *temp; + + portB = (island->ports)[I1_PORT_Br]; + portC = (island->ports)[I1_PORT_Cw]; + temp = portB->buffer; + portB->portIsFull = FALSE; + portC->buffer = temp; + portC->portIsFull = TRUE; + + islandOnOtherSide = (VReoIsland *)portC->reader; + VReo__check_an_island( islandOnOtherSide, islandOnOtherSide->numCheckerFns, + islandOnOtherSide->checkerFns, islandOnOtherSide->doerFns ); + + //was full, so guaranteed to have a VP waiting to resume + PR_PI__make_slave_ready_for_lang( portB->waitingWriterVP, VReo_MAGIC_NUMBER ); + portB->waitingWriterVP = NULL; + } + +/*Island 2 + *Checkers: + * 1) Cp full and D has a waiting VP + */ +bool32 +Checker_1__I2( VReoIsland *island ) + { VReoPort *portC, *portD; + bool32 satisfied; + + portC = (island->ports)[I2_PORT_Cr]; + portD = (island->ports)[I2_PORT_Dw]; + satisfied = portC->portIsFull && portD->waitingReaderVP; + return satisfied; + } + +/*Island 2 + *Doers: + * 1) take from Cp, put into D, resume VP waiting on D, recheck I1 + */ +void +Doer_1__I2( VReoIsland *island ) + { VReoPort *portC, *portD; + VReoIsland *islandOnOtherSide; + void *temp; + + portC = (island->ports)[I2_PORT_Cr]; + portD = (island->ports)[I2_PORT_Dw]; + temp = portC->buffer; + portC->portIsFull = FALSE; + + + portD->buffer = temp; + portD->portIsFull = TRUE; + + //D guaranteed to be empty, with VP waiting to take, so always have a VP + // that takes what is put into D and resumes with that value. So, can + // do an optimization where don't write buffer, nor set full flag, if + // want. + + //Here, take value out of port, and resume VP with it. + portD->waitingReaderVP->dataRetFromReq = portD->buffer; + portD->portIsFull = FALSE; + PR_PI__make_slave_ready_for_lang( portD->waitingReaderVP, VReo_MAGIC_NUMBER ); + portD->waitingReaderVP = NULL; + + //Just emptied C, which has an island on the other side, so check it + //Note, may have been that island that caused THIS check.. but check it + // anyway, this second go may not satisfy any checkers.. later do an + // optimization that remembers what triggered, to avoid redundancy + islandOnOtherSide = (VReoIsland *)portC->writer; + VReo__check_an_island( islandOnOtherSide, islandOnOtherSide->numCheckerFns, + islandOnOtherSide->checkerFns, islandOnOtherSide->doerFns ); + } + + + diff -r 000000000000 -r 5b757d5a7044 VReo__Test_App/Circuit.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VReo__Test_App/Circuit.h Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,67 @@ +/* + * Copyright 2009 OpenSourceResearchInstitute.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + +#ifndef _Circuit_App1_H +#define _Circuit_App1_H + +#include "PR_impl/PR.h" +#include "VReo_impl/VReo.h" + +//========================================================================== +#define NUM_ISLANDS 2 +#define NUM_PORTS 4 +#define NUM_BOUNDARY_PORTS 3 +#define NUM_VPs 3 + +//Using defined symbols like this modularizes the process of generating the +// code +#define CKT_I1 0 +#define CKT_I2 1 + +#define CKT_PORT_A 0 +#define CKT_PORT_B 1 +#define CKT_PORT_C 2 +#define CKT_PORT_D 4 + +#define I1_PORT_Ar 0 +#define I1_PORT_Br 1 +#define I1_PORT_Cw 2 + +#define I2_PORT_Cr 0 +#define I2_PORT_Dw 1 + +#define CKT_VP1 0 +#define CKT_VP2 1 +#define CKT_VP3 2 + +//called by seedVP to create the circuit structs, including ports and islands +VReoCircuit * +create_circuit__Test_App( SlaveVP *animVP ); + +void +create_VPs_and_connect__Test_App( VReoCircuit *circuit, SlaveVP *animVP ); + + +bool32 +Checker_1__I1( VReoIsland *island ); +bool32 +Checker_2__I1( VReoIsland *island ); +void +Doer_1__I1( VReoIsland *island ); +void +Doer_2__I1( VReoIsland *island ); + + +bool32 +Checker_1__I2( VReoIsland *island ); +void +Doer_1__I2( VReoIsland *island ); + + +#endif /* _Circuit_App1_H */ + diff -r 000000000000 -r 5b757d5a7044 VReo__Test_App/Producer_and_Consumer.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VReo__Test_App/Producer_and_Consumer.c Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,64 @@ +/* + * Copyright 2009 OpenSourceResearchInstitute.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + + +#include +#include +#include "VReo__Test_App.h" + +/*The input to a VP's birth function is a struct that holds two arrays of + * pointers to ports -- one for input ports, one for output ports + */ +void producer_Fn( void *_birthParams, SlaveVP *animVP ) + { TestAppProducerParams *birthParams = (TestAppProducerParams *)_birthParams; + //Tell the Reo tool that generates circuit about the ports of this VP + //#Reo numInPorts 0 | numOutports 1 + VReoPort **outPorts = birthParams->outPorts; + VReoPort *port; + TestAppProdConsMsg *msg; + int32 i; + + DEBUG__printf1(dbgAppFlow, "Producer on core: %d", animVP->coreAnimatedBy); + + port = outPorts[0]; + + //A producer puts out 5 items, doing a print for each. + for( i=0; i<5; i++) + { + msg = PR__malloc( sizeof(TestAppProdConsMsg) ); + msg->producerID = animVP->slaveNum; + msg->producedCnt = i + 1; + DEBUG__printf2(dbgAppFlow,"Producer %d, put in %d", msg->producerID, msg->producedCnt); + VReo__put_into_port( msg, port, animVP ); + } + VReo__end_VP( animVP ); + } + + +void consumer_Fn( void *_args, SlaveVP *animVP ) + { TestAppConsumerParams *params = (TestAppConsumerParams *)_args; + //Tell the Reo tool that generates circuit about the ports of this VP + //#Reo numInPorts 1 | numOutports 0 + VReoPort **inPorts = params->inPorts; + VReoPort *port; + int32 i, got; + TestAppProdConsMsg *msg; + + DEBUG__printf1(dbgAppFlow, "Consumer on core: %d", animVP->coreAnimatedBy); + + port = inPorts[0]; + + //A producer puts out 5 items, doing a print for each. + for( i=0; i<10; i++) + { + msg = (TestAppProdConsMsg *) VReo__get_from_port( port, animVP ); + DEBUG__printf2(dbgAppFlow,"Consumer got %d from %d", msg->producedCnt, msg->producerID ); + } + VReo__end_VP( animVP ); + } + diff -r 000000000000 -r 5b757d5a7044 VReo__Test_App/SeedVP.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VReo__Test_App/SeedVP.c Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,66 @@ +/* + * Copyright 2009 OpenSourceResearchInstitute.org + * Licensed under GNU General Public License version 2 + * + * Author: seanhalle@yahoo.com + * + */ + + +#include +#include +#include "VReo__Test_App.h" + +#define NO_INPUT NULL + +/*The _params was passed into the create_process call inside main. + * + * the seed first starts up VReo, then it calls the create circuit Fn, +which returns a pointer to the circuit, then it calls create_VP three +times. The first, it hands it the pointer to the producer Fn, along with +a pointer to the circuit and an integer that indicates that it connects to +port 1 of the circuit. Second, it creates another producer, but connected +to port 2, then it creates a consumer connected to port 3. + +Then, it waits for the computation to end. + +A producer puts out 5 items, doing a print for each. The consumer consumes +10 items, doing a print for each. + +Then each of them call "end_VP". + +That ends the computation, and the seed comes back, and calls "end_seed_VP" + + */ +void test_app_seed_Fn( void *_params, SlaveVP *seedVP ) + { + //int32 *results = (int32 *)_params; //_params passed to create_process call + VReoCircuit *circuit; + + DEBUG__printf( dbgAppFlow, "start test_app"); + + //first thing to do is start the langlets going to use in this + // proglet (AKA process). + VReo__start( seedVP ); + + //Invoke the create circuit command, which returns a pointer to circuit + //This creates the VPs, which starts them running. + circuit = (VReoCircuit *)create_circuit__Test_App( seedVP ); + create_VPs_and_connect__Test_App( circuit, seedVP ); + + //Wait for work to end -- means the VPs have to end themselves once + // they've completed their work. + //Alternatively, could connect a port to the process that receives a + // communication that tells the process when to end the VPs and shutdown. + VReo__wait_for_all_VReo_created_work_to_end( seedVP ); + + DEBUG__printf(TRUE, "work done"); + + VReo__shutdown( seedVP ); //Shuts down VReo within the process + + //Tells PR to end the process, which it will do even + // if work is active, or suspended work entities are still live, or the + // process has input ports that could trigger future work. + PR__end_process_from_inside( seedVP ); + } + diff -r 000000000000 -r 5b757d5a7044 VReo__Test_App/VReo__Test_App.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/VReo__Test_App/VReo__Test_App.h Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,59 @@ +/* + * Copyright Oct 24, 2009 OpenSourceResearchInstitute.org + * Licensed under GNU General Public License version 2 + */ + +#ifndef _VReo_TEST_APP_H_ +#define _VReo_TEST_APP_H_ + +#include + +#include "VReo_impl/VReo.h" +#include "Circuit.h" + + +//=============================== Defines ============================== + +//============================== Structures ============================== + +//NOTE: this is a birth function param. The first field of any structure +// that is passed as the argument to a birth function must be a pointer to +// the Reo circuit +typedef struct + { //The first field must be pointer to a circuit (because is param to birth Fn) + VReoCircuit *circuit; //First field must ALWAYS be a pointer to a circuit + + VReoPort **inPorts; //array of pointers into circuit's array of ports + VReoPort **outPorts; //array of pointers into circuit's array of ports + } +TestAppProducerParams; + +typedef struct + { //The first field must be pointer to a circuit (because is param to birth Fn) + VReoCircuit *circuit; //First field must ALWAYS be a pointer to a circuit + + VReoPort **inPorts; //array of pointers into circuit's array of ports + VReoPort **outPorts; //array of pointers into circuit's array of ports + } +TestAppConsumerParams; + +typedef struct + { + int32 producerID; + int32 producedCnt; + } +TestAppProdConsMsg; + +//============================= Processor Functions ========================= +void test_app_seed_Fn( void *data, SlaveVP *animatingVP ); //seed VP function +void producer_Fn( void *data, SlaveVP *animatingVP ); +void consumer_Fn( void *data, SlaveVP *animatingVP ); + + +//================================ Entry Point ============================== +void +VReo__Test_App( ); + +//================================ Global Vars ============================== + +#endif /*_SSR_MATRIX_MULT_H_*/ diff -r 000000000000 -r 5b757d5a7044 __brch__ML_dev --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/__brch__ML_dev Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,1 @@ +Applications normally have only the default branch -- they shouldn't be affected by any choices in VMS or language.. diff -r 000000000000 -r 5b757d5a7044 main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.c Wed Jun 12 15:13:34 2013 -0700 @@ -0,0 +1,56 @@ +/* + * Copyright 2012 OpenSourceResearchInstitute.org + * Licensed under GNU General Public License version 2 + * + * author seanhalle@yahoo.com + */ + +#include +#include + +#include "VReo__Test_App/VReo__Test_App.h" + +#define NO_INPUT_OR_OUTPUT NULL + +/*This demonstrates the use of the proto-runtime system. It allows multiple + * languages to be mixed within a single sub-program. It also allows multiple + * sub-programs to be started, where each uses its own set of languages. The + * running sub-programs can then communicate with each other. + * + */ +int main( int argc, char **argv ) + { PRProcess *testProcess1, *testProcess2; + + DEBUG__printf2(TRUE, "arguments: %s | %s", argv[0], argv[1] ); + + //A proto-runtime based language sits on top of the proto-runtime. So, + // first start the proto-runtime system, then create processes (which + // start languages inside themselves) + PR__start(); + + //This info shows up in the header of output files holding measurements + //These calls MUST be made after PR__start and before creating a process + PR__set_app_info("Test for developing VReo"); + PR__set_input_info("no input"); + + + //Now that PR is started, create processes. + //Each process creates a seedVP and starts it running -- that then starts + // the languages used inside the process.. + //To get results from a process, it gets complicated.. simple soln is + // just use PR's malloc and free, in the main thread, between PR__start + // and PR__shutdown + //The call returns a process struct + //int32 *result = PR__malloc( 2 * sizeof(int32) ); + testProcess1 = PR__create_process( &test_app_seed_Fn, NO_INPUT_OR_OUTPUT ); + + PR__wait_for_process_to_end( testProcess1 ); + printf("done \n\n" ); + + //PR__free(result); + + PR__wait_for_all_activity_to_end(); //equivalent of detecting shutdown + PR__shutdown(); + + exit(0); //cleans up + }