/* * Thread Control Block, kernel portion. * * Copyright (C) 2007 Bahadir Balban */ #ifndef __TCB_H__ #define __TCB_H__ #include #include #include #include #include #include INC_GLUE(memory.h) #include INC_GLUE(syscall.h) #include INC_GLUE(message.h) #include INC_GLUE(context.h) #include INC_SUBARCH(mm.h) /* * These are a mixture of flags that indicate the task is * in a transitional state that could include one or more * scheduling states. */ #define TASK_INTERRUPTED (1 << 0) #define TASK_SUSPENDING (1 << 1) #define TASK_RESUMING (1 << 2) /* IPC resulted in a fault error (For ipcs that cannot page fault) */ #define IPC_EFAULT (1 << 3) /* Task states */ enum task_state { TASK_INACTIVE = 0, TASK_SLEEPING = 1, TASK_RUNNABLE = 2, }; #define TASK_ID_INVALID -1 struct task_ids { l4id_t tid; l4id_t spid; l4id_t tgid; }; struct ktcb { /* User context */ task_context_t context; /* * Reference to the context on stack * saved at the beginning of a syscall trap. */ syscall_context_t *syscall_regs; /* Runqueue related */ struct list_head rq_list; struct runqueue *rq; /* Thread information */ l4id_t tid; /* Global thread id */ l4id_t tgid; /* Global thread group id */ /* See space for space id */ /* Flags to indicate various task status */ unsigned int flags; /* Lock for blocking thread state modifications via a syscall */ struct mutex thread_control_lock; /* Other related threads */ l4id_t pagerid; u32 ts_need_resched; /* Scheduling flag */ enum task_state state; struct list_head task_list; /* Global task list. */ /* UTCB related, see utcb.txt in docs */ unsigned long utcb_address; /* Virtual ref to task's utcb area */ /* Thread times */ u32 kernel_time; /* Ticks spent in kernel */ u32 user_time; /* Ticks spent in userland */ u32 ticks_left; /* Timeslice ticks left for reschedule */ u32 ticks_assigned; /* Ticks assigned to this task on this HZ */ u32 sched_granule; /* Granularity ticks left for reschedule */ int priority; /* Task's fixed, default priority */ /* Number of locks the task currently has acquired */ int nlocks; /* Page table information */ struct address_space *space; /* Fields for ipc rendezvous */ struct waitqueue_head wqh_recv; struct waitqueue_head wqh_send; l4id_t expected_sender; /* Waitqueue for pagers to wait for task states */ struct waitqueue_head wqh_pager; /* Tells where we are when we sleep */ struct spinlock waitlock; struct waitqueue_head *waiting_on; struct waitqueue *wq; }; /* Per thread kernel stack unified on a single page. */ union ktcb_union { struct ktcb ktcb; char kstack[PAGE_SIZE]; }; /* * Each task is allocated a unique global id. A thread group can only belong to * a single leader, and every thread can only belong to a single thread group. * These rules allow the fact that every global id can be used to define a * unique thread group id. Thread local ids are used as an index into the thread * group's utcb area to discover the per-thread utcb structure. */ static inline void set_task_ids(struct ktcb *task, struct task_ids *ids) { task->tid = ids->tid; task->tgid = ids->tgid; } #define THREAD_IDS_MAX 1024 #define SPACE_IDS_MAX 1024 #define TGROUP_IDS_MAX 1024 extern struct id_pool *thread_id_pool; extern struct id_pool *space_id_pool; struct ktcb *tcb_find(l4id_t tid); struct ktcb *tcb_find_by_space(l4id_t tid); void tcb_add(struct ktcb *tcb); void tcb_remove(struct ktcb *tcb); void tcb_init(struct ktcb *tcb); struct ktcb *tcb_alloc_init(void); void tcb_delete(struct ktcb *tcb); void init_ktcb_list(void); void task_update_utcb(struct ktcb *cur, struct ktcb *next); int tcb_check_and_lazy_map_utcb(struct ktcb *task); #endif /* __TCB_H__ */