PRT_TYPE * PRT_CALL_CONV PrtMkNmdTupType(_In_ PRT_UINT32 arity) { PrtAssert(arity > 0, "Invalid tuple arity"); PRT_TYPE *type = (PRT_TYPE *)PrtMalloc(sizeof(PRT_TYPE)); PRT_NMDTUPTYPE *nmdTup = (PRT_NMDTUPTYPE *)PrtMalloc(sizeof(PRT_NMDTUPTYPE)); type->typeKind = PRT_KIND_NMDTUP; type->typeUnion.nmTuple = nmdTup; nmdTup->arity = arity; nmdTup->fieldNames = (PRT_STRING *)PrtCalloc((size_t)arity, sizeof(PRT_STRING)); nmdTup->fieldTypes = (PRT_TYPE **)PrtCalloc((size_t)arity, sizeof(PRT_TYPE *)); return type; }
PRT_VALUE* PrtFormatPrintf(_In_ PRT_CSTRING msg, ...) { PrtPrintf(msg); va_list argp; va_start(argp, msg); PRT_UINT32 numArgs, numSegs; numArgs = va_arg(argp, PRT_UINT32); PRT_VALUE **args = (PRT_VALUE **)PrtCalloc(numArgs, sizeof(PRT_VALUE *)); for (PRT_UINT32 i = 0; i < numArgs; i++) { // skip over arg status PRT_FUN_PARAM_STATUS argStatus = va_arg(argp, PRT_FUN_PARAM_STATUS); args[i] = va_arg(argp, PRT_VALUE *); } numSegs = va_arg(argp, PRT_UINT32); for (PRT_UINT32 i = 0; i < numSegs; i++) { PRT_UINT32 argIndex = va_arg(argp, PRT_UINT32); PrtPrintValue(args[argIndex]); PRT_CSTRING seg = va_arg(argp, PRT_CSTRING); PrtPrintf(seg); } va_end(argp); PrtFree(args); return NULL; }
static void ResizeBuffer(_Inout_ char **buffer, _Inout_ PRT_UINT32 *bufferSize, _Inout_ PRT_UINT32 numCharsWritten, PRT_UINT32 resizeNum) { PRT_UINT32 padding = 100; if (*buffer == NULL) { *bufferSize = resizeNum + 1 + padding; *buffer = (char *)PrtCalloc(*bufferSize, sizeof(char)); } else if (*bufferSize < numCharsWritten + resizeNum + 1) { PRT_UINT32 newBufferSize = numCharsWritten + resizeNum + 1 + padding; char *newBuffer = (char *)PrtCalloc(newBufferSize, sizeof(char)); strcpy_s(newBuffer, newBufferSize, *buffer); PrtFree(*buffer); *buffer = newBuffer; *bufferSize = newBufferSize; } }
PRT_TYPE * PRT_CALL_CONV PrtMkTupType(_In_ PRT_UINT32 arity) { PrtAssert(arity > 0, "Invalid tuple arity"); PRT_TYPE *type = (PRT_TYPE *)PrtMalloc(sizeof(PRT_TYPE)); PRT_TUPTYPE *tup = (PRT_TUPTYPE *)PrtMalloc(sizeof(PRT_TUPTYPE)); type->typeKind = PRT_KIND_TUPLE; type->typeUnion.tuple = tup; tup->arity = arity; tup->fieldTypes = (PRT_TYPE **)PrtCalloc((size_t)arity, sizeof(PRT_TYPE *)); return type; }
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; }
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 PrtResizeEventQueue( _Inout_ PRT_MACHINEINST_PRIV *context ) { PRT_UINT32 maxEventQueueSize = context->process->program->machines[context->instanceOf].maxQueueSize; PRT_UINT32 currEventQueueSize = context->eventQueue.eventsSize; PRT_UINT32 newQueueSize = (maxEventQueueSize != 0xffffffff && currEventQueueSize * 2 > maxEventQueueSize) ? maxEventQueueSize : currEventQueueSize * 2; PRT_EVENT* oldQueue = context->eventQueue.events; PRT_UINT32 oldHead = context->eventQueue.headIndex; PRT_UINT32 oldTail = context->eventQueue.tailIndex; PRT_EVENT *newQueue = (PRT_EVENT*)PrtCalloc(newQueueSize, sizeof(PRT_EVENT)); PRT_UINT32 newHead = 0; PRT_UINT32 newTail = 0; // // Check from head to end of Array // while (oldHead < currEventQueueSize) { newQueue[newTail] = oldQueue[oldHead]; newTail++; oldHead++; } // // Reset Head to the start of Array oldHead = 0; // // Check from start of Array till head // while (oldHead < oldTail) { newQueue[newTail] = oldQueue[oldHead]; newTail++; oldHead++; } //Update the Queue context->eventQueue.events = newQueue; context->eventQueue.headIndex = newHead; context->eventQueue.size = newTail - newHead; context->eventQueue.tailIndex = newTail; context->eventQueue.eventsSize = newQueueSize; //Release the older Queue PrtFree(oldQueue); }
PRT_UINT32 * PrtClonePackedSet( _In_ PRT_UINT32 * packedSet, _In_ PRT_UINT32 size ) { PRT_UINT32 *clone; PRT_UINT32 i; clone = (PRT_UINT32 *)PrtCalloc(size, sizeof(PRT_UINT32)); for (i = 0; i < size; i++) { clone[i] = packedSet[i]; } return clone; }
void PRT_CALL_CONV PrtSetFieldName(_Inout_ PRT_TYPE *tupleType, _In_ PRT_UINT32 index, _In_ PRT_STRING fieldName) { PrtAssert(PrtIsValidType(tupleType), "Invalid type expression"); PrtAssert(tupleType->typeKind == PRT_KIND_NMDTUP, "Invalid type expression"); PrtAssert(fieldName != NULL && *fieldName != '\0', "Invalid field name"); PrtAssert(index < tupleType->typeUnion.nmTuple->arity, "Invalid tuple index"); size_t nameLen; PRT_STRING fieldNameClone; nameLen = strnlen(fieldName, PRT_MAXFLDNAME_LENGTH); PrtAssert(nameLen > 0 && nameLen < PRT_MAXFLDNAME_LENGTH, "Invalid field name"); fieldNameClone = (PRT_STRING)PrtCalloc(nameLen + 1, sizeof(PRT_CHAR)); strncpy(fieldNameClone, fieldName, nameLen); fieldNameClone[nameLen] = '\0'; tupleType->typeUnion.nmTuple->fieldNames[index] = fieldNameClone; }
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; }