1 // Copyright 2016 The Fuchsia Authors
2 // Copyright (c) 2008-2015 Travis Geiselbrecht
3 //
4 // Use of this source code is governed by a MIT-style
5 // license that can be found in the LICENSE file or at
6 // https://opensource.org/licenses/MIT
7
8 #pragma once
9
10 #include <arch/defines.h>
11 #include <arch/ops.h>
12 #include <arch/thread.h>
13 #include <debug.h>
14 #include <kernel/cpu.h>
15 #include <kernel/spinlock.h>
16 #include <kernel/timer.h>
17 #include <kernel/wait.h>
18 #include <list.h>
19 #include <sys/types.h>
20 #include <vm/kstack.h>
21 #include <zircon/compiler.h>
22 #include <zircon/types.h>
23
24 // fwd decl for the user_thread member below.
25 class ThreadDispatcher;
26
27 __BEGIN_CDECLS
28
29 enum thread_state {
30 THREAD_INITIAL = 0,
31 THREAD_READY,
32 THREAD_RUNNING,
33 THREAD_BLOCKED,
34 THREAD_SLEEPING,
35 THREAD_SUSPENDED,
36 THREAD_DEATH,
37 };
38
39 enum thread_user_state_change {
40 THREAD_USER_STATE_EXIT,
41 THREAD_USER_STATE_SUSPEND,
42 THREAD_USER_STATE_RESUME,
43 };
44
45 // scheduler lock
46 extern spin_lock_t thread_lock;
47
48 typedef int (*thread_start_routine)(void* arg);
49 typedef void (*thread_trampoline_routine)(void) __NO_RETURN;
50 typedef void (*thread_user_callback_t)(enum thread_user_state_change new_state,
51 struct thread* thread_context);
52 typedef void (*thread_tls_callback_t)(void* tls_value);
53
54 // clang-format off
55 #define THREAD_FLAG_DETACHED (1 << 0)
56 #define THREAD_FLAG_FREE_STRUCT (1 << 1)
57 #define THREAD_FLAG_REAL_TIME (1 << 2)
58 #define THREAD_FLAG_IDLE (1 << 3)
59
60 #define THREAD_SIGNAL_KILL (1 << 0)
61 #define THREAD_SIGNAL_SUSPEND (1 << 1)
62 #define THREAD_SIGNAL_POLICY_EXCEPTION (1 << 2)
63 // clang-format on
64
65 #define THREAD_MAGIC (0x74687264) // 'thrd'
66
67 // This includes the trailing NUL.
68 // N.B. This must match ZX_MAX_NAME_LEN.
69 #define THREAD_NAME_LENGTH 32
70
71 #define THREAD_LINEBUFFER_LENGTH 128
72
73 // Number of kernel tls slots.
74 #define THREAD_MAX_TLS_ENTRY 2
75
76 struct vmm_aspace;
77
78 // This is a parallel structure to lockdep::ThreadLockState to work around the
79 // fact that this header is included by C code and cannot reference C++ types
80 // directly. This structure MUST NOT be touched by code outside of the lockdep
81 // implementation and MUST be kept in sync with the C++ counterpart.
82 typedef struct lockdep_state {
83 uintptr_t acquired_locks;
84 uint16_t reporting_disabled_count;
85 uint8_t last_result;
86 } lockdep_state_t;
87
88 typedef struct thread {
89 int magic;
90 struct list_node thread_list_node;
91
92 // active bits
93 struct list_node queue_node;
94 enum thread_state state;
95 zx_time_t last_started_running;
96 zx_duration_t remaining_time_slice;
97 unsigned int flags;
98 unsigned int signals;
99
100 // Total time in THREAD_RUNNING state. If the thread is currently in
101 // THREAD_RUNNING state, this excludes the time it has accrued since it
102 // left the scheduler.
103 zx_duration_t runtime_ns;
104
105 // priority: in the range of [MIN_PRIORITY, MAX_PRIORITY], from low to high.
106 // base_priority is set at creation time, and can be tuned with thread_set_priority().
107 // priority_boost is a signed value that is moved around within a range by the scheduler.
108 // inherited_priority is temporarily set to >0 when inheriting a priority from another
109 // thread blocked on a locking primitive this thread holds. -1 means no inherit.
110 // effective_priority is MAX(base_priority + priority boost, inherited_priority) and is
111 // the working priority for run queue decisions.
112 int effec_priority;
113 int base_priority;
114 int priority_boost;
115 int inherited_priority;
116
117 // current cpu the thread is either running on or in the ready queue, undefined otherwise
118 cpu_num_t curr_cpu;
119 cpu_num_t last_cpu; // last cpu the thread ran on, INVALID_CPU if it's never run
120 cpu_mask_t cpu_affinity; // mask of cpus that this thread can run on
121
122 // if blocked, a pointer to the wait queue
123 struct wait_queue* blocking_wait_queue;
124
125 // list of other wait queue heads if we're a head
126 struct list_node wait_queue_heads_node;
127
128 // return code if woken up abnormally from suspend, sleep, or block
129 zx_status_t blocked_status;
130
131 // are we allowed to be interrupted on the current thing we're blocked/sleeping on
132 bool interruptable;
133
134 // number of mutexes we currently hold
135 int mutexes_held;
136
137 #if WITH_LOCK_DEP
138 // state for runtime lock validation when in thread context
139 lockdep_state_t lock_state;
140 #endif
141
142 // pointer to the kernel address space this thread is associated with
143 struct vmm_aspace* aspace;
144
145 // pointer to user thread if one exists for this thread
146 ThreadDispatcher* user_thread;
147 uint64_t user_tid;
148 uint64_t user_pid;
149
150 // callback for user thread state changes; do not invoke directly, use invoke_user_callback
151 // helper function instead
152 thread_user_callback_t user_callback;
153
154 // non-NULL if stopped in an exception
155 const struct arch_exception_context* exception_context;
156
157 // architecture stuff
158 struct arch_thread arch;
159
160 kstack_t stack;
161
162 // entry point
163 thread_start_routine entry;
164 void* arg;
165
166 // return code
167 int retcode;
168 struct wait_queue retcode_wait_queue;
169
170 // disable_counts contains two fields:
171 //
172 // * Bottom 16 bits: the preempt_disable counter. See
173 // thread_preempt_disable().
174 // * Top 16 bits: the resched_disable counter. See
175 // thread_resched_disable().
176 //
177 // This is a single field so that both counters can be compared against
178 // zero with a single memory access and comparison.
179 //
180 // disable_counts is modified by interrupt handlers, but it is always
181 // restored to its original value before the interrupt handler returns,
182 // so modifications are not visible to the interrupted thread. Despite
183 // that, "volatile" is still technically needed. Otherwise the
184 // compiler is technically allowed to compile
185 // "++thread->disable_counts" into code that stores a junk value into
186 // preempt_disable temporarily.
187 volatile uint32_t disable_counts;
188
189 // preempt_pending tracks whether a thread reschedule is pending.
190 //
191 // This is volatile because it can be changed asynchronously by an
192 // interrupt handler: If preempt_disable is set, an interrupt handler
193 // may change this from false to true. Otherwise, if resched_disable
194 // is set, an interrupt handler may change this from true to false.
195 //
196 // preempt_pending should only be true:
197 // * if preempt_disable or resched_disable are non-zero, or
198 // * after preempt_disable or resched_disable have been decremented,
199 // while preempt_pending is being checked.
200 volatile bool preempt_pending;
201
202 // thread local storage, initialized to zero
203 void* tls[THREAD_MAX_TLS_ENTRY];
204
205 // callback for cleanup of tls slots
206 thread_tls_callback_t tls_callback[THREAD_MAX_TLS_ENTRY];
207
208 char name[THREAD_NAME_LENGTH];
209 #if WITH_DEBUG_LINEBUFFER
210 // buffering for debug/klog output
211 size_t linebuffer_pos;
212 char linebuffer[THREAD_LINEBUFFER_LENGTH];
213 #endif
214 } thread_t;
215
216 // thread priority
217 #define NUM_PRIORITIES (32)
218 #define LOWEST_PRIORITY (0)
219 #define HIGHEST_PRIORITY (NUM_PRIORITIES - 1)
220 #define DPC_PRIORITY (NUM_PRIORITIES - 2)
221 #define IDLE_PRIORITY LOWEST_PRIORITY
222 #define LOW_PRIORITY (NUM_PRIORITIES / 4)
223 #define DEFAULT_PRIORITY (NUM_PRIORITIES / 2)
224 #define HIGH_PRIORITY ((NUM_PRIORITIES / 4) * 3)
225
226 // stack size
227 #ifdef CUSTOM_DEFAULT_STACK_SIZE
228 #define DEFAULT_STACK_SIZE CUSTOM_DEFAULT_STACK_SIZE
229 #else
230 #define DEFAULT_STACK_SIZE ARCH_DEFAULT_STACK_SIZE
231 #endif
232
233 // functions
234 void thread_init_early(void);
235 void thread_become_idle(void) __NO_RETURN;
236 void thread_secondary_cpu_init_early(thread_t* t);
237 void thread_secondary_cpu_entry(void) __NO_RETURN;
238 void thread_construct_first(thread_t* t, const char* name);
239 thread_t* thread_create_idle_thread(uint cpu_num);
240 void thread_set_name(const char* name);
241 void thread_set_priority(thread_t* t, int priority);
242 void thread_set_user_callback(thread_t* t, thread_user_callback_t cb);
243 thread_t* thread_create(const char* name, thread_start_routine entry, void* arg, int priority);
244 thread_t* thread_create_etc(thread_t* t, const char* name, thread_start_routine entry, void* arg,
245 int priority, thread_trampoline_routine alt_trampoline);
246 void thread_resume(thread_t*);
247 zx_status_t thread_suspend(thread_t*);
248 void thread_signal_policy_exception(void);
249 void thread_exit(int retcode) __NO_RETURN;
250 void thread_forget(thread_t*);
251
252 // set the mask of valid cpus to run the thread on. migrates the thread to satisfy
253 // the new constraint
254 void thread_set_cpu_affinity(thread_t* t, cpu_mask_t mask);
255
256 // migrates the current thread to the CPU identified by target_cpu
257 void thread_migrate_to_cpu(cpu_num_t target_cpuid);
258
259 zx_status_t thread_detach(thread_t* t);
260 zx_status_t thread_join(thread_t* t, int* retcode, zx_time_t deadline);
261 zx_status_t thread_detach_and_resume(thread_t* t);
262 zx_status_t thread_set_real_time(thread_t* t);
263
264 // scheduler routines to be used by regular kernel code
265 void thread_yield(void); // give up the cpu and time slice voluntarily
266 void thread_preempt(void); // get preempted at irq time
267 void thread_reschedule(void); // re-evaluate the run queue on the current cpu
268
269 void thread_owner_name(thread_t* t, char out_name[THREAD_NAME_LENGTH]);
270
271 // print the backtrace on the current thread
272 void thread_print_current_backtrace(void);
273
274 // append the backtrace of the current thread to the passed in char pointer up
275 // to `len' characters.
276 // return the number of chars appended.
277 size_t thread_append_current_backtrace(char* out, size_t len);
278
279 // print the backtrace on the current thread at the given frame
280 void thread_print_current_backtrace_at_frame(void* caller_frame);
281
282 // print the backtrace of the passed in thread, if possible
283 zx_status_t thread_print_backtrace(thread_t* t);
284
285 // Return true if stopped in an exception.
thread_stopped_in_exception(const thread_t * thread)286 static inline bool thread_stopped_in_exception(const thread_t* thread) {
287 return !!thread->exception_context;
288 }
289
290 // wait until the slack-adjusted deadline has occurred.
291 //
292 // if interruptable, may return early with ZX_ERR_INTERNAL_INTR_KILLED if
293 // thread is signaled for kill.
294 zx_status_t thread_sleep_etc(zx_time_t deadline,
295 TimerSlack slack,
296 bool interruptable,
297 zx_time_t now);
298
299 // non-interruptable version of thread_sleep_etc
300 zx_status_t thread_sleep(zx_time_t deadline);
301
302 // non-interruptable relative delay version of thread_sleep
303 zx_status_t thread_sleep_relative(zx_duration_t delay);
304
305 // interruptable version of thread_sleep
306 zx_status_t thread_sleep_interruptable(zx_time_t deadline);
307
308 // return the number of nanoseconds a thread has been running for
309 zx_duration_t thread_runtime(const thread_t* t);
310
311 // deliver a kill signal to a thread
312 void thread_kill(thread_t* t);
313
314 // return true if thread has been signaled
thread_is_signaled(thread_t * t)315 static inline bool thread_is_signaled(thread_t* t) {
316 return t->signals != 0;
317 }
318
319 // process pending signals, may never return because of kill signal
320 void thread_process_pending_signals(void);
321 void dump_thread_locked(thread_t* t, bool full) TA_REQ(thread_lock);
322 void dump_thread(thread_t* t, bool full) TA_EXCL(thread_lock);
323 void arch_dump_thread(thread_t* t);
324 void dump_all_threads_locked(bool full) TA_REQ(thread_lock);
325 void dump_all_threads(bool full) TA_EXCL(thread_lock);
326 void dump_thread_user_tid(uint64_t tid, bool full) TA_EXCL(thread_lock);
327 void dump_thread_user_tid_locked(uint64_t tid, bool full) TA_REQ(thread_lock);
328
dump_thread_during_panic(thread_t * t,bool full)329 static inline void dump_thread_during_panic(thread_t* t, bool full) TA_NO_THREAD_SAFETY_ANALYSIS {
330 // Skip grabbing the lock if we are panic'ing
331 dump_thread_locked(t, full);
332 }
333
dump_all_threads_during_panic(bool full)334 static inline void dump_all_threads_during_panic(bool full) TA_NO_THREAD_SAFETY_ANALYSIS {
335 // Skip grabbing the lock if we are panic'ing
336 dump_all_threads_locked(full);
337 }
338
dump_thread_user_tid_during_panic(uint64_t tid,bool full)339 static inline void dump_thread_user_tid_during_panic(uint64_t tid, bool full)
340 TA_NO_THREAD_SAFETY_ANALYSIS {
341 // Skip grabbing the lock if we are panic'ing
342 dump_thread_user_tid_locked(tid, full);
343 }
344
345 // find a thread based on the thread id
346 // NOTE: used only for debugging, its a slow linear search through the
347 // global thread list
348 thread_t* thread_id_to_thread_slow(uint64_t tid);
349
thread_is_realtime(thread_t * t)350 static inline bool thread_is_realtime(thread_t* t) {
351 return (t->flags & THREAD_FLAG_REAL_TIME) && t->base_priority > DEFAULT_PRIORITY;
352 }
353
thread_is_idle(thread_t * t)354 static inline bool thread_is_idle(thread_t* t) {
355 return !!(t->flags & THREAD_FLAG_IDLE);
356 }
357
thread_is_real_time_or_idle(thread_t * t)358 static inline bool thread_is_real_time_or_idle(thread_t* t) {
359 return !!(t->flags & (THREAD_FLAG_REAL_TIME | THREAD_FLAG_IDLE));
360 }
361
362 // the current thread
363 #include <arch/current_thread.h>
364 thread_t* get_current_thread(void);
365 void set_current_thread(thread_t*);
366
thread_lock_held(void)367 static inline bool thread_lock_held(void) {
368 return spin_lock_held(&thread_lock);
369 }
370
371 // Thread local storage. See tls_slots.h in the object layer above for
372 // the current slot usage.
373
tls_get(uint entry)374 static inline void* tls_get(uint entry) {
375 return get_current_thread()->tls[entry];
376 }
377
tls_set(uint entry,void * val)378 static inline void* tls_set(uint entry, void* val) {
379 thread_t* curr_thread = get_current_thread();
380 void* oldval = curr_thread->tls[entry];
381 curr_thread->tls[entry] = val;
382 return oldval;
383 }
384
385 // set the callback that is issued when the thread exits
tls_set_callback(uint entry,thread_tls_callback_t cb)386 static inline void tls_set_callback(uint entry, thread_tls_callback_t cb) {
387 get_current_thread()->tls_callback[entry] = cb;
388 }
389
390 void thread_check_preempt_pending(void);
391
thread_preempt_disable_count(void)392 static inline uint32_t thread_preempt_disable_count(void) {
393 return get_current_thread()->disable_counts & 0xffff;
394 }
395
thread_resched_disable_count(void)396 static inline uint32_t thread_resched_disable_count(void) {
397 return get_current_thread()->disable_counts >> 16;
398 }
399
400 // thread_preempt_disable() increments the preempt_disable counter for the
401 // current thread. While preempt_disable is non-zero, preemption of the
402 // thread is disabled, including preemption from interrupt handlers.
403 // During this time, any call to thread_reschedule() or sched_reschedule()
404 // will only record that a reschedule is pending, and won't do a context
405 // switch.
406 //
407 // Note that this does not disallow blocking operations
408 // (e.g. mutex_acquire()). Disabling preemption does not prevent switching
409 // away from the current thread if it blocks.
410 //
411 // A call to thread_preempt_disable() must be matched by a later call to
412 // thread_preempt_reenable() to decrement the preempt_disable counter.
thread_preempt_disable(void)413 static inline void thread_preempt_disable(void) {
414 DEBUG_ASSERT(thread_preempt_disable_count() < 0xffff);
415
416 thread_t* current_thread = get_current_thread();
417 atomic_signal_fence();
418 ++current_thread->disable_counts;
419 atomic_signal_fence();
420 }
421
422 // thread_preempt_reenable() decrements the preempt_disable counter. See
423 // thread_preempt_disable().
thread_preempt_reenable(void)424 static inline void thread_preempt_reenable(void) {
425 DEBUG_ASSERT(!arch_blocking_disallowed());
426 DEBUG_ASSERT(thread_preempt_disable_count() > 0);
427
428 thread_t* current_thread = get_current_thread();
429 atomic_signal_fence();
430 uint32_t new_count = --current_thread->disable_counts;
431 atomic_signal_fence();
432
433 if (new_count == 0) {
434 thread_check_preempt_pending();
435 }
436 }
437
438 // This is the same as thread_preempt_reenable(), except that it does not
439 // check for any pending reschedules. This is useful in interrupt handlers
440 // when we know that no reschedules should have become pending since
441 // calling thread_preempt_disable().
thread_preempt_reenable_no_resched(void)442 static inline void thread_preempt_reenable_no_resched(void) {
443 DEBUG_ASSERT(thread_preempt_disable_count() > 0);
444
445 thread_t* current_thread = get_current_thread();
446 atomic_signal_fence();
447 --current_thread->disable_counts;
448 atomic_signal_fence();
449 }
450
451 // thread_resched_disable() increments the resched_disable counter for the
452 // current thread. When resched_disable is non-zero, preemption of the
453 // thread from outside interrupt handlers is disabled. However, interrupt
454 // handlers may still preempt the thread.
455 //
456 // This is a weaker version of thread_preempt_disable().
457 //
458 // As with preempt_disable, blocking operations are still allowed while
459 // resched_disable is non-zero.
460 //
461 // A call to thread_resched_disable() must be matched by a later call to
462 // thread_resched_reenable() to decrement the preempt_disable counter.
thread_resched_disable(void)463 static inline void thread_resched_disable(void) {
464 DEBUG_ASSERT(thread_resched_disable_count() < 0xffff);
465
466 thread_t* current_thread = get_current_thread();
467 atomic_signal_fence();
468 current_thread->disable_counts += 1 << 16;
469 atomic_signal_fence();
470 }
471
472 // thread_resched_reenable() decrements the preempt_disable counter. See
473 // thread_resched_disable().
thread_resched_reenable(void)474 static inline void thread_resched_reenable(void) {
475 DEBUG_ASSERT(!arch_blocking_disallowed());
476 DEBUG_ASSERT(thread_resched_disable_count() > 0);
477
478 thread_t* current_thread = get_current_thread();
479 atomic_signal_fence();
480 uint32_t new_count = current_thread->disable_counts - (1 << 16);
481 current_thread->disable_counts = new_count;
482 atomic_signal_fence();
483
484 if (new_count == 0) {
485 thread_check_preempt_pending();
486 }
487 }
488
489 // thread_preempt_set_pending() marks a preemption as pending for the
490 // current CPU.
491 //
492 // This is similar to thread_reschedule(), except that it may only be
493 // used inside an interrupt handler while interrupts and preemption
494 // are disabled, between thread_preempt_disable() and
495 // thread_preempt_reenable(). It is similar to sched_reschedule(),
496 // except that it does not need to be called with thread_lock held.
thread_preempt_set_pending(void)497 static inline void thread_preempt_set_pending(void) {
498 DEBUG_ASSERT(arch_ints_disabled());
499 DEBUG_ASSERT(arch_blocking_disallowed());
500 thread_t* current_thread = get_current_thread();
501 DEBUG_ASSERT(thread_preempt_disable_count() > 0);
502
503 current_thread->preempt_pending = true;
504 }
505
506 __END_CDECLS
507
508 #ifdef __cplusplus
509
510 #include <fbl/macros.h>
511
512 // AutoReschedDisable is an RAII helper for disabling rescheduling
513 // using thread_resched_disable()/thread_resched_reenable().
514 //
515 // A typical use case is when we wake another thread while holding a
516 // mutex. If the other thread is likely to claim the same mutex when
517 // runs (either immediately or later), then it is useful to defer
518 // waking the thread until after we have released the mutex. We can
519 // do that by disabling rescheduling while holding the lock. This is
520 // beneficial when there are no free CPUs for running the woken thread
521 // on.
522 //
523 // Example usage:
524 //
525 // AutoReschedDisable resched_disable;
526 // AutoLock al(&lock_);
527 // // Do some initial computation...
528 // resched_disable.Disable();
529 // // Possibly wake another thread...
530 //
531 // The AutoReschedDisable must be placed before the AutoLock to ensure that
532 // rescheduling is re-enabled only after releasing the mutex.
533 class AutoReschedDisable {
534 public:
AutoReschedDisable()535 AutoReschedDisable() {}
~AutoReschedDisable()536 ~AutoReschedDisable() {
537 if (started_) {
538 thread_resched_reenable();
539 }
540 }
541
Disable()542 void Disable() {
543 if (!started_) {
544 thread_resched_disable();
545 started_ = true;
546 }
547 }
548
549 DISALLOW_COPY_ASSIGN_AND_MOVE(AutoReschedDisable);
550
551 private:
552 bool started_ = false;
553 };
554
555 #endif // __cplusplus
556