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