kernel/sched: Fix race between thread wakeup timeout and abort

Aborted threads will cancel their timeouts, but the timeout subsystem
isn't protected under the same lock so it's possible for a timeout to
fire just as a thread is being aborted and wake it up unexpectedly.
Check the state before blowing anything up.

Signed-off-by: Andy Ross <andrew.j.ross@intel.com>
diff --git a/kernel/sched.c b/kernel/sched.c
index e378978..9089f9b 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -765,16 +765,21 @@
 /* Timeout handler for *_thread_timeout() APIs */
 void z_thread_timeout(struct _timeout *timeout)
 {
-	LOCKED(&sched_spinlock) {
-		struct k_thread *thread = CONTAINER_OF(timeout,
-						struct k_thread, base.timeout);
+	struct k_thread *thread = CONTAINER_OF(timeout,
+					       struct k_thread, base.timeout);
 
-		if (thread->base.pended_on != NULL) {
-			unpend_thread_no_timeout(thread);
+	LOCKED(&sched_spinlock) {
+		bool killed = ((thread->base.thread_state & _THREAD_DEAD) ||
+			       (thread->base.thread_state & _THREAD_ABORTING));
+
+		if (!killed) {
+			if (thread->base.pended_on != NULL) {
+				unpend_thread_no_timeout(thread);
+			}
+			z_mark_thread_as_started(thread);
+			z_mark_thread_as_not_suspended(thread);
+			ready_thread(thread);
 		}
-		z_mark_thread_as_started(thread);
-		z_mark_thread_as_not_suspended(thread);
-		ready_thread(thread);
 	}
 }
 #endif