diff options
author | Mate Toth-Pal <mate.toth-pal@arm.com> | 2019-01-30 14:04:13 +0100 |
---|---|---|
committer | Mate Toth-Pal <mate.toth-pal@arm.com> | 2019-02-11 09:55:59 +0100 |
commit | 82cc07cbbc7c03e67dc88d9490dad27cbd823048 (patch) | |
tree | 0505e809309ef96c3e03504f0f9b1d8d8f003fc4 | |
parent | 4bf9fd49e78862182f7e72263770e5eae86e8194 (diff) | |
download | trusted-firmware-m-82cc07cbbc7c03e67dc88d9490dad27cbd823048.tar.gz |
Core: Fix thread list handling
The function update_running_head(...) updates the pointer pointing to
the highest priority runnable thread.
The old implementation updates RUNN_HEAD pointer to the new running
thread, if the new running thread has the same or higher priority then
current RUNN_HEAD. However this is not the correct behaviour.
If a thread with the same priority as a running thread becomes running,
then RUNN_HEAD is updated to this thread. Then if this second thread
gets blocked, then the previous thread will never be scheduled, as the
RUNN_HEAD pointer is past it, and the search always starts at
RUNN_HEAD.
Fix: Change tfm_thrd_set_status to update the RUNN_HEAD to the new
running thread, if it has higher priority than the thread at RUNN_HEAD.
In other cases start the search from the beginning of the thread list.
Change-Id: I3738fa2e728d731b5b2553ad64ba232b47509c5a
Signed-off-by: Mate Toth-Pal <mate.toth-pal@arm.com>
-rw-r--r-- | secure_fw/core/ipc/tfm_thread.c | 21 |
1 files changed, 12 insertions, 9 deletions
diff --git a/secure_fw/core/ipc/tfm_thread.c b/secure_fw/core/ipc/tfm_thread.c index 39f42ee234..359aa71db8 100644 --- a/secure_fw/core/ipc/tfm_thread.c +++ b/secure_fw/core/ipc/tfm_thread.c @@ -21,20 +21,23 @@ static struct tfm_thrd_ctx *p_curr_thrd = NULL; #define RUNN_HEAD p_runn_head #define CURR_THRD p_curr_thrd +static struct tfm_thrd_ctx *find_next_running_thread(struct tfm_thrd_ctx *pth) +{ + while (pth && pth->status != THRD_STAT_RUNNING) { + pth = pth->next; + } + + return pth; +} + /* To get next running thread for scheduler */ struct tfm_thrd_ctx *tfm_thrd_next_thread(void) { - struct tfm_thrd_ctx *pth = RUNN_HEAD; - /* * First RUNNING thread has highest priority since threads are sorted with * priority. */ - while (pth && pth->status != THRD_STAT_RUNNING) { - pth = pth->next; - } - - return pth; + return find_next_running_thread(RUNN_HEAD); } /* To get current thread for caller */ @@ -69,10 +72,10 @@ static void update_running_head(struct tfm_thrd_ctx **runn, struct tfm_thrd_ctx *node) { if ((node->status == THRD_STAT_RUNNING) && - (*runn == NULL || (node->prior <= (*runn)->prior))) { + (*runn == NULL || (node->prior < (*runn)->prior))) { *runn = node; } else { - *runn = tfm_thrd_next_thread(); + *runn = find_next_running_thread(LIST_HEAD); } } |