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 /**
9  * @file
10  * @brief  Kernel threading
11  *
12  * This file is the core kernel threading interface.
13  *
14  * @defgroup thread Threads
15  * @{
16  */
17 #include <kernel/thread.h>
18 
19 #include <arch/exception.h>
20 #include <assert.h>
21 #include <debug.h>
22 #include <err.h>
23 #include <inttypes.h>
24 
25 #include <kernel/atomic.h>
26 #include <kernel/dpc.h>
27 #include <kernel/lockdep.h>
28 #include <kernel/mp.h>
29 #include <kernel/percpu.h>
30 #include <kernel/sched.h>
31 #include <kernel/stats.h>
32 #include <kernel/thread.h>
33 #include <kernel/thread_lock.h>
34 #include <kernel/timer.h>
35 
36 #include <lib/counters.h>
37 #include <lib/heap.h>
38 #include <lib/ktrace.h>
39 
40 #include <list.h>
41 #include <malloc.h>
42 #include <object/process_dispatcher.h>
43 #include <object/thread_dispatcher.h>
44 #include <platform.h>
45 #include <printf.h>
46 #include <string.h>
47 #include <target.h>
48 #include <vm/kstack.h>
49 #include <vm/vm.h>
50 #include <vm/vm_address_region.h>
51 #include <vm/vm_aspace.h>
52 #include <zircon/time.h>
53 #include <zircon/types.h>
54 
55 #include <lockdep/lockdep.h>
56 
57 // kernel counters. TODO(cpu): remove LK-era counters
58 // The counters below never decrease.
59 //
60 // counts the number of thread_t successfully created.
61 KCOUNTER(thread_create_count, "kernel.thread.create");
62 // counts the number of thread_t joined. Never decreases.
63 KCOUNTER(thread_join_count, "kernel.thread.join");
64 // counts the number of calls to suspend() that succeeded.
65 KCOUNTER(thread_suspend_count, "kernel.thread.suspend");
66 // counts the number of calls to resume() that succeeded.
67 KCOUNTER(thread_resume_count, "kernel.thread.resume");
68 
69 // global thread list
70 static struct list_node thread_list = LIST_INITIAL_VALUE(thread_list);
71 
72 // master thread spinlock
73 spin_lock_t thread_lock __CPU_ALIGN_EXCLUSIVE = SPIN_LOCK_INITIAL_VALUE;
74 
75 // local routines
76 static void thread_exit_locked(thread_t* current_thread, int retcode) __NO_RETURN;
77 static void thread_do_suspend(void);
78 
init_thread_lock_state(thread_t * t)79 static void init_thread_lock_state(thread_t* t) {
80 #if WITH_LOCK_DEP
81     auto* state = reinterpret_cast<lockdep::ThreadLockState*>(&t->lock_state);
82     lockdep::SystemInitThreadLockState(state);
83 #endif
84 }
85 
init_thread_struct(thread_t * t,const char * name)86 static void init_thread_struct(thread_t* t, const char* name) {
87     memset(t, 0, sizeof(thread_t));
88     t->magic = THREAD_MAGIC;
89     strlcpy(t->name, name, sizeof(t->name));
90     wait_queue_init(&t->retcode_wait_queue);
91     init_thread_lock_state(t);
92 }
93 
94 static void initial_thread_func(void) TA_REQ(thread_lock) __NO_RETURN;
initial_thread_func(void)95 static void initial_thread_func(void) {
96     int ret;
97 
98     // release the thread lock that was implicitly held across the reschedule
99     spin_unlock(&thread_lock);
100     arch_enable_ints();
101 
102     thread_t* ct = get_current_thread();
103     ret = ct->entry(ct->arg);
104 
105     thread_exit(ret);
106 }
107 
108 // Invoke |t|'s user_callback with |new_state|.
109 //
110 // Since user_callback may call into the scheduler it's crucial that the scheduler lock
111 // (thread_lock) is not held when calling this function.  Otherwise, we risk recursive deadlock.
invoke_user_callback(thread_t * t,enum thread_user_state_change new_state)112 static void invoke_user_callback(thread_t* t, enum thread_user_state_change new_state)
113     TA_EXCL(thread_lock) {
114     DEBUG_ASSERT(!arch_ints_disabled() || !spin_lock_held(&thread_lock));
115     if (t->user_callback) {
116         t->user_callback(new_state, t);
117     }
118 }
119 
120 /**
121  * @brief  Create a new thread
122  *
123  * This function creates a new thread.  The thread is initially suspended, so you
124  * need to call thread_resume() to execute it.
125  *
126  * @param  t               If not NULL, use the supplied thread_t
127  * @param  name            Name of thread
128  * @param  entry           Entry point of thread
129  * @param  arg             Arbitrary argument passed to entry()
130  * @param  priority        Execution priority for the thread.
131  * @param  alt_trampoline  If not NULL, an alternate trampoline for the thread
132  *                         to start on.
133  *
134  * Thread priority is an integer from 0 (lowest) to 31 (highest).  Some standard
135  * priorities are defined in <kernel/thread.h>:
136  *
137  *  HIGHEST_PRIORITY
138  *  DPC_PRIORITY
139  *  HIGH_PRIORITY
140  *  DEFAULT_PRIORITY
141  *  LOW_PRIORITY
142  *  IDLE_PRIORITY
143  *  LOWEST_PRIORITY
144  *
145  * Stack size is set to DEFAULT_STACK_SIZE
146  *
147  * @return  Pointer to thread object, or NULL on failure.
148  */
thread_create_etc(thread_t * t,const char * name,thread_start_routine entry,void * arg,int priority,thread_trampoline_routine alt_trampoline)149 thread_t* thread_create_etc(
150     thread_t* t,
151     const char* name,
152     thread_start_routine entry, void* arg,
153     int priority,
154     thread_trampoline_routine alt_trampoline) {
155     unsigned int flags = 0;
156 
157     if (!t) {
158         t = static_cast<thread_t*>(malloc(sizeof(thread_t)));
159         if (!t) {
160             return NULL;
161         }
162         flags |= THREAD_FLAG_FREE_STRUCT;
163     }
164 
165     init_thread_struct(t, name);
166 
167     t->entry = entry;
168     t->arg = arg;
169     t->state = THREAD_INITIAL;
170     t->signals = 0;
171     t->blocking_wait_queue = NULL;
172     t->blocked_status = ZX_OK;
173     t->interruptable = false;
174     t->curr_cpu = INVALID_CPU;
175     t->last_cpu = INVALID_CPU;
176     t->cpu_affinity = CPU_MASK_ALL;
177 
178     t->retcode = 0;
179     wait_queue_init(&t->retcode_wait_queue);
180 
181     sched_init_thread(t, priority);
182 
183     zx_status_t status = vm_allocate_kstack(&t->stack);
184     if (status != ZX_OK) {
185         if (flags & THREAD_FLAG_FREE_STRUCT) {
186             free(t);
187         }
188         return nullptr;
189     }
190 
191     // save whether or not we need to free the thread struct and/or stack
192     t->flags = flags;
193 
194     if (likely(alt_trampoline == NULL)) {
195         alt_trampoline = initial_thread_func;
196     }
197 
198     // set up the initial stack frame
199     arch_thread_initialize(t, (vaddr_t)alt_trampoline);
200 
201     // add it to the global thread list
202     {
203         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
204         list_add_head(&thread_list, &t->thread_list_node);
205     }
206 
207     kcounter_add(thread_create_count, 1);
208     return t;
209 }
210 
thread_create(const char * name,thread_start_routine entry,void * arg,int priority)211 thread_t* thread_create(const char* name, thread_start_routine entry, void* arg, int priority) {
212     return thread_create_etc(NULL, name, entry, arg, priority, NULL);
213 }
214 
free_thread_resources(thread_t * t)215 static void free_thread_resources(thread_t* t) {
216     if (t->stack.vmar != nullptr) {
217 #if __has_feature(safe_stack)
218         DEBUG_ASSERT(t->stack.unsafe_vmar != nullptr);
219 #endif
220         zx_status_t status = vm_free_kstack(&t->stack);
221         DEBUG_ASSERT(status == ZX_OK);
222     }
223 
224     // call the tls callback for each slot as long there is one
225     for (uint ix = 0; ix != THREAD_MAX_TLS_ENTRY; ++ix) {
226         if (t->tls_callback[ix]) {
227             t->tls_callback[ix](t->tls[ix]);
228         }
229     }
230 
231     // free the thread structure itself
232     t->magic = 0;
233     if (t->flags & THREAD_FLAG_FREE_STRUCT) {
234         free(t);
235     }
236 }
237 
238 /**
239  * @brief Flag a thread as real time
240  *
241  * @param t Thread to flag
242  *
243  * @return ZX_OK on success
244  */
thread_set_real_time(thread_t * t)245 zx_status_t thread_set_real_time(thread_t* t) {
246     if (!t) {
247         return ZX_ERR_INVALID_ARGS;
248     }
249 
250     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
251 
252     {
253         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
254         if (t == get_current_thread()) {
255             // if we're currently running, cancel the preemption timer.
256             timer_preempt_cancel();
257         }
258         t->flags |= THREAD_FLAG_REAL_TIME;
259     }
260 
261     return ZX_OK;
262 }
263 
264 /**
265  * @brief  Make a suspended thread executable.
266  *
267  * This function is called to start a thread which has just been
268  * created with thread_create() or which has been suspended with
269  * thread_suspend(). It can not fail.
270  *
271  * @param t  Thread to resume
272  */
thread_resume(thread_t * t)273 void thread_resume(thread_t* t) {
274     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
275 
276     bool ints_disabled = arch_ints_disabled();
277     bool resched = false;
278     if (!ints_disabled) { // HACK, don't resced into bootstrap thread before idle thread is set up
279         resched = true;
280     }
281 
282     {
283         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
284 
285         if (t->state == THREAD_DEATH) {
286             // The thread is dead, resuming it is a no-op.
287             return;
288         }
289 
290         // Clear the suspend signal in case there is a pending suspend
291         t->signals &= ~THREAD_SIGNAL_SUSPEND;
292 
293         if (t->state == THREAD_INITIAL || t->state == THREAD_SUSPENDED) {
294             // wake up the new thread, putting it in a run queue on a cpu. reschedule if the local
295             // cpu run queue was modified
296             bool local_resched = sched_unblock(t);
297             if (resched && local_resched) {
298                 sched_reschedule();
299             }
300         }
301     }
302 
303     kcounter_add(thread_resume_count, 1);
304 }
305 
thread_detach_and_resume(thread_t * t)306 zx_status_t thread_detach_and_resume(thread_t* t) {
307     zx_status_t err;
308     err = thread_detach(t);
309     if (err < 0) {
310         return err;
311     }
312     thread_resume(t);
313     return ZX_OK;
314 }
315 
316 /**
317  * @brief  Suspend an initialized/ready/running thread
318  *
319  * @param t  Thread to suspend
320  *
321  * @return ZX_OK on success, ZX_ERR_BAD_STATE if the thread is dead
322  */
thread_suspend(thread_t * t)323 zx_status_t thread_suspend(thread_t* t) {
324     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
325     DEBUG_ASSERT(!thread_is_idle(t));
326 
327     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
328 
329     if (t->state == THREAD_DEATH) {
330         return ZX_ERR_BAD_STATE;
331     }
332 
333     t->signals |= THREAD_SIGNAL_SUSPEND;
334 
335     bool local_resched = false;
336     switch (t->state) {
337     case THREAD_DEATH:
338         // This should be unreachable because this state was handled above.
339         panic("Unexpected thread state");
340     case THREAD_INITIAL:
341         // Thread hasn't been started yet, add it to the run queue to transition
342         // properly through the INITIAL -> READY state machine first, then it
343         // will see the signal and go to SUSPEND before running user code.
344         //
345         // Though the state here is still INITIAL, the higher-level code has
346         // already executed ThreadDispatcher::Start() so all the userspace
347         // entry data has been initialized and will be ready to go as soon as
348         // the thread is unsuspended.
349         local_resched = sched_unblock(t);
350         break;
351     case THREAD_READY:
352         // thread is ready to run and not blocked or suspended.
353         // will wake up and deal with the signal soon.
354         break;
355     case THREAD_RUNNING:
356         // thread is running (on another cpu)
357         // The following call is not essential.  It just makes the
358         // thread suspension happen sooner rather than at the next
359         // timer interrupt or syscall.
360         mp_reschedule(cpu_num_to_mask(t->curr_cpu), 0);
361         break;
362     case THREAD_SUSPENDED:
363         // thread is suspended already
364         break;
365     case THREAD_BLOCKED:
366         // thread is blocked on something and marked interruptable
367         if (t->interruptable) {
368             wait_queue_unblock_thread(t, ZX_ERR_INTERNAL_INTR_RETRY);
369         }
370         break;
371     case THREAD_SLEEPING:
372         // thread is sleeping
373         if (t->interruptable) {
374             t->blocked_status = ZX_ERR_INTERNAL_INTR_RETRY;
375 
376             local_resched = sched_unblock(t);
377         }
378         break;
379     }
380 
381     // reschedule if the local cpu run queue was modified
382     if (local_resched) {
383         sched_reschedule();
384     }
385 
386     kcounter_add(thread_suspend_count, 1);
387     return ZX_OK;
388 }
389 
390 // Signal an exception on the current thread, to be handled when the
391 // current syscall exits.  Unlike other signals, this is synchronous, in
392 // the sense that a thread signals itself.  This exists primarily so that
393 // we can unwind the stack in order to get the state of userland's
394 // callee-saved registers at the point where userland invoked the
395 // syscall.
thread_signal_policy_exception(void)396 void thread_signal_policy_exception(void) {
397     thread_t* t = get_current_thread();
398     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
399     t->signals |= THREAD_SIGNAL_POLICY_EXCEPTION;
400 }
401 
thread_join(thread_t * t,int * retcode,zx_time_t deadline)402 zx_status_t thread_join(thread_t* t, int* retcode, zx_time_t deadline) {
403     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
404 
405     {
406         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
407 
408         if (t->flags & THREAD_FLAG_DETACHED) {
409             // the thread is detached, go ahead and exit
410             return ZX_ERR_BAD_STATE;
411         }
412 
413         // wait for the thread to die
414         if (t->state != THREAD_DEATH) {
415             zx_status_t err = wait_queue_block(&t->retcode_wait_queue, deadline);
416             if (err < 0) {
417                 return err;
418             }
419         }
420 
421         DEBUG_ASSERT(t->magic == THREAD_MAGIC);
422         DEBUG_ASSERT(t->state == THREAD_DEATH);
423         DEBUG_ASSERT(t->blocking_wait_queue == NULL);
424         DEBUG_ASSERT(!list_in_list(&t->queue_node));
425 
426         // save the return code
427         if (retcode) {
428             *retcode = t->retcode;
429         }
430 
431         // remove it from the master thread list
432         list_delete(&t->thread_list_node);
433 
434         // clear the structure's magic
435         t->magic = 0;
436     }
437 
438     free_thread_resources(t);
439 
440     kcounter_add(thread_join_count, 1);
441 
442     return ZX_OK;
443 }
444 
thread_detach(thread_t * t)445 zx_status_t thread_detach(thread_t* t) {
446     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
447 
448     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
449 
450     // if another thread is blocked inside thread_join() on this thread,
451     // wake them up with a specific return code
452     wait_queue_wake_all(&t->retcode_wait_queue, false, ZX_ERR_BAD_STATE);
453 
454     // if it's already dead, then just do what join would have and exit
455     if (t->state == THREAD_DEATH) {
456         t->flags &= ~THREAD_FLAG_DETACHED; // makes sure thread_join continues
457         guard.Release();
458         return thread_join(t, NULL, 0);
459     } else {
460         t->flags |= THREAD_FLAG_DETACHED;
461         return ZX_OK;
462     }
463 }
464 
465 // called back in the DPC worker thread to free the stack and/or the thread structure
466 // itself for a thread that is exiting on its own.
thread_free_dpc(struct dpc * dpc)467 static void thread_free_dpc(struct dpc* dpc) {
468     thread_t* t = (thread_t*)dpc->arg;
469 
470     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
471     DEBUG_ASSERT(t->state == THREAD_DEATH);
472 
473     // grab and release the thread lock, which effectively serializes us with
474     // the thread that is queuing itself for destruction.
475     {
476         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
477         atomic_signal_fence();
478     }
479 
480     free_thread_resources(t);
481 }
482 
thread_exit_locked(thread_t * current_thread,int retcode)483 __NO_RETURN static void thread_exit_locked(thread_t* current_thread,
484                                            int retcode) TA_REQ(thread_lock) {
485     // create a dpc on the stack to queue up a free.
486     // must be put at top scope in this function to force the compiler to keep it from
487     // reusing the stack before the function exits
488     dpc_t free_dpc = DPC_INITIAL_VALUE;
489 
490     // enter the dead state
491     current_thread->state = THREAD_DEATH;
492     current_thread->retcode = retcode;
493 
494     // if we're detached, then do our teardown here
495     if (current_thread->flags & THREAD_FLAG_DETACHED) {
496         // remove it from the master thread list
497         list_delete(&current_thread->thread_list_node);
498 
499         // queue a dpc to free the stack and, optionally, the thread structure
500         if (current_thread->stack.base || (current_thread->flags & THREAD_FLAG_FREE_STRUCT)) {
501             free_dpc.func = thread_free_dpc;
502             free_dpc.arg = (void*)current_thread;
503             zx_status_t status = dpc_queue_thread_locked(&free_dpc);
504             DEBUG_ASSERT(status == ZX_OK);
505         }
506     } else {
507         // signal if anyone is waiting
508         wait_queue_wake_all(&current_thread->retcode_wait_queue, false, 0);
509     }
510 
511     // reschedule
512     sched_resched_internal();
513 
514     panic("somehow fell through thread_exit()\n");
515 }
516 
517 /**
518  * @brief Remove this thread from the scheduler, discarding
519  * its execution state.
520  *
521  * This is almost certainly not the function you want.  In the general case,
522  * this is incredibly unsafe.
523  *
524  * This will free any resources allocated by thread_create.
525  */
thread_forget(thread_t * t)526 void thread_forget(thread_t* t) {
527     {
528         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
529 
530         __UNUSED thread_t* current_thread = get_current_thread();
531         DEBUG_ASSERT(current_thread != t);
532 
533         list_delete(&t->thread_list_node);
534     }
535 
536     DEBUG_ASSERT(!list_in_list(&t->queue_node));
537 
538     free_thread_resources(t);
539 }
540 
541 /**
542  * @brief  Terminate the current thread
543  *
544  * Current thread exits with the specified return code.
545  *
546  * This function does not return.
547  */
thread_exit(int retcode)548 void thread_exit(int retcode) {
549     thread_t* current_thread = get_current_thread();
550 
551     DEBUG_ASSERT(current_thread->magic == THREAD_MAGIC);
552     DEBUG_ASSERT(current_thread->state == THREAD_RUNNING);
553     DEBUG_ASSERT(!thread_is_idle(current_thread));
554 
555     invoke_user_callback(current_thread, THREAD_USER_STATE_EXIT);
556 
557     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
558     thread_exit_locked(current_thread, retcode);
559 }
560 
561 // kill a thread
thread_kill(thread_t * t)562 void thread_kill(thread_t* t) {
563     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
564 
565     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
566 
567     // deliver a signal to the thread.
568     // NOTE: it's not important to do this atomically, since we're inside
569     // the thread lock, but go ahead and flush it out to memory to avoid the amount
570     // of races if another thread is looking at this.
571     t->signals |= THREAD_SIGNAL_KILL;
572     smp_mb();
573 
574     bool local_resched = false;
575 
576     // we are killing ourself
577     if (t == get_current_thread()) {
578         return;
579     }
580 
581     // general logic is to wake up the thread so it notices it had a signal delivered to it
582 
583     switch (t->state) {
584     case THREAD_INITIAL:
585         // thread hasn't been started yet.
586         // not really safe to wake it up, since it's only in this state because it's under
587         // construction by the creator thread.
588         break;
589     case THREAD_READY:
590         // thread is ready to run and not blocked or suspended.
591         // will wake up and deal with the signal soon.
592         // TODO: short circuit if it was blocked from user space
593         break;
594     case THREAD_RUNNING:
595         // thread is running (on another cpu).
596         // The following call is not essential.  It just makes the
597         // thread termination happen sooner rather than at the next
598         // timer interrupt or syscall.
599         mp_reschedule(cpu_num_to_mask(t->curr_cpu), 0);
600         break;
601     case THREAD_SUSPENDED:
602         // thread is suspended, resume it so it can get the kill signal
603         local_resched = sched_unblock(t);
604         break;
605     case THREAD_BLOCKED:
606         // thread is blocked on something and marked interruptable
607         if (t->interruptable) {
608             wait_queue_unblock_thread(t, ZX_ERR_INTERNAL_INTR_KILLED);
609         }
610         break;
611     case THREAD_SLEEPING:
612         // thread is sleeping
613         if (t->interruptable) {
614             t->blocked_status = ZX_ERR_INTERNAL_INTR_KILLED;
615 
616             local_resched = sched_unblock(t);
617         }
618         break;
619     case THREAD_DEATH:
620         // thread is already dead
621         return;
622     }
623 
624     if (local_resched) {
625         // reschedule if the local cpu run queue was modified
626         sched_reschedule();
627     }
628 }
629 
630 // Sets the cpu affinity mask of a thread to the passed in mask and migrate
631 // the thread if active.
thread_set_cpu_affinity(thread_t * t,cpu_mask_t affinity)632 void thread_set_cpu_affinity(thread_t* t, cpu_mask_t affinity) {
633     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
634 
635     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
636 
637     // make sure the passed in mask is valid and at least one cpu can run the thread
638     if (affinity & mp_get_active_mask()) {
639         // set the affinity mask
640         t->cpu_affinity = affinity;
641 
642         // let the scheduler deal with it
643         sched_migrate(t);
644     }
645 }
646 
thread_migrate_to_cpu(const cpu_num_t target_cpu)647 void thread_migrate_to_cpu(const cpu_num_t target_cpu) {
648     thread_set_cpu_affinity(get_current_thread(), cpu_num_to_mask(target_cpu));
649 }
650 
651 // Returns true if it decides to kill the thread. The thread_lock must be held
652 // when calling this function.
check_kill_signal(thread_t * current_thread)653 static bool check_kill_signal(thread_t* current_thread) TA_REQ(thread_lock) {
654     DEBUG_ASSERT(arch_ints_disabled());
655     DEBUG_ASSERT(spin_lock_held(&thread_lock));
656 
657     if (current_thread->signals & THREAD_SIGNAL_KILL) {
658         // Ensure we don't recurse into thread_exit.
659         DEBUG_ASSERT(current_thread->state != THREAD_DEATH);
660         return true;
661     } else {
662         return false;
663     }
664 }
665 
666 // finish suspending the current thread
thread_do_suspend(void)667 static void thread_do_suspend(void) {
668     thread_t* current_thread = get_current_thread();
669     // Note: After calling this callback, we must not return without
670     // calling the callback with THREAD_USER_STATE_RESUME.  That is
671     // because those callbacks act as barriers which control when it is
672     // safe for the zx_thread_read_state()/zx_thread_write_state()
673     // syscalls to access the userland register state kept by thread_t.
674     invoke_user_callback(current_thread, THREAD_USER_STATE_SUSPEND);
675 
676     {
677         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
678 
679         // make sure we haven't been killed while the lock was dropped for the user callback
680         if (check_kill_signal(current_thread)) {
681             guard.Release();
682             thread_exit(0);
683         }
684 
685         // Make sure the suspend signal wasn't cleared while we were running the
686         // callback.
687         if (current_thread->signals & THREAD_SIGNAL_SUSPEND) {
688             current_thread->state = THREAD_SUSPENDED;
689             current_thread->signals &= ~THREAD_SIGNAL_SUSPEND;
690 
691             // directly invoke the context switch, since we've already manipulated this thread's state
692             sched_resched_internal();
693 
694             // If the thread was killed, we should not allow it to resume.  We
695             // shouldn't call user_callback() with THREAD_USER_STATE_RESUME in
696             // this case, because there might not have been any request to
697             // resume the thread.
698             if (check_kill_signal(current_thread)) {
699                 guard.Release();
700                 thread_exit(0);
701             }
702         }
703     }
704 
705     invoke_user_callback(current_thread, THREAD_USER_STATE_RESUME);
706 }
707 
708 // check for any pending signals and handle them
thread_process_pending_signals(void)709 void thread_process_pending_signals(void) {
710     thread_t* current_thread = get_current_thread();
711     if (likely(current_thread->signals == 0)) {
712         return;
713     }
714 
715     // grab the thread lock so we can safely look at the signal mask
716     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
717     if (check_kill_signal(current_thread)) {
718         guard.Release();
719         thread_exit(0);
720     }
721 
722     // Report exceptions raised by syscalls
723     if (current_thread->signals & THREAD_SIGNAL_POLICY_EXCEPTION) {
724         current_thread->signals &= ~THREAD_SIGNAL_POLICY_EXCEPTION;
725         guard.Release();
726 
727         zx_status_t status = arch_dispatch_user_policy_exception();
728         if (status != ZX_OK) {
729             panic("arch_dispatch_user_policy_exception() failed: status=%d\n",
730                   status);
731         }
732         return;
733     }
734 
735     if (current_thread->signals & THREAD_SIGNAL_SUSPEND) {
736         // transition the thread to the suspended state
737         DEBUG_ASSERT(current_thread->state == THREAD_RUNNING);
738         guard.Release();
739 
740         thread_do_suspend();
741     }
742 }
743 
744 /**
745  * @brief Yield the cpu to another thread
746  *
747  * This function places the current thread at the end of the run queue
748  * and yields the cpu to another waiting thread (if any.)
749  *
750  * This function will return at some later time. Possibly immediately if
751  * no other threads are waiting to execute.
752  */
thread_yield(void)753 void thread_yield(void) {
754     __UNUSED thread_t* current_thread = get_current_thread();
755 
756     DEBUG_ASSERT(current_thread->magic == THREAD_MAGIC);
757     DEBUG_ASSERT(current_thread->state == THREAD_RUNNING);
758     DEBUG_ASSERT(!arch_blocking_disallowed());
759 
760     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
761 
762     CPU_STATS_INC(yields);
763     sched_yield();
764 }
765 
766 /**
767  * @brief Preempt the current thread from an interrupt
768  *
769  * This function places the current thread at the head of the run
770  * queue and then yields the cpu to another thread.
771  */
thread_preempt(void)772 void thread_preempt(void) {
773     thread_t* current_thread = get_current_thread();
774 
775     DEBUG_ASSERT(current_thread->magic == THREAD_MAGIC);
776     DEBUG_ASSERT(current_thread->state == THREAD_RUNNING);
777     DEBUG_ASSERT(!arch_blocking_disallowed());
778 
779     if (!thread_is_idle(current_thread)) {
780         // only track when a meaningful preempt happens
781         CPU_STATS_INC(irq_preempts);
782     }
783 
784     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
785 
786     sched_preempt();
787 }
788 
789 /**
790  * @brief Reevaluate the run queue on the current cpu.
791  *
792  * This function places the current thread at the head of the run
793  * queue and then yields the cpu to another thread. Similar to
794  * thread_preempt, but intended to be used at non interrupt context.
795  */
thread_reschedule(void)796 void thread_reschedule(void) {
797     thread_t* current_thread = get_current_thread();
798 
799     DEBUG_ASSERT(current_thread->magic == THREAD_MAGIC);
800     DEBUG_ASSERT(current_thread->state == THREAD_RUNNING);
801     DEBUG_ASSERT(!arch_blocking_disallowed());
802 
803     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
804 
805     sched_reschedule();
806 }
807 
thread_check_preempt_pending(void)808 void thread_check_preempt_pending(void) {
809     thread_t* current_thread = get_current_thread();
810 
811     // First check preempt_pending without the expense of taking the lock.
812     // At this point, interrupts could be enabled, so an interrupt handler
813     // might preempt us and set preempt_pending to false after we read it.
814     if (unlikely(current_thread->preempt_pending)) {
815         Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
816         // Recheck preempt_pending just in case it got set to false after
817         // our earlier check.  Its value now cannot change because
818         // interrupts are now disabled.
819         if (likely(current_thread->preempt_pending)) {
820             // This will set preempt_pending = false for us.
821             sched_reschedule();
822         }
823     }
824 }
825 
826 // timer callback to wake up a sleeping thread
thread_sleep_handler(timer_t * timer,zx_time_t now,void * arg)827 static void thread_sleep_handler(timer_t* timer, zx_time_t now, void* arg) {
828     thread_t* t = (thread_t*)arg;
829 
830     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
831 
832     // spin trylocking on the thread lock since the routine that set up the callback,
833     // thread_sleep_etc, may be trying to simultaneously cancel this timer while holding the
834     // thread_lock.
835     if (timer_trylock_or_cancel(timer, &thread_lock)) {
836         return;
837     }
838 
839     if (t->state != THREAD_SLEEPING) {
840         spin_unlock(&thread_lock);
841         return;
842     }
843 
844     t->blocked_status = ZX_OK;
845 
846     // unblock the thread
847     if (sched_unblock(t)) {
848         sched_reschedule();
849     }
850 
851     spin_unlock(&thread_lock);
852 }
853 
854 #define MIN_SLEEP_SLACK ZX_USEC(1)
855 #define MAX_SLEEP_SLACK ZX_SEC(1)
856 #define DIV_SLEEP_SLACK 10u
857 
858 // computes the amount of slack the thread_sleep timer will use
sleep_slack(zx_time_t deadline,zx_time_t now)859 static zx_duration_t sleep_slack(zx_time_t deadline, zx_time_t now) {
860     if (deadline < now) {
861         return MIN_SLEEP_SLACK;
862     }
863     zx_duration_t slack = zx_time_sub_time(deadline, now) / DIV_SLEEP_SLACK;
864     return MAX(MIN_SLEEP_SLACK, MIN(slack, MAX_SLEEP_SLACK));
865 }
866 
867 /**
868  * @brief  Put thread to sleep; deadline specified in ns
869  *
870  * This function puts the current thread to sleep until the specified
871  * slack-adjusted deadline has occurred.
872  *
873  * Note that this function could continue to sleep after the specified deadline
874  * if other threads are running.  When the deadline occurrs, this thread will
875  * be placed at the head of the run queue.
876  *
877  * interruptable argument allows this routine to return early if the thread was signaled
878  * for something.
879  */
thread_sleep_etc(zx_time_t deadline,TimerSlack slack,bool interruptable,zx_time_t now)880 zx_status_t thread_sleep_etc(zx_time_t deadline,
881                              TimerSlack slack,
882                              bool interruptable,
883                              zx_time_t now) {
884 
885     thread_t* current_thread = get_current_thread();
886 
887     DEBUG_ASSERT(current_thread->magic == THREAD_MAGIC);
888     DEBUG_ASSERT(current_thread->state == THREAD_RUNNING);
889     DEBUG_ASSERT(!thread_is_idle(current_thread));
890     DEBUG_ASSERT(!arch_blocking_disallowed());
891 
892     // Skip all of the work if the deadline has already passed.
893     if (deadline <= now) {
894         return ZX_OK;
895     }
896 
897     timer_t timer;
898     timer_init(&timer);
899 
900     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
901 
902     // if we've been killed and going in interruptable, abort here
903     if (interruptable && unlikely((current_thread->signals))) {
904         if (current_thread->signals & THREAD_SIGNAL_KILL) {
905             return ZX_ERR_INTERNAL_INTR_KILLED;
906         } else {
907             return ZX_ERR_INTERNAL_INTR_RETRY;
908         }
909     }
910 
911     // set a one shot timer to wake us up and reschedule
912     timer_set(&timer, deadline, slack, thread_sleep_handler, current_thread);
913 
914     current_thread->state = THREAD_SLEEPING;
915     current_thread->blocked_status = ZX_OK;
916 
917     current_thread->interruptable = interruptable;
918     sched_block();
919     current_thread->interruptable = false;
920 
921     // always cancel the timer, since we may be racing with the timer tick on other cpus
922     timer_cancel(&timer);
923 
924     return current_thread->blocked_status;
925 }
926 
thread_sleep(zx_time_t deadline)927 zx_status_t thread_sleep(zx_time_t deadline) {
928     const zx_time_t now = current_time();
929     return thread_sleep_etc(deadline, kNoSlack, false, now);
930 }
931 
thread_sleep_relative(zx_duration_t delay)932 zx_status_t thread_sleep_relative(zx_duration_t delay) {
933     const zx_time_t now = current_time();
934     const zx_time_t deadline = zx_time_add_duration(now, delay);
935     return thread_sleep_etc(deadline, kNoSlack, false, now);
936 }
937 
thread_sleep_interruptable(zx_time_t deadline)938 zx_status_t thread_sleep_interruptable(zx_time_t deadline) {
939     const zx_time_t now = current_time();
940     const TimerSlack slack{sleep_slack(deadline, now), TIMER_SLACK_LATE};
941     return thread_sleep_etc(deadline, slack, true, now);
942 }
943 
944 /**
945  * @brief Return the number of nanoseconds a thread has been running for.
946  *
947  * This takes the thread_lock to ensure there are no races while calculating the
948  * runtime of the thread.
949  */
thread_runtime(const thread_t * t)950 zx_duration_t thread_runtime(const thread_t* t) {
951     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
952 
953     zx_duration_t runtime = t->runtime_ns;
954     if (t->state == THREAD_RUNNING) {
955         zx_duration_t recent = zx_time_sub_time(current_time(), t->last_started_running);
956         runtime = zx_duration_add_duration(runtime, recent);
957     }
958 
959     return runtime;
960 }
961 
962 /**
963  * @brief Construct a thread t around the current running state
964  *
965  * This should be called once per CPU initialization.  It will create
966  * a thread that is pinned to the current CPU and running at the
967  * highest priority.
968  */
thread_construct_first(thread_t * t,const char * name)969 void thread_construct_first(thread_t* t, const char* name) {
970     DEBUG_ASSERT(arch_ints_disabled());
971 
972     cpu_num_t cpu = arch_curr_cpu_num();
973 
974     init_thread_struct(t, name);
975     t->state = THREAD_RUNNING;
976     t->flags = THREAD_FLAG_DETACHED;
977     t->signals = 0;
978     t->curr_cpu = cpu;
979     t->last_cpu = cpu;
980     t->cpu_affinity = cpu_num_to_mask(cpu);
981     sched_init_thread(t, HIGHEST_PRIORITY);
982 
983     arch_thread_construct_first(t);
984     set_current_thread(t);
985 
986     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
987     list_add_head(&thread_list, &t->thread_list_node);
988 }
989 
990 /**
991  * @brief  Initialize threading system
992  *
993  * This function is called once, from kmain()
994  */
thread_init_early(void)995 void thread_init_early(void) {
996     DEBUG_ASSERT(arch_curr_cpu_num() == 0);
997 
998     // create a thread to cover the current running state
999     thread_t* t = &percpu[0].idle_thread;
1000     thread_construct_first(t, "bootstrap");
1001 
1002 #if WITH_LOCK_DEP
1003     // Initialize the lockdep tracking state for irq context.
1004     for (unsigned int cpu = 0; cpu < SMP_MAX_CPUS; cpu++) {
1005         auto* state = reinterpret_cast<lockdep::ThreadLockState*>(&percpu[cpu].lock_state);
1006         lockdep::SystemInitThreadLockState(state);
1007     }
1008 #endif
1009 
1010     sched_init_early();
1011 }
1012 
1013 /**
1014  * @brief Change name of current thread
1015  */
thread_set_name(const char * name)1016 void thread_set_name(const char* name) {
1017     thread_t* current_thread = get_current_thread();
1018     strlcpy(current_thread->name, name, sizeof(current_thread->name));
1019 }
1020 
1021 /**
1022  * @brief Set the callback pointer to a function called on user thread state
1023  *        changes (e.g. exit, suspend, resume)
1024  */
thread_set_user_callback(thread_t * t,thread_user_callback_t cb)1025 void thread_set_user_callback(thread_t* t, thread_user_callback_t cb) {
1026     DEBUG_ASSERT(t->state == THREAD_INITIAL);
1027     t->user_callback = cb;
1028 }
1029 
1030 /**
1031  * @brief Change priority of current thread
1032  *
1033  * See thread_create() for a discussion of priority values.
1034  */
thread_set_priority(thread_t * t,int priority)1035 void thread_set_priority(thread_t* t, int priority) {
1036     DEBUG_ASSERT(t->magic == THREAD_MAGIC);
1037 
1038     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
1039 
1040     if (priority <= IDLE_PRIORITY) {
1041         priority = IDLE_PRIORITY + 1;
1042     }
1043     if (priority > HIGHEST_PRIORITY) {
1044         priority = HIGHEST_PRIORITY;
1045     }
1046 
1047     sched_change_priority(t, priority);
1048 }
1049 
1050 /**
1051  * @brief  Become an idle thread
1052  *
1053  * This function marks the current thread as the idle thread -- the one which
1054  * executes when there is nothing else to do.  This function does not return.
1055  * This thread is called once at boot on the first cpu.
1056  */
thread_become_idle(void)1057 void thread_become_idle(void) {
1058     DEBUG_ASSERT(arch_ints_disabled());
1059 
1060     thread_t* t = get_current_thread();
1061     cpu_num_t curr_cpu = arch_curr_cpu_num();
1062 
1063     // Set our name
1064     char name[16];
1065     snprintf(name, sizeof(name), "idle %u", curr_cpu);
1066     thread_set_name(name);
1067 
1068     // Mark ourself as idle
1069     t->flags |= THREAD_FLAG_IDLE;
1070     sched_init_thread(t, IDLE_PRIORITY);
1071 
1072     // Pin the thread on the current cpu and mark it as already running
1073     t->last_cpu = curr_cpu;
1074     t->curr_cpu = curr_cpu;
1075     t->cpu_affinity = cpu_num_to_mask(curr_cpu);
1076 
1077     // Cpu is active now
1078     mp_set_curr_cpu_active(true);
1079 
1080     // Grab the thread lock, mark ourself idle and reschedule
1081     {
1082         Guard<spin_lock_t, NoIrqSave> guard{ThreadLock::Get()};
1083 
1084         mp_set_cpu_idle(curr_cpu);
1085 
1086         sched_reschedule();
1087     }
1088 
1089     // We're now properly in the idle routine. Reenable interrupts and drop
1090     // into the idle routine, never return.
1091     arch_enable_ints();
1092     arch_idle_thread_routine(NULL);
1093 
1094     __UNREACHABLE;
1095 }
1096 
1097 /**
1098  * @brief Create a thread around the current execution context, preserving |t|'s stack
1099  *
1100  * Prior to calling, |t->stack| must be properly constructed. See |vm_allocate_kstack|.
1101  */
thread_secondary_cpu_init_early(thread_t * t)1102 void thread_secondary_cpu_init_early(thread_t* t) {
1103     DEBUG_ASSERT(arch_ints_disabled());
1104     DEBUG_ASSERT(t->stack.base != 0);
1105 
1106     // Save |t|'s stack because |thread_construct_first| will zero out the whole struct.
1107     kstack_t stack = t->stack;
1108 
1109     char name[16];
1110     snprintf(name, sizeof(name), "cpu_init %u", arch_curr_cpu_num());
1111     thread_construct_first(t, name);
1112 
1113     // Restore the stack.
1114     t->stack = stack;
1115 }
1116 
1117 /**
1118  * @brief The last routine called on the secondary cpu's bootstrap thread.
1119  */
thread_secondary_cpu_entry(void)1120 void thread_secondary_cpu_entry(void) {
1121     mp_set_curr_cpu_active(true);
1122 
1123     dpc_init_for_cpu();
1124 
1125     // Exit from our bootstrap thread, and enter the scheduler on this cpu
1126     thread_exit(0);
1127 }
1128 
1129 /**
1130  * @brief Create an idle thread for a secondary CPU
1131  */
thread_create_idle_thread(cpu_num_t cpu_num)1132 thread_t* thread_create_idle_thread(cpu_num_t cpu_num) {
1133     DEBUG_ASSERT(cpu_num != 0 && cpu_num < SMP_MAX_CPUS);
1134 
1135     // Shouldn't be initialized yet
1136     DEBUG_ASSERT(percpu[cpu_num].idle_thread.magic != THREAD_MAGIC);
1137 
1138     char name[16];
1139     snprintf(name, sizeof(name), "idle %u", cpu_num);
1140 
1141     thread_t* t = thread_create_etc(
1142         &percpu[cpu_num].idle_thread, name,
1143         arch_idle_thread_routine, NULL,
1144         IDLE_PRIORITY, NULL);
1145     if (t == NULL) {
1146         return t;
1147     }
1148     t->flags |= THREAD_FLAG_IDLE | THREAD_FLAG_DETACHED;
1149     t->cpu_affinity = cpu_num_to_mask(cpu_num);
1150 
1151     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
1152     sched_unblock_idle(t);
1153     return t;
1154 }
1155 
1156 /**
1157  * @brief Return the name of the "owner" of the thread.
1158  *
1159  * Returns "kernel" if there is no owner.
1160  */
1161 
thread_owner_name(thread_t * t,char out_name[THREAD_NAME_LENGTH])1162 void thread_owner_name(thread_t* t, char out_name[THREAD_NAME_LENGTH]) {
1163     if (t->user_thread) {
1164         t->user_thread->process()->get_name(out_name);
1165         return;
1166     }
1167     memcpy(out_name, "kernel", 7);
1168 }
1169 
thread_state_to_str(enum thread_state state)1170 static const char* thread_state_to_str(enum thread_state state) {
1171     switch (state) {
1172     case THREAD_INITIAL:
1173         return "init";
1174     case THREAD_SUSPENDED:
1175         return "susp";
1176     case THREAD_READY:
1177         return "rdy";
1178     case THREAD_RUNNING:
1179         return "run";
1180     case THREAD_BLOCKED:
1181         return "blok";
1182     case THREAD_SLEEPING:
1183         return "slep";
1184     case THREAD_DEATH:
1185         return "deth";
1186     default:
1187         return "unkn";
1188     }
1189 }
1190 
1191 /**
1192  * @brief  Dump debugging info about the specified thread.
1193  */
dump_thread_locked(thread_t * t,bool full_dump)1194 void dump_thread_locked(thread_t* t, bool full_dump) {
1195     if (t->magic != THREAD_MAGIC) {
1196         dprintf(INFO, "dump_thread WARNING: thread at %p has bad magic\n", t);
1197     }
1198 
1199     zx_duration_t runtime = t->runtime_ns;
1200     if (t->state == THREAD_RUNNING) {
1201         zx_duration_t recent = zx_time_sub_time(current_time(), t->last_started_running);
1202         runtime = zx_duration_add_duration(runtime, recent);
1203     }
1204 
1205     char oname[THREAD_NAME_LENGTH];
1206     thread_owner_name(t, oname);
1207 
1208     if (full_dump) {
1209         dprintf(INFO, "dump_thread: t %p (%s:%s)\n", t, oname, t->name);
1210         dprintf(INFO, "\tstate %s, curr/last cpu %d/%d, cpu_affinity %#x, priority %d [%d:%d,%d], "
1211                       "remaining time slice %" PRIi64 "\n",
1212                 thread_state_to_str(t->state), (int)t->curr_cpu, (int)t->last_cpu, t->cpu_affinity,
1213                 t->effec_priority, t->base_priority,
1214                 t->priority_boost, t->inherited_priority, t->remaining_time_slice);
1215         dprintf(INFO, "\truntime_ns %" PRIi64 ", runtime_s %" PRIi64 "\n",
1216                 runtime, runtime / 1000000000);
1217         dprintf(INFO, "\tstack.base 0x%lx, stack.vmar %p, stack.size %zu\n",
1218                 t->stack.base, t->stack.vmar, t->stack.size);
1219 #if __has_feature(safe_stack)
1220         dprintf(INFO, "\tstack.unsafe_base 0x%lx, stack.unsafe_vmar %p\n",
1221                 t->stack.unsafe_base, t->stack.unsafe_vmar);
1222 #endif
1223         dprintf(INFO, "\tentry %p, arg %p, flags 0x%x %s%s%s%s\n", t->entry, t->arg, t->flags,
1224                 (t->flags & THREAD_FLAG_DETACHED) ? "Dt" : "",
1225                 (t->flags & THREAD_FLAG_FREE_STRUCT) ? "Ft" : "",
1226                 (t->flags & THREAD_FLAG_REAL_TIME) ? "Rt" : "",
1227                 (t->flags & THREAD_FLAG_IDLE) ? "Id" : "");
1228         dprintf(INFO, "\twait queue %p, blocked_status %d, interruptable %d, mutexes held %d\n",
1229                 t->blocking_wait_queue, t->blocked_status, t->interruptable, t->mutexes_held);
1230         dprintf(INFO, "\taspace %p\n", t->aspace);
1231         dprintf(INFO, "\tuser_thread %p, pid %" PRIu64 ", tid %" PRIu64 "\n",
1232                 t->user_thread, t->user_pid, t->user_tid);
1233         arch_dump_thread(t);
1234     } else {
1235         printf("thr %p st %4s m %d pri %2d [%d:%d,%d] pid %" PRIu64 " tid %" PRIu64 " (%s:%s)\n",
1236                t, thread_state_to_str(t->state), t->mutexes_held, t->effec_priority, t->base_priority,
1237                t->priority_boost, t->inherited_priority, t->user_pid,
1238                t->user_tid, oname, t->name);
1239     }
1240 }
1241 
dump_thread(thread_t * t,bool full)1242 void dump_thread(thread_t* t, bool full) {
1243     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
1244     dump_thread_locked(t, full);
1245 }
1246 
1247 /**
1248  * @brief  Dump debugging info about all threads
1249  */
dump_all_threads_locked(bool full)1250 void dump_all_threads_locked(bool full) {
1251     thread_t* t;
1252 
1253     list_for_every_entry (&thread_list, t, thread_t, thread_list_node) {
1254         if (t->magic != THREAD_MAGIC) {
1255             dprintf(INFO, "bad magic on thread struct %p, aborting.\n", t);
1256             hexdump(t, sizeof(thread_t));
1257             break;
1258         }
1259         dump_thread_locked(t, full);
1260     }
1261 }
1262 
dump_all_threads(bool full)1263 void dump_all_threads(bool full) {
1264     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
1265     dump_all_threads_locked(full);
1266 }
1267 
dump_thread_user_tid(uint64_t tid,bool full)1268 void dump_thread_user_tid(uint64_t tid, bool full) {
1269     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
1270     dump_thread_user_tid_locked(tid, full);
1271 }
1272 
dump_thread_user_tid_locked(uint64_t tid,bool full)1273 void dump_thread_user_tid_locked(uint64_t tid, bool full) {
1274     thread_t* t;
1275 
1276     list_for_every_entry (&thread_list, t, thread_t, thread_list_node) {
1277         if (t->user_tid != tid) {
1278             continue;
1279         }
1280 
1281         if (t->magic != THREAD_MAGIC) {
1282             dprintf(INFO, "bad magic on thread struct %p, aborting.\n", t);
1283             hexdump(t, sizeof(thread_t));
1284             break;
1285         }
1286         dump_thread_locked(t, full);
1287     }
1288 }
1289 
thread_id_to_thread_slow(uint64_t tid)1290 thread_t* thread_id_to_thread_slow(uint64_t tid) {
1291     thread_t* t;
1292     list_for_every_entry (&thread_list, t, thread_t, thread_list_node) {
1293         if (t->user_tid == tid) {
1294             return t;
1295         }
1296     }
1297 
1298     return NULL;
1299 }
1300 
1301 /** @} */
1302 
1303 // Used by ktrace at the start of a trace to ensure that all
1304 // the running threads, processes, and their names are known
ktrace_report_live_threads(void)1305 void ktrace_report_live_threads(void) {
1306     thread_t* t;
1307 
1308     Guard<spin_lock_t, IrqSave> guard{ThreadLock::Get()};
1309     list_for_every_entry (&thread_list, t, thread_t, thread_list_node) {
1310         DEBUG_ASSERT(t->magic == THREAD_MAGIC);
1311         if (t->user_tid) {
1312             ktrace_name(TAG_THREAD_NAME,
1313                         static_cast<uint32_t>(t->user_tid), static_cast<uint32_t>(t->user_pid), t->name);
1314         } else {
1315             ktrace_name(TAG_KTHREAD_NAME,
1316                         static_cast<uint32_t>(reinterpret_cast<uintptr_t>(t)), 0, t->name);
1317         }
1318     }
1319 }
1320 
1321 #define THREAD_BACKTRACE_DEPTH 16
1322 typedef struct thread_backtrace {
1323     void* pc[THREAD_BACKTRACE_DEPTH];
1324 } thread_backtrace_t;
1325 
thread_read_stack(thread_t * t,void * ptr,void * out,size_t sz)1326 static zx_status_t thread_read_stack(thread_t* t, void* ptr, void* out, size_t sz) {
1327     if (!is_kernel_address((uintptr_t)ptr) ||
1328         (reinterpret_cast<vaddr_t>(ptr) < t->stack.base) ||
1329         (reinterpret_cast<vaddr_t>(ptr) > (t->stack.base + t->stack.size - sizeof(void*)))) {
1330         return ZX_ERR_NOT_FOUND;
1331     }
1332     memcpy(out, ptr, sz);
1333     return ZX_OK;
1334 }
1335 
thread_get_backtrace(thread_t * t,void * fp,thread_backtrace_t * tb)1336 static size_t thread_get_backtrace(thread_t* t, void* fp, thread_backtrace_t* tb) {
1337     // without frame pointers, dont even try
1338     // the compiler should optimize out the body of all the callers if it's not present
1339     if (!WITH_FRAME_POINTERS) {
1340         return 0;
1341     }
1342 
1343     void* pc;
1344     if (t == NULL) {
1345         return 0;
1346     }
1347     size_t n = 0;
1348     for (; n < THREAD_BACKTRACE_DEPTH; n++) {
1349         if (thread_read_stack(t, static_cast<char*>(fp) + 8, &pc, sizeof(void*))) {
1350             break;
1351         }
1352         tb->pc[n] = pc;
1353         if (thread_read_stack(t, fp, &fp, sizeof(void*))) {
1354             break;
1355         }
1356     }
1357     return n;
1358 }
1359 
_thread_print_backtrace(thread_t * t,void * fp)1360 static zx_status_t _thread_print_backtrace(thread_t* t, void* fp) {
1361     if (!t || !fp) {
1362         return ZX_ERR_BAD_STATE;
1363     }
1364 
1365     thread_backtrace_t tb;
1366     size_t count = thread_get_backtrace(t, fp, &tb);
1367     if (count == 0) {
1368         return ZX_ERR_BAD_STATE;
1369     }
1370 
1371     // TODO(jakehehrlich): Remove the legacy format.
1372     for (size_t n = 0; n < count; n++) {
1373         printf("bt#%02zu: %p\n", n, tb.pc[n]);
1374     }
1375     printf("bt#%02zu: end\n", count);
1376 
1377     for (size_t n = 0; n < count; n++) {
1378         printf("{{{bt:%zu:%p}}}\n", n, tb.pc[n]);
1379     }
1380 
1381     return ZX_OK;
1382 }
1383 
1384 // print the backtrace of the current thread, at the current spot
thread_print_current_backtrace(void)1385 void thread_print_current_backtrace(void) {
1386     _thread_print_backtrace(get_current_thread(), __GET_FRAME(0));
1387 }
1388 
1389 // append the backtrace of the current thread to the passed in char pointer.
1390 // return the number of chars appended.
thread_append_current_backtrace(char * out,const size_t out_len)1391 size_t thread_append_current_backtrace(char* out, const size_t out_len) {
1392     thread_t* current = get_current_thread();
1393     void* fp = __GET_FRAME(0);
1394 
1395     if (!current || !fp) {
1396         return 0;
1397     }
1398 
1399     thread_backtrace_t tb;
1400     size_t count = thread_get_backtrace(current, fp, &tb);
1401     if (count == 0) {
1402         return 0;
1403     }
1404 
1405     char* buf = out;
1406     size_t remain = out_len;
1407     size_t len;
1408     for (size_t n = 0; n < count; n++) {
1409         len = snprintf(buf, remain, "bt#%02zu: %p\n", n, tb.pc[n]);
1410         if (len > remain) {
1411             return out_len;
1412         }
1413         remain -= len;
1414         buf += len;
1415     }
1416     len = snprintf(buf, remain, "bt#%02zu: end\n", count);
1417     if (len > remain) {
1418         return out_len;
1419     }
1420     remain -= len;
1421     buf += len;
1422 
1423     return out_len - remain;
1424 }
1425 
1426 // print the backtrace of the current thread, at the given spot
thread_print_current_backtrace_at_frame(void * caller_frame)1427 void thread_print_current_backtrace_at_frame(void* caller_frame) {
1428     _thread_print_backtrace(get_current_thread(), caller_frame);
1429 }
1430 
1431 // print the backtrace of a passed in thread, if possible
thread_print_backtrace(thread_t * t)1432 zx_status_t thread_print_backtrace(thread_t* t) {
1433     // get the starting point if it's in a usable state
1434     void* fp = NULL;
1435     switch (t->state) {
1436     case THREAD_BLOCKED:
1437     case THREAD_SLEEPING:
1438     case THREAD_SUSPENDED:
1439         // thread is blocked, so ask the arch code to get us a starting point
1440         fp = arch_thread_get_blocked_fp(t);
1441         break;
1442     // we can't deal with every other state
1443     default:
1444         return ZX_ERR_BAD_STATE;
1445     }
1446 
1447     return _thread_print_backtrace(t, fp);
1448 }
1449