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