void PrtPop( _Inout_ PRT_MACHINEINST_PRIV *context ) { context->lastOperation = PopStatement; PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); context->currentTrigger = PrtMkEventValue(PRT_SPECIAL_EVENT_NULL); context->currentPayload = PrtMkNullValue(); // Actual pop happens in PrtPopState; the exit function must be executed first. // context->{currentTrigger,currentPayload} are set on for the benefit of the exit function. }
void PrtPushNewEventHandlerFrame( _Inout_ PRT_MACHINEINST_PRIV *context, _In_ PRT_UINT32 funIndex, _In_ PRT_VALUE **locals ) { PRT_UINT16 length = context->funStack.length; PrtAssert(length < PRT_MAX_FUNSTACK_DEPTH, "Fun stack overflow"); context->funStack.length = length + 1; context->funStack.funs[length].funIndex = funIndex; PRT_BOOLEAN freeLocals = (locals == NULL); PRT_FUNDECL *funDecl = &(context->process->program->machines[context->instanceOf].funs[funIndex]); if (locals == NULL && funDecl->maxNumLocals != 0) { locals = PrtCalloc(funDecl->maxNumLocals, sizeof(PRT_VALUE *)); for (PRT_UINT32 i = 0; i < funDecl->maxNumLocals; i++) { locals[i] = NULL; } } PRT_UINT32 count = funDecl->numEnvVars; if (funDecl->name == NULL) { PrtAssert(0 < count, "numEnvVars must be positive for anonymous function"); PRT_UINT32 payloadIndex = count - 1; if (locals[payloadIndex] != NULL) { PrtFreeValue(locals[payloadIndex]); } locals[payloadIndex] = PrtCloneValue(context->currentPayload); } if (funDecl->localsNmdTupType != NULL) { PRT_UINT32 size = funDecl->localsNmdTupType->typeUnion.nmTuple->arity; for (PRT_UINT32 i = 0; i < size; i++) { PRT_TYPE *indexType = funDecl->localsNmdTupType->typeUnion.nmTuple->fieldTypes[i]; if (locals[count] != NULL) { PrtFreeValue(locals[count]); } locals[count] = PrtMkDefaultValue(indexType); count++; } } context->funStack.funs[length].locals = locals; context->funStack.funs[length].freeLocals = freeLocals; context->funStack.funs[length].returnTo = 0xFFFF; context->funStack.funs[length].rcase = NULL; }
void PrtFreeLocals( _In_ PRT_MACHINEINST_PRIV *context, _Inout_ PRT_FUNSTACK_INFO *frame ) { if (!frame->freeLocals) { return; } if (frame->locals == NULL) { return; } PRT_FUNDECL *funDecl = &context->process->program->machines[context->instanceOf].funs[frame->funIndex]; for (PRT_UINT32 i = 0; i < funDecl->maxNumLocals; i++) { if (frame->locals[i] != NULL) { PrtFreeValue(frame->locals[i]); } } PrtFree(frame->locals); }
void PrtRaise( _Inout_ PRT_MACHINEINST_PRIV *context, _In_ PRT_VALUE *event, _In_ PRT_VALUE *payload ) { PrtAssert(!PrtIsSpecialEvent(event), "Raised event must not be null"); PrtAssert(PrtInhabitsType(payload, PrtGetPayloadType(context, event)), "Payload must be member of event payload type"); context->lastOperation = RaiseStatement; PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); context->currentTrigger = PrtCloneValue(event); context->currentPayload = PrtCloneValue(payload); PrtLog(PRT_STEP_RAISE, context); }
PRT_VALUE *P_FUN_StartTimer_IMPL(PRT_MACHINEINST *context) { PRT_MACHINEINST_PRIV *p_tmp_mach_priv = (PRT_MACHINEINST_PRIV *)context; PRT_VALUE *p_tmp_ret = NULL; PRT_FUNSTACK_INFO p_tmp_frame; // pop frame PrtPopFrame(p_tmp_mach_priv, &p_tmp_frame); PRT_VALUE* timerMachineId = p_tmp_frame.locals[0]; PRT_MACHINEINST* timerMachine = PrtGetMachine(context->process, timerMachineId); TimerContext *timerContext = (TimerContext *)timerMachine->extContext; int timeout_value = p_tmp_frame.locals[1]->valueUnion.nt; SleepMs(timeout_value); PRT_VALUE *ev = PrtMkEventValue(P_EVENT_TIMEOUT); PRT_MACHINEINST* clientMachine = PrtGetMachine(context->process, timerContext->client); PrtSend(context, clientMachine, ev, context->id, PRT_FALSE); PrtFreeValue(ev); // free the frame PrtFreeLocals(p_tmp_mach_priv, &p_tmp_frame); return NULL; }
void PRT_CALL_CONV PrtSetLocalVarEx(_Inout_ PRT_VALUE **locals, _In_ PRT_UINT32 varIndex, _In_ PRT_VALUE *value, _In_ PRT_BOOLEAN cloneValue) { PRT_DBG_ASSERT(PrtIsValidValue(value), "value is not valid"); PRT_DBG_ASSERT(PrtIsValidValue(locals[varIndex]), "Variable must contain a valid value"); PrtFreeValue(locals[varIndex]); locals[varIndex] = cloneValue ? PrtCloneValue(value) : value; }
void PRT_CALL_CONV PrtSetGlobalVarEx(_Inout_ PRT_MACHINEINST_PRIV *context, _In_ PRT_UINT32 varIndex, _In_ PRT_VALUE *value, _In_ PRT_BOOLEAN cloneValue) { PRT_DBG_ASSERT(PrtIsValidValue(value), "value is not valid"); PRT_DBG_ASSERT(PrtIsValidValue(context->varValues[varIndex]), "Variable must contain a valid value"); PrtFreeValue(context->varValues[varIndex]); context->varValues[varIndex] = cloneValue ? PrtCloneValue(value) : value; }
void P_SEND_Timer_IMPL(PRT_MACHINEINST *context, PRT_VALUE *evnt, PRT_VALUE *payload, PRT_BOOLEAN doTransfer) { printf("Entering P_SEND_Timer_IMPL\n"); PRT_VALUE *ev; BOOL success; TimerContext *timerContext = (TimerContext *)context->extContext; if (!inStart && evnt->valueUnion.ev == P_EVENT_START) { printf("Timer received START\n"); LARGE_INTEGER liDueTime; liDueTime.QuadPart = -10000 * payload->valueUnion.nt; success = SetWaitableTimer(timerContext->timer, &liDueTime, 0, Callback, context, FALSE); inStart = TRUE; PrtAssert(success, "SetWaitableTimer failed"); } else if (evnt->valueUnion.ev == P_EVENT_CANCEL) { printf("Timer received CANCEL\n"); inStart = FALSE; success = CancelWaitableTimer(timerContext->timer); if (success) { ev = PrtMkEventValue(P_EVENT_CANCEL_SUCCESS); PrtSend(context, PrtGetMachine(context->process, timerContext->client), ev, context->id, PRT_FALSE); } else { ev = PrtMkEventValue(P_EVENT_CANCEL_FAILURE); PrtSend(context, PrtGetMachine(context->process, timerContext->client), ev, context->id, PRT_FALSE); } PrtFreeValue(ev); } else { PrtAssert(FALSE, "Illegal event"); } }
void P_DTOR_Timer_IMPL(PRT_MACHINEINST *context) { TimerContext *timerContext; timerContext = (TimerContext *)context->extContext; PrtFreeValue(timerContext->client); PrtFree(timerContext); }
VOID CALLBACK Callback(LPVOID arg, DWORD dwTimerLowValue, DWORD dwTimerHighValue) { inStart = FALSE; PRT_MACHINEINST *context = (PRT_MACHINEINST *)arg; TimerContext *timerContext = (TimerContext *)context->extContext; PRT_VALUE *ev = PrtMkEventValue(P_EVENT_TIMEOUT); PrtSend(PrtGetMachine(context->process, timerContext->client), ev, context->id, PRT_FALSE); PrtFreeValue(ev); }
void PrtCleanupModel( _Inout_ PRT_MACHINEINST *context ) { if (context->extContext != NULL) context->process->program->modelImpls[context->instanceOf].dtorFun(context); PrtFreeValue(context->id); }
void P_DTOR_Timer_IMPL(PRT_MACHINEINST *context) { printf("Entering P_DTOR_Timer_IMPL\n"); TimerContext *timerContext; timerContext = (TimerContext *)context->extContext; PrtFreeValue(timerContext->client); CloseHandle(timerContext->timer); free(timerContext); }
void PrtPushNewFrame( _Inout_ PRT_MACHINEINST_PRIV *context, _In_ PRT_UINT32 funIndex, _In_ PRT_VALUE *parameters ) { PRT_UINT16 length = context->funStack.length; PrtAssert(length < PRT_MAX_FUNSTACK_DEPTH, "Fun stack overflow"); context->funStack.length = length + 1; context->funStack.funs[length].funIndex = funIndex; PRT_FUNDECL *funDecl = &(context->process->program->machines[context->instanceOf].funs[funIndex]); PRT_VALUE **locals = NULL; if (funDecl->maxNumLocals == 0) { PrtAssert(parameters == NULL && funDecl->localsNmdTupType == NULL, "Incorrect maxNumLocals value"); } else { locals = PrtCalloc(funDecl->maxNumLocals, sizeof(PRT_VALUE *)); for (PRT_UINT32 i = 0; i < funDecl->maxNumLocals; i++) { locals[i] = NULL; } PRT_UINT32 count = 0; if (parameters != NULL) { PRT_UINT32 size = parameters->valueUnion.tuple->size; for (PRT_UINT32 i = 0; i < size; i++) { locals[count] = PrtTupleGet(parameters, i); count++; } PrtFreeValue(parameters); } if (funDecl->localsNmdTupType != NULL) { PRT_UINT32 size = funDecl->localsNmdTupType->typeUnion.nmTuple->arity; for (PRT_UINT32 i = 0; i < size; i++) { PRT_TYPE *indexType = funDecl->localsNmdTupType->typeUnion.nmTuple->fieldTypes[i]; locals[count] = PrtMkDefaultValue(indexType); count++; } } } context->funStack.funs[length].locals = locals; context->funStack.funs[length].freeLocals = PRT_TRUE; context->funStack.funs[length].returnTo = 0xFFFF; context->funStack.funs[length].rcase = NULL; }
int main(int argc, char *argv[]) { PRT_PROCESS *process; PRT_GUID processGuid; PRT_VALUE *payload; processGuid.data1 = 1; processGuid.data2 = 0; processGuid.data3 = 0; processGuid.data4 = 0; process = PrtStartProcess(processGuid, &P_GEND_PROGRAM, ErrorHandler, Log); payload = PrtMkNullValue(); PrtMkMachine(process, P_MACHINE_TestMachine, payload); PrtFreeValue(payload); PrtStopProcess(process); }
int main(int argc, char *argv[]) { //The commandline arguments FirstArgument = argv[0]; if (argc != 5) { PrintUsage(); return; } int createMain = atoi(argv[2]); PrtAssert(createMain == 0 || createMain == 1, "CreateMain should be either 0 or 1"); int processId = atoi(argv[3]); PrtAssert(processId >= 0, "Process Id should be positive"); int nodeId = atoi(argv[4]); PRT_DBG_START_MEM_BALANCED_REGION { //Initialize the cluster configuration. PrtDistClusterConfigInitialize(argv[1]); SetCurrentDirectory(ClusterConfiguration.LocalFolder); PRT_GUID processGuid; processGuid.data1 = processId; processGuid.data2 = nodeId; //nodeId processGuid.data3 = 0; processGuid.data4 = 0; ContainerProcess = PrtStartProcess(processGuid, &P_GEND_PROGRAM, PrtDistSMExceptionHandler, PrtDistSMLogHandler); HANDLE listener = NULL; PRT_INT32 portNumber = atoi(ClusterConfiguration.ContainerPortStart) + processId; listener = CreateThread(NULL, 0, PrtDistCreateRPCServerForEnqueueAndWait, &portNumber, 0, NULL); if (listener == NULL) { PrtDistLog("Error Creating RPC server in PrtDistStartNodeManagerMachine"); } else { DWORD status; //Sleep(3000); //check if the thread is all ok GetExitCodeThread(listener, &status); if (status != STILL_ACTIVE) PrtDistLog("ERROR : Thread terminated"); } if (createMain) { //create main machine PRT_VALUE* payload = PrtMkNullValue(); PrtMkMachine(ContainerProcess, _P_MACHINE_MAIN, payload); PrtFreeValue(payload); } else { //create container machine PrtDistLog("Creating Container Machine"); PRT_VALUE* payload = PrtMkNullValue(); PrtMkMachine(ContainerProcess, P_MACHINE_Container, payload); PrtFreeValue(payload); } //after performing all operations block and wait WaitForSingleObject(listener, INFINITE); PrtStopProcess(ContainerProcess); } PRT_DBG_END_MEM_BALANCED_REGION }
void PrtCleanupMachine( _Inout_ PRT_MACHINEINST_PRIV *context ) { if (context->isHalted) return; if (context->eventQueue.events != NULL) { PRT_EVENT *queue = context->eventQueue.events; PRT_UINT32 head = context->eventQueue.headIndex; PRT_UINT32 tail = context->eventQueue.tailIndex; PRT_UINT32 count = 0; while (count < context->eventQueue.size && head < context->eventQueue.eventsSize) { if (queue[head].payload != NULL) { PrtFreeValue(queue[head].payload); } if (queue[head].trigger != NULL) { PrtFreeValue(queue[head].trigger); } head++; count++; } head = 0; while (count < context->eventQueue.size) { if (queue[head].payload != NULL) { PrtFreeValue(queue[head].payload); } if (queue[head].trigger != NULL) { PrtFreeValue(queue[head].trigger); } head++; count++; } PrtFree(context->eventQueue.events); } for (int i = 0; i < context->callStack.length; i++) { PRT_STATESTACK_INFO *info = &context->callStack.stateStack[i]; if (info->inheritedActionSetCompact != NULL) { PrtFree(info->inheritedActionSetCompact); } if (info->inheritedDeferredSetCompact != NULL) { PrtFree(info->inheritedDeferredSetCompact); } } for (int i = 0; i < context->funStack.length; i++) { PRT_FUNSTACK_INFO *info = &context->funStack.funs[i]; PrtFreeLocals(context, info); } if (context->currentActionSetCompact != NULL) { PrtFree(context->currentActionSetCompact); } if (context->currentDeferredSetCompact != NULL) { PrtFree(context->currentDeferredSetCompact); } if (context->inheritedActionSetCompact != NULL) { PrtFree(context->inheritedActionSetCompact); } if (context->inheritedDeferredSetCompact != NULL) { PrtFree(context->inheritedDeferredSetCompact); } if (context->varValues != NULL) { UINT i; PRT_MACHINEDECL *mdecl = &(context->process->program->machines[context->instanceOf]); for (i = 0; i < mdecl->nVars; i++) { PrtFreeValue(context->varValues[i]); } PrtFree(context->varValues); } if (context->stateMachineLock != NULL) { PrtDestroyMutex(context->stateMachineLock); } if (context->extContext != NULL) context->process->program->machines[context->instanceOf].extDtorFun((PRT_MACHINEINST *)context); PrtFreeValue(context->id); PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); if (context->recvMap != NULL) { PrtFreeValue(context->recvMap); } }
void P_DTOR_Client_IMPL(PRT_MACHINEINST *context) { ClientContext *clientContext = (ClientContext *)context->extContext; PrtFreeValue(clientContext->client); PrtFree(clientContext); }
int main(int argc, char *argv[]) { #ifndef PRT_PLAT_WINUSER init_ros("test_motion_planner", &argc, argv); #endif if (!ParseCommandLine(argc, argv)) { PrintUsage(); return 1; } const char* motion_planner_delta_s = getenv("MOTION_PLANNER_DELTA"); if(motion_planner_delta_s) { Delta = atoi(motion_planner_delta_s); printf("Using MOTION_PLANNER_DELTA = %d\n", Delta); } printf("Press any key to start simulation\n"); getchar(); PRT_DBG_START_MEM_BALANCED_REGION { PRT_PROCESS *process; PRT_GUID processGuid; PRT_VALUE *payload; //Initialize the workspace WORKSPACE_INFO = ParseWorkspaceConfig(workspaceConfig); #ifdef USE_DIJKSTRA_PRECOMPUTATION WS_LocationsList ends; ends.size = WORKSPACE_INFO->starts.size + WORKSPACE_INFO->ends.size; ends.locations = malloc(sizeof(WS_Coord) * ends.size); int count = 0; for(int i=0; i < WORKSPACE_INFO->starts.size; i++) { ends.locations[count++] = WORKSPACE_INFO->starts.locations[i]; } for(int i=0; i < WORKSPACE_INFO->ends.size; i++) { ends.locations[count++] = WORKSPACE_INFO->ends.locations[i]; } PreComputeObstacleDistanceH(WORKSPACE_INFO->dimension, WORKSPACE_INFO->obstacles, ends); #endif processGuid.data1 = 1; processGuid.data2 = 0; processGuid.data3 = 0; processGuid.data4 = 0; process = PrtStartProcess(processGuid, &P_GEND_PROGRAM, ErrorHandler, Log); if (cooperative) { PrtSetSchedulingPolicy(process, PRT_SCHEDULINGPOLICY_COOPERATIVE); } if (parg == NULL) { payload = PrtMkNullValue(); } else { int i = atoi(parg); payload = PrtMkIntValue(i); } PrtUpdateAssertFn(MyAssert); PrtMkMachine(process, P_MACHINE_Main, payload); if (cooperative) { // test some multithreading across state machines. #if defined(PRT_PLAT_WINUSER) HANDLE* threadsArr = (HANDLE*)PrtMalloc(threads*sizeof(HANDLE)); for (int i = 0; i < threads; i++) { DWORD threadId; threadsArr[i] = CreateThread(NULL, 16000, (LPTHREAD_START_ROUTINE)RunToIdle, process, 0, &threadId); } WaitForMultipleObjects(threads, threadsArr, TRUE, INFINITE); PrtFree(threadsArr); #elif defined(PRT_PLAT_LINUXUSER) typedef void *(*start_routine) (void *); pthread_t tid[threads]; for (int i = 0; i < threads; i++) { pthread_create(&tid[i], NULL, (start_routine)RunToIdle, (void*)process); } for (int i = 0; i < threads; i++) { pthread_join(tid[i], NULL); } #else #error Invalid Platform #endif } PrtFreeValue(payload); PrtStopProcess(process); } PRT_DBG_END_MEM_BALANCED_REGION //_CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_DEBUG); //_CrtDumpMemoryLeaks(); }
PRT_BOOLEAN PrtDequeueEvent( _Inout_ PRT_MACHINEINST_PRIV *context, _Inout_ PRT_FUNSTACK_INFO *frame ) { PRT_UINT32 queueLength; PRT_EVENTQUEUE *queue; PRT_UINT32* deferPacked; PRT_UINT32 i, head; queue = &context->eventQueue; queueLength = queue->eventsSize; deferPacked = PrtGetDeferredPacked(context, context->currentState); head = queue->headIndex; PRT_DBG_ASSERT(queue->size <= queueLength, "Check Failed"); PRT_DBG_ASSERT(queue->size >= 0, "Check Failed"); PRT_DBG_ASSERT(queue->headIndex >= 0, "Check Failed"); PRT_DBG_ASSERT(queue->tailIndex >= 0, "Check Failed"); // // Find the element to dequeue // for (i = 0; i < queue->size; i++) { PRT_UINT32 index = (head + i) % queueLength; PRT_EVENT e = queue->events[index]; PRT_UINT32 triggerIndex = PrtPrimGetEvent(e.trigger); if (context->receive == NULL) { if (!PrtIsEventDeferred(triggerIndex, context->currentDeferredSetCompact)) { PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); context->currentTrigger = e.trigger; context->currentPayload = e.payload; break; } } else { if (PrtIsEventReceivable(context, triggerIndex)) { PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); context->currentTrigger = e.trigger; context->currentPayload = e.payload; for (PRT_UINT32 i = 0; i < context->receive->nCases; i++) { PRT_CASEDECL *rcase = &context->receive->cases[i]; if (triggerIndex == rcase->triggerEventIndex) { frame->rcase = rcase; PrtPushNewEventHandlerFrame(context, rcase->funIndex, frame->locals); break; } } context->receive = NULL; break; } } } // // Check if not found // if (i == queue->size) { if (context->receive == NULL) { if (PrtStateHasDefaultTransitionOrAction(context)) { PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); context->currentTrigger = PrtMkEventValue(PRT_SPECIAL_EVENT_NULL); context->currentPayload = PrtMkNullValue(); return PRT_TRUE; } else { return PRT_FALSE; } } else { PRT_BOOLEAN hasDefaultCase = (context->process->program->eventSets[context->receive->caseSetIndex].packedEvents[0] & 0x1) == 1; if (hasDefaultCase) { PrtFreeValue(context->currentTrigger); PrtFreeValue(context->currentPayload); context->currentTrigger = PrtMkEventValue(PRT_SPECIAL_EVENT_NULL); context->currentPayload = PrtMkNullValue(); for (PRT_UINT32 i = 0; i < context->receive->nCases; i++) { PRT_CASEDECL *rcase = &context->receive->cases[i]; if (PRT_SPECIAL_EVENT_NULL == rcase->triggerEventIndex) { frame->rcase = rcase; PrtPushNewEventHandlerFrame(context, rcase->funIndex, frame->locals); break; } } context->receive = NULL; return PRT_TRUE; } else { return PRT_FALSE; } } } // // Collapse the event queue on the removed event // by moving the previous elements forward. // for (; i > 0; i--) { INT index = (head + i) % queueLength; INT prev = (index - 1 + queueLength) % queueLength; queue->events[index] = queue->events[prev]; } // // Adjust the queue size // queue->headIndex = (queue->headIndex + 1) % queueLength; queue->size--; PRT_DBG_ASSERT(queue->size <= queueLength, "Check Failed"); PRT_DBG_ASSERT(queue->size >= 0, "Check Failed"); PRT_DBG_ASSERT(queue->headIndex >= 0, "Check Failed"); PRT_DBG_ASSERT(queue->tailIndex >= 0, "Check Failed"); // //Log // PrtLog(PRT_STEP_DEQUEUE, context); return PRT_TRUE; }
static void *machine_thread(void *arg) { int maxSteps = 0; printf("PingPong starting...\n"); lastCpuTime = 0; PrintHeader(); if (arg != NULL) { char* ptr = (char*)arg; maxSteps = atoi(ptr); } PRT_GUID processGuid; processGuid.data1 = 1; processGuid.data2 = 1; processGuid.data3 = 0; processGuid.data4 = 0; ContainerProcess = PrtStartProcess(processGuid, &P_GEND_PROGRAM, ErrorHandler, LogHandler); PrtSetSchedulingPolicy(ContainerProcess, PRT_SCHEDULINGPOLICY_COOPERATIVE); //create main machine PRT_VALUE* payload = PrtMkNullValue(); PrtMkMachine(ContainerProcess, _P_MACHINE_MAIN, payload); PrtFreeValue(payload); start = clock_systimer(); intervalStart = start; steps = 0; intervalSteps = 0; // push the state machines while yielding the CPU to other higher priority tasks. PRT_PROCESS_PRIV* privateProcess = (PRT_PROCESS_PRIV*)ContainerProcess; while (privateProcess->terminating == PRT_FALSE && (maxSteps == 0 || steps < maxSteps)) { PRT_STEP_RESULT result = PrtStepProcess(ContainerProcess); switch (result) { case PRT_STEP_TERMINATING: break; case PRT_STEP_IDLE: PrtWaitForWork(ContainerProcess); break; case PRT_STEP_MORE: PrtYieldThread(); break; } CountSteps(); } int32_t elapsed = clock_systimer() - start; int32_t milliseconds = elapsed / (TICK_PER_SEC / 1000); printf("PingPong ran %d steps in %d ms\n", steps, milliseconds); if (maxSteps != 0) { // cleanup the memory for the process PrtStopProcess(ContainerProcess); ContainerProcess = NULL; } return NULL; }