Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
void P_CTOR_Timer_IMPL(PRT_MACHINEINST *context, PRT_VALUE *value)
{
	TimerContext *timerContext = (TimerContext *)PrtMalloc(sizeof(TimerContext));
	timerContext->client = PrtCloneValue(value);
	timerContext->started = PRT_FALSE;
	context->extContext = timerContext;
}
Exemplo n.º 5
0
void P_CTOR_Timer_IMPL(PRT_MACHINEINST *context, PRT_VALUE *value)
{
    printf("Entering P_CTOR_Timer_IMPL\n");
    TimerContext *timerContext = (TimerContext *)malloc(sizeof(TimerContext));
    timerContext->client = PrtCloneValue(value);
    timerContext->timer = CreateWaitableTimer(NULL, TRUE, NULL);
    PrtAssert(timerContext->timer != NULL, "CreateWaitableTimer failed");
    context->extContext = timerContext;
}
Exemplo n.º 6
0
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;
}
Exemplo n.º 7
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;
}
Exemplo n.º 8
0
void
PrtSendPrivate(
_Inout_ PRT_MACHINEINST_PRIV		*context,
_In_ PRT_VALUE					*event,
_In_ PRT_VALUE					*payload
)
{
	PRT_EVENTQUEUE *queue;
	PRT_UINT32 tail;
	PRT_UINT32 eventMaxInstances;
	PRT_UINT32 maxQueueSize;
	PRT_UINT32 eventIndex;

	PrtAssert(!PrtIsSpecialEvent(event), "Enqueued event must not be null");
	PrtAssert(PrtInhabitsType(payload, PrtGetPayloadType(context, event)), "Payload must be member of event payload type");

	if (context->isHalted)
	{
		// drop the event silently
		return;
	}

	eventIndex = PrtPrimGetEvent(event);
	eventMaxInstances = context->process->program->events[eventIndex].eventMaxInstances;
	maxQueueSize = context->process->program->machines[context->instanceOf].maxQueueSize;

	PrtLockMutex(context->stateMachineLock);

	queue = &context->eventQueue;

	// check if maximum allowed instances of event are already present in queue
	if (eventMaxInstances != 0xffffffff && PrtIsEventMaxInstanceExceeded(queue, eventIndex, eventMaxInstances))
	{
		PrtUnlockMutex(context->stateMachineLock);
		PrtHandleError(PRT_STATUS_EVENT_OVERFLOW, context);
		return;
	}

	// if queue is full, resize the queue if possible
	if (queue->eventsSize == queue->size)
	{
		if (maxQueueSize != 0xffffffff && queue->size == maxQueueSize)
		{
			PrtUnlockMutex(context->stateMachineLock);
			PrtHandleError(PRT_STATUS_QUEUE_OVERFLOW, context);
			return;
		}
		PrtResizeEventQueue(context);
	}

	tail = queue->tailIndex;

	//
	// Add event to the queue
	//
	queue->events[tail].trigger = PrtCloneValue(event);
	queue->events[tail].payload = PrtCloneValue(payload);
	queue->size++;
	queue->tailIndex = (tail + 1) % queue->eventsSize;

	//
	//Log
	//
	PrtLog(PRT_STEP_ENQUEUE, context);
	//
	// Now try to run the machine if its not running already
	//
	if (context->isRunning)
	{
		PrtUnlockMutex(context->stateMachineLock);
	}
	else if (context->receive == NULL)
	{
		PrtRunStateMachine(context, PRT_TRUE);
	}
	else if (PrtIsEventReceivable(context, PrtPrimGetEvent(event)))
	{
		PrtRunStateMachine(context, PRT_FALSE);
	}
	else
	{
		PrtUnlockMutex(context->stateMachineLock);
	}
	return;
}
Exemplo n.º 9
0
void P_CTOR_Client_IMPL(PRT_MACHINEINST *context, PRT_VALUE *value)
{
    ClientContext *clientContext = (ClientContext *)PrtMalloc(sizeof(ClientContext));
    clientContext->client = PrtCloneValue(value);
    context->extContext = clientContext;
}