mt: Fix preemption

Preemption was supposed to be supported, but it had no means of safely
updating the state of a thread, so mt_exec() could fail to resume a
preempted thread.

mt_exec() is allowed to be called only from the main Contiki thread, so
the mt threads passed to it may be only ready or exited, not running.
Consequently, there is no need for a distinction between the ready and
running states, so merge them as a started state, which avoids having to
update the state of a thread upon preemption.

Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau.dev@gmail.com>
This commit is contained in:
Benoît Thébaudeau 2016-08-10 04:01:11 +02:00
parent 927e9b8150
commit 81805129f8
2 changed files with 4 additions and 10 deletions

View File

@ -68,14 +68,13 @@ mt_start(struct mt_thread *thread, void (* function)(void *), void *data)
stack with the correct parameters. */ stack with the correct parameters. */
mtarch_start(&thread->thread, function, data); mtarch_start(&thread->thread, function, data);
thread->state = MT_STATE_READY; thread->state = MT_STATE_STARTED;
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void void
mt_exec(struct mt_thread *thread) mt_exec(struct mt_thread *thread)
{ {
if(thread->state == MT_STATE_READY) { if(thread->state == MT_STATE_STARTED) {
thread->state = MT_STATE_RUNNING;
current = thread; current = thread;
/* Switch context to the thread. The function call will not return /* Switch context to the thread. The function call will not return
until the the thread has yielded, or is preempted. */ until the the thread has yielded, or is preempted. */
@ -87,14 +86,11 @@ void
mt_yield(void) mt_yield(void)
{ {
mtarch_pstop(); mtarch_pstop();
current->state = MT_STATE_READY;
current = NULL;
/* This function is called from the running thread, and we call the /* This function is called from the running thread, and we call the
switch function in order to switch the thread to the main Contiki switch function in order to switch the thread to the main Contiki
program instead. For us, the switch function will not return program instead. For us, the switch function will not return
until the next time we are scheduled to run. */ until the next time we are scheduled to run. */
mtarch_yield(); mtarch_yield();
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/
void void
@ -102,7 +98,6 @@ mt_exit(void)
{ {
mtarch_pstop(); mtarch_pstop();
current->state = MT_STATE_EXITED; current->state = MT_STATE_EXITED;
current = NULL;
mtarch_yield(); mtarch_yield();
} }
/*--------------------------------------------------------------------------*/ /*--------------------------------------------------------------------------*/

View File

@ -84,9 +84,8 @@
#include "contiki.h" #include "contiki.h"
#define MT_STATE_READY 1 #define MT_STATE_STARTED 1
#define MT_STATE_RUNNING 2 #define MT_STATE_EXITED 2
#define MT_STATE_EXITED 5
/** /**
* An opaque structure that is used for holding the state of a thread. * An opaque structure that is used for holding the state of a thread.