tlk: 6/19 update
[3rdparty/ote_partner/tlk.git] / kernel / thread.c
index 46c8578..be1e689 100644 (file)
@@ -41,6 +41,7 @@
 #include <kernel/dpc.h>
 #include <platform.h>
 #include <target.h>
+#include <kernel/task_unload.h>
 
 #if DEBUGLEVEL > 1
 #define THREAD_CHECKS 1
@@ -228,6 +229,12 @@ static void thread_cleanup_dpc(void *thread)
        list_delete(&t->thread_list_node);
        exit_critical_section();
 
+#if HAVE_UNLOAD_TASKS != 0
+       /* If this thread is associated with a task, deal with it */
+       if (t->arch.task)
+               task_thread_killed(t);
+#endif /* HAVE_UNLOAD_TASKS != 0 */
+
        /* free its stack and the thread structure itself */
        if (t->stack)
                free(t->stack);
@@ -235,6 +242,61 @@ static void thread_cleanup_dpc(void *thread)
        free(t);
 }
 
+/* Remove thread from queue if it is there.
+ */
+static void thread_remove_from_queue(thread_t *t)
+{
+#if THREAD_CHECKS
+       ASSERT(t->magic == THREAD_MAGIC);
+       ASSERT(in_critical_section());
+#endif
+
+       /* kick thread out of wait queue (if there)... */
+       (void)thread_unblock_from_wait_queue(t, false, NO_ERROR);
+
+       if (list_in_list(&t->queue_node)) {
+               list_delete(&t->queue_node);
+
+               if (list_is_empty(&run_queue[t->priority]))
+                       run_queue_bitmap &= ~(1<<t->priority);
+       }
+}
+
+/**
+ * @brief  Terminate a thread
+ *
+ * Specified thread is terminated.
+ */
+void thread_kill(thread_t *thread)
+{
+       if (!thread)
+               return;
+
+       if (thread == current_thread) {
+               thread_exit(0);
+               panic("somehow fell through thread_kill(self)\n");
+       }
+
+#if THREAD_CHECKS
+       ASSERT(thread->magic == THREAD_MAGIC);
+#endif
+
+       enter_critical_section();
+
+       /* Kick thread out of any wait/run/priority queue (if there)... */
+       thread_remove_from_queue(thread);
+
+       /* ...and enter the dead state... */
+       thread->state   = THREAD_DEATH;
+       thread->retcode = 0;
+       thread->remaining_quantum = 0;
+
+       exit_critical_section();
+
+       /* ...and finally cleanup the thread resources */
+       thread_cleanup_dpc(thread);
+}
+
 /**
  * @brief  Suspend the current thread
  *