RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
clock.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2024 RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2006-03-12 Bernard first version
9 * 2006-05-27 Bernard add support for same priority thread schedule
10 * 2006-08-10 Bernard remove the last rt_schedule in rt_tick_increase
11 * 2010-03-08 Bernard remove rt_passed_second
12 * 2010-05-20 Bernard fix the tick exceeds the maximum limits
13 * 2010-07-13 Bernard fix rt_tick_from_millisecond issue found by kuronca
14 * 2011-06-26 Bernard add rt_tick_set function.
15 * 2018-11-22 Jesven add per cpu tick
16 * 2020-12-29 Meco Man implement rt_tick_get_millisecond()
17 * 2021-06-01 Meco Man add critical section projection for rt_tick_increase()
18 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
19 * 2023-10-16 RiceChen fix: only the main core detection rt_timer_check(), in SMP mode
20 */
21
22#include <rthw.h>
23#include <rtthread.h>
24#include <rtatomic.h>
25
26#if defined(RT_USING_SMART) && defined(RT_USING_VDSO)
27#include <vdso.h>
28#endif
29
30#ifdef RT_USING_SMP
31#define rt_tick rt_cpu_index(0)->tick
32#else
33static volatile rt_atomic_t rt_tick = 0;
34#endif /* RT_USING_SMP */
35
36#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
37static void (*rt_tick_hook)(void);
38
42
44
51void rt_tick_sethook(void (*hook)(void))
52{
53 rt_tick_hook = hook;
54}
56#endif /* RT_USING_HOOK */
57
61
63
70{
71 /* return the global tick */
72 return (rt_tick_t)rt_atomic_load(&(rt_tick));
73}
75
82{
83 rt_atomic_store(&(rt_tick), tick);
84}
85
86#ifdef RT_USING_CPU_USAGE_TRACER
87static void _update_process_times(rt_tick_t tick)
88{
89 struct rt_thread *thread = rt_thread_self();
90 struct rt_cpu *pcpu = rt_cpu_self();
91
92 if (!LWP_IS_USER_MODE(thread))
93 {
94 thread->user_time += tick;
95 pcpu->cpu_stat.user += tick;
96 }
97 else
98 {
99 thread->system_time += tick;
100 if (thread == pcpu->idle_thread)
101 {
102 pcpu->cpu_stat.idle += tick;
103 }
104 else
105 {
106 pcpu->cpu_stat.system += tick;
107 }
108 }
109}
110
111#else
112
113#define _update_process_times(tick)
114#endif /* RT_USING_CPU_USAGE_TRACER */
115
121{
123
124 RT_OBJECT_HOOK_CALL(rt_tick_hook, ());
125
126 /* tracing cpu usage */
128
129 /* increase the global tick */
130#ifdef RT_USING_SMP
131 /* get percpu and increase the tick */
132 rt_atomic_add(&(rt_cpu_self()->tick), 1);
133#else
134 rt_atomic_add(&(rt_tick), 1);
135#endif /* RT_USING_SMP */
136
137 /* check time slice */
139
140 /* check timer */
141#ifdef RT_USING_SMP
142 if (rt_cpu_get_id() != 0)
143 {
144 return;
145 }
146#endif
148}
149
155{
157
158 RT_OBJECT_HOOK_CALL(rt_tick_hook, ());
159
160 /* tracing cpu usage */
162
163 /* increase the global tick */
164#ifdef RT_USING_SMP
165 /* get percpu and increase the tick */
166 rt_atomic_add(&(rt_cpu_self()->tick), tick);
167#else
168 rt_atomic_add(&(rt_tick), tick);
169#endif /* RT_USING_SMP */
170
171 /* check time slice */
173
174 /* check timer */
175#ifdef RT_USING_SMP
176 if (rt_cpu_get_id() != 0)
177 {
178 return;
179 }
180#endif
182
183#ifdef RT_USING_VDSO
184 rt_vdso_update_glob_time();
185#endif
186}
187
199{
200 rt_tick_t tick;
201
202 if (ms < 0)
203 {
205 }
206 else
207 {
208#if RT_TICK_PER_SECOND == 1000u
209 tick = ms;
210#else
211 tick = RT_TICK_PER_SECOND * (ms / 1000);
212 tick += (RT_TICK_PER_SECOND * (ms % 1000) + 999) / 1000;
213#endif /* RT_TICK_PER_SECOND == 1000u */
214 }
215
216 /* return the calculated tick */
217 return tick;
218}
220
231{
232#if RT_TICK_PER_SECOND == 0 /* make cppcheck happy*/
233#error "RT_TICK_PER_SECOND must be greater than zero"
234#endif
235
236#if 1000 % RT_TICK_PER_SECOND == 0u
237 return rt_tick_get() * (1000u / RT_TICK_PER_SECOND);
238#else
239 #warning "rt-thread cannot provide a correct 1ms-based tick any longer,\
240 please redefine this function in another file by using a high-precision hard-timer."
241 return 0;
242#endif /* 1000 % RT_TICK_PER_SECOND == 0u */
243}
244
struct rt_cpu * rt_cpu_self(void)
This fucntion will return current cpu object.
void rt_tick_increase(void)
This function will notify kernel there is one tick passed. Normally, this function is invoked by cloc...
void rt_timer_check(void)
This function will check timer list, if a timeout event happens, the corresponding timeout function w...
void rt_tick_increase_tick(rt_tick_t tick)
This function will notify kernel there is n tick passed. Normally, this function is invoked by clock ...
rt_tick_t rt_tick_get(void)
This function will return current tick from operating system startup.
定义 clock.c:69
#define _update_process_times(tick)
rt_weak rt_tick_t rt_tick_get_millisecond(void)
This function will return the passed millisecond from boot.
void rt_tick_set(rt_tick_t tick)
This function will set current tick.
定义 clock.c:81
rt_tick_t rt_tick_from_millisecond(rt_int32_t ms)
This function will calculate the tick from millisecond.
void rt_tick_sethook(void(*hook)(void))
#define RT_WAITING_FOREVER
rt_weak rt_uint8_t rt_interrupt_get_nest(void)
This function will return the nest of interrupt.
定义 irq.c:136
#define RT_OBJECT_HOOK_CALL(func, argv)
#define RT_ASSERT(EX)
rt_thread_t rt_thread_self(void)
This function will return self thread object.
#define LWP_IS_USER_MODE(t)
#define rt_atomic_add(ptr, v)
#define rt_atomic_store(ptr, v)
#define rt_atomic_load(ptr)
#define RTM_EXPORT(symbol)
定义 rtm.h:33
#define rt_cpu_get_id()
rt_uint32_t rt_tick_t
rt_base_t rt_atomic_t
signed int rt_int32_t
rt_err_t rt_sched_tick_increase(rt_tick_t tick)
struct rt_thread * idle_thread