MME_ERROR MME_Init(void) { if (manager) { return MME_DRIVER_ALREADY_INITIALIZED; } manager = malloc(sizeof(MMEManager_t)); if (NULL == manager) { return MME_NOMEM; } memset(manager, 0, sizeof(*manager)); if (!EMBX_OS_MUTEX_INIT(&(manager->factoryListMutex))) { goto error_recovery; } if (!EMBX_OS_MUTEX_INIT(&(manager->abortMutex))) { goto error_recovery; } return MME_SUCCESS; error_recovery: if (manager->factoryListMutex) { EMBX_OS_MUTEX_DESTROY(&(manager->factoryListMutex)); } if (manager->abortMutex) { EMBX_OS_MUTEX_DESTROY(&(manager->abortMutex)); } EMBX_OS_MemFree(manager); return MME_NOMEM; }
MME_ERROR MME_MessageQueue_Init(MMEMessageQueue * msgQ, int maxEntries) { MME_ERROR err; int size = maxEntries * sizeof(MMEMessageQueueEntry); MME_Info(MME_INFO_QUEUE, (">>>MME_MessageQueue_Init(0x%08x, %d)\n", (unsigned) msgQ, maxEntries)); msgQ->maxEntries = maxEntries; msgQ->queue = (MMEMessageQueueEntry*) EMBX_OS_MemAlloc(size); if (msgQ->queue == NULL) { MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Init = MME_NOMEM\n")); return MME_NOMEM; } memset(msgQ->queue, 0, size); if (!EMBX_OS_MUTEX_INIT(&msgQ->queueLock)) { MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Init = MME_NOMEM\n")); return MME_NOMEM; } err = MME_MessageQueue_RemoveAll(msgQ); MME_Assert(MME_SUCCESS == err); /* currently has no failure path */ MME_Info(MME_INFO_QUEUE, ("<<<MME_MessageQueue_Init = MME_SUCCESS\n")); return MME_SUCCESS; }
MME_ERROR MME_HostInit(void) #endif { if (NULL != manager) { return MME_DRIVER_ALREADY_INITIALIZED; } manager = EMBX_OS_MemAlloc(sizeof(HostManager_t)); if (!manager) { return MME_NOMEM; } memset(manager, 0, sizeof(HostManager_t)); manager->transformerInstances = MME_LookupTable_Create(MAX_TRANSFORMER_INSTANCES, 1); if (!manager->transformerInstances) { goto error_path; } if (EMBX_FALSE == EMBX_OS_MUTEX_INIT(&manager->monitorMutex)) { goto error_path; } if (EMBX_FALSE == EMBX_OS_MUTEX_INIT(&manager->eventLock)) { goto error_path; } if (EMBX_FALSE == EMBX_OS_EVENT_INIT(&manager->waitorDone)) { goto error_path; } return MME_SUCCESS; error_path: if (manager->transformerInstances) { MME_LookupTable_Delete(manager->transformerInstances); } EMBX_OS_MemFree(manager); manager = NULL; return MME_NOMEM; }
static MME_ERROR createExecutionLoop(MMEManager_t *manager, int id) { const struct { MME_UINT priority; const char *name; } lookup[MME_NUM_EXECUTION_LOOPS] = { { MME_TUNEABLE_EXECUTION_LOOP_LOWEST_PRIORITY, "ExecutionLoopLowest" }, { MME_TUNEABLE_EXECUTION_LOOP_BELOW_NORMAL_PRIORITY, "ExecutionLoopBelowNormal" }, { MME_TUNEABLE_EXECUTION_LOOP_NORMAL_PRIORITY, "ExecutionLoopNormal" }, { MME_TUNEABLE_EXECUTION_LOOP_ABOVE_NORMAL_PRIORITY, "ExecutionLoopAboveNormal" }, { MME_TUNEABLE_EXECUTION_LOOP_HIGHEST_PRIORITY, "ExecutionLoopHighest" }, }; MME_Assert(manager); MME_Assert(id < MME_NUM_EXECUTION_LOOPS); if (manager->loopTasksRunning[id]) { return MME_SUCCESS; } MME_Assert(0 == manager->loopTasks[id]); MME_Assert(0 == manager->receiverLists[id]); /* this code can only be called from the manager thread and therefore needs * no thread protection. */ if (!EMBX_OS_MUTEX_INIT(&(manager->receiverListMutexes[id]))) { return MME_NOMEM; } if (!EMBX_OS_EVENT_INIT(&(manager->commandEvents[id]))) { goto cleanup_mutex; } /* spawn the worker thread */ manager->loopTasks[id] = EMBX_OS_ThreadCreate((void(*)()) executionLoopTask, (void *) id, MME_GetTuneable(lookup[id].priority), lookup[id].name); if (0 == manager->loopTasks[id]) { goto cleanup_event; } /* mark the task as running */ manager->loopTasksRunning[id] = 1; return MME_SUCCESS; cleanup_event: EMBX_OS_EVENT_DESTROY(&(manager->commandEvents[id])); cleanup_mutex: EMBX_OS_MUTEX_DESTROY(&(manager->receiverListMutexes[id])); return MME_NOMEM; }
EMBX_EVENT EMBX_OS_EventCreate(void) { EMBX_EVENT ev = NULL; /* This is not multithread safe - perhaps use an atomic test&set ? */ if (!cacheInitialised) { cacheInitialised = 1; (void) EMBX_OS_MUTEX_INIT(&cacheLock); } EMBX_OS_MUTEX_TAKE(&cacheLock); if ((ev = cacheHead) != NULL) { cacheHead = cacheHead->next; /* Mark desc as being in use */ ev->next = (EMBX_EVENT) EMBX_HANDLE_VALID; EMBX_OS_MUTEX_RELEASE(&cacheLock); } else { EMBX_OS_MUTEX_RELEASE(&cacheLock); /* Dynamically allocate a new cache container * and initialise the event inside it */ ev = EMBX_OS_MemAlloc(sizeof(*ev)); if (ev) { /* Mark desc as being in use */ ev->next = (EMBX_EVENT) EMBX_HANDLE_VALID; ev->event = semaphore_create_fifo(0); } } return ev; }
Transformer_t* MME_RemoteTransformer_Create(HostManager_t *manager, TransportInfo_t* info, EMBX_PORT adminPort) { static const TransformerVTable_t vtable = { RemoteTransformer_Destroy, RemoteTransformer_Init, RemoteTransformer_Term, RemoteTransformer_Kill, RemoteTransformer_AbortCommand, RemoteTransformer_KillCommand, RemoteTransformer_SendCommand, RemoteTransformer_IsStillAlive, RemoteTransformer_GetTransformerCapability, RemoteTransformer_WaitForMessage, RemoteTransformer_LookupCommand, RemoteTransformer_ReleaseCommandSlot }; RemoteTransformer_t* remoteTransformer; int i; remoteTransformer = EMBX_OS_MemAlloc(sizeof(RemoteTransformer_t)); if (!remoteTransformer) { return NULL; } /* zero the structure */ memset(remoteTransformer, 0, sizeof(RemoteTransformer_t)); /* initialize the non-zero elements */ remoteTransformer->super.vtable = &vtable; remoteTransformer->super.manager = manager; remoteTransformer->super.info = info; remoteTransformer->adminPort = adminPort; remoteTransformer->maxCommandSlots = MAX_TRANSFORMER_SEND_OPS; /* allocate the command slots (used to keep track of in-flight commands) */ remoteTransformer->commandSlots = EMBX_OS_MemAlloc(sizeof(CommandSlot_t) * remoteTransformer->maxCommandSlots); if (0 == remoteTransformer->commandSlots) { goto error_recovery; } for (i=0; i<remoteTransformer->maxCommandSlots; i++) { remoteTransformer->commandSlots[i].command = 0; remoteTransformer->commandSlots[i].status = MME_COMMAND_COMPLETED_EVT; } if (!EMBX_OS_EVENT_INIT(&remoteTransformer->terminateWasReplied)) { goto error_recovery; } if (!EMBX_OS_MUTEX_INIT(&remoteTransformer->commandSlotLock)) { EMBX_OS_EVENT_DESTROY(&remoteTransformer->terminateWasReplied); goto error_recovery; } /* reference the transport info structure (so it can't be deregistered) */ info->referenceCount++; return &remoteTransformer->super; error_recovery: /* EMBX_OS_MemFree() will ignore NULL pointers */ EMBX_OS_MemFree(remoteTransformer->commandSlots); EMBX_OS_MemFree(remoteTransformer); return NULL; }