+ if (proc_terminated(thread)) {
+ return false;
+ }
+
+ if (preempt_check_stalled(thread)) {
+ thread_flags_set(thread, TH_STALLED);
+ return true;
+ }
+
+ if (unlikely(kernel_process(thread->process))) {
+ // a kernel process is always runnable
+ return thread->state == PS_READY;
+ }
+
+ struct sigctx* sh = &thread->sigctx;
+
+ if ((thread->state & PS_PAUSED)) {
+ return !!(sh->sig_pending & ~1);
+ }
+
+ if ((thread->state & PS_BLOCKED)) {
+ return sigset_test(sh->sig_pending, _SIGINT);
+ }
+
+ if (sigset_test(sh->sig_pending, _SIGSTOP)) {
+ // If one thread is experiencing SIGSTOP, then we know
+ // all other threads are also SIGSTOP (as per POSIX-2008.1)
+ // In which case, the entire process is stopped.
+ thread->state = PS_STOPPED;
+ return false;
+ }
+
+ if (sigset_test(sh->sig_pending, _SIGCONT)) {
+ thread->state = PS_READY;
+ }
+
+ return (thread->state == PS_READY) \
+ && proc_runnable(thread->process);