diff --git a/Makefile.am b/Makefile.am index 2bd5402..dd8d8da 100644 --- a/Makefile.am +++ b/Makefile.am @@ -133,7 +133,8 @@ common_sources = \ src/tasks/TaskInfo.cpp \ src/tasks/TaskInfoAPI.cpp \ src/tasks/TaskiterMetadata.cpp \ - src/tasks/TaskloopMetadata.cpp + src/tasks/TaskloopMetadata.cpp \ + src/tasks/TaskMetadata.cpp dependency_flags = -I$(srcdir)/src/dependencies -I$(srcdir)/src/dependencies/discrete diff --git a/src/bootstrap/Initialization.cpp b/src/bootstrap/Initialization.cpp index 704ffe1..d022af9 100644 --- a/src/bootstrap/Initialization.cpp +++ b/src/bootstrap/Initialization.cpp @@ -38,6 +38,9 @@ void nanos6_init(void) if (int err = nosv_attach(&task, &defaultAffinity, "main task", NOSV_ATTACH_NONE)) ErrorHandler::fail("nosv_attach failed: ", nosv_get_error_string(err)); + // Set the root of the task stack + TaskMetadata::setLastTask(nosv_self()); + // Gather hardware info HardwareInfo::initialize(); @@ -61,6 +64,9 @@ void nanos6_shutdown(void) // Shutdown hardware info HardwareInfo::shutdown(); + // Unset the last task stack + TaskMetadata::setLastTask(nullptr); + // Detach the wrapped main process if (int err = nosv_detach(NOSV_DETACH_NONE)) ErrorHandler::fail("nosv_detach failed: ", nosv_get_error_string(err)); diff --git a/src/system/EventsAPI.cpp b/src/system/EventsAPI.cpp index adae3f5..5318fa9 100644 --- a/src/system/EventsAPI.cpp +++ b/src/system/EventsAPI.cpp @@ -24,10 +24,7 @@ extern "C" void *nanos6_get_current_event_counter(void) extern "C" void nanos6_increase_current_task_event_counter(void *, unsigned int increment) { - nosv_task_t current_task = nosv_self(); - assert(current_task != nullptr); - - TaskMetadata *metadata = TaskMetadata::getTaskMetadata(current_task); + TaskMetadata *metadata = TaskMetadata::getCurrentTask(); assert(metadata != nullptr); // Mark this task as a potential communication task (TAMPI), which we need for some diff --git a/src/system/TaskCreation.cpp b/src/system/TaskCreation.cpp index be4bd19..0668f5e 100644 --- a/src/system/TaskCreation.cpp +++ b/src/system/TaskCreation.cpp @@ -132,12 +132,10 @@ template void TaskCreation::createTask( static inline bool creatingInTaskiter() { // Figure out if the parent task is a Taskiter to create the child task as derived from TaskiterNode - nosv_task_t parentTask = nosv_self(); + TaskMetadata *parentTask = TaskMetadata::getCurrentTask(); if (parentTask) { - TaskMetadata *task = TaskMetadata::getTaskMetadata(parentTask); - if (task) - return task->isTaskiter(); + return parentTask->isTaskiter(); } return false; @@ -273,13 +271,13 @@ void nanos6_submit_task(void *taskHandle) // is not a spawned task, since spawned tasks are independent and have their // own space of data dependencies TaskMetadata *taskMetadata = TaskMetadata::getTaskMetadata(task); - nosv_task_t parentTask = nosv_self(); // Initialize nOS-V priority if needed taskMetadata->computePriority(); + TaskMetadata *parentTask = TaskMetadata::getCurrentTask(); if (!taskMetadata->isSpawned() && parentTask != nullptr) { - taskMetadata->setParent(parentTask); + taskMetadata->setParent(parentTask->getTaskHandle()); } TaskCreation::submitTask(task); diff --git a/src/system/TaskFinalization.cpp b/src/system/TaskFinalization.cpp index 90b9c89..32bd387 100644 --- a/src/system/TaskFinalization.cpp +++ b/src/system/TaskFinalization.cpp @@ -24,6 +24,11 @@ void TaskFinalization::taskEndedCallback(nosv_task_t task) { + assert(task); + + nosv_task_t lastTask = TaskMetadata::getLastTask(); + TaskMetadata::setLastTask(task); + TaskMetadata *taskMetadata = TaskMetadata::getTaskMetadata(task); // Negative returned values mean the call failed, and the error is codified within @@ -33,10 +38,17 @@ void TaskFinalization::taskEndedCallback(nosv_task_t task) } DataAccessRegistration::combineTaskReductions(taskMetadata, cpuId); + + TaskMetadata::setLastTask(lastTask); } void TaskFinalization::taskCompletedCallback(nosv_task_t task) { + assert(task); + + nosv_task_t lastTask = TaskMetadata::getLastTask(); + TaskMetadata::setLastTask(task); + // Mark that the task has finished user code execution TaskMetadata *taskMetadata = TaskMetadata::getTaskMetadata(task); taskMetadata->markAsFinished(); @@ -95,6 +107,8 @@ void TaskFinalization::taskCompletedCallback(nosv_task_t task) TaskFinalization::disposeTask(taskMetadata); } } + + TaskMetadata::setLastTask(lastTask); } void TaskFinalization::taskFinished(TaskMetadata *task) diff --git a/src/tasks/Task.cpp b/src/tasks/Task.cpp index e6c14e4..dd2169a 100644 --- a/src/tasks/Task.cpp +++ b/src/tasks/Task.cpp @@ -15,18 +15,14 @@ extern "C" signed int nanos6_in_final(void) { - nosv_task_t currentTask = nosv_self(); - assert(currentTask != nullptr); - - TaskMetadata *taskMetadata = TaskMetadata::getTaskMetadata(currentTask); + TaskMetadata *taskMetadata = TaskMetadata::getCurrentTask(); + assert(taskMetadata != nullptr); return taskMetadata->isFinal(); } extern "C" signed int nanos6_in_serial_context(void) { - nosv_task_t currentTask = nosv_self(); - assert(currentTask != nullptr); - - TaskMetadata *taskMetadata = TaskMetadata::getTaskMetadata(currentTask); + TaskMetadata *taskMetadata = TaskMetadata::getCurrentTask(); + assert(taskMetadata != nullptr); return taskMetadata->isFinal() || taskMetadata->isIf0(); } diff --git a/src/tasks/TaskInfo.cpp b/src/tasks/TaskInfo.cpp index b733492..6a9c486 100644 --- a/src/tasks/TaskInfo.cpp +++ b/src/tasks/TaskInfo.cpp @@ -16,7 +16,6 @@ SpinLock TaskInfo::_lock; bool TaskInfo::_initialized; size_t TaskInfo::unlabeledTaskInfos = 0; - void TaskInfo::registerTaskInfo(nanos6_task_info_t *taskInfo) { assert(taskInfo != nullptr); diff --git a/src/tasks/TaskInfo.hpp b/src/tasks/TaskInfo.hpp index 51d5760..bb24543 100644 --- a/src/tasks/TaskInfo.hpp +++ b/src/tasks/TaskInfo.hpp @@ -54,12 +54,14 @@ class TaskInfo { { assert(task != nullptr); + nosv_task_t lastTask = TaskMetadata::getLastTask(); + TaskMetadata::setLastTask(task); + nanos6_task_info_t *taskInfo = TaskMetadata::getTaskInfo(task); assert(taskInfo != nullptr); assert(taskInfo->implementation_count == 1); assert(taskInfo->implementations != nullptr); - TaskMetadata *taskMetadata = TaskMetadata::getTaskMetadata(task); Chrono chrono; if (taskMetadata->isTaskiterChild()) @@ -137,6 +139,8 @@ class TaskInfo { if (int err = nosv_submit(taskMetadata->getParent()->getTaskHandle(), NOSV_SUBMIT_UNLOCKED)) ErrorHandler::fail("nosv_submit failed: ", nosv_get_error_string(err)); } + + TaskMetadata::setLastTask(lastTask); } //! \brief Initialize the TaskInfo manager after the runtime has been initialized diff --git a/src/tasks/TaskMetadata.cpp b/src/tasks/TaskMetadata.cpp new file mode 100644 index 0000000..0c7f2b8 --- /dev/null +++ b/src/tasks/TaskMetadata.cpp @@ -0,0 +1,9 @@ +/* + This file is part of NODES and is licensed under the terms contained in the COPYING file. + + Copyright (C) 2023 Barcelona Supercomputing Center (BSC) +*/ + +#include "TaskMetadata.hpp" + +thread_local nosv_task_t TaskMetadata::_lastTask; diff --git a/src/tasks/TaskMetadata.hpp b/src/tasks/TaskMetadata.hpp index 71c2fc4..9795111 100644 --- a/src/tasks/TaskMetadata.hpp +++ b/src/tasks/TaskMetadata.hpp @@ -117,6 +117,9 @@ class TaskMetadata { //! Detected communication task bool _isCommunicationTask; + //! Pointer to the last task in the run stack + static thread_local nosv_task_t _lastTask; + protected: //! A pointer to the original task that wraps this metadata @@ -494,7 +497,11 @@ class TaskMetadata { static inline TaskMetadata *getCurrentTask() { nosv_task_t task = nosv_self(); - return TaskMetadata::getTaskMetadata(task); + + if (task && TaskMetadata::isLastTask(task)) + return TaskMetadata::getTaskMetadata(task); + else // External task from other nosv-enabled library + return nullptr; } static inline nanos6_task_info_t *getTaskInfo(TaskMetadata *task) @@ -636,6 +643,21 @@ class TaskMetadata { _group = group; } + static inline void setLastTask(nosv_task_t task) + { + _lastTask = task; + } + + static inline nosv_task_t getLastTask() + { + return _lastTask; + } + + static inline bool isLastTask(nosv_task_t task) + { + return _lastTask == task; + } + virtual ~TaskMetadata() = default; };