Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / include / lwk / task.h
diff --git a/kitten/include/lwk/task.h b/kitten/include/lwk/task.h
new file mode 100644 (file)
index 0000000..c88e10c
--- /dev/null
@@ -0,0 +1,185 @@
+#ifndef _LWK_TASK_H
+#define _LWK_TASK_H
+
+#include <lwk/types.h>
+#include <lwk/idspace.h>
+#include <lwk/cpumask.h>
+
+/**
+ * Valid user-space created task IDs are in interval
+ * [TASK_MIN_ID, TASK_MAX_ID].
+ */
+#define TASK_MIN_ID                    0
+#define TASK_MAX_ID                    4094
+
+/**
+ * The task ID to use for the init_task.
+ * Put it at the top of the space to keep it out of the way.
+ */
+#define INIT_TASK_ID                   TASK_MAX_ID
+
+/**
+ * Task states
+ */
+#define TASKSTATE_READY                (1 << 0)
+#define TASKSTATE_UNINTERRUPTIBLE      (1 << 1)
+#define TASKSTATE_INTERRUPTIBLE        (1 << 2)
+#define TASKSTATE_EXIT_ZOMBIE          (1 << 3)
+typedef unsigned int taskstate_t;
+
+/**
+ * Events that tasks may wait for and be sent.
+ */
+#define LWKEVENT_CHILD_TASK_EXITED     (1 << 0)
+#define LWKEVENT_PORTALS_EVENT_POSTED  (1 << 1)
+typedef unsigned long event_t;
+
+/**
+ * Initial conditions to use for new task.
+ */
+typedef struct {
+       uid_t                  uid;
+       uid_t                  gid;
+       id_t                   aspace_id;
+       vaddr_t                entry_point;
+       vaddr_t                stack_ptr;
+       id_t                   cpu_id;
+       const user_cpumask_t * cpumask;
+} start_state_t;
+
+/**
+ * Core task management API.
+ * These are accessible from both kernel-space and user-space (via syscalls).
+ */
+extern int task_get_myid(id_t *id);
+extern int task_create(id_t id_request, const char *name,
+                       const start_state_t *start_state, id_t *id);
+extern int task_exit(int status);
+extern int task_yield(void);
+
+#ifdef __KERNEL__
+
+#include <lwk/types.h>
+#include <lwk/init.h>
+#include <lwk/spinlock.h>
+#include <lwk/list.h>
+#include <lwk/seqlock.h>
+#include <lwk/signal.h>
+#include <lwk/idspace.h>
+#include <arch/atomic.h>
+#include <arch/page.h>
+#include <arch/processor.h>
+#include <arch/task.h>
+#include <arch/current.h>
+#include <arch/mmu.h>
+
+/**
+ * Flags for task_struct.flags field.
+ */
+#define PF_USED_MATH    0x00002000      /* if unset the fpu must be initialized before use */
+
+/**
+ * Signal handler structure.
+ */
+struct sighand_struct {
+       atomic_t                count;
+       struct k_sigaction      action[_NSIG];
+       spinlock_t              siglock;
+       struct list_head        signalfd_list;
+};
+
+/**
+ * Task structure (aka Process Control Block).
+ * There is one of these for each OS-managed thread of execution in the
+ * system.  A task is a generic "context of execution"... it either
+ * represents a user-level process, user-level thread, or kernel thread.
+ */
+struct task_struct {
+       id_t                    id;              /* The task's ID */
+       char                    name[16];        /* The task's name */
+       struct hlist_node       ht_link;         /* Task hash table linkage */
+
+       taskstate_t             state;           /* The task's current state */
+
+       uid_t                   uid;             /* user ID */
+       gid_t                   gid;             /* group ID */
+
+       struct aspace *         aspace;          /* Address space task is in */
+       struct sighand_struct * sighand;         /* signal handler info */
+
+       cpumask_t               cpumask;         /* CPUs this task may migrate
+                                                   to and create tasks on */
+       id_t                    cpu_id;          /* CPU this task is bound to */
+
+       struct list_head        sched_link;      /* For per-CPU scheduling lists */
+
+       unsigned long           ptrace;
+       uint32_t                flags;
+
+       int                     exit_status;     /* Reason the task exited */
+
+       struct arch_task        arch;            /* arch specific task info */
+};
+
+union task_union {
+       struct task_struct      task_info;
+       unsigned long           stack[TASK_SIZE/sizeof(long)];
+};
+
+extern union task_union bootstrap_task_union;
+extern struct aspace bootstrap_aspace;
+
+/**
+ * Valid task IDs are in interval [__TASK_MIN_ID, __TASK_MAX_ID].
+ */
+#define __TASK_MIN_ID   TASK_MIN_ID
+#define __TASK_MAX_ID   TASK_MAX_ID+1  /* +1 for IDLE_TASK_ID */
+
+/**
+ * ID of the idle task.
+ */
+#define IDLE_TASK_ID    TASK_MAX_ID+1
+
+/**
+ * Checks to see if a task structure is the init task.
+ * The init task is the first user-space task created by the kernel.
+ */
+static inline int
+is_init(struct task_struct *tsk)
+{
+       return (tsk->id == 1);
+}
+
+#define clear_stopped_child_used_math(child) do { (child)->flags &= ~PF_USED_MATH; } while (0)
+#define set_stopped_child_used_math(child) do { (child)->flags |= PF_USED_MATH; } while (0)
+#define clear_used_math() clear_stopped_child_used_math(current)
+#define set_used_math() set_stopped_child_used_math(current)
+#define conditional_stopped_child_used_math(condition, child) \
+        do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= (condition) ? PF_USED_MATH : 0; } while (0)
+#define conditional_used_math(condition) \
+        conditional_stopped_child_used_math(condition, current)
+#define copy_to_stopped_child_used_math(child) \
+        do { (child)->flags &= ~PF_USED_MATH, (child)->flags |= current->flags & PF_USED_MATH; } while (0)
+/* NOTE: this will return 0 or PF_USED_MATH, it will never return 1 */
+#define tsk_used_math(p) ((p)->flags & PF_USED_MATH)
+#define used_math() tsk_used_math(current)
+
+extern int __init task_subsys_init(void);
+
+extern int arch_task_create(struct task_struct *task,
+                            const start_state_t *start_state);
+
+extern int sys_task_get_myid(id_t __user *id);
+extern int sys_task_create(id_t id_request, const char __user *name,
+                           const start_state_t __user *start_state,
+                           id_t __user *id);
+extern int sys_task_exit(int status);
+extern int sys_task_yield(void);
+
+extern int __task_reserve_id(id_t id);
+extern int __task_create(id_t id, const char *name,
+                         const start_state_t *start_state,
+                         struct task_struct **task);
+
+#endif
+#endif