source: mainline/uspace/app/top/top.c@ a325832

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

Fixed division by zero in top.c

  • Property mode set to 100644
File size: 5.9 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 <ps.h>
46#include "screen.h"
47#include "input.h"
48#include "top.h"
49#include "ps.h"
50
51#define UPDATE_INTERVAL 1
52
53#define DAY 86400
54#define HOUR 3600
55#define MINUTE 60
56
57int number = 0;
58int number2 = 0;
59static void read_data(data_t *target)
60{
61 /* Read current time */
62 struct timeval time;
63 if (gettimeofday(&time, NULL) != 0) {
64 printf("Cannot get time of day!\n");
65 exit(1);
66 }
67 target->hours = (time.tv_sec % DAY) / HOUR;
68 target->minutes = (time.tv_sec % HOUR) / MINUTE;
69 target->seconds = time.tv_sec % MINUTE;
70
71 /* Read uptime */
72 uint64_t uptime;
73 get_uptime(&uptime);
74 target->uptime_d = uptime / DAY;
75 target->uptime_h = (uptime % DAY) / HOUR;
76 target->uptime_m = (uptime % HOUR) / MINUTE;
77 target->uptime_s = uptime % MINUTE;
78
79 /* Read load */
80 get_load(target->load);
81
82 /* Read task ids */
83 target->task_count = get_tasks(&target->taskinfos);
84
85 /* Read cpu infos */
86 target->cpu_count = get_cpu_infos(&target->cpus);
87
88 /* Read mem info */
89 get_mem_info(&target->mem_info);
90}
91
92/** Computes percentage differencies from old_data to new_data
93 *
94 * @param old_data Pointer to old data strucutre.
95 * @param new_data Pointer to actual data where percetages are stored.
96 *
97 */
98static void compute_percentages(data_t *old_data, data_t *new_data)
99{
100 /* Foreach cpu, compute total ticks and divide it between user and
101 * system */
102 unsigned int i;
103 new_data->cpu_perc = malloc(new_data->cpu_count * sizeof(cpu_perc_t));
104 for (i = 0; i < new_data->cpu_count; ++i) {
105 uint64_t idle = new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks;
106 uint64_t busy = new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks;
107 uint64_t sum = idle + busy;
108 new_data->cpu_perc[i].idle = (float)(idle * 100) / sum;
109 new_data->cpu_perc[i].busy = (float)(busy * 100) / sum;
110 }
111
112 /* For all tasks compute sum and differencies of all cycles */
113 uint64_t mem_total = 1; /*< Must NOT be null! */
114 uint64_t ucycles_total = 1; /*< Must NOT be null! */
115 uint64_t kcycles_total = 1; /*< Must NOT be null! */
116 uint64_t *ucycles_diff = malloc(new_data->task_count * sizeof(uint64_t));
117 uint64_t *kcycles_diff = malloc(new_data->task_count * sizeof(uint64_t));
118 unsigned int j = 0;
119 for (i = 0; i < new_data->task_count; ++i) {
120 /* Jump over all death tasks */
121 while (old_data->taskinfos[j].taskid < new_data->taskinfos[i].taskid)
122 ++j;
123 if (old_data->taskinfos[j].taskid > new_data->taskinfos[i].taskid) {
124 /* This is newly borned task, ignore it */
125 ucycles_diff[i] = 0;
126 kcycles_diff[i] = 0;
127 continue;
128 }
129 /* Now we now we have task with same id */
130 ucycles_diff[i] = new_data->taskinfos[i].ucycles - old_data->taskinfos[j].ucycles;
131 kcycles_diff[i] = new_data->taskinfos[i].kcycles - old_data->taskinfos[j].kcycles;
132
133 mem_total += new_data->taskinfos[i].virt_mem;
134 ucycles_total += ucycles_diff[i];
135 kcycles_total += kcycles_diff[i];
136 }
137
138 /* And now compute percental change */
139 new_data->task_perc = malloc(new_data->task_count * sizeof(task_perc_t));
140 for (i = 0; i < new_data->task_count; ++i) {
141 new_data->task_perc[i].mem = (float)(new_data->taskinfos[i].virt_mem * 100) / mem_total;
142 new_data->task_perc[i].ucycles = (float)(ucycles_diff[i] * 100) / ucycles_total;
143 new_data->task_perc[i].kcycles = (float)(kcycles_diff[i] * 100) / kcycles_total;
144 }
145
146 /* And free temporary structures */
147 free(ucycles_diff);
148 free(kcycles_diff);
149}
150
151static void free_data(data_t *target)
152{
153 free(target->taskinfos);
154 free(target->cpus);
155 free(target->cpu_perc);
156 free(target->task_perc);
157}
158
159static inline void swap(data_t **first, data_t **second)
160{
161 data_t *temp;
162 temp = *first;
163 *first = *second;
164 *second = temp;
165}
166
167static data_t data[2];
168
169int main(int argc, char *argv[])
170{
171 data_t *data1 = &data[0];
172 data_t *data2 = &data[1];
173 screen_init();
174
175 /* Read initial stats */
176 printf("Reading initial data...\n");
177 read_data(data1);
178 /* Compute some rubbish to have initialised values */
179 compute_percentages(data1, data1);
180
181 /* And paint screen until death... */
182 while (true) {
183 char c = tgetchar(UPDATE_INTERVAL);
184 if (c < 0) {
185 read_data(data2);
186 compute_percentages(data1, data2);
187 free_data(data1);
188 print_data(data2);
189 swap(&data1, &data2);
190 continue;
191 }
192 switch (c) {
193 case 'q':
194 clear_screen();
195 return 0;
196 default:
197 PRINT_WARNING("Unknown command: %c", c);
198 break;
199 }
200
201 }
202
203 free_data(data1);
204 free_data(data2);
205 return 0;
206}
207
208/** @}
209 */
Note: See TracBrowser for help on using the repository browser.