1 #include<unistd.h>
2 #include "ff_ipc.h"
3
4 void
usage(void)5 usage(void)
6 {
7 printf("Usage:\n");
8 printf(" top [-p <f-stack proc_id>] [-P <max proc_id>] "
9 "[-d <secs>] [-n <num>]\n");
10 }
11
cpu_status(struct ff_top_args * top)12 int cpu_status(struct ff_top_args *top)
13 {
14 int ret;
15 struct ff_msg *msg, *retmsg = NULL;
16
17 msg = ff_ipc_msg_alloc();
18 if (msg == NULL) {
19 errno = ENOMEM;
20 return -1;
21 }
22
23 msg->msg_type = FF_TOP;
24 ret = ff_ipc_send(msg);
25 if (ret < 0) {
26 errno = EPIPE;
27 ff_ipc_msg_free(msg);
28 return -1;
29 }
30
31 do {
32 if (retmsg != NULL) {
33 ff_ipc_msg_free(retmsg);
34 }
35
36 ret = ff_ipc_recv(&retmsg, msg->msg_type);
37 if (ret < 0) {
38 errno = EPIPE;
39 return -1;
40 }
41 } while (msg != retmsg);
42
43 *top = retmsg->top;
44
45 ff_ipc_msg_free(msg);
46
47 return 0;
48 }
49
main(int argc,char ** argv)50 int main(int argc, char **argv)
51 {
52 int ch, delay = 1, n = 0;
53 unsigned int i, j;
54 struct ff_top_args top, otop;
55 struct ff_top_args ptop[RTE_MAX_LCORE], potop[RTE_MAX_LCORE];
56 int proc_id = 0, max_proc_id = -1;
57 float sys, usr, idle;
58 float psys, pusr, pidle;
59 unsigned long loops, ploops;
60 int title_line = 40;
61
62 ff_ipc_init();
63
64 #define TOP_DIFF(member) (top.member - otop.member)
65 #define TOP_DIFF_P(member) (ptop[j].member - potop[j].member)
66
67 while ((ch = getopt(argc, argv, "hp:P:d:n:")) != -1) {
68 switch(ch) {
69 case 'p':
70 proc_id = atoi(optarg);
71 ff_set_proc_id(proc_id);
72 break;
73 case 'P':
74 max_proc_id = atoi(optarg);
75 if (max_proc_id < 0 || max_proc_id >= RTE_MAX_LCORE) {
76 usage();
77 ff_ipc_exit();
78 return -1;
79 }
80 if (max_proc_id > title_line - 2)
81 title_line = max_proc_id + 2;
82 break;
83 case 'd':
84 delay = atoi(optarg) ?: 1;
85 break;
86 case 'n':
87 n = atoi(optarg);
88 break;
89 case 'h':
90 default:
91 usage();
92 ff_ipc_exit();
93 return -1;
94 }
95 }
96
97 for (i = 0; ; i++) {
98 if (max_proc_id == -1) {
99 if (cpu_status(&top)) {
100 printf("fstack ipc message error !\n");
101 ff_ipc_exit();
102 return -1;
103 }
104
105 if (i % title_line == 0) {
106 printf("|---------|---------|---------|---------------|\n");
107 printf("|%9s|%9s|%9s|%15s|\n", "idle", "sys", "usr", "loop");
108 printf("|---------|---------|---------|---------------|\n");
109 }
110
111 if (i) {
112 sys = TOP_DIFF(sys_tsc) / (TOP_DIFF(work_tsc) / 100.0);
113 usr = TOP_DIFF(usr_tsc) / (TOP_DIFF(work_tsc) / 100.0);
114 idle = TOP_DIFF(idle_tsc) / (TOP_DIFF(work_tsc) / 100.0);
115
116 printf("|%8.2f%%|%8.2f%%|%8.2f%%|%15lu|\n",
117 idle, sys, usr, TOP_DIFF(loops));
118 }
119 }else {
120 /*
121 * get and show cpu usage from proc_id to max_proc_id.
122 */
123 if (i % (title_line / (max_proc_id - proc_id + 2)) == 0) {
124 printf("|---------|---------|---------|"
125 "---------|---------------|\n");
126 printf("|%9s|%9s|%9s|%9s|%15s|\n",
127 "proc_id", "idle", "sys", "usr", "loop");
128 printf("|---------|---------|---------|"
129 "---------|---------------|\n");
130 }
131
132 sys = usr = idle = loops = 0;
133 for (j = proc_id; j <= max_proc_id; j++) {
134 potop[j] = ptop[j];
135
136 ff_set_proc_id(j);
137 if (cpu_status(&ptop[j])) {
138 printf("fstack ipc message error, proc id:%d!\n", j);
139 ff_ipc_exit();
140 return -1;
141 }
142
143 if (i) {
144 psys = TOP_DIFF_P(sys_tsc) / \
145 (TOP_DIFF_P(work_tsc) / 100.0);
146 pusr = TOP_DIFF_P(usr_tsc) / \
147 (TOP_DIFF_P(work_tsc) / 100.0);
148 pidle = TOP_DIFF_P(idle_tsc) / \
149 (TOP_DIFF_P(work_tsc) / 100.0);
150 ploops = TOP_DIFF_P(loops);
151 printf("|%9d|%8.2f%%|%8.2f%%|%8.2f%%|%15lu|\n",
152 j, pidle, psys, pusr, ploops);
153
154 sys += psys;
155 usr += pusr;
156 idle += pidle;
157 loops += ploops;
158
159 if (j == max_proc_id) {
160 printf("|%9s|%8.2f%%|%8.2f%%|%8.2f%%|%15lu|\n",
161 "total", idle, sys, usr, loops);
162 printf("| | | |"
163 " | |\n");
164 }
165 }
166 }
167 }
168
169 if (n && i >= n) {
170 break;
171 }
172
173 otop = top;
174 sleep(delay);
175 }
176
177 ff_ipc_exit();
178
179 return 0;
180 }
181