summaryrefslogtreecommitdiffstats
path: root/src/include/kernel/taskmgr.H
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/kernel/taskmgr.H')
-rw-r--r--src/include/kernel/taskmgr.H133
1 files changed, 129 insertions, 4 deletions
diff --git a/src/include/kernel/taskmgr.H b/src/include/kernel/taskmgr.H
index db267523b..8f1deb264 100644
--- a/src/include/kernel/taskmgr.H
+++ b/src/include/kernel/taskmgr.H
@@ -26,31 +26,156 @@
#include <kernel/types.h>
#include <util/lockfree/counter.H>
#include <kernel/vmmmgr.H>
+#include <sys/task.h>
+#include <util/locked/list.H>
+#include <kernel/spinlock.H>
+ // Forward declaration.
+struct task_tracking_t;
+struct task_wait_t;
+ /** Typedef for a list of task_tracking_t's. */
+typedef Util::Locked::List<task_tracking_t, tid_t> task_tracking_list_t;
+
+/** @struct task_tracking_t
+ * Stores the parent/child relationships and join information for tasks.
+ *
+ * The task_tracking_t's become a tree so that we can create a ps-like
+ * debug output and so that a task can do a wait() on all of its children.
+ */
+struct task_tracking_t
+{
+ typedef tid_t key_type;
+
+ /** previous pointer for list. */
+ task_tracking_t* prev;
+ /** next pointer for list. */
+ task_tracking_t* next;
+
+ /** pointer to parent's tracking info. */
+ task_tracking_t* parent;
+ /** list of all children. */
+ task_tracking_list_t children;
+
+ /** tid as a key for list. */
+ key_type key;
+ /** Pointer to task structure if it is still running. */
+ task_t* task;
+
+ /** Crash/clean-exit status if task has ended. */
+ int status;
+ /** Return-value to task_end2() if task has ended. */
+ void* retval;
+ /** Task-wait state object. */
+ task_wait_t* wait_info;
+
+ /** Record the original entry point of the thread for debug purpose. */
+ void* entry_point;
+};
+
+/** @struct task_wait_t
+ * Stores the parameters for the task_wait syscall for a task which is
+ * deferred due to the syscall.
+ */
+struct task_wait_t
+{
+ /** Tid waiting on (or -1 for any). */
+ int64_t tid;
+ /** Address to return the child status. */
+ int* status;
+ /** Address to return the child return-value. */
+ void** retval;
+};
+
+/** @class TaskManager
+ * Kernel management class to deal with task creation / exit.
+ */
class TaskManager
{
public:
+ /** @brief Returns a pointer to the currently running task on this
+ * CPU.
+ *
+ * @retval NULL - Kernel has never started running any tasks.
+ * @retval non-NULL - The task most recently running and/or will be
+ * running when kernel returns to user-space.
+ */
static task_t* getCurrentTask();
+
+ /** @brief Sets the current task pointer in this CPU object.
+ *
+ * @param[in] t - The task to assign on this CPU.
+ */
static void setCurrentTask(task_t* t);
+ /** Typedef for task entry points. */
typedef void(*task_fn_t)(void*);
- static task_t* createTask(task_fn_t, void*);
+
+ /** @brief Create a new task object.
+ *
+ * @param[in] t - The entry point to start the task at.
+ * @param[in] p - An argument pointer to pass to the task.
+ */
+ static task_t* createTask(task_fn_t t, void* p);
+
+ /** @brief End / destroy a task object.
+ *
+ * @param[in] t - The task to end.
+ * @param[in] retval - Return value from the task.
+ * @param[in] status - TASK_STATUS_* enumeration of how the task ended.
+ */
+ static void endTask(task_t* t, void* retval, int status);
+
+ /** @brief Perform the 'task_wait' for a task.
+ *
+ * Returns the child information if the requested child has already
+ * ended or defers the task if the child requested is still running.
+ *
+ * @param[in] t - The task requesting the wait.
+ * @param[in] tid - The child task requested to wait on or -1 for any.
+ * @param[out] status - The address to write the child status.
+ * @param[out] retval - The address to write the child retval.
+ */
+ static void waitTask(task_t* t, int64_t tid,
+ int* status, void** retval);
friend class CpuManager;
+
protected:
TaskManager();
~TaskManager() {};
+ /** Create a new task where the entry point is idleTaskLoop. */
static task_t* createIdleTask();
private:
- tid_t getNextTid()
- { return iv_nextTid.next(); };
- Util::Lockfree::Counter<tid_t> iv_nextTid;
+ /** Get the next TID in the task sequence. */
+ tid_t getNextTid() { return iv_nextTid.next(); };
+ /** Run the idle task loop */
static void idleTaskLoop(void*);
+
+ // Internal implementations of non-static / non-_ functions.
task_t* _createIdleTask();
task_t* _createTask(task_fn_t, void*, bool);
+ void _endTask(task_t*, void*, int);
+ void _waitTask(task_t*, int64_t, int*, void**);
+
+ /** Remove a tracker from the tracker-tree and delete it.
+ *
+ * @param[in] t - The tracker to remove.
+ * @note Spinlock-locking of the tracker-tree is the
+ * responsibility of the caller.
+ */
+ void removeTracker(task_tracking_t* t);
+
+ /** Atomic monotonically increasing counter to use for TIDs. */
+ Util::Lockfree::Counter<tid_t> iv_nextTid;
+
+ /** Task-tracking tree spinlock. */
+ Spinlock iv_spinlock;
+ /** Task-tracking tree. */
+ task_tracking_list_t iv_taskList;
+
};
#endif
OpenPOWER on IntegriCloud