Пример #1
0
static void executionLoopTask(void *params)
{
	int id = (int) params;

	for (EMBX_OS_EVENT_WAIT(&(manager->commandEvents[id]));
	     manager->loopTasksRunning[id];
	     EMBX_OS_EVENT_WAIT(&(manager->commandEvents[id]))) {

		MMEReceiver *receiver;
		MMEReceiver *lowestReceiver;
		MME_Time_t dueTime, lowestDueTime;
		int found = 0;

		EMBX_OS_MUTEX_TAKE(&(manager->receiverListMutexes[id]));

		EMBX_OS_MUTEX_TAKE(&(manager->abortMutex));

		/* Find the receiver with the lowest dueTime. */
		lowestReceiver = manager->receiverLists[id];
		lowestDueTime = MME_MaxTime_c;
		for (receiver = lowestReceiver; receiver; receiver = receiver->next) {
			if (MME_SUCCESS == MME_Receiver_NextDueTime(receiver, &dueTime)) {
				if (dueTime < lowestDueTime) {
					found = 1;
					lowestReceiver = receiver;
					lowestDueTime = dueTime;
				}
			}
		}

		/* TODO: Note that if we support the bufferQueue, we need to serve it here */
		if (found) {
			EMBX_OS_MUTEX_RELEASE(&(manager->receiverListMutexes[id]));
			/* Execute this receiver's command. */
			/* Mutex will be released once the message is dequeued - otherwise
			   an abort requiest may come take the message off the queue
                           but leave the receiver in the executing state 
                        */
			MME_Receiver_ProcessCommand(lowestReceiver);
		} else {
			/* Nothing is pending. We could waste some time. */
			MME_Info(MME_INFO_MANAGER, ("Execution loop error: Semaphore signalled but no command found!\n"));
			EMBX_OS_MUTEX_RELEASE(&(manager->receiverListMutexes[id]));

			EMBX_OS_MUTEX_RELEASE(&(manager->abortMutex));
		}
	}
}
Пример #2
0
/*
 * Notification routine to inform us that a local port has been
 * closed. We need to invalidate all our remote port
 */
void EMBXSHM_portClosedNotification (EMBXSHM_Transport_t *tpshm)
{
    EMBX_Info(EMBX_INFO_REMOTEPORT, (">>>EMBXSHM_portClosedNotification\n"));

    EMBX_Assert (tpshm);

    /*
     * Wait for notification of a local port closing,
     * then look for it and service it
     */
    while (1)
    {
	EMBX_BOOL signalPending;

	EMBX_Info(EMBX_INFO_REMOTEPORT, ("   waiting for port closed notification\n"));
        signalPending = EMBX_OS_EVENT_WAIT (&tpshm->closedPortEvent);
	EMBX_Info(EMBX_INFO_REMOTEPORT, ("   received port closed notification\n"));

        /*
         * If we've been told to die, then do so
         */
        if (signalPending || tpshm->closedPortDieFlag)
        {
	    EMBX_Info(EMBX_INFO_REMOTEPORT, ("<<<EMBXSHM_portClosedNotification\n"));
            return;
        }

        /* Close the port */
        EMBXSHM_portClose(tpshm);
    }
}
Пример #3
0
static void unblockWaitors(RemoteTransformer_t* remoteTransformer, MME_Event_t event, CommandSlot_t* command) 
{
	HostManager_t* manager = MMEGetManager();
	
	/* Lock whilst this thread does event notification */
	MME_Assert(manager);

	EMBX_OS_MUTEX_TAKE(&manager->eventLock);

	manager->eventTransformer = remoteTransformer;
	manager->eventCommand     = command;
	manager->eventCommandType = event;

	EMBX_OS_EVENT_POST(command->waitor);

	EMBX_OS_EVENT_WAIT(&manager->waitorDone);

	EMBX_OS_MUTEX_RELEASE(&manager->eventLock);
}
Пример #4
0
static MME_ERROR RemoteTransformer_TermOrKill(Transformer_t* transformer, int doKill)
{
	RemoteTransformer_t *remoteTransformer = (RemoteTransformer_t *) transformer;
	EMBX_ERROR err;
	EMBX_VOID *buffer;
	TransformerTerminateMessage *message;
	MME_ERROR result, res;
	result = MME_NOMEM;

	if (!remoteTransformer->sendPort.valid) {
		DP("MME port does not exist\n");
		return MME_INVALID_ARGUMENT;
	}
	/* No command must be pending on the companion side */
	if (remoteTransformer->numCommandSlots > 0) {
		DP("RemoteTransformer::Terminate() failed, commands pending\n");
		return MME_COMMAND_STILL_EXECUTING;
	}

	res = createTerminateMessage(remoteTransformer, 0, &buffer);
	if (res != MME_SUCCESS) {
		DP("CreateTerminateMsg() failed, error=%d\n", res);
		return res;
	}

	/* Send the message */
	message = (TransformerTerminateMessage *) buffer;
	DP("Sending %s message @$%08x...\n", message, (doKill ? "kill" : "terminate"));
	if (doKill) {
		EMBX_PORT replyPort;

		/* connect to our own reply port */
		err = EMBX_Connect(remoteTransformer->super.info->handle, remoteTransformer->replyPort.name, &replyPort);
		if (EMBX_SUCCESS != err) {
			DP("RemoteTransformer_Term(): failed to connect to self\n");
			cleanupTerminateMessage(remoteTransformer, message);
			return MME_EMBX_ERROR;	
		}

		err = EMBX_SendMessage(replyPort, message, message->messageSize);
		if (EMBX_SUCCESS != err) {
			DP("RemoteTransformer_Term(): failed to send message to self\n");
			cleanupTerminateMessage(remoteTransformer, message);
			return MME_EMBX_ERROR;	
		}

		EMBX_ClosePort(replyPort);
	} else {
		err = EMBX_SendMessage(remoteTransformer->adminPort, message, message->messageSize);
		if (EMBX_SUCCESS != err) {
			DP("RemoteTransformer_Term(): failed to send message to coprocessor\n");
			cleanupTerminateMessage(remoteTransformer, message);
			return MME_EMBX_ERROR;	
		}
	}

	/* lost ownership */
	message = NULL;

	/* Wait for ReceiverThread to terminate itself after receiving the reply message */
	DP("Waiting for ReceiverThread to terminate itself...\n");
	DP("terminateWasReplied 0x%08x\n", remoteTransformer->terminateWasReplied);
	EMBX_OS_EVENT_WAIT(&remoteTransformer->terminateWasReplied);

	if (remoteTransformer->terminationResult != MME_SUCCESS) {
		DP("Failed to terminate receiver thread properly\n");
		return MME_INTERNAL_ERROR;
	}

	err = EMBX_OS_ThreadDelete(remoteTransformer->receiverThread);
	if (err != EMBX_SUCCESS) {
		DP("EMBX_OS_ThreadDelete() failed, error=d\n", err);
	}

	remoteTransformer->receiverThread = NULL;

	/* Close the MME port */
	DP("Close mmePort...\n");
	err = EMBX_ClosePort(remoteTransformer->sendPort.port);
	if (err != EMBX_SUCCESS) {
		DP("EMBX_ClosePort(mmePort) failed, error=d\n", err);
	}
	/* Close the reply port */
	DP("Invalidate replyPort...\n");
	err = EMBX_InvalidatePort(remoteTransformer->replyPort.port);
	if (err != EMBX_SUCCESS) {
		DP("EMBX_InvalidatePort(replyPort) failed, error=%d\n", err);
	}
	DP("Close replyPort...\n");
	err = EMBX_ClosePort(remoteTransformer->replyPort.port);
	if (err != EMBX_SUCCESS) {
		DP("EMBX_ClosePort(replyPort) failed, error=%d\n", err);
	}
	remoteTransformer->replyPort.valid = EMBX_FALSE;

	return MME_SUCCESS;
}
Пример #5
0
MME_ERROR MME_SendCommand(MME_TransformerHandle_t handle, MME_Command_t * commandInfo)
{
	Transformer_t *transformer;
	MME_ERROR         result;
	CommandSlot_t     *commandPrivate;

#ifndef MME_LEAN_AND_MEAN
        if (manager == NULL) {
                MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Driver not initialized\n"));
                return MME_DRIVER_NOT_INITIALIZED;      /* the manager must exist */
        }

        if (0 == handle) {
 	        MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Invalid handle - NULL\n"));
                return MME_INVALID_HANDLE;
        }

        if (NULL == commandInfo ||
            commandInfo->StructSize != sizeof(MME_Command_t)) {
                MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Invalid struct size\n"));
                return MME_INVALID_ARGUMENT;
        }

        if (commandInfo->CmdCode != MME_SET_GLOBAL_TRANSFORM_PARAMS &&
            commandInfo->CmdCode != MME_TRANSFORM &&
            commandInfo->CmdCode != MME_SEND_BUFFERS) {
                MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Invalid command code\n"));
                return MME_INVALID_ARGUMENT;
        }

        if (commandInfo->CmdEnd != MME_COMMAND_END_RETURN_NO_INFO &&
            commandInfo->CmdEnd != MME_COMMAND_END_RETURN_NOTIFY) {
                MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Invalid command notify type\n"));
                return MME_INVALID_ARGUMENT;
        }
#endif

	EMBX_OS_MUTEX_TAKE(&manager->monitorMutex);

	result = findTransformerInstance(handle, &transformer);
	if (result != MME_SUCCESS) {
		/* cannot find transformer for this handle */
                MME_Info( MME_INFO_MANAGER, (DEBUG_ERROR_STR "Cannot find transformer with handle 0x%08x\n", handle));
		result = MME_INVALID_HANDLE;
		goto EXIT;
	}

	result = transformer->vtable->sendCommand(transformer, commandInfo, &commandPrivate);

#ifdef ENABLE_MME_WAITCOMMAND
	/* Wake up any thread waiting for new commands with MME_WaitCommand
           or place the new command in a 1-deep buffer for thread that is
           about to wait
         */

	/* Grab this mutex to prevent any command completion events from 
           fiddling with the manager event state */
	EMBX_OS_MUTEX_TAKE(&manager->eventLock);

	if (manager->newCommandEvents) {
		/* One or more threads waiting for a new command event */
		int i, waitors=0;
		NewCommand_t* current;

		manager->eventTransformer = transformer;
		manager->eventCommand = commandPrivate;
		manager->eventCommandType = MME_NEW_COMMAND_EVT;

		current = manager->newCommandEvents;
		while (current) {
			waitors++;
			EMBX_OS_EVENT_POST(current->event);
			current = current->next;
		}

		for (i=0; i<waitors; i++) {
			/* Wait for the last waitor thread to unblock and remove it's event */
			EMBX_OS_EVENT_WAIT(&manager->waitorDone);
		}

		/* All waitor threads have let us know they have dealt with new event - now remove them from the list */
		RemoveNewCommandEvents_HostManager();

		manager->newCommand = NULL;
		manager->newCommandTransformer = NULL;
	} else {
		manager->newCommand = commandInfo;
		manager->newCommandTransformer = transformer;
	}
	EMBX_OS_MUTEX_RELEASE(&manager->eventLock);
#endif

EXIT:
	EMBX_OS_MUTEX_RELEASE(&manager->monitorMutex);
        MME_Info( MME_INFO_MANAGER, (DEBUG_NOTIFY_STR "<<<< (%d)\n", result));
	return result;
}