示例#1
0
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");
    }
}
示例#2
0
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;
}
示例#3
0
文件: Timer.c 项目: annakoppad/P
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);
}
示例#4
0
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.
}
示例#5
0
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;
}
示例#6
0
PRT_MACHINEINST_PRIV *
PrtMkMachinePrivate(
_Inout_  PRT_PROCESS_PRIV		*process,
_In_  PRT_UINT32				instanceOf,
_In_  PRT_VALUE					*payload
)
{
	PRT_UINT32 packSize;
	PRT_UINT32 nVars;
	PRT_UINT8 eQSize;
	PRT_MACHINEINST_PRIV *context;
	PRT_UINT32 i;

	PrtLockMutex(process->processLock);

	nVars = process->program->machines[instanceOf].nVars;
	eQSize = PRT_QUEUE_LEN_DEFAULT;

	//
	// Allocate memory for state machine context
	//
	context = (PRT_MACHINEINST_PRIV*)PrtMalloc(sizeof(PRT_MACHINEINST_PRIV));

	//
	// Add it to the array of machines in the process
	//
	PRT_UINT32 numMachines = process->numMachines;
	PRT_UINT32 machineCount = process->machineCount;
	PRT_MACHINEINST **machines = process->machines;
	if (machineCount == 0)
	{
		machines = (PRT_MACHINEINST **)PrtCalloc(1, sizeof(PRT_MACHINEINST *));
		process->machines = machines;
		process->machineCount = 1;
	}
	else if (machineCount == numMachines) {
		PRT_MACHINEINST **newMachines = (PRT_MACHINEINST **)PrtCalloc(2 * machineCount, sizeof(PRT_MACHINEINST *));
		for (PRT_UINT32 i = 0; i < machineCount; i++)
		{
			newMachines[i] = machines[i];
		}
		PrtFree(machines);
		machines = newMachines;
		process->machines = newMachines;
		process->machineCount = 2 * machineCount;
	}
	machines[numMachines] = (PRT_MACHINEINST *)context;
	process->numMachines++;

	//
	// Initialize Machine Identity
	//
	context->process = (PRT_PROCESS *)process;
	context->instanceOf = instanceOf;
	PRT_MACHINEID id;
	id.machineId = process->numMachines; // index begins with 1 since 0 is reserved
	id.processId = process->guid;
	context->id = PrtMkMachineValue(id);
	context->extContext = NULL;
	context->isModel = PRT_FALSE;

	//
	// Initialize the map used in PrtDist, map from sender to the last seqnumber received
	//
	PRT_TYPE *domType = PrtMkPrimitiveType(PRT_KIND_MACHINE);
	PRT_TYPE *codType = PrtMkPrimitiveType(PRT_KIND_INT);
	PRT_TYPE *recvMapType = PrtMkMapType(domType, codType);
	context->recvMap = PrtMkDefaultValue(recvMapType);
	PrtFreeType(domType);
	PrtFreeType(codType);
	PrtFreeType(recvMapType);

	// Initialize Machine Internal Variables
	//
	context->currentState = process->program->machines[context->instanceOf].initStateIndex;
	context->isRunning = PRT_FALSE;
	context->isHalted = PRT_FALSE;
	context->lastOperation = ReturnStatement;

	context->currentTrigger = PrtMkEventValue(PRT_SPECIAL_EVENT_NULL);
	context->currentPayload = PrtCloneValue(payload);

	//
	// Allocate memory for local variables and initialize them
	//
	context->varValues = NULL;
	if (nVars > 0)
	{
		context->varValues = PrtCalloc(nVars, sizeof(PRT_VALUE*));
		for (i = 0; i < nVars; i++)
		{
			context->varValues[i] = PrtMkDefaultValue(process->program->machines[instanceOf].vars[i].type);
		}
	}

	context->receive = NULL;

	//
	// Initialize various stacks
	//
	context->callStack.length = 0;
	context->funStack.length = 0;

	//
	// Initialize event queue
	//
	context->eventQueue.eventsSize = eQSize;
	context->eventQueue.events = (PRT_EVENT*)PrtCalloc(eQSize, sizeof(PRT_EVENT));
	context->eventQueue.headIndex = 0;
	context->eventQueue.tailIndex = 0;
	context->eventQueue.size = 0;

	packSize = PrtGetPackSize(context);

	//
	// Initialize Inherited Deferred Set
	//
	context->inheritedDeferredSetCompact = (PRT_UINT32*)PrtCalloc(packSize, sizeof(PRT_UINT32));

	//
	// Initialize the current deferred set
	//
	context->currentDeferredSetCompact = (PRT_UINT32*)PrtCalloc(packSize, sizeof(PRT_UINT32));

	//
	// Initialize actions
	//
	context->inheritedActionSetCompact = (PRT_UINT32*)PrtCalloc(packSize, sizeof(PRT_UINT32));
	context->currentActionSetCompact = (PRT_UINT32*)PrtCalloc(packSize, sizeof(PRT_UINT32));

	//
	//Initialize state machine lock
	//
	context->stateMachineLock = PrtCreateMutex();

	//
	//Log
	//
	PrtLog(PRT_STEP_CREATE, context);

	//
	// Allocate external context Structure
	//
	process->program->machines[context->instanceOf].extCtorFun((PRT_MACHINEINST *)context, payload);

	PrtUnlockMutex(process->processLock);

	//
	// Run the state machine
	//
	PrtLockMutex(context->stateMachineLock);
	PrtRunStateMachine(context, PRT_FALSE);

	return context;
}