source: mainline/kernel/generic/include/proc/thread.h@ 8996582

Last change on this file since 8996582 was 5663872, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 18 months ago

Move stuff around for thread sleep

Only mark the thread as ready for wakeup after we switch to
another context. This way, soundness of the sychronization
does not depend on thread lock being held across the context
switch, which gives us more freedom.

  • Property mode set to 100644
File size: 7.2 KB
Line 
1/*
2 * Copyright (c) 2001-2007 Jakub Jermar
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup kernel_generic_proc
30 * @{
31 */
32/** @file
33 */
34
35#ifndef KERN_THREAD_H_
36#define KERN_THREAD_H_
37
38#include <synch/waitq.h>
39#include <proc/task.h>
40#include <time/timeout.h>
41#include <cpu.h>
42#include <synch/spinlock.h>
43#include <adt/odict.h>
44#include <mm/slab.h>
45#include <arch/cpu.h>
46#include <mm/tlb.h>
47#include <abi/proc/uarg.h>
48#include <udebug/udebug.h>
49#include <abi/proc/thread.h>
50#include <abi/sysinfo.h>
51#include <arch.h>
52
53#define THREAD CURRENT->thread
54
55#define THREAD_NAME_BUFLEN 20
56
57extern const char *thread_states[];
58
59/* Thread flags */
60typedef enum {
61 THREAD_FLAG_NONE = 0,
62 /** Thread executes in user space. */
63 THREAD_FLAG_USPACE = (1 << 0),
64 /** Thread will be attached by the caller. */
65 THREAD_FLAG_NOATTACH = (1 << 1),
66 /** Thread accounting doesn't affect accumulated task accounting. */
67 THREAD_FLAG_UNCOUNTED = (1 << 2)
68} thread_flags_t;
69
70/** Thread structure. There is one per thread. */
71typedef struct thread {
72 atomic_refcount_t refcount;
73
74 link_t rq_link; /**< Run queue link. */
75 link_t wq_link; /**< Wait queue link. */
76 link_t th_link; /**< Links to threads within containing task. */
77
78 /** Link to @c threads ordered dictionary. */
79 odlink_t lthreads;
80
81 /** Tracking variable for thread_wait/thread_wakeup */
82 atomic_int sleep_state;
83
84 /**
85 * If true, the thread is terminating.
86 * It will not go to sleep in interruptible synchronization functions
87 * and will call thread_exit() before returning to userspace.
88 */
89 volatile bool interrupted;
90
91 /** Wait queue in which this thread sleeps. Used for debug printouts. */
92 _Atomic(waitq_t *) sleep_queue;
93
94 /** Waitq for thread_join_timeout(). */
95 waitq_t join_wq;
96
97 /** Lock protecting thread structure.
98 *
99 * Protects the whole thread structure except fields listed above.
100 */
101 IRQ_SPINLOCK_DECLARE(lock);
102
103 char name[THREAD_NAME_BUFLEN];
104
105 /** Function implementing the thread. */
106 void (*thread_code)(void *);
107 /** Argument passed to thread_code() function. */
108 void *thread_arg;
109
110 /**
111 * From here, the stored context is restored
112 * when the thread is scheduled.
113 */
114 context_t saved_context;
115 ipl_t saved_ipl;
116
117 /**
118 * True if this thread is executing copy_from_uspace().
119 * False otherwise.
120 */
121 bool in_copy_from_uspace;
122
123 /**
124 * True if this thread is executing copy_to_uspace().
125 * False otherwise.
126 */
127 bool in_copy_to_uspace;
128
129#ifdef CONFIG_FPU
130 fpu_context_t fpu_context;
131#endif
132 bool fpu_context_exists;
133
134 /* The thread will not be migrated if nomigrate is non-zero. */
135 unsigned int nomigrate;
136
137 /** Thread state. */
138 state_t state;
139
140 /** Thread CPU. */
141 cpu_t *cpu;
142 /** Containing task. */
143 task_t *task;
144 /** Thread was migrated to another CPU and has not run yet. */
145 bool stolen;
146 /** Thread is executed in user space. */
147 bool uspace;
148
149 /** Thread accounting. */
150 uint64_t ucycles;
151 uint64_t kcycles;
152 /** Last sampled cycle. */
153 uint64_t last_cycle;
154 /** Thread doesn't affect accumulated accounting. */
155 bool uncounted;
156
157 /** Thread's priority. Implemented as index to CPU->rq */
158 int priority;
159 /** Thread ID. */
160 thread_id_t tid;
161
162 /** Architecture-specific data. */
163 thread_arch_t arch;
164
165 /** Thread's kernel stack. */
166 uint8_t *kstack;
167
168#ifdef CONFIG_UDEBUG
169 /**
170 * If true, the scheduler will print a stack trace
171 * to the kernel console upon scheduling this thread.
172 */
173 bool btrace;
174
175 /** Debugging stuff */
176 udebug_thread_t udebug;
177#endif /* CONFIG_UDEBUG */
178} thread_t;
179
180IRQ_SPINLOCK_EXTERN(threads_lock);
181extern odict_t threads;
182
183extern void thread_init(void);
184extern thread_t *thread_create(void (*)(void *), void *, task_t *,
185 thread_flags_t, const char *);
186extern void thread_wire(thread_t *, cpu_t *);
187extern void thread_attach(thread_t *, task_t *);
188extern void thread_ready(thread_t *);
189extern void thread_exit(void) __attribute__((noreturn));
190extern void thread_interrupt(thread_t *);
191
192enum sleep_state {
193 SLEEP_INITIAL,
194 SLEEP_ASLEEP,
195 SLEEP_WOKE,
196};
197
198typedef enum {
199 THREAD_OK,
200 THREAD_TERMINATING,
201} thread_termination_state_t;
202
203typedef enum {
204 THREAD_WAIT_SUCCESS,
205 THREAD_WAIT_TIMEOUT,
206} thread_wait_result_t;
207
208extern thread_termination_state_t thread_wait_start(void);
209extern thread_wait_result_t thread_wait_finish(deadline_t);
210extern void thread_wakeup(thread_t *);
211
212static inline thread_t *thread_ref(thread_t *thread)
213{
214 refcount_up(&thread->refcount);
215 return thread;
216}
217
218static inline thread_t *thread_try_ref(thread_t *thread)
219{
220 if (refcount_try_up(&thread->refcount))
221 return thread;
222 else
223 return NULL;
224}
225
226extern void thread_put(thread_t *);
227
228#ifndef thread_create_arch
229extern errno_t thread_create_arch(thread_t *, thread_flags_t);
230#endif
231
232#ifndef thr_constructor_arch
233extern void thr_constructor_arch(thread_t *);
234#endif
235
236#ifndef thr_destructor_arch
237extern void thr_destructor_arch(thread_t *);
238#endif
239
240extern void thread_sleep(uint32_t);
241extern void thread_usleep(uint32_t);
242
243extern errno_t thread_join(thread_t *);
244extern errno_t thread_join_timeout(thread_t *, uint32_t, unsigned int);
245
246extern void thread_print_list(bool);
247extern thread_t *thread_find_by_id(thread_id_t);
248extern size_t thread_count(void);
249extern thread_t *thread_first(void);
250extern thread_t *thread_next(thread_t *);
251extern void thread_update_accounting(bool);
252extern thread_t *thread_try_get(thread_t *);
253
254extern void thread_migration_disable(void);
255extern void thread_migration_enable(void);
256
257#ifdef CONFIG_UDEBUG
258extern void thread_stack_trace(thread_id_t);
259#endif
260
261/** Fpu context slab cache. */
262extern slab_cache_t *fpu_context_cache;
263
264/* Thread syscall prototypes. */
265extern sys_errno_t sys_thread_create(uspace_ptr_uspace_arg_t, uspace_ptr_char, size_t,
266 uspace_ptr_thread_id_t);
267extern sys_errno_t sys_thread_exit(int);
268extern sys_errno_t sys_thread_get_id(uspace_ptr_thread_id_t);
269extern sys_errno_t sys_thread_usleep(uint32_t);
270extern sys_errno_t sys_thread_udelay(uint32_t);
271
272#endif
273
274/** @}
275 */
Note: See TracBrowser for help on using the repository browser.