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(¤t_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(¤t_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