~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to kernel/generic/include/proc/thread.h

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 genericproc
 
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/rwlock.h>
 
43
#include <synch/spinlock.h>
 
44
#include <adt/avl.h>
 
45
#include <mm/slab.h>
 
46
#include <arch/cpu.h>
 
47
#include <mm/tlb.h>
 
48
#include <proc/uarg.h>
 
49
#include <udebug/udebug.h>
 
50
 
 
51
#define THREAD_STACK_SIZE       STACK_SIZE
 
52
#define THREAD_NAME_BUFLEN      20
 
53
 
 
54
extern char *thread_states[];
 
55
 
 
56
/* Thread flags */
 
57
 
 
58
/** Thread cannot be migrated to another CPU.
 
59
 *
 
60
 * When using this flag, the caller must set cpu in the thread_t
 
61
 * structure manually before calling thread_ready (even on uniprocessor).
 
62
 */ 
 
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)
 
70
 
 
71
/** Thread states. */
 
72
typedef enum {
 
73
        /** It is an error, if thread is found in this state. */
 
74
        Invalid,
 
75
        /** State of a thread that is currently executing on some CPU. */
 
76
        Running,
 
77
        /** Thread in this state is waiting for an event. */
 
78
        Sleeping,
 
79
        /** State of threads in a run queue. */
 
80
        Ready,
 
81
        /** Threads are in this state before they are first readied. */
 
82
        Entering,
 
83
        /** After a thread calls thread_exit(), it is put into Exiting state. */
 
84
        Exiting,
 
85
        /** Threads that were not detached but exited are Lingering. */
 
86
        Lingering
 
87
} state_t;
 
88
 
 
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. */
 
94
 
 
95
        /** Threads linkage to the threads_tree. */
 
96
        avltree_node_t threads_tree_node;
 
97
        
 
98
        /** Lock protecting thread structure.
 
99
         *
 
100
         * Protects the whole thread structure except list links above.
 
101
         */
 
102
        SPINLOCK_DECLARE(lock);
 
103
 
 
104
        char name[THREAD_NAME_BUFLEN];
 
105
 
 
106
        /** Function implementing the thread. */
 
107
        void (* thread_code)(void *);
 
108
        /** Argument passed to thread_code() function. */
 
109
        void *thread_arg;
 
110
 
 
111
        /**
 
112
         * From here, the stored context is restored when the thread is
 
113
         * scheduled.
 
114
         */
 
115
        context_t saved_context;
 
116
        /**
 
117
         * From here, the stored timeout context is restored when sleep times
 
118
         * out.
 
119
         */
 
120
        context_t sleep_timeout_context;
 
121
        /**
 
122
         * From here, the stored interruption context is restored when sleep is
 
123
         * interrupted.
 
124
         */
 
125
        context_t sleep_interruption_context;
 
126
 
 
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;
 
135
 
 
136
        /**
 
137
         * True if this thread is executing copy_from_uspace().
 
138
         * False otherwise.
 
139
         */
 
140
        bool in_copy_from_uspace;
 
141
        /**
 
142
         * True if this thread is executing copy_to_uspace().
 
143
         * False otherwise.
 
144
         */
 
145
        bool in_copy_to_uspace;
 
146
        
 
147
        /**
 
148
         * If true, the thread will not go to sleep at all and will call
 
149
         * thread_exit() before returning to userspace.
 
150
         */
 
151
        bool interrupted;                       
 
152
        
 
153
        /** If true, thread_join_timeout() cannot be used on this thread. */
 
154
        bool detached;
 
155
        /** Waitq for thread_join_timeout(). */
 
156
        waitq_t join_wq;
 
157
        /** Link used in the joiner_head list. */
 
158
        link_t joiner_link;
 
159
 
 
160
        fpu_context_t *saved_fpu_context;
 
161
        int fpu_context_exists;
 
162
 
 
163
        /*
 
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.
 
167
         */
 
168
        int fpu_context_engaged;
 
169
 
 
170
        rwlock_type_t rwlock_holder_type;
 
171
 
 
172
        /** Callback fired in scheduler before the thread is put asleep. */
 
173
        void (* call_me)(void *);
 
174
        /** Argument passed to call_me(). */
 
175
        void *call_me_with;
 
176
 
 
177
        /** Thread's state. */
 
178
        state_t state;
 
179
        /** Thread's flags. */
 
180
        int flags;
 
181
        
 
182
        /** Thread's CPU. */
 
183
        cpu_t *cpu;
 
184
        /** Containing task. */
 
185
        task_t *task;
 
186
 
 
187
        /** Ticks before preemption. */
 
188
        uint64_t ticks;
 
189
        
 
190
        /** Thread accounting. */
 
191
        uint64_t cycles;
 
192
        /** Last sampled cycle. */
 
193
        uint64_t last_cycle;
 
194
        /** Thread doesn't affect accumulated accounting. */    
 
195
        bool uncounted;
 
196
 
 
197
        /** Thread's priority. Implemented as index to CPU->rq */
 
198
        int priority;
 
199
        /** Thread ID. */
 
200
        thread_id_t tid;
 
201
        
 
202
        /** Architecture-specific data. */
 
203
        thread_arch_t arch;
 
204
 
 
205
        /** Thread's kernel stack. */
 
206
        uint8_t *kstack;
 
207
 
 
208
#ifdef CONFIG_UDEBUG
 
209
        /** Debugging stuff */
 
210
        udebug_thread_t udebug;
 
211
#endif
 
212
 
 
213
} thread_t;
 
214
 
 
215
/** Thread list lock.
 
216
 *
 
217
 * This lock protects the threads_tree.
 
218
 * Must be acquired before T.lock for each T of type thread_t.
 
219
 *
 
220
 */
 
221
SPINLOCK_EXTERN(threads_lock);
 
222
 
 
223
/** AVL tree containing all threads. */
 
224
extern avltree_t threads_tree;
 
225
 
 
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));
 
232
 
 
233
#ifndef thread_create_arch
 
234
extern void thread_create_arch(thread_t *t);
 
235
#endif
 
236
#ifndef thr_constructor_arch
 
237
extern void thr_constructor_arch(thread_t *t);
 
238
#endif
 
239
#ifndef thr_destructor_arch
 
240
extern void thr_destructor_arch(thread_t *t);
 
241
#endif
 
242
 
 
243
extern void thread_sleep(uint32_t sec);
 
244
extern void thread_usleep(uint32_t usec);
 
245
 
 
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);
 
250
 
 
251
extern void thread_register_call_me(void (* call_me)(void *),
 
252
    void *call_me_with);
 
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);
 
257
 
 
258
/** Fpu context slab cache. */
 
259
extern slab_cache_t *fpu_context_slab;
 
260
 
 
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);
 
266
 
 
267
#endif
 
268
 
 
269
/** @}
 
270
 */