RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
scheduler_comm.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * (scheduler_comm.c) Common API of scheduling routines.
7 *
8 * Change Logs:
9 * Date Author Notes
10 * 2024-01-18 Shell Separate scheduling related codes from thread.c, scheduler_.*
11 */
12
13#define DBG_TAG "kernel.sched"
14#define DBG_LVL DBG_INFO
15#include <rtdbg.h>
16
17#include <rtthread.h>
18
19void rt_sched_thread_init_ctx(struct rt_thread *thread, rt_uint32_t tick, rt_uint8_t priority)
20{
21 /* setup thread status */
22 RT_SCHED_CTX(thread).stat = RT_THREAD_INIT;
23
24#ifdef RT_USING_SMP
25 /* not bind on any cpu */
26 RT_SCHED_CTX(thread).bind_cpu = RT_CPUS_NR;
27 RT_SCHED_CTX(thread).oncpu = RT_CPU_DETACHED;
28#endif /* RT_USING_SMP */
29
30 rt_sched_thread_init_priv(thread, tick, priority);
31}
32
34{
36 RT_SCHED_CTX(thread).sched_flag_ttmr_set = 1;
37 return RT_EOK;
38}
39
41{
42 rt_err_t error;
44
45 if (RT_SCHED_CTX(thread).sched_flag_ttmr_set)
46 {
47 error = rt_timer_stop(&thread->thread_timer);
48
49 /* mask out timer flag no matter stop success or not */
50 RT_SCHED_CTX(thread).sched_flag_ttmr_set = 0;
51 }
52 else
53 {
54 error = RT_EOK;
55 }
56 return error;
57}
58
64
66{
68 return RT_SCHED_PRIV(thread).current_priority;
69}
70
72{
73 /* read only fields, so lock is unecessary */
74 return RT_SCHED_PRIV(thread).init_priority;
75}
76
85
87{
89 RT_SCHED_CTX(thread).stat = RT_THREAD_CLOSE;
90 return RT_EOK;
91}
92
94{
96
97 RT_SCHED_PRIV(thread).remaining_tick = RT_SCHED_PRIV(thread).init_tick;
98 RT_SCHED_CTX(thread).stat |= RT_THREAD_STAT_YIELD;
99
100 return RT_EOK;
101}
102
104{
105 rt_err_t error;
106
108
109 if (!rt_sched_thread_is_suspended(thread))
110 {
111 /* failed to proceed, and that's possibly due to a racing condition */
112 error = -RT_EINVAL;
113 }
114 else
115 {
116 if (RT_SCHED_CTX(thread).sched_flag_ttmr_set)
117 {
123 error = rt_sched_thread_timer_stop(thread);
124 }
125 else
126 {
127 error = RT_EOK;
128 }
129
130 if (!error)
131 {
132 /* remove from suspend list */
134
135 #ifdef RT_USING_SMART
136 thread->wakeup_handle.func = RT_NULL;
137 #endif
138
139 /* insert to schedule ready list and remove from susp list */
140 rt_sched_insert_thread(thread);
141 }
142 }
143
144 return error;
145}
146
148{
149 struct rt_thread *thread;
151
152 thread = rt_thread_self();
153
154 rt_sched_lock(&slvl);
155
156 if(RT_SCHED_PRIV(thread).remaining_tick > tick)
157 {
158 RT_SCHED_PRIV(thread).remaining_tick -= tick;
159 }
160 else
161 {
162 RT_SCHED_PRIV(thread).remaining_tick = 0;
163 }
164
165 if (RT_SCHED_PRIV(thread).remaining_tick)
166 {
167 rt_sched_unlock(slvl);
168 }
169 else
170 {
171 rt_sched_thread_yield(thread);
172
173 /* request a rescheduling even though we are probably in an ISR */
175 }
176
177 return RT_EOK;
178}
179
184{
185 RT_ASSERT(priority < RT_THREAD_PRIORITY_MAX);
187
188 /* for ready thread, change queue; otherwise simply update the priority */
190 {
191 /* remove thread from schedule queue first */
192 rt_sched_remove_thread(thread);
193
194 /* change thread priority */
195 RT_SCHED_PRIV(thread).current_priority = priority;
196
197 /* recalculate priority attribute */
198#if RT_THREAD_PRIORITY_MAX > 32
199 RT_SCHED_PRIV(thread).number = RT_SCHED_PRIV(thread).current_priority >> 3; /* 5bit */
200 RT_SCHED_PRIV(thread).number_mask = 1 << RT_SCHED_PRIV(thread).number;
201 RT_SCHED_PRIV(thread).high_mask = 1 << (RT_SCHED_PRIV(thread).current_priority & 0x07); /* 3bit */
202#else
203 RT_SCHED_PRIV(thread).number_mask = 1 << RT_SCHED_PRIV(thread).current_priority;
204#endif /* RT_THREAD_PRIORITY_MAX > 32 */
205 RT_SCHED_CTX(thread).stat = RT_THREAD_INIT;
206
207 /* insert thread to schedule queue again */
208 rt_sched_insert_thread(thread);
209 }
210 else
211 {
212 RT_SCHED_PRIV(thread).current_priority = priority;
213
214 /* recalculate priority attribute */
215#if RT_THREAD_PRIORITY_MAX > 32
216 RT_SCHED_PRIV(thread).number = RT_SCHED_PRIV(thread).current_priority >> 3; /* 5bit */
217 RT_SCHED_PRIV(thread).number_mask = 1 << RT_SCHED_PRIV(thread).number;
218 RT_SCHED_PRIV(thread).high_mask = 1 << (RT_SCHED_PRIV(thread).current_priority & 0x07); /* 3bit */
219#else
220 RT_SCHED_PRIV(thread).number_mask = 1 << RT_SCHED_PRIV(thread).current_priority;
221#endif /* RT_THREAD_PRIORITY_MAX > 32 */
222 }
223
224 return RT_EOK;
225}
226
227#ifdef RT_USING_OVERFLOW_CHECK
228void rt_scheduler_stack_check(struct rt_thread *thread)
229{
230 RT_ASSERT(thread != RT_NULL);
231
232#ifdef RT_USING_SMART
233#ifndef ARCH_MM_MMU
234 struct rt_lwp *lwp = thread ? (struct rt_lwp *)thread->lwp : 0;
235
236 /* if stack pointer locate in user data section skip stack check. */
237 if (lwp && ((rt_uint32_t)thread->sp > (rt_uint32_t)lwp->data_entry &&
238 (rt_uint32_t)thread->sp <= (rt_uint32_t)lwp->data_entry + (rt_uint32_t)lwp->data_size))
239 {
240 return;
241 }
242#endif /* not defined ARCH_MM_MMU */
243#endif /* RT_USING_SMART */
244
245#ifndef RT_USING_HW_STACK_GUARD
246#ifdef ARCH_CPU_STACK_GROWS_UPWARD
247 if (*((rt_uint8_t *)((rt_uintptr_t)thread->stack_addr + thread->stack_size - 1)) != '#' ||
248#else
249 if (*((rt_uint8_t *)thread->stack_addr) != '#' ||
250#endif /* ARCH_CPU_STACK_GROWS_UPWARD */
251 (rt_uintptr_t)thread->sp <= (rt_uintptr_t)thread->stack_addr ||
252 (rt_uintptr_t)thread->sp >
254 {
255 rt_base_t dummy = 1;
256
257 LOG_E("thread:%s stack overflow\n", thread->parent.name);
258
259 while (dummy);
260 }
261#endif /* RT_USING_HW_STACK_GUARD */
262#ifdef ARCH_CPU_STACK_GROWS_UPWARD
263#ifndef RT_USING_HW_STACK_GUARD
264 else if ((rt_uintptr_t)thread->sp > ((rt_uintptr_t)thread->stack_addr + thread->stack_size))
265#else
266 if ((rt_uintptr_t)thread->sp > ((rt_uintptr_t)thread->stack_addr + thread->stack_size))
267#endif
268 {
269 LOG_W("warning: %s stack is close to the top of stack address.\n",
270 thread->parent.name);
271 }
272#else
273#ifndef RT_USING_HW_STACK_GUARD
274 else if ((rt_uintptr_t)thread->sp <= ((rt_uintptr_t)thread->stack_addr + 32))
275#else
276 if ((rt_uintptr_t)thread->sp <= ((rt_uintptr_t)thread->stack_addr + 32))
277#endif
278 {
279 LOG_W("warning: %s stack is close to end of stack address.\n",
280 thread->parent.name);
281 }
282#endif /* ARCH_CPU_STACK_GROWS_UPWARD */
283}
284
285#endif /* RT_USING_OVERFLOW_CHECK */
rt_err_t rt_timer_stop(rt_timer_t timer)
This function will stop the timer
int stat(const char *file, struct stat *buf)
rt_inline void rt_list_remove(rt_list_t *n)
remove node from list.
#define RT_ASSERT(EX)
#define RT_THREAD_CLOSE
#define RT_THREAD_READY
#define RT_THREAD_STAT_MASK
rt_thread_t rt_thread_self(void)
This function will return self thread object.
#define RT_THREAD_STAT_YIELD
#define RT_THREAD_SUSPEND_MASK
#define RT_THREAD_INIT
#define RT_SCHED_CTX(thread)
#define RT_SCHED_DEBUG_IS_LOCKED
#define RT_SCHED_PRIV(thread)
#define RT_THREAD_LIST_NODE(thread)
rt_ubase_t rt_sched_lock_level_t
rt_base_t rt_uintptr_t
rt_base_t rt_err_t
unsigned char rt_uint8_t
rt_uint32_t rt_tick_t
unsigned int rt_uint32_t
#define RT_NULL
void rt_sched_thread_init_ctx(struct rt_thread *thread, rt_uint32_t tick, rt_uint8_t priority)
rt_uint8_t rt_sched_thread_get_stat(struct rt_thread *thread)
rt_uint8_t rt_sched_thread_get_curr_prio(struct rt_thread *thread)
rt_err_t rt_sched_thread_timer_stop(struct rt_thread *thread)
rt_uint8_t rt_sched_thread_get_init_prio(struct rt_thread *thread)
rt_err_t rt_sched_thread_change_priority(struct rt_thread *thread, rt_uint8_t priority)
Update priority of the target thread
rt_err_t rt_sched_thread_close(struct rt_thread *thread)
rt_err_t rt_sched_thread_ready(struct rt_thread *thread)
rt_uint8_t rt_sched_thread_is_suspended(struct rt_thread *thread)
rt_err_t rt_sched_tick_increase(rt_tick_t tick)
rt_err_t rt_sched_thread_yield(struct rt_thread *thread)
rt_err_t rt_sched_thread_timer_start(struct rt_thread *thread)
rt_err_t rt_sched_lock(rt_sched_lock_level_t *plvl)
rt_err_t rt_sched_unlock(rt_sched_lock_level_t level)
rt_err_t rt_sched_unlock_n_resched(rt_sched_lock_level_t level)
void * stack_addr
void * sp
rt_uint32_t stack_size
RT_SCHED_THREAD_CTX struct rt_timer thread_timer