xme_status_t xme_core_exec_dispatcher_initializeTask ( xme_core_component_t componentId, xme_core_component_functionId_t functionId ) { /* Look up for a task descriptor */ xme_core_exec_taskDescriptor_t* thisTask = NULL; /* We only deal with an initialized component */ if (!xme_core_exec_isInitialized()) return XME_STATUS_UNEXPECTED; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): > [%d|%d] dispatcher_initializeTask()\n", componentId, functionId); XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &thisTask), XME_STATUS_NOT_FOUND); /* Move the task to running state */ XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_setTaskState(componentId, functionId, XME_CORE_EXEC_FUNCTION_STATE_RUNNING), XME_STATUS_INTERNAL_ERROR); /* Execution manager initially owns the mutex allowing the task to execute */ xme_core_exec_lockMutex("S/t",thisTask->waitLock, componentId, functionId); XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): < [%d|%d] dispatcher_initializeTask()\n", componentId, functionId); return XME_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------*/ xme_status_t xme_core_exec_getTaskState ( xme_core_component_t componentId, xme_core_component_functionId_t functionId, xme_core_exec_functionState_t* taskState ) { xme_core_exec_taskDescriptor_t* task = NULL; xme_status_t status; XME_CHECK_MSG(XME_STATUS_SUCCESS == (status = xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &task)), status, XME_LOG_WARNING, MODULE_ACRONYM "error getting task descriptor for [%d|%d]\n", componentId, functionId); XME_CHECK(NULL != task, XME_STATUS_INTERNAL_ERROR); /* todo Is locking while reading such a thing necessary? */ xme_hal_sync_enterCriticalSection(taskDescriptorsMutex); *taskState = task->state; xme_hal_sync_leaveCriticalSection(taskDescriptorsMutex); return XME_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------*/ xme_status_t xme_core_exec_dispatcher_setRunnable ( xme_core_component_t componentId, xme_core_component_functionId_t functionId, xme_hal_sched_taskHandle_t handle ) { xme_core_exec_taskDescriptor_t* taskRecord; xme_status_t status; /* We only deal with an initialized component */ if (!xme_core_exec_isInitialized()) return XME_STATUS_UNEXPECTED; XME_CHECK(XME_STATUS_SUCCESS == (status=xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &taskRecord)), status); xme_hal_sync_enterCriticalSection(taskDescriptorsMutex); taskRecord->handle = handle; xme_hal_sync_leaveCriticalSection(taskDescriptorsMutex); return XME_STATUS_SUCCESS; }
static xme_status_t xme_core_exec_dispatcher_startFunction ( xme_core_component_t componentId, xme_core_component_functionId_t functionId, void* functionArgs ) { xme_core_exec_taskDescriptor_t* task = NULL; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(m): > [%d|%d] dispatcher_startFunction\n", componentId, functionId); XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor( componentId, functionId, &task), XME_STATUS_NOT_FOUND); XME_LOG(XME_LOG_VERBOSE, MODULE_ACRONYM "(m): [%d|%d]: starting\n", componentId, functionId); /* XXX should the descriptor table not bbe locked? */ task->running = true; task->startTime = xme_hal_time_getCurrentTime(); startData = functionArgs; XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_grantExecutionToken(task), XME_STATUS_INTERNAL_ERROR); XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(m): < [%d|%d] dispatcher_startFunction()\n", componentId, functionId); return XME_STATUS_SUCCESS; }
/** TODO: refactor: implement */ static xme_status_t xme_core_exec_dispatcher_checkWCETConformance( xme_core_component_t componentId, xme_core_component_functionId_t functionId) { xme_core_exec_taskDescriptor_t* thisTask = NULL; XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &thisTask), XME_STATUS_NOT_FOUND); // TODO: Monitor time to completion return XME_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------*/ xme_status_t xme_core_exec_dispatcher_createFunctionExecutionUnit ( xme_core_exec_functionDescriptor_t* functionDescriptor, bool eventTriggeredBehavior ) { xme_core_exec_taskDescriptor_t* taskRecord = NULL; if (!xme_core_exec_isInitialized()) return XME_STATUS_UNEXPECTED; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "> dispatcher_createFunctionExecutionUnit()\n"); XME_CHECK_MSG( true == xme_core_exec_isValidFunctionDescriptor(functionDescriptor), XME_STATUS_INVALID_PARAMETER, XME_LOG_WARNING, "error adding a new task descriptor to the descriptor table.\n"); XME_CHECK_MSG( XME_STATUS_NOT_FOUND == xme_core_exec_descriptorTable_getTaskDescriptor( functionDescriptor->componentId, functionDescriptor->functionId, &taskRecord), XME_STATUS_ALREADY_EXIST, XME_LOG_WARNING, MODULE_ACRONYM "error: the task descriptor exists for [%d|%d]\n", functionDescriptor->componentId, functionDescriptor->functionId); XME_CHECK_MSG( XME_STATUS_SUCCESS == xme_core_exec_dispatcher_addNewTaskDescriptor(&taskRecord), XME_STATUS_INTERNAL_ERROR, XME_LOG_WARNING, "error adding a new task descriptor to the descriptor table.\n"); XME_CHECK_MSG(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_initializeTaskDescriptor(taskRecord, functionDescriptor, eventTriggeredBehavior), XME_STATUS_INTERNAL_ERROR, XME_LOG_WARNING, "error adding a new task descriptor to the descriptor table.\n"); XME_CHECK_MSG(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_startRunnable(functionDescriptor), XME_STATUS_INTERNAL_ERROR, XME_LOG_WARNING, "error starting runnable.\n"); XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "< dispatcher_createFunctionExecutionUnit()\n"); return XME_STATUS_SUCCESS; }
xme_status_t xme_core_exec_dispatcher_waitForStart ( xme_core_component_t componentId, xme_core_component_functionId_t functionId, void** functionArguments ) { xme_core_exec_taskDescriptor_t* thisTask = NULL; /* We only deal with an initialized component */ if (!xme_core_exec_isInitialized()) return XME_STATUS_UNEXPECTED; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): > dispatcher_waitForStart()\n"); XME_CHECK_MSG(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &thisTask), XME_STATUS_NOT_FOUND, XME_LOG_FATAL, MODULE_ACRONYM "task [%d|%d] not present in the task table!\n", componentId, functionId); XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): [%d|%d] waitForStart()\n", componentId, functionId); XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_requestExecutionToken(thisTask), XME_STATUS_INTERNAL_ERROR); XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "passing %" PRIu32 " to function [%d|%d]\n", (uint32_t)(uintptr_t)startData, componentId, functionId); if (NULL != functionArguments) *functionArguments = startData; /* XXX temporary workaround to allow smooth transition to xme_core_exec_getTaskState() */ thisTask->wrapper->state = thisTask->state; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): < [%d|%d] dispatcher_waitForStart()\n", componentId, functionId); return XME_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------*/ xme_status_t xme_core_exec_dispatcher_getRunnable ( xme_core_component_t componentId, xme_core_component_functionId_t functionId, xme_hal_sched_taskHandle_t* taskHandle ) { xme_core_exec_taskDescriptor_t* taskRecord = NULL; xme_status_t status; XME_CHECK(XME_STATUS_SUCCESS == (status = xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &taskRecord)), status); *taskHandle = taskRecord->handle; return XME_STATUS_SUCCESS; }
xme_status_t xme_core_exec_dispatcher_executionCompleted ( xme_core_component_t componentId, xme_core_component_functionId_t functionId ) { xme_core_exec_taskDescriptor_t* thisTask = NULL; /* We only deal with an initialized component */ if (!xme_core_exec_isInitialized()) return XME_STATUS_UNEXPECTED; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): > [%d|%d] dispatcher_executionCompleted()\n", componentId, functionId); /* Look up for a task descriptor */ XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &thisTask), XME_STATUS_NOT_FOUND); /* Stop monitoring the task */ thisTask->running = false; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(t): [%d|%d] execution time total = %" PRIu64 "\n", componentId, functionId, xme_hal_time_getTimeInterval(&(thisTask->startTime), (bool)false)); XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_returnExecutionToken(thisTask), XME_STATUS_INTERNAL_ERROR); XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "***************** /executionCompleted [%d|%d] *********************\n", componentId, functionId); return XME_STATUS_SUCCESS; }
/*--------------------------------------------------------------------------*/ xme_status_t xme_core_exec_setTaskState ( xme_core_component_t componentId, xme_core_component_functionId_t functionId, xme_core_exec_functionState_t newTaskState ) { xme_core_exec_taskDescriptor_t* task = NULL; XME_CHECK_MSG(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor(componentId, functionId, &task), XME_STATUS_INTERNAL_ERROR, XME_LOG_WARNING, MODULE_ACRONYM "error getting task descriptor for [%d|%d]\n", componentId, functionId); XME_CHECK(NULL != task, XME_STATUS_INTERNAL_ERROR); xme_hal_sync_enterCriticalSection(taskDescriptorsMutex); task->state = newTaskState; xme_hal_sync_leaveCriticalSection(taskDescriptorsMutex); return XME_STATUS_SUCCESS; }
xme_status_t xme_core_exec_dispatcher_executeStep ( const xme_core_exec_schedule_table_entry_t* const nextSlot, ///< Schedule table entry for the next slot xme_hal_time_timeInterval_t slack ///< Current slack ) { /* Descriptor of the task to be executed */ xme_core_exec_taskDescriptor_t* executedTask = NULL; /* Determines if the task will be executed at all */ bool executeTask = true; XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(m): nextSlot = [%d|%d]\n", nextSlot->componentId, nextSlot->functionId); // XXX: Code review: maybe merge the branches??? /* Scheduler tells us also the slack that we have; we either sleep or immediately execute */ if (slack > 0) { XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "Schedule slack: [%" PRIu64 "] us\n", xme_hal_time_timeIntervalInMicroseconds(slack)); xme_hal_sleep_sleep(slack); } else { // XXX: Code review : remove sleep(0) // XXX incorrect context for the comment (we don't see the negative slack) XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "[Negative slack in schedule]\n"); xme_hal_sleep_sleep(0ULL); } /* Get descriptor of the next task that scheduler told us */ XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_descriptorTable_getTaskDescriptor(nextSlot->componentId, nextSlot->functionId, &executedTask), XME_STATUS_NOT_FOUND); if (executedTask->eventTriggered) { // XXX Code Review: use descriptor of task instead of cid/fid in the internal calls /* Check if an ET task has all data ready */ xme_status_t functionReady = XME_STATUS_UNEXPECTED; functionReady = xme_core_broker_isFunctionReady(nextSlot->componentId, nextSlot->functionId, nextSlot->functionArgs); if(XME_STATUS_SUCCESS != functionReady) // XXX Code Review: RETURN from here executeTask = false; } if( executeTask ) { XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_startFunction(nextSlot->componentId, nextSlot->functionId, nextSlot->functionArgs), XME_STATUS_INTERNAL_ERROR); /* If we have started a task, we have to catch its S-lock before we exit, and check the runtime */ XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_recaptureExecutionToken(executedTask), XME_STATUS_INTERNAL_ERROR); if(NULL != xme_core_exec_intConfig.onFunctionReturned) { xme_core_exec_intConfig.onFunctionReturned(nextSlot->componentId, nextSlot->functionId); } if( nextSlot->completion ) XME_CHECK(XME_STATUS_SUCCESS == xme_core_exec_dispatcher_checkWCETConformance(nextSlot->componentId, nextSlot->functionId), XME_STATUS_TIMEOUT); } XME_LOG(XME_LOG_DEBUG, MODULE_ACRONYM "(m): < dispatcher_executeStep()\n"); return XME_STATUS_SUCCESS; }