source: mainline/uspace/app/top/top.c@ 452268a1

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 452268a1 was 452268a1, checked in by Stanislav Kozina <stanislav.kozina@…>, 15 years ago

top echoes also percentage differencies of task cycles

  • Property mode set to 100644
File size: 5.8 KB
Line 
1/*
2 * Copyright (c) 2010 Stanislav Kozina
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup top
30 * @brief Top utility.
31 * @{
32 */
33/**
34 * @file
35 */
36
37#include <stdio.h>
38#include <stdlib.h>
39#include <unistd.h>
40#include <uptime.h>
41#include <task.h>
42#include <thread.h>
43#include <sys/time.h>
44#include <load.h>
45#include "screen.h"
46#include "input.h"
47#include "top.h"
48#include "ps.h"
49
50#define UPDATE_INTERVAL 1
51
52#define DAY 86400
53#define HOUR 3600
54#define MINUTE 60
55
56int number = 0;
57int number2 = 0;
58static void read_data(data_t *target)
59{
60 /* Read current time */
61 struct timeval time;
62 if (gettimeofday(&time, NULL) != 0) {
63 printf("Cannot get time of day!\n");
64 exit(1);
65 }
66 target->hours = (time.tv_sec % DAY) / HOUR;
67 target->minutes = (time.tv_sec % HOUR) / MINUTE;
68 target->seconds = time.tv_sec % MINUTE;
69
70 /* Read uptime */
71 uint64_t uptime;
72 get_uptime(&uptime);
73 target->uptime_d = uptime / DAY;
74 target->uptime_h = (uptime % DAY) / HOUR;
75 target->uptime_m = (uptime % HOUR) / MINUTE;
76 target->uptime_s = uptime % MINUTE;
77
78 /* Read load */
79 get_load(target->load);
80
81 /* Read task ids */
82 target->task_count = get_tasks(&target->taskinfos);
83
84 /* Read cpu infos */
85 target->cpu_count = get_cpu_infos(&target->cpus);
86}
87
88/** Computes percentage differencies from old_data to new_data
89 *
90 * @param old_data Pointer to old data strucutre.
91 * @param new_data Pointer to actual data where percetages are stored.
92 *
93 */
94static void compute_percentages(data_t *old_data, data_t *new_data)
95{
96 /* Foreach cpu, compute total ticks and divide it between user and
97 * system */
98 unsigned int i;
99 new_data->cpu_perc = malloc(new_data->cpu_count * sizeof(cpu_perc_t));
100 for (i = 0; i < new_data->cpu_count; ++i) {
101 uint64_t idle = new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
102 uint64_t busy = new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
103 uint64_t sum = idle + busy;
104 new_data->cpu_perc[i].idle = (float)(idle * 100) / sum;
105 new_data->cpu_perc[i].busy = (float)(busy * 100) / sum;
106 }
107
108 /* For all tasks compute sum and differencies of all cycles */
109 uint64_t pages_total = 0;
110 uint64_t ucycles_total = 0;
111 uint64_t kcycles_total = 0;
112 uint64_t *ucycles_diff = malloc(new_data->task_count * sizeof(uint64_t));
113 uint64_t *kcycles_diff = malloc(new_data->task_count * sizeof(uint64_t));
114 unsigned int j = 0;
115 for (i = 0; i < new_data->task_count; ++i) {
116 /* Jump over all death tasks */
117 while (old_data->taskinfos[j].taskid < new_data->taskinfos[i].taskid)
118 ++j;
119 if (old_data->taskinfos[j].taskid > new_data->taskinfos[i].taskid) {
120 /* This is newly borned task, ignore it */
121 ucycles_diff[i] = 0;
122 kcycles_diff[i] = 0;
123 continue;
124 }
125 /* Now we now we have task with same id */
126 ucycles_diff[i] = new_data->taskinfos[i].ucycles - old_data->taskinfos[j].ucycles;
127 kcycles_diff[i] = new_data->taskinfos[i].kcycles - old_data->taskinfos[j].kcycles;
128
129 pages_total += new_data->taskinfos[i].pages;
130 ucycles_total += ucycles_diff[i];
131 kcycles_total += kcycles_diff[i];
132 }
133
134 /* And now compute percental change */
135 new_data->task_perc = malloc(new_data->task_count * sizeof(task_perc_t));
136 for (i = 0; i < new_data->task_count; ++i) {
137 new_data->task_perc[i].pages = (float)(new_data->taskinfos[i].pages * 100) / pages_total;
138 new_data->task_perc[i].ucycles = (float)(ucycles_diff[i] * 100) / ucycles_total;
139 new_data->task_perc[i].kcycles = (float)(kcycles_diff[i] * 100) / kcycles_total;
140 }
141
142 /* And free temporary structures */
143 free(ucycles_diff);
144 free(kcycles_diff);
145}
146
147static void free_data(data_t *target)
148{
149 free(target->taskinfos);
150 free(target->cpus);
151 free(target->cpu_perc);
152 free(target->task_perc);
153}
154
155static inline void swap(data_t **first, data_t **second)
156{
157 data_t *temp;
158 temp = *first;
159 *first = *second;
160 *second = temp;
161}
162
163static data_t data[2];
164
165int main(int argc, char *argv[])
166{
167 data_t *data1 = &data[0];
168 data_t *data2 = &data[1];
169 screen_init();
170
171 /* Read initial stats */
172 printf("Reading initial data...\n");
173 read_data(data1);
174 /* Compute some rubbish to have initialised values */
175 compute_percentages(data1, data1);
176
177 /* And paint screen until death... */
178 while (true) {
179 char c = tgetchar(UPDATE_INTERVAL);
180 if (c < 0) {
181 read_data(data2);
182 compute_percentages(data1, data2);
183 free_data(data1);
184 print_data(data2);
185 swap(&data1, &data2);
186 continue;
187 }
188 switch (c) {
189 case 'q':
190 clear_screen();
191 return 0;
192 default:
193 PRINT_WARNING("Unknown command: %c", c);
194 break;
195 }
196
197 }
198
199 free_data(data1);
200 free_data(data2);
201 return 0;
202}
203
204/** @}
205 */
Note: See TracBrowser for help on using the repository browser.