Files
codezero/include/l4/generic/tcb.h
Bahadir Balban 0f537ea1f5 Wait on working.
Multi-threaded apps can now wait on children to destroy.
WAIT_ON is useful when a child exists with an exit code and the pager
of the child does not want to take the hassle of destorying it via an
ipc. It provides an alternative method of synchronous thread destruction,
where the child destroys itself directly rather than the parent issuing
a destroy on it explicitly.
2009-10-31 23:28:54 +02:00

171 lines
4.2 KiB
C

/*
* Thread Control Block, kernel portion.
*
* Copyright (C) 2007-2009 Bahadir Bilgehan Balban
*/
#ifndef __TCB_H__
#define __TCB_H__
#include <l4/lib/list.h>
#include <l4/lib/mutex.h>
#include <l4/lib/spinlock.h>
#include <l4/generic/scheduler.h>
#include <l4/generic/resource.h>
#include <l4/generic/capability.h>
#include <l4/generic/space.h>
#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__ */