2
* Copyright (c) 2001-2007 Jakub Jermar
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
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.
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.
29
/** @addtogroup genericproc
35
#ifndef KERN_THREAD_H_
36
#define KERN_THREAD_H_
38
#include <synch/waitq.h>
39
#include <proc/task.h>
40
#include <time/timeout.h>
42
#include <synch/rwlock.h>
43
#include <synch/spinlock.h>
48
#include <proc/uarg.h>
49
#include <udebug/udebug.h>
51
#define THREAD_STACK_SIZE STACK_SIZE
52
#define THREAD_NAME_BUFLEN 20
54
extern char *thread_states[];
58
/** Thread cannot be migrated to another CPU.
60
* When using this flag, the caller must set cpu in the thread_t
61
* structure manually before calling thread_ready (even on uniprocessor).
63
#define THREAD_FLAG_WIRED (1 << 0)
64
/** Thread was migrated to another CPU and has not run yet. */
65
#define THREAD_FLAG_STOLEN (1 << 1)
66
/** Thread executes in userspace. */
67
#define THREAD_FLAG_USPACE (1 << 2)
68
/** Thread will be attached by the caller. */
69
#define THREAD_FLAG_NOATTACH (1 << 3)
73
/** It is an error, if thread is found in this state. */
75
/** State of a thread that is currently executing on some CPU. */
77
/** Thread in this state is waiting for an event. */
79
/** State of threads in a run queue. */
81
/** Threads are in this state before they are first readied. */
83
/** After a thread calls thread_exit(), it is put into Exiting state. */
85
/** Threads that were not detached but exited are Lingering. */
89
/** Thread structure. There is one per thread. */
90
typedef struct thread {
91
link_t rq_link; /**< Run queue link. */
92
link_t wq_link; /**< Wait queue link. */
93
link_t th_link; /**< Links to threads within containing task. */
95
/** Threads linkage to the threads_tree. */
96
avltree_node_t threads_tree_node;
98
/** Lock protecting thread structure.
100
* Protects the whole thread structure except list links above.
102
SPINLOCK_DECLARE(lock);
104
char name[THREAD_NAME_BUFLEN];
106
/** Function implementing the thread. */
107
void (* thread_code)(void *);
108
/** Argument passed to thread_code() function. */
112
* From here, the stored context is restored when the thread is
115
context_t saved_context;
117
* From here, the stored timeout context is restored when sleep times
120
context_t sleep_timeout_context;
122
* From here, the stored interruption context is restored when sleep is
125
context_t sleep_interruption_context;
127
/** If true, the thread can be interrupted from sleep. */
128
bool sleep_interruptible;
129
/** Wait queue in which this thread sleeps. */
130
waitq_t *sleep_queue;
131
/** Timeout used for timeoutable sleeping. */
132
timeout_t sleep_timeout;
133
/** Flag signalling sleep timeout in progress. */
134
volatile int timeout_pending;
137
* True if this thread is executing copy_from_uspace().
140
bool in_copy_from_uspace;
142
* True if this thread is executing copy_to_uspace().
145
bool in_copy_to_uspace;
148
* If true, the thread will not go to sleep at all and will call
149
* thread_exit() before returning to userspace.
153
/** If true, thread_join_timeout() cannot be used on this thread. */
155
/** Waitq for thread_join_timeout(). */
157
/** Link used in the joiner_head list. */
160
fpu_context_t *saved_fpu_context;
161
int fpu_context_exists;
164
* Defined only if thread doesn't run.
165
* It means that fpu context is in CPU that last time executes this
166
* thread. This disables migration.
168
int fpu_context_engaged;
170
rwlock_type_t rwlock_holder_type;
172
/** Callback fired in scheduler before the thread is put asleep. */
173
void (* call_me)(void *);
174
/** Argument passed to call_me(). */
177
/** Thread's state. */
179
/** Thread's flags. */
184
/** Containing task. */
187
/** Ticks before preemption. */
190
/** Thread accounting. */
192
/** Last sampled cycle. */
194
/** Thread doesn't affect accumulated accounting. */
197
/** Thread's priority. Implemented as index to CPU->rq */
202
/** Architecture-specific data. */
205
/** Thread's kernel stack. */
209
/** Debugging stuff */
210
udebug_thread_t udebug;
215
/** Thread list lock.
217
* This lock protects the threads_tree.
218
* Must be acquired before T.lock for each T of type thread_t.
221
SPINLOCK_EXTERN(threads_lock);
223
/** AVL tree containing all threads. */
224
extern avltree_t threads_tree;
226
extern void thread_init(void);
227
extern thread_t *thread_create(void (* func)(void *), void *arg, task_t *task,
228
int flags, char *name, bool uncounted);
229
extern void thread_attach(thread_t *t, task_t *task);
230
extern void thread_ready(thread_t *t);
231
extern void thread_exit(void) __attribute__((noreturn));
233
#ifndef thread_create_arch
234
extern void thread_create_arch(thread_t *t);
236
#ifndef thr_constructor_arch
237
extern void thr_constructor_arch(thread_t *t);
239
#ifndef thr_destructor_arch
240
extern void thr_destructor_arch(thread_t *t);
243
extern void thread_sleep(uint32_t sec);
244
extern void thread_usleep(uint32_t usec);
246
#define thread_join(t) \
247
thread_join_timeout((t), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE)
248
extern int thread_join_timeout(thread_t *t, uint32_t usec, int flags);
249
extern void thread_detach(thread_t *t);
251
extern void thread_register_call_me(void (* call_me)(void *),
253
extern void thread_print_list(void);
254
extern void thread_destroy(thread_t *t);
255
extern void thread_update_accounting(void);
256
extern bool thread_exists(thread_t *t);
258
/** Fpu context slab cache. */
259
extern slab_cache_t *fpu_context_slab;
261
/* Thread syscall prototypes. */
262
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg,
263
char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id);
264
extern unative_t sys_thread_exit(int uspace_status);
265
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id);