blob: d629ab9a02ec1d61b5f24f72348c7a6347dec3ed (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
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
}
|