1 #include<unistd.h> 2 #include "ff_ipc.h" 3 4 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 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 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