| 981 | asm("_photon_switch_context_defer_die"); |
| 982 | |
| 983 | __attribute__((noreturn)) |
| 984 | inline void thread::die() { |
| 985 | deallocate_tls(&tls); |
| 986 | // if CURRENT is idle stub and during vcpu_fini |
| 987 | // main thread waiting for idle stub joining, now idle might be only |
| 988 | // thread in run-queue. To keep going, wake up waiter before remove |
| 989 | // current from run-queue. |
| 990 | lock.lock(); |
| 991 | state = states::DONE; |
| 992 | cond.notify_one(); |
| 993 | get_vcpu()->nthreads--; |
| 994 | auto sw = AtomicRunQ().remove_current(states::DONE); |
| 995 | assert(this == sw.from); |
| 996 | uint64_t func; |
| 997 | void* arg; |
| 998 | if (!is_joinable()) { |
| 999 | auto f = &thread::dispose; |
| 1000 | func = (uint64_t&)f; |
| 1001 | arg = this; |
| 1002 | } else { |
| 1003 | func = (uint64_t)&spinlock_unlock; |
| 1004 | arg = &lock; |
| 1005 | } |
| 1006 | auto ref = sw.to->stack.pointer_ref(); |
| 1007 | ASAN_DIE_SWITCH(sw.to); |
| 1008 | _photon_switch_context_defer_die(arg, func, ref); |
| 1009 | __builtin_unreachable(); |
| 1010 | } |
| 1011 | |
| 1012 | extern "C" __attribute__((noreturn)) |
| 1013 | void _photon_thread_die(thread* th) asm("_photon_thread_die"); |
no test coverage detected