/* * Thread Control Block, kernel portion. * * Copyright (C) 2007-2009 Bahadir Bilgehan Balban */ #ifndef __TCB_H__ #define __TCB_H__ #include #include #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) #define TASK_EXITING (1 << 3) #define TASK_PENDING_SIGNAL (TASK_SUSPENDING | TASK_EXITING) /* Task states */ enum task_state { TASK_INACTIVE = 0, TASK_SLEEPING = 1, TASK_RUNNABLE = 2, TASK_DEAD = 3, }; #define TASK_ID_INVALID -1 struct task_ids { l4id_t tid; l4id_t spid; l4id_t tgid; }; struct container; 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 link rq_list; struct runqueue *rq; /* Thread Id information (See space for space id) */ l4id_t tid; /* Global thread id */ l4id_t tgid; /* Global thread group id */ /* Other related threads */ l4id_t pagerid; /* Flags to indicate various task status */ unsigned int flags; /* IPC flags */ unsigned int ipc_flags; /* Lock for blocking thread state modifications via a syscall */ struct mutex thread_control_lock; u32 ts_need_resched; /* Scheduling flag */ enum task_state state; struct link task_list; /* Global task list. */ struct ktcb_list child_exit_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; /* Task exit code */ unsigned int exit_code; /* Page table information */ struct address_space *space; /* Container */ struct container *container; struct pager *pager; /* Capability lists */ struct cap_list cap_list; /* Own private capabilities */ /* 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; /* * Extended ipc size and buffer that * points to the space after ktcb */ unsigned long extended_ipc_size; char extended_ipc_buffer[]; }; /* 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; } struct ktcb *tcb_find(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 ktcb_list_remove(struct ktcb *task, struct ktcb_list *ktcb_list); void ktcb_list_add(struct ktcb *new, struct ktcb_list *ktcb_list); void init_ktcb_list(struct ktcb_list *ktcb_list); void task_update_utcb(struct ktcb *task); int tcb_check_and_lazy_map_utcb(struct ktcb *task); #endif /* __TCB_H__ */