1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  */
9 
10 #include "proc.h"
11 #include "procfs.h"
12 
13 #include <rthw.h>
14 #include <rtdbg.h>
15 
16 #include <fcntl.h>
17 #include <errno.h>
18 
19 #include <dfs_dentry.h>
20 
21 
seq_start(struct dfs_seq_file * seq,off_t * index)22 static void *seq_start(struct dfs_seq_file *seq, off_t *index)
23 {
24     off_t i = *index; // seq->index
25 
26     return NULL + (i == 0);
27 }
28 
seq_stop(struct dfs_seq_file * seq,void * data)29 static void seq_stop(struct dfs_seq_file *seq, void *data)
30 {
31 }
32 
seq_next(struct dfs_seq_file * seq,void * data,off_t * index)33 static void *seq_next(struct dfs_seq_file *seq, void *data, off_t *index)
34 {
35     /* data: The return value of the start or next*/
36     off_t i = *index + 1; // seq->index
37 
38     *index = i;
39 
40     return NULL;
41 }
42 
seq_show(struct dfs_seq_file * seq,void * data)43 static int seq_show(struct dfs_seq_file *seq, void *data)
44 {
45     int i;
46     rt_cpu_t pcpu;
47     rt_uint64_t user_total = 0;
48     rt_uint64_t system_total = 0;
49     rt_uint64_t idle_total = 0;
50 
51     for (i = 0; i < RT_CPUS_NR; i++)
52     {
53         pcpu   = rt_cpu_index(i);
54         user_total = user_total + pcpu->cpu_stat.user;
55         system_total = system_total + pcpu->cpu_stat.system;
56         idle_total = idle_total + pcpu->cpu_stat.idle;
57     }
58     dfs_seq_printf(seq, "cpu  %llu 0 %llu %llu 0 0 0 0 0 0\n", user_total, system_total, idle_total);
59 
60     for (i = 0; i < RT_CPUS_NR; i++)
61     {
62         pcpu   = rt_cpu_index(i);
63         dfs_seq_printf(seq, "cpu%d ",i);
64         dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.user);//user
65         dfs_seq_printf(seq, "0 ");//nice
66         dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.system);//system
67         dfs_seq_printf(seq, "%llu ",pcpu->cpu_stat.idle);//idle
68         dfs_seq_printf(seq, "0 ");//iowait
69         dfs_seq_printf(seq, "0 ");//irq
70         dfs_seq_printf(seq, "0 ");//softirq
71         dfs_seq_printf(seq, "0 0 0\n");//steal,guest,guest_nice
72 
73     }
74 
75     return 0;
76 }
77 
78 static const struct dfs_seq_ops seq_ops = {
79     .start  = seq_start,
80     .stop   = seq_stop,
81     .next   = seq_next,
82     .show   = seq_show,
83 };
84 
stat_get_seq_ops(void)85 rt_weak const struct dfs_seq_ops *stat_get_seq_ops(void)
86 {
87     return &seq_ops;
88 }
89 
proc_open(struct dfs_file * file)90 static int proc_open(struct dfs_file *file)
91 {
92     return dfs_seq_open(file, stat_get_seq_ops());
93 }
94 
proc_close(struct dfs_file * file)95 static int proc_close(struct dfs_file *file)
96 {
97     return dfs_seq_release(file);
98 }
99 
100 static const struct dfs_file_ops file_ops = {
101     .open   = proc_open,
102     .read   = dfs_seq_read,
103     .lseek  = dfs_seq_lseek,
104     .close  = proc_close,
105 };
106 
proc_stat_init(void)107 int proc_stat_init(void)
108 {
109     struct proc_dentry *dentry = proc_create_data("stat", 0, NULL, &file_ops, NULL);
110     proc_release(dentry);
111 
112     return 0;
113 }
114 INIT_ENV_EXPORT(proc_stat_init);
115