summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Braun <rbraun@sceen.net>2012-12-18 21:41:52 +0100
committerRichard Braun <rbraun@sceen.net>2012-12-18 21:41:52 +0100
commit39b79e00c60c3da0e8ad1519cac9f808d877070e (patch)
tree9dfd5e36f26319528f892882a5718b37aaa6a7c4
parent8fb359f3d5c6826a1efb6b9fb9e0a7b1431eb3a4 (diff)
kern/task: task creation and information
-rw-r--r--kern/task.c56
-rw-r--r--kern/task.h20
-rw-r--r--kern/thread.h6
3 files changed, 75 insertions, 7 deletions
diff --git a/kern/task.c b/kern/task.c
index d333776f..9a34f7c3 100644
--- a/kern/task.c
+++ b/kern/task.c
@@ -15,9 +15,11 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <kern/error.h>
#include <kern/init.h>
#include <kern/kmem.h>
#include <kern/list.h>
+#include <kern/spinlock.h>
#include <kern/stddef.h>
#include <kern/string.h>
#include <kern/task.h>
@@ -39,10 +41,12 @@ static struct kmem_cache task_cache;
* Global list of tasks.
*/
static struct list task_list;
+static struct spinlock task_list_lock;
static void
task_init(struct task *task, const char *name, struct vm_map *map)
{
+ spinlock_init(&task->lock);
list_init(&task->threads);
task->map = map;
strlcpy(task->name, name, sizeof(task->name));
@@ -53,13 +57,63 @@ task_setup(void)
{
kmem_cache_init(&task_cache, "task", sizeof(struct task),
0, NULL, NULL, NULL, 0);
- task_init(kernel_task, "x15", kernel_map);
list_init(&task_list);
+ spinlock_init(&task_list_lock);
+ task_init(kernel_task, "x15", kernel_map);
+ list_insert(&task_list, &kernel_task->node);
+}
+
+int
+task_create(struct task **taskp, const char *name)
+{
+ struct task *task;
+
+ task = kmem_cache_alloc(&task_cache);
+
+ if (task == NULL)
+ return ERROR_NOMEM;
+
+ /* TODO VM map */
+ task_init(task, name, NULL);
+
+ spinlock_lock(&task_list_lock);
list_insert(&task_list, &kernel_task->node);
+ spinlock_unlock(&task_list_lock);
+
+ *taskp = task;
+ return 0;
}
void
task_add_thread(struct task *task, struct thread *thread)
{
+ spinlock_lock(&task->lock);
list_insert_tail(&task->threads, &thread->task_node);
+ spinlock_unlock(&task->lock);
+}
+
+void
+task_info(struct task *task)
+{
+ struct thread *thread;
+
+ if (task == NULL) {
+ spinlock_lock(&task_list_lock);
+
+ list_for_each_entry(&task_list, task, node)
+ printk("task: %s\n", task->name);
+
+ spinlock_unlock(&task_list_lock);
+
+ return;
+ }
+
+ spinlock_lock(&task->lock);
+
+ printk("task: name: %s, threads :\n", task->name);
+
+ list_for_each_entry(&task->threads, thread, task_node)
+ printk("task: %s: %s\n", task->name, thread->name);
+
+ spinlock_unlock(&task->lock);
}
diff --git a/kern/task.h b/kern/task.h
index 319651db..ed074acf 100644
--- a/kern/task.h
+++ b/kern/task.h
@@ -19,11 +19,8 @@
#define _KERN_TASK_H
#include <kern/list.h>
-
-/*
- * Forward declaration.
- */
-struct thread;
+#include <kern/spinlock.h>
+#include <kern/thread.h>
/*
* Task name buffer size.
@@ -34,6 +31,7 @@ struct thread;
* Task structure.
*/
struct task {
+ struct spinlock lock;
struct list node;
struct list threads;
struct vm_map *map;
@@ -51,8 +49,20 @@ extern struct task *kernel_task;
void task_setup(void);
/*
+ * Create a task.
+ */
+int task_create(struct task **taskp, const char *name);
+
+/*
* Add a thread to a task.
*/
void task_add_thread(struct task *task, struct thread *thread);
+/*
+ * Display task information.
+ *
+ * If task is NULL, this function displays all tasks.
+ */
+void task_info(struct task *task);
+
#endif /* _KERN_TASK_H */
diff --git a/kern/thread.h b/kern/thread.h
index b68b5b38..59e17ad7 100644
--- a/kern/thread.h
+++ b/kern/thread.h
@@ -22,11 +22,15 @@
#include <kern/list.h>
#include <kern/macros.h>
#include <kern/param.h>
-#include <kern/task.h>
#include <machine/cpu.h>
#include <machine/tcb.h>
/*
+ * Forward declaration.
+ */
+struct task;
+
+/*
* Thread name buffer size.
*/
#define THREAD_NAME_SIZE 32