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 * PRT_CALL_CONV PrtMalloc(_In_ size_t size) { PrtAssert(size > 0, "Size must be positive to avoid platform-specific behavior"); void *ptr = malloc(size); PrtAssert(ptr != NULL, "Memory allocation error"); return ptr; }
PRT_TYPE * PRT_CALL_CONV PrtCloneType(_In_ PRT_TYPE *type) { PrtAssert(PrtIsValidType(type), "Invalid type expression"); PRT_TYPE_KIND kind = type->typeKind; switch (kind) { case PRT_KIND_ANY: case PRT_KIND_BOOL: case PRT_KIND_EVENT: case PRT_KIND_MACHINE: case PRT_KIND_INT: case PRT_KIND_NULL: { return PrtMkPrimitiveType(kind); } case PRT_KIND_FORGN: { return PrtMkForeignType(type->typeUnion.typeTag); } case PRT_KIND_MAP: { PRT_MAPTYPE *mtype = type->typeUnion.map; return PrtMkMapType(mtype->domType, mtype->codType); } case PRT_KIND_NMDTUP: { PRT_UINT32 i; PRT_NMDTUPTYPE *ntype = type->typeUnion.nmTuple; PRT_TYPE *clone = PrtMkNmdTupType(ntype->arity); for (i = 0; i < ntype->arity; ++i) { PrtSetFieldName(clone, i, ntype->fieldNames[i]); PrtSetFieldType(clone, i, ntype->fieldTypes[i]); } return clone; } case PRT_KIND_SEQ: { PRT_SEQTYPE *stype = type->typeUnion.seq; return PrtMkSeqType(stype->innerType); } case PRT_KIND_TUPLE: { PRT_UINT32 i; PRT_TUPTYPE *ttype = type->typeUnion.tuple; PRT_TYPE *clone = PrtMkTupType(ttype->arity); for (i = 0; i < ttype->arity; ++i) { PrtSetFieldType(clone, i, ttype->fieldTypes[i]); } return clone; } default: PrtAssert(PRT_FALSE, "PrtCloneType: Invalid type"); return PrtMkPrimitiveType(PRT_KIND_NULL); } }
void * PRT_CALL_CONV PrtRealloc(_Inout_ void *ptr, _In_ size_t size) { PrtAssert(ptr != NULL, "Memory must be non-null to avoid platform-specific behavior"); PrtAssert(size > 0, "Size must be positive to avoid platform-specific behavior"); ptr = realloc(ptr, size); PrtAssert(ptr != NULL, "Memory allocation error"); return ptr; }
PRT_TYPE * PRT_CALL_CONV PrtMkMapType(_In_ PRT_TYPE *domType, _In_ PRT_TYPE *codType) { PrtAssert(PrtIsValidType(domType), "Invalid type expression"); PrtAssert(PrtIsValidType(codType), "Invalid type expression"); PRT_TYPE *type = (PRT_TYPE *)PrtMalloc(sizeof(PRT_TYPE)); PRT_MAPTYPE *map = (PRT_MAPTYPE *)PrtMalloc(sizeof(PRT_MAPTYPE)); type->typeKind = PRT_KIND_MAP; type->typeUnion.map = map; map->domType = PrtCloneType(domType); map->codType = PrtCloneType(codType); return type; }
PRT_TYPE * PRT_CALL_CONV PrtMkForeignType(_In_ PRT_UINT16 typeTag) { PrtAssert(typeTag < prtNumForeignTypeDecls, "Invalid type tag"); PRT_TYPE *type = (PRT_TYPE *)PrtMalloc(sizeof(PRT_TYPE)); type->typeKind = PRT_KIND_FORGN; type->typeUnion.typeTag = typeTag; return type; }
void PRT_CALL_CONV PrtSetFieldType(_Inout_ PRT_TYPE *tupleType, _In_ PRT_UINT32 index, _In_ PRT_TYPE *fieldType) { PrtAssert(PrtIsValidType(tupleType), "Invalid type expression"); PrtAssert(PrtIsValidType(fieldType), "Invalid type expression"); PrtAssert(tupleType->typeKind == PRT_KIND_TUPLE || tupleType->typeKind == PRT_KIND_NMDTUP, "Invalid type expression"); if (tupleType->typeKind == PRT_KIND_TUPLE) { PrtAssert(index < tupleType->typeUnion.tuple->arity, "Invalid tuple index"); tupleType->typeUnion.tuple->fieldTypes[index] = PrtCloneType(fieldType); } else if (tupleType->typeKind == PRT_KIND_NMDTUP) { PrtAssert(index < tupleType->typeUnion.nmTuple->arity, "Invalid tuple index"); tupleType->typeUnion.nmTuple->fieldTypes[index] = PrtCloneType(fieldType); } }
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; }
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; }
PRT_TYPE * PRT_CALL_CONV PrtMkSeqType(_In_ PRT_TYPE *innerType) { PrtAssert(PrtIsValidType(innerType), "Invalid type expression"); PRT_TYPE *type = (PRT_TYPE *)PrtMalloc(sizeof(PRT_TYPE)); PRT_SEQTYPE *seq = (PRT_SEQTYPE *)PrtMalloc(sizeof(PRT_SEQTYPE)); type->typeKind = PRT_KIND_SEQ; type->typeUnion.seq = seq; seq->innerType = PrtCloneType(innerType); return type; }
PRT_API PRT_SEMAPHORE PRT_CALL_CONV PrtCreateSemaphore(int initialCount, int maximumCount) { sem_t* semaphore = malloc(sizeof(sem_t)); // value of 1 means semaphore is available. sem_init(semaphore, /* shared */ 0, /* value*/ initialCount); PrtAssert(semaphore != NULL, "Unable to create semaphore"); return semaphore; }
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; }
const char* FormatMessageBuffer(const char* format, ...) { char* buffer = (char*)malloc(5000); if (buffer == NULL) { EventTrace(PProgram, 0, "Out of memory"); PrtAssert(PRT_FALSE, "Out of memory"); } va_list args; va_start(args, format); vsprintf_s(buffer, 5000, format, args); va_end(args); return buffer; }
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_RECURSIVE_MUTEX PRT_CALL_CONV PrtCreateMutex() { pthread_mutex_t* mutex = malloc(sizeof(pthread_mutex_t)); pthread_mutexattr_t attr; attr.pshared = 0; #ifdef CONFIG_MUTEX_TYPES attr.type = PTHREAD_MUTEX_RECURSIVE; #endif int status = pthread_mutex_init(mutex, &attr); PrtAssert(status == 0, "Unable to create mutex"); return mutex; }
handle_t PrtDistCreateRPCClient( PRT_VALUE* target ) { PRT_INT32 nodeId = target->valueUnion.mid->processId.data2; PRT_INT32 portNumber = PrtDistGetRecvPortNumber(target); RPC_STATUS status; unsigned char* szStringBinding = NULL; handle_t handle; //get centralserverID char buffPort[100]; _itoa(portNumber, buffPort, 10); // Creates a string binding handle. // This function is nothing more than a printf. // Connection is not done here. status = RpcStringBindingCompose( NULL, // UUID to bind to. (unsigned char*)("ncacn_ip_tcp"), // Use TCP/IP // protocol. (unsigned char*)(ClusterConfiguration.ClusterMachines[nodeId]), // TCP/IP network // address to use. (unsigned char*)buffPort, // TCP/IP port to use. NULL, // Protocol dependent network options to use. &szStringBinding); // String binding output. if (status) exit(status); // Validates the format of the string binding handle and converts // it to a binding handle. // Connection is not done here either. status = RpcBindingFromStringBinding( szStringBinding, // The string binding to validate. &handle); // Put the result in the implicit binding // handle defined in the IDL file. if (status) { PrtAssert(PRT_FALSE, "Failed to create an RPC Client"); } return handle; }
PRT_TYPE * PRT_CALL_CONV PrtMkPrimitiveType(_In_ PRT_TYPE_KIND primType) { PRT_TYPE *type = (PRT_TYPE *)PrtMalloc(sizeof(PRT_TYPE)); type->typeUnion.map = NULL; switch (primType) { case PRT_KIND_ANY: case PRT_KIND_BOOL: case PRT_KIND_EVENT: case PRT_KIND_MACHINE: case PRT_KIND_INT: case PRT_KIND_NULL: { type->typeKind = primType; return type; } default: { PrtAssert(PRT_FALSE, "Expected a primitive type."); type->typeKind = PRT_TYPE_KIND_CANARY; return type; } } }
PRT_BOOLEAN PRT_CALL_CONV PrtIsSubtype(_In_ PRT_TYPE *subType, _In_ PRT_TYPE *supType) { PrtAssert(PrtIsValidType(subType), "Invalid type expression"); PrtAssert(PrtIsValidType(supType), "Invalid type expression"); PRT_TYPE_KIND subKind = subType->typeKind; PRT_TYPE_KIND supKind = supType->typeKind; switch (supKind) { case PRT_KIND_ANY: { //// Everything is a subtype of `any`. return PRT_TRUE; } case PRT_KIND_NULL: case PRT_KIND_EVENT: case PRT_KIND_MACHINE: { return (subKind == supKind || subKind == PRT_KIND_NULL) ? PRT_TRUE : PRT_FALSE; } case PRT_KIND_BOOL: case PRT_KIND_INT: case PRT_KIND_FORGN: { //// These types do not have any proper subtypes. return (subKind == supKind && subType->typeUnion.typeTag == supType->typeUnion.typeTag) ? PRT_TRUE : PRT_FALSE; } case PRT_KIND_MAP: { //// Both types are maps and inner types are in subtype relationship. PRT_MAPTYPE *subMap; PRT_MAPTYPE *supMap; if (subKind != PRT_KIND_MAP) { return PRT_FALSE; } subMap = (PRT_MAPTYPE *)subType->typeUnion.map; supMap = (PRT_MAPTYPE *)supType->typeUnion.map; return PrtIsSubtype(subMap->domType, supMap->domType) && PrtIsSubtype(subMap->codType, supMap->codType) ? PRT_TRUE : PRT_FALSE; } case PRT_KIND_NMDTUP: { //// Both types are named tuples with same field names, arity, and inner types are in subtype relationship. PRT_UINT32 i; PRT_NMDTUPTYPE *subNmdTup; PRT_NMDTUPTYPE *supNmdTup; if (subKind != PRT_KIND_NMDTUP) { return PRT_FALSE; } subNmdTup = (PRT_NMDTUPTYPE *)subType->typeUnion.nmTuple; supNmdTup = (PRT_NMDTUPTYPE *)supType->typeUnion.nmTuple; if (subNmdTup->arity != supNmdTup->arity) { return PRT_FALSE; } //// Next check field names. for (i = 0; i < subNmdTup->arity; ++i) { if (strncmp(subNmdTup->fieldNames[i], supNmdTup->fieldNames[i], PRT_MAXFLDNAME_LENGTH) != 0) { return PRT_FALSE; } } //// Finally check field types. for (i = 0; i < subNmdTup->arity; ++i) { if (!PrtIsSubtype(subNmdTup->fieldTypes[i], supNmdTup->fieldTypes[i])) { return PRT_FALSE; } } return PRT_TRUE; } case PRT_KIND_SEQ: { //// Both types are sequences and inner types are in subtype relationship. PRT_SEQTYPE *subSeq; PRT_SEQTYPE *supSeq; if (subKind != PRT_KIND_SEQ) { return PRT_FALSE; } subSeq = (PRT_SEQTYPE *)subType->typeUnion.seq; supSeq = (PRT_SEQTYPE *)supType->typeUnion.seq; return PrtIsSubtype(subSeq->innerType, supSeq->innerType); } case PRT_KIND_TUPLE: { //// Both types are tuples with same arity, and inner types are in subtype relationship. PRT_UINT32 i; PRT_TUPTYPE *subTup; PRT_TUPTYPE *supTup; if (subKind != PRT_KIND_TUPLE) { return PRT_FALSE; } subTup = (PRT_TUPTYPE *)subType->typeUnion.tuple; supTup = (PRT_TUPTYPE *)supType->typeUnion.tuple; if (subTup->arity != supTup->arity) { return PRT_FALSE; } //// Finally check field types. for (i = 0; i < subTup->arity; ++i) { if (!PrtIsSubtype(subTup->fieldTypes[i], supTup->fieldTypes[i])) { return PRT_FALSE; } } return PRT_TRUE; } default: PrtAssert(PRT_FALSE, "PrtIsSubtype: Invalid type"); return PRT_FALSE; } }
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 }
static void PrtUserPrintType(_In_ PRT_TYPE *type, _Inout_ char **buffer, _Inout_ PRT_UINT32 *bufferSize, _Inout_ PRT_UINT32 *numCharsWritten) { PRT_TYPE_KIND kind = type->typeKind; switch (kind) { case PRT_KIND_NULL: PrtUserPrintString("null", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_ANY: PrtUserPrintString("any", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_BOOL: PrtUserPrintString("bool", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_EVENT: PrtUserPrintString("event", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_MACHINE: PrtUserPrintString("machine", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_INT: PrtUserPrintString("int", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_FORGN: PrtUserPrintString("foreign", buffer, bufferSize, numCharsWritten); break; case PRT_KIND_MAP: { PRT_MAPTYPE *mtype = type->typeUnion.map; PrtUserPrintString("map[", buffer, bufferSize, numCharsWritten); PrtUserPrintType(mtype->domType, buffer, bufferSize, numCharsWritten); PrtUserPrintString(", ", buffer, bufferSize, numCharsWritten); PrtUserPrintType(mtype->codType, buffer, bufferSize, numCharsWritten); PrtUserPrintString("]", buffer, bufferSize, numCharsWritten); break; } case PRT_KIND_NMDTUP: { PRT_UINT32 i; PRT_NMDTUPTYPE *ntype = type->typeUnion.nmTuple; PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); for (i = 0; i < ntype->arity; ++i) { PrtUserPrintString(ntype->fieldNames[i], buffer, bufferSize, numCharsWritten); PrtUserPrintString(": ", buffer, bufferSize, numCharsWritten); PrtUserPrintType(ntype->fieldTypes[i], buffer, bufferSize, numCharsWritten); if (i < ntype->arity - 1) { PrtUserPrintString(", ", buffer, bufferSize, numCharsWritten); } else { PrtUserPrintString(")", buffer, bufferSize, numCharsWritten); } } break; } case PRT_KIND_SEQ: { PRT_SEQTYPE *stype = type->typeUnion.seq; PrtUserPrintString("seq[", buffer, bufferSize, numCharsWritten); PrtUserPrintType(stype->innerType, buffer, bufferSize, numCharsWritten); PrtUserPrintString("]", buffer, bufferSize, numCharsWritten); break; } case PRT_KIND_TUPLE: { PRT_UINT32 i; PRT_TUPTYPE *ttype = type->typeUnion.tuple; PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); if (ttype->arity == 1) { PrtUserPrintType(ttype->fieldTypes[0], buffer, bufferSize, numCharsWritten); PrtUserPrintString(",)", buffer, bufferSize, numCharsWritten); } else { for (i = 0; i < ttype->arity; ++i) { PrtUserPrintType(ttype->fieldTypes[i], buffer, bufferSize, numCharsWritten); if (i < ttype->arity - 1) { PrtUserPrintString(", ", buffer, bufferSize, numCharsWritten); } else { PrtUserPrintString(")", buffer, bufferSize, numCharsWritten); } } } break; } default: PrtAssert(PRT_FALSE, "PrtUserPrintType: Invalid type"); break; } }
static void PrtUserPrintStep(_In_ PRT_STEP step, PRT_MACHINEINST *sender, _In_ PRT_MACHINEINST *receiver, _In_ PRT_VALUE* event, _In_ PRT_VALUE* payload, _Inout_ char **buffer, _Inout_ PRT_UINT32 *bufferSize, _Inout_ PRT_UINT32 *numCharsWritten) { PRT_MACHINEINST_PRIV * c = (PRT_MACHINEINST_PRIV *)receiver; PRT_STRING machineName = c->process->program->machines[c->instanceOf]->name; PRT_UINT32 machineId = c->id->valueUnion.mid->machineId; PRT_STRING stateName = PrtGetCurrentStateDecl(c)->name; PRT_STRING eventName; switch (step) { case PRT_STEP_HALT: PrtUserPrintString("<HaltLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") halted in state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_ENQUEUE: eventName = c->process->program->events[PrtPrimGetEvent(event)].name; PrtUserPrintString("<EnqueueLog> Enqueued event ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(eventName, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" with payload ", buffer, bufferSize, numCharsWritten); PrtUserPrintValue(payload, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" on Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(")\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_DEQUEUE: eventName = c->process->program->events[PrtPrimGetEvent(event)].name; PrtUserPrintString("<DequeueLog> Dequeued event ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(eventName, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" with payload ", buffer, bufferSize, numCharsWritten); PrtUserPrintValue(payload, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" by Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(")\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_ENTRY: PrtUserPrintString("<StateLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") entered state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_CREATE: PrtUserPrintString("<CreateLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") is created\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_GOTO: { PRT_MACHINEINST_PRIV *context = (PRT_MACHINEINST_PRIV *)sender; PRT_STRING destStateName = c->process->program->machines[context->instanceOf]->states[context->destStateIndex].name; PrtUserPrintString("<GotoLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") goes to state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(destStateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" with payload ", buffer, bufferSize, numCharsWritten); PrtUserPrintValue(payload, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; } case PRT_STEP_RAISE: eventName = c->process->program->events[PrtPrimGetEvent(event)].name; PrtUserPrintString("<RaiseLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") raised event ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(eventName, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" with payload ", buffer, bufferSize, numCharsWritten); PrtUserPrintValue(payload, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_POP: PrtUserPrintString("<PopLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") popped and reentered state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_PUSH: PrtUserPrintString("<PushLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") pushed\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_UNHANDLED: eventName = c->process->program->events[c->eventValue].name; PrtUserPrintString("<PopLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") popped with unhandled event ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(eventName, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" and reentered state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_DO: PrtUserPrintString("<ActionLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") executed action in state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_EXIT: PrtUserPrintString("<ExitLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") exiting state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; case PRT_STEP_IGNORE: eventName = c->process->program->events[PrtPrimGetEvent(event)].name; PrtUserPrintString("<ActionLog> Machine ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(machineName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(machineId, buffer, bufferSize, numCharsWritten); PrtUserPrintString(") ignored event ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(eventName, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" in state ", buffer, bufferSize, numCharsWritten); PrtUserPrintString(stateName, buffer, bufferSize, numCharsWritten); PrtUserPrintString("\n", buffer, bufferSize, numCharsWritten); break; default: PrtAssert(PRT_FALSE, "Illegal PRT_STEP value"); break; } }
static void PrtUserPrintValue(_In_ PRT_VALUE *value, _Inout_ char **buffer, _Inout_ PRT_UINT32 *bufferSize, _Inout_ PRT_UINT32 *numCharsWritten) { PRT_STRING frgnStr; PRT_VALUE_KIND kind = value->discriminator; switch (kind) { case PRT_VALUE_KIND_NULL: PrtUserPrintString("null", buffer, bufferSize, numCharsWritten); break; case PRT_VALUE_KIND_BOOL: PrtUserPrintString(PrtPrimGetBool(value) == PRT_TRUE ? "true" : "false", buffer, bufferSize, numCharsWritten); break; case PRT_VALUE_KIND_INT: PrtUserPrintInt32(PrtPrimGetInt(value), buffer, bufferSize, numCharsWritten); break; case PRT_VALUE_KIND_EVENT: PrtUserPrintString("<", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(PrtPrimGetEvent(value), buffer, bufferSize, numCharsWritten); PrtUserPrintString(">", buffer, bufferSize, numCharsWritten); break; case PRT_VALUE_KIND_MID: PrtUserPrintMachineId(PrtPrimGetMachine(value), buffer, bufferSize, numCharsWritten); break; case PRT_VALUE_KIND_FORGN: frgnStr = prtForeignTypeDecls[value->valueUnion.frgn->typeTag].toStringFun(value->valueUnion.frgn->value); PrtUserPrintString(frgnStr, buffer, bufferSize, numCharsWritten); PrtFree(frgnStr); break; case PRT_VALUE_KIND_MAP: { PRT_MAPVALUE *mval = value->valueUnion.map; PRT_MAPNODE *next = mval->first; PrtUserPrintString("{", buffer, bufferSize, numCharsWritten); while (next != NULL) { PrtUserPrintValue(next->key, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" --> ", buffer, bufferSize, numCharsWritten); PrtUserPrintValue(next->value, buffer, bufferSize, numCharsWritten); if (next->bucketNext != NULL) { PrtUserPrintString("*", buffer, bufferSize, numCharsWritten); } if (next->insertNext != NULL) { PrtUserPrintString(", ", buffer, bufferSize, numCharsWritten); } next = next->insertNext; } PrtUserPrintString("} (", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(mval->size, buffer, bufferSize, numCharsWritten); PrtUserPrintString(" / ", buffer, bufferSize, numCharsWritten); PrtUserPrintUint32(PrtMapCapacity(value), buffer, bufferSize, numCharsWritten); PrtUserPrintString(")", buffer, bufferSize, numCharsWritten); break; } case PRT_VALUE_KIND_SEQ: { PRT_UINT32 i; PRT_SEQVALUE *sVal = value->valueUnion.seq; PrtUserPrintString("[", buffer, bufferSize, numCharsWritten); for (i = 0; i < sVal->size; ++i) { PrtUserPrintValue(sVal->values[i], buffer, bufferSize, numCharsWritten); if (i < sVal->size - 1) { PrtUserPrintString(", ", buffer, bufferSize, numCharsWritten); } } PrtUserPrintString("]", buffer, bufferSize, numCharsWritten); break; } case PRT_VALUE_KIND_TUPLE: { PRT_UINT32 i; PRT_TUPVALUE *tval = value->valueUnion.tuple; PrtUserPrintString("(", buffer, bufferSize, numCharsWritten); if (tval->size == 1) { PrtUserPrintValue(tval->values[0], buffer, bufferSize, numCharsWritten); PrtUserPrintString(",)", buffer, bufferSize, numCharsWritten); } else { for (i = 0; i < tval->size; ++i) { PrtUserPrintValue(tval->values[i], buffer, bufferSize, numCharsWritten); if (i < tval->size - 1) { PrtUserPrintString(", ", buffer, bufferSize, numCharsWritten); } else { PrtUserPrintString(")", buffer, bufferSize, numCharsWritten); } } } break; } default: PrtAssert(PRT_FALSE, "PrtUserPrintValue: Invalid value"); break; } }
void PRT_CALL_CONV PrtFreeType(_Inout_ PRT_TYPE *type) { PRT_TYPE_KIND kind = type->typeKind; switch (kind) { case PRT_KIND_ANY: case PRT_KIND_BOOL: case PRT_KIND_EVENT: case PRT_KIND_MACHINE: case PRT_KIND_INT: case PRT_KIND_FORGN: case PRT_KIND_NULL: type->typeKind = PRT_TYPE_KIND_CANARY; PrtFree(type); break; case PRT_KIND_MAP: { PRT_MAPTYPE *mtype = (PRT_MAPTYPE *)type->typeUnion.map; PrtFreeType(mtype->domType); PrtFreeType(mtype->codType); type->typeKind = PRT_TYPE_KIND_CANARY; PrtFree(mtype); PrtFree(type); break; } case PRT_KIND_NMDTUP: { PRT_UINT32 i; PRT_NMDTUPTYPE *ntype = type->typeUnion.nmTuple; for (i = 0; i < ntype->arity; ++i) { PrtFree(ntype->fieldNames[i]); PrtFreeType(ntype->fieldTypes[i]); } PrtFree(ntype->fieldNames); PrtFree(ntype->fieldTypes); type->typeKind = PRT_TYPE_KIND_CANARY; PrtFree(ntype); PrtFree(type); break; } case PRT_KIND_SEQ: { PRT_SEQTYPE *stype = type->typeUnion.seq; PrtFreeType(stype->innerType); type->typeKind = PRT_TYPE_KIND_CANARY; PrtFree(stype); PrtFree(type); break; } case PRT_KIND_TUPLE: { PRT_UINT32 i; PRT_TUPTYPE *ttype = type->typeUnion.tuple; for (i = 0; i < ttype->arity; ++i) { PrtFreeType(ttype->fieldTypes[i]); } PrtFree(ttype->fieldTypes); type->typeKind = PRT_TYPE_KIND_CANARY; PrtFree(ttype); PrtFree(type); break; } default: PrtAssert(PRT_FALSE, "PrtFreeType: Invalid type"); break; } }