flounder: moving receiving cap slots from a thread to a dispatcher
[barrelfish] / lib / barrelfish / include / threads_priv.h
1 /*
2  * Copyright (c) 2009, 2010, 2012, ETH Zurich.
3  * All rights reserved.
4  *
5  * This file is distributed under the terms in the attached LICENSE file.
6  * If you do not find this file, copies can be found by writing to:
7  * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
8  */
9
10 #ifndef LIBBARRELFISH_THREADS_PRIV_H
11 #define LIBBARRELFISH_THREADS_PRIV_H
12
13 #include <barrelfish/dispatcher_arch.h>
14 #include <barrelfish/except.h>
15
16 /// Maximum number of thread-local storage keys
17 #define MAX_TLS         16
18
19 /** \brief TLS dynamic thread vector data structure
20  *
21  * See: ELF handling for thread-local storage. Ulrich Drepper, Dec 2005.
22  * http://www.akkadia.org/drepper/tls.pdf
23  */
24 struct tls_dtv {
25     uintptr_t gen; ///< Generation count
26     void *dtv[0];  ///< Variable-length array of pointers to TLS blocks
27 };
28
29 enum thread_state {
30     THREAD_STATE_NULL = 0,
31     THREAD_STATE_RUNNABLE,
32     THREAD_STATE_BLOCKED,
33     THREAD_STATE_EXITED
34 };
35
36 /** \brief A thread of execution / thread control block (TCB)
37  *
38  * NB: on some ABIs (namely x86_{32,64}), the TLS blocks for initially-loaded
39  * (i.e. not dlopen()ed) modules _precede_ this structure in memory. Therefore
40  * it's not safe to directly malloc() or free() a thread structure.
41  */
42 struct thread {
43     /* XXX: The offsets of the first two fields (self pointer and dispatcher
44      * pointer) are depended upon by the ABI and/or assembly code. Don't change!
45      */
46     struct thread       *self;              ///< Points to itself
47     dispatcher_handle_t disp;               ///< Dispatcher affinity
48     struct tls_dtv      *tls_dtv;           ///< TLS thread vector
49     struct thread       *next, *prev;       ///< Next/prev threads in list
50     arch_registers_state_t regs;            ///< Register state snapshot
51     void                *stack;             ///< Malloced stack area
52     void                *stack_top;         ///< Stack bounds
53     void                *exception_stack;   ///< Stack for exception handling
54     void                *exception_stack_top; ///< Bounds of exception stack
55     exception_handler_fn exception_handler; ///< Exception handler, or NULL
56     void                *userptr;           ///< User's thread local pointer
57     void                *userptrs[MAX_TLS]; ///< User's thread local pointers
58     uintptr_t           yield_epoch;        ///< Yield epoch
59     void                *wakeup_reason;     ///< Value returned from block()
60     coreid_t            coreid;             ///< XXX: Core ID affinity
61     int                 return_value;       ///< Value returned on exit
62     struct thread_cond  exit_condition;     ///< Thread exit condition
63     struct thread_mutex exit_lock;          ///< Protects exited state
64     enum thread_state   state;              ///< Thread state
65     bool                paused;             ///< Thread is paused (not runnable)
66     bool                detached;           ///< true if detached
67     bool                joining;            ///< true if someone is joining
68     bool                in_exception;       ///< true if running exception handler
69     bool                used_fpu;           ///< Ever used FPU?
70 #if defined(__x86_64__)
71     uint16_t            thread_seg_selector; ///< Segment selector for TCB
72 #endif
73     arch_registers_fpu_state_t fpu_state;   ///< FPU state
74     void                *slab;              ///< Base of slab block containing this TCB
75     uintptr_t           id;                 ///< User-defined thread identifier
76
77     uint32_t            token_number;       ///< RPC next token
78     uint32_t            token;              ///< Token to be received
79     struct waitset_chanstate *channel;      ///< on right channel
80
81     bool    rpc_in_progress;                ///< RPC in progress
82     errval_t    async_error;                ///< RPC async error
83     uint32_t    outgoing_token;             ///< Token of outgoing message
84     struct waitset_chanstate *local_trigger; ///< Trigger for a local thread event
85 };
86
87 void thread_enqueue(struct thread *thread, struct thread **queue);
88 struct thread *thread_dequeue(struct thread **queue);
89 void thread_remove_from_queue(struct thread **queue, struct thread *thread);
90
91 /* must only be called by dispatcher, while disabled */
92 void thread_init_disabled(dispatcher_handle_t handle, bool init_domain);
93
94 /// Returns true if there is non-threaded work to be done on this dispatcher
95 /// (ie. if we still need to run)
96 static inline bool havework_disabled(dispatcher_handle_t handle)
97 {
98     struct dispatcher_generic *disp = get_dispatcher_generic(handle);
99     return disp->runq != NULL
100 #ifdef CONFIG_INTERCONNECT_DRIVER_LMP
101             || disp->lmp_send_events_list != NULL
102 #endif
103             || disp->polled_channels != NULL
104             || disp->notificators != NULL
105             || disp->ump_send_events_list != NULL
106             ;
107 }
108
109 void *thread_block(struct thread **queue);
110 void *thread_block_disabled(dispatcher_handle_t handle, struct thread **queue);
111 void *thread_block_and_release_spinlock_disabled(dispatcher_handle_t handle,
112                                                  struct thread **queue,
113                                                  spinlock_t *spinlock);
114 struct thread *thread_unblock_one(struct thread **queue, void *reason);
115 struct thread *thread_unblock_one_disabled(dispatcher_handle_t handle,
116                                            struct thread **queue, void *reason);
117 struct thread *thread_unblock_all_disabled(dispatcher_handle_t handle,
118                                            struct thread **queue, void *reason);
119
120 struct thread *thread_create_unrunnable(thread_func_t start_func, void *arg,
121                                         size_t stacksize);
122
123 void thread_init_remote(dispatcher_handle_t handle, struct thread *thread);
124 void threads_prepare_to_span(dispatcher_handle_t newdh);
125
126 void thread_run_disabled(dispatcher_handle_t handle);
127 void thread_deliver_exception_disabled(dispatcher_handle_t handle,
128                                        enum exception_type type, int subtype,
129                                        void *addr, arch_registers_state_t *regs);
130
131 #endif // LIBBARRELFISH_THREADS_PRIV_H