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
|
/*
* Copyright (c) 2023-2024, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2024-01-19 Shell Separate scheduling statements from rt_thread_t
* to rt_sched_thread_ctx. Add definitions of scheduler.
*/
#ifndef __RT_SCHED_H__
#define __RT_SCHED_H__
#include "rttypes.h"
#include "rtcompiler.h"
#ifdef __cplusplus
extern "C" {
#endif
struct rt_thread;
typedef rt_uint8_t rt_sched_thread_status_t;
/**
* Scheduler private status binding on thread. Caller should never accessing
* these members.
*/
struct rt_sched_thread_priv
{
rt_tick_t init_tick; /**< thread's initialized tick */
rt_tick_t remaining_tick; /**< remaining tick */
/* priority */
rt_uint8_t current_priority; /**< current priority */
rt_uint8_t init_priority; /**< initialized priority */
#if RT_THREAD_PRIORITY_MAX > 32
rt_uint8_t number; /**< priority low number */
rt_uint8_t high_mask; /**< priority high mask */
#endif /* RT_THREAD_PRIORITY_MAX > 32 */
rt_uint32_t number_mask; /**< priority number mask */
};
/**
* Scheduler public status binding on thread. Caller must hold the scheduler
* lock before access any one of its member.
*/
struct rt_sched_thread_ctx
{
rt_list_t thread_list_node; /**< node in thread list */
rt_uint8_t stat; /**< thread status */
rt_uint8_t sched_flag_locked:1; /**< calling thread have the scheduler locked */
rt_uint8_t sched_flag_ttmr_set:1; /**< thread timer is start */
#ifdef ARCH_USING_HW_THREAD_SELF
rt_uint8_t critical_switch_flag:1; /**< critical switch pending */
#endif /* ARCH_USING_HW_THREAD_SELF */
#ifdef RT_USING_SMP
rt_uint8_t bind_cpu; /**< thread is bind to cpu */
rt_uint8_t oncpu; /**< process on cpu */
rt_base_t critical_lock_nest; /**< critical lock count */
#endif
struct rt_sched_thread_priv sched_thread_priv; /**< private context of scheduler */
};
#define RT_SCHED_THREAD_CTX struct rt_sched_thread_ctx sched_thread_ctx;
#define RT_SCHED_PRIV(thread) ((thread)->sched_thread_ctx.sched_thread_priv)
#define RT_SCHED_CTX(thread) ((thread)->sched_thread_ctx)
/**
* Convert a list node in container RT_SCHED_CTX(thread)->thread_list_node
* to a thread pointer.
*/
#define RT_THREAD_LIST_NODE_ENTRY(node) \
rt_container_of( \
rt_list_entry((node), struct rt_sched_thread_ctx, thread_list_node), \
struct rt_thread, sched_thread_ctx)
#define RT_THREAD_LIST_NODE(thread) (RT_SCHED_CTX(thread).thread_list_node)
/**
* System Scheduler Locking
*/
typedef rt_ubase_t rt_sched_lock_level_t;
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);
rt_bool_t rt_sched_is_locked(void);
#ifdef RT_USING_SMP
#define RT_SCHED_DEBUG_IS_LOCKED do { RT_ASSERT(rt_sched_is_locked()); } while (0)
#define RT_SCHED_DEBUG_IS_UNLOCKED do { RT_ASSERT(!rt_sched_is_locked()); } while (0)
#else /* !RT_USING_SMP */
#define RT_SCHED_DEBUG_IS_LOCKED
#define RT_SCHED_DEBUG_IS_UNLOCKED
#endif /* RT_USING_SMP */
/**
* NOTE: user should NEVER use these APIs directly. See rt_thread_.* or IPC
* methods instead.
*/
#if defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__)
/* thread initialization and startup routine */
void rt_sched_thread_init_ctx(struct rt_thread *thread, rt_uint32_t tick, rt_uint8_t priority);
void rt_sched_thread_init_priv(struct rt_thread *thread, rt_uint32_t tick, rt_uint8_t priority);
void rt_sched_thread_startup(struct rt_thread *thread);
/* scheduler related routine */
void rt_sched_post_ctx_switch(struct rt_thread *thread);
rt_err_t rt_sched_tick_increase(rt_tick_t tick);
/* thread status operation */
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_uint8_t rt_sched_thread_get_init_prio(struct rt_thread *thread);
rt_err_t rt_sched_thread_yield(struct rt_thread *thread);
rt_err_t rt_sched_thread_close(struct rt_thread *thread);
rt_err_t rt_sched_thread_ready(struct rt_thread *thread);
rt_err_t rt_sched_thread_suspend(struct rt_thread *thread, rt_sched_lock_level_t level);
rt_err_t rt_sched_thread_change_priority(struct rt_thread *thread, rt_uint8_t priority);
rt_err_t rt_sched_thread_reset_priority(struct rt_thread *thread, rt_uint8_t priority);
rt_err_t rt_sched_thread_bind_cpu(struct rt_thread *thread, int cpu);
rt_uint8_t rt_sched_thread_is_suspended(struct rt_thread *thread);
rt_err_t rt_sched_thread_timer_stop(struct rt_thread *thread);
rt_err_t rt_sched_thread_timer_start(struct rt_thread *thread);
void rt_sched_insert_thread(struct rt_thread *thread);
void rt_sched_remove_thread(struct rt_thread *thread);
struct rt_thread *rt_sched_thread_self(void);
#endif /* defined(__RT_KERNEL_SOURCE__) || defined(__RT_IPC_SOURCE__) */
#ifdef __cplusplus
}
#endif
#endif /* __RT_SCHED_H__ */
|