-
Notifications
You must be signed in to change notification settings - Fork 2
/
cpu_usage.c
135 lines (118 loc) · 3.11 KB
/
cpu_usage.c
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
/*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-12-04 tyx first implementation
*/
#include "cpu_usage.h"
#ifndef CPU_USAGE_PERIOD_TICK
#define CPU_USAGE_PERIOD_TICK RT_TICK_PER_SECOND
#endif
cpu_usage_t *cpu_usage_obj(void)
{
static struct cpu_usage _usage;
return &_usage;
}
static void timeout(void *param)
{
cpu_usage_t *obj = param;
if (obj->state == CPU_USAGE_STATE_ACTIVATED)
{
if (++obj->period == CPU_USAGE_PERIOD_TICK)
{
obj->period = 0;
obj->idle_stat[0].load = CPU_USAGE_PERIOD_TICK -
(obj->idle_stat[0].idle_tick - obj->idle_stat[0].last_tick);
obj->idle_stat[0].last_tick = obj->idle_stat[0].idle_tick;
}
if (rt_thread_self() == obj->idle_stat[0].tid)
{
obj->idle_stat[0].idle_tick++;
}
}
}
int cpu_usage_init(void)
{
cpu_usage_t *obj = cpu_usage_obj();
rt_timer_t t = &obj->time;
char idle_name[RT_NAME_MAX];
int i;
if (rt_object_get_type(&t->parent) != RT_Object_Class_Timer)
{
/* init time */
rt_timer_init(t, "usage", timeout, obj, 1,
RT_TIMER_FLAG_PERIODIC | RT_TIMER_FLAG_HARD_TIMER);
/* set cpus */
obj->cpus = sizeof(obj->idle_stat) / sizeof(obj->idle_stat[0]);
/* get idle thread handle */
for (i = 0; i < obj->cpus; i++)
{
rt_snprintf(idle_name, sizeof(idle_name), "tidle%d", i);
obj->idle_stat[i].tid = rt_thread_find(idle_name);
}
/* set flags */
obj->state = CPU_USAGE_STATE_ACTIVATED;
/* start */
rt_timer_start(t);
}
return 0;
}
void cpu_usage_deinit(void)
{
cpu_usage_t *obj = cpu_usage_obj();
rt_timer_t t = &obj->time;
if (rt_object_get_type(&t->parent) == RT_Object_Class_Timer)
{
rt_timer_stop(t);
rt_timer_detach(t);
rt_memset(obj, 0, sizeof(*obj));
}
}
void cpu_usage_suspend(void)
{
cpu_usage_t *obj = cpu_usage_obj();
rt_timer_t t = &obj->time;
if (obj->state == CPU_USAGE_STATE_ACTIVATED)
{
rt_timer_stop(t);
obj->state = CPU_USAGE_STATE_SUSPEND;
obj->suspend_tick = rt_tick_get();
}
}
void cpu_usage_resume(void)
{
cpu_usage_t *obj = cpu_usage_obj();
rt_timer_t t = &obj->time;
rt_tick_t tick;
int i;
if (obj->state == CPU_USAGE_STATE_SUSPEND)
{
tick = rt_tick_get() - obj->suspend_tick;
for (i = 0; i < obj->cpus; i++)
{
obj->idle_stat[i].idle_tick += tick;
}
obj->state = CPU_USAGE_STATE_ACTIVATED;
rt_timer_start(t);
}
}
float cpu_load_average(void)
{
cpu_usage_t *obj = cpu_usage_obj();
rt_tick_t usage = 0;
float load = 0.0;
int i;
if (obj->state == CPU_USAGE_STATE_ACTIVATED)
{
for (i = 0; i < obj->cpus; i++)
{
usage += obj->idle_stat[i].load;
}
load = 100.0 * usage / (CPU_USAGE_PERIOD_TICK * obj->cpus);
}
return load;
}
#ifdef RT_USING_COMPONENTS_INIT
INIT_APP_EXPORT(cpu_usage_init);
#endif