diff options
Diffstat (limited to 'common/src/tx_thread_time_slice.c')
| -rw-r--r-- | common/src/tx_thread_time_slice.c | 184 |
1 files changed, 184 insertions, 0 deletions
diff --git a/common/src/tx_thread_time_slice.c b/common/src/tx_thread_time_slice.c new file mode 100644 index 00000000..d629ab9a --- /dev/null +++ b/common/src/tx_thread_time_slice.c @@ -0,0 +1,184 @@ +/**************************************************************************/ +/* */ +/* Copyright (c) Microsoft Corporation. All rights reserved. */ +/* */ +/* This software is licensed under the Microsoft Software License */ +/* Terms for Microsoft Azure RTOS. Full text of the license can be */ +/* found in the LICENSE file at https://aka.ms/AzureRTOS_EULA */ +/* and in the root directory of this software. */ +/* */ +/**************************************************************************/ + + +/**************************************************************************/ +/**************************************************************************/ +/** */ +/** ThreadX Component */ +/** */ +/** Thread */ +/** */ +/**************************************************************************/ +/**************************************************************************/ + +#define TX_SOURCE_CODE + + +/* Include necessary system files. */ + +#include "tx_api.h" +#include "tx_timer.h" +#include "tx_thread.h" +#include "tx_trace.h" + + +/**************************************************************************/ +/* */ +/* FUNCTION RELEASE */ +/* */ +/* _tx_thread_time_slice PORTABLE C */ +/* 6.0 */ +/* AUTHOR */ +/* */ +/* William E. Lamie, Microsoft Corporation */ +/* */ +/* DESCRIPTION */ +/* */ +/* This function moves the currently executing thread to the end of */ +/* the threads ready at the same priority level as a result of a */ +/* time-slice interrupt. If no other thread of the same priority is */ +/* ready, this function simply returns. */ +/* */ +/* INPUT */ +/* */ +/* None */ +/* */ +/* OUTPUT */ +/* */ +/* None */ +/* */ +/* CALLS */ +/* */ +/* None */ +/* */ +/* CALLED BY */ +/* */ +/* _tx_timer_interrupt Timer interrupt handling */ +/* */ +/* RELEASE HISTORY */ +/* */ +/* DATE NAME DESCRIPTION */ +/* */ +/* 05-19-2020 William E. Lamie Initial Version 6.0 */ +/* */ +/**************************************************************************/ +VOID _tx_thread_time_slice(VOID) +{ + +TX_INTERRUPT_SAVE_AREA + +TX_THREAD *thread_ptr; +#ifdef TX_ENABLE_STACK_CHECKING +TX_THREAD *next_thread_ptr; +#endif +#ifdef TX_ENABLE_EVENT_TRACE +ULONG system_state; +UINT preempt_disable; +#endif + + /* Pickup thread pointer. */ + TX_THREAD_GET_CURRENT(thread_ptr) + +#ifdef TX_ENABLE_STACK_CHECKING + + /* Check this thread's stack. */ + TX_THREAD_STACK_CHECK(thread_ptr) + + /* Set the next thread pointer to NULL. */ + next_thread_ptr = TX_NULL; +#endif + + /* Lockout interrupts while the time-slice is evaluated. */ + TX_DISABLE + + /* Clear the expired time-slice flag. */ + _tx_timer_expired_time_slice = TX_FALSE; + + /* Make sure the thread pointer is valid. */ + if (thread_ptr != TX_NULL) + { + + /* Make sure the thread is still active, i.e. not suspended. */ + if (thread_ptr -> tx_thread_state == TX_READY) + { + + /* Setup a fresh time-slice for the thread. */ + thread_ptr -> tx_thread_time_slice = thread_ptr -> tx_thread_new_time_slice; + + /* Reset the actual time-slice variable. */ + _tx_timer_time_slice = thread_ptr -> tx_thread_time_slice; + + /* Determine if there is another thread at the same priority and preemption-threshold + is not set. Preemption-threshold overrides time-slicing. */ + if (thread_ptr -> tx_thread_ready_next != thread_ptr) + { + + /* Check to see if preemption-threshold is not being used. */ + if (thread_ptr -> tx_thread_priority == thread_ptr -> tx_thread_preempt_threshold) + { + + /* Preemption-threshold is not being used by this thread. */ + + /* There is another thread at this priority, make it the highest at + this priority level. */ + _tx_thread_priority_list[thread_ptr -> tx_thread_priority] = thread_ptr -> tx_thread_ready_next; + + /* Designate the highest priority thread as the one to execute. Don't use this + thread's priority as an index just in case a higher priority thread is now + ready! */ + _tx_thread_execute_ptr = _tx_thread_priority_list[_tx_thread_highest_priority]; + +#ifdef TX_THREAD_ENABLE_PERFORMANCE_INFO + + /* Increment the thread's time-slice counter. */ + thread_ptr -> tx_thread_performance_time_slice_count++; + + /* Increment the total number of thread time-slice operations. */ + _tx_thread_performance_time_slice_count++; +#endif + + +#ifdef TX_ENABLE_STACK_CHECKING + + /* Pickup the next execute pointer. */ + next_thread_ptr = _tx_thread_execute_ptr; +#endif + } + } + } + } + +#ifdef TX_ENABLE_EVENT_TRACE + + /* Pickup the volatile information. */ + system_state = TX_THREAD_GET_SYSTEM_STATE(); + preempt_disable = _tx_thread_preempt_disable; + + /* Insert this event into the trace buffer. */ + TX_TRACE_IN_LINE_INSERT(TX_TRACE_TIME_SLICE, _tx_thread_execute_ptr, system_state, preempt_disable, TX_POINTER_TO_ULONG_CONVERT(&thread_ptr), TX_TRACE_INTERNAL_EVENTS) +#endif + + /* Restore previous interrupt posture. */ + TX_RESTORE + +#ifdef TX_ENABLE_STACK_CHECKING + + /* Determine if there is a next thread pointer to perform stack checking on. */ + if (next_thread_ptr != TX_NULL) + { + + /* Yes, check this thread's stack. */ + TX_THREAD_STACK_CHECK(next_thread_ptr) + } +#endif +} + |
