Changes in uspace/app/top/top.c [172aad6:9e05055] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/top/top.c
r172aad6 r9e05055 44 44 #include <arch/barrier.h> 45 45 #include <errno.h> 46 #include <sort.h>47 46 #include "screen.h" 48 47 #include "input.h" … … 57 56 #define MINUTE 60 58 57 59 op_mode_t op_mode = OP_TASKS; 60 sort_mode_t sort_mode = SORT_TASK_CYCLES; 61 bool excs_all = false; 58 int operation_type; 62 59 63 60 static const char *read_data(data_t *target) … … 69 66 target->tasks = NULL; 70 67 target->tasks_perc = NULL; 71 target->tasks_map = NULL;72 68 target->threads = NULL; 73 target->exceptions = NULL;74 target->exceptions_perc = NULL;75 69 target->physmem = NULL; 76 target->ucycles_diff = NULL;77 target->kcycles_diff = NULL;78 target->ecycles_diff = NULL;79 target->ecount_diff = NULL;80 70 81 71 /* Get current time */ … … 120 110 return "Not enough memory for task utilization"; 121 111 122 target->tasks_map =123 (size_t *) calloc(target->tasks_count, sizeof(size_t));124 if (target->tasks_map == NULL)125 return "Not enough memory for task map";126 127 112 /* Get threads */ 128 113 target->threads = stats_get_threads(&(target->threads_count)); … … 130 115 return "Cannot get threads"; 131 116 132 /* Get Exceptions */133 target->exceptions = stats_get_exceptions(&(target->exceptions_count));134 if (target->exceptions == NULL)135 return "Cannot get exceptions";136 137 target->exceptions_perc =138 (perc_exc_t *) calloc(target->exceptions_count, sizeof(perc_exc_t));139 if (target->exceptions_perc == NULL)140 return "Not enough memory for exception utilization";141 142 117 /* Get physical memory */ 143 118 target->physmem = stats_get_physmem(); … … 145 120 return "Cannot get physical memory"; 146 121 147 target->ucycles_diff = calloc(target->tasks_count,148 sizeof(uint64_t));149 if (target->ucycles_diff == NULL)150 return "Not enough memory for user utilization";151 152 /* Allocate memory for computed values */153 target->kcycles_diff = calloc(target->tasks_count,154 sizeof(uint64_t));155 if (target->kcycles_diff == NULL)156 return "Not enough memory for kernel utilization";157 158 target->ecycles_diff = calloc(target->exceptions_count,159 sizeof(uint64_t));160 if (target->ecycles_diff == NULL)161 return "Not enough memory for exception cycles utilization";162 163 target->ecount_diff = calloc(target->exceptions_count,164 sizeof(uint64_t));165 if (target->ecount_diff == NULL)166 return "Not enough memory for exception count utilization";167 168 122 return NULL; 169 123 } … … 175 129 * 176 130 */ 177 static voidcompute_percentages(data_t *old_data, data_t *new_data)131 static const char *compute_percentages(data_t *old_data, data_t *new_data) 178 132 { 179 /* For each CPU: Compute total cycles and divide it between 133 /* Allocate memory */ 134 135 uint64_t *ucycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t)); 136 if (ucycles_diff == NULL) 137 return "Not enough memory for user utilization"; 138 139 uint64_t *kcycles_diff = calloc(new_data->tasks_count, sizeof(uint64_t)); 140 if (kcycles_diff == NULL) { 141 free(ucycles_diff); 142 return "Not enough memory for kernel utilization"; 143 } 144 145 /* For each CPU: Compute total ticks and divide it between 180 146 user and kernel */ 181 147 … … 183 149 for (i = 0; i < new_data->cpus_count; i++) { 184 150 uint64_t idle = 185 new_data->cpus[i].idle_ cycles - old_data->cpus[i].idle_cycles;151 new_data->cpus[i].idle_ticks - old_data->cpus[i].idle_ticks; 186 152 uint64_t busy = 187 new_data->cpus[i].busy_ cycles - old_data->cpus[i].busy_cycles;153 new_data->cpus[i].busy_ticks - old_data->cpus[i].busy_ticks; 188 154 uint64_t sum = idle + busy; 189 155 … … 194 160 /* For all tasks compute sum and differencies of all cycles */ 195 161 196 uint64_t virtmem_total = 0;197 uint64_t ucycles_total = 0;198 uint64_t kcycles_total = 0;162 uint64_t virtmem_total = 1; /* Must NOT be zero */ 163 uint64_t ucycles_total = 1; /* Must NOT be zero */ 164 uint64_t kcycles_total = 1; /* Must NOT be zero */ 199 165 200 166 for (i = 0; i < new_data->tasks_count; i++) { … … 212 178 if (!found) { 213 179 /* This is newly borned task, ignore it */ 214 new_data->ucycles_diff[i] = 0;215 new_data->kcycles_diff[i] = 0;180 ucycles_diff[i] = 0; 181 kcycles_diff[i] = 0; 216 182 continue; 217 183 } 218 184 219 new_data->ucycles_diff[i] =185 ucycles_diff[i] = 220 186 new_data->tasks[i].ucycles - old_data->tasks[j].ucycles; 221 new_data->kcycles_diff[i] =187 kcycles_diff[i] = 222 188 new_data->tasks[i].kcycles - old_data->tasks[j].kcycles; 223 189 224 190 virtmem_total += new_data->tasks[i].virtmem; 225 ucycles_total += new_data->ucycles_diff[i];226 kcycles_total += new_data->kcycles_diff[i];227 } 228 229 /* For each task compute percential change */191 ucycles_total += ucycles_diff[i]; 192 kcycles_total += kcycles_diff[i]; 193 } 194 195 /* For each task: Compute percential change */ 230 196 231 197 for (i = 0; i < new_data->tasks_count; i++) { … … 233 199 new_data->tasks[i].virtmem * 100, virtmem_total); 234 200 FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles, 235 new_data->ucycles_diff[i] * 100, ucycles_total);201 ucycles_diff[i] * 100, ucycles_total); 236 202 FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles, 237 new_data->kcycles_diff[i] * 100, kcycles_total); 238 } 239 240 /* For all exceptions compute sum and differencies of cycles */ 241 242 uint64_t ecycles_total = 0; 243 uint64_t ecount_total = 0; 244 245 for (i = 0; i < new_data->exceptions_count; i++) { 246 /* 247 * March exception with the previous instance. 248 * This is quite paranoid since exceptions do not 249 * usually disappear, but it does not hurt. 250 */ 251 252 bool found = false; 253 size_t j; 254 for (j = 0; j < old_data->exceptions_count; j++) { 255 if (new_data->exceptions[i].id == old_data->exceptions[j].id) { 256 found = true; 257 break; 258 } 259 } 260 261 if (!found) { 262 /* This is a new exception, ignore it */ 263 new_data->ecycles_diff[i] = 0; 264 new_data->ecount_diff[i] = 0; 265 continue; 266 } 267 268 new_data->ecycles_diff[i] = 269 new_data->exceptions[i].cycles - old_data->exceptions[j].cycles; 270 new_data->ecount_diff[i] = 271 new_data->exceptions[i].count - old_data->exceptions[i].count; 272 273 ecycles_total += new_data->ecycles_diff[i]; 274 ecount_total += new_data->ecount_diff[i]; 275 } 276 277 /* For each exception compute percential change */ 278 279 for (i = 0; i < new_data->exceptions_count; i++) { 280 FRACTION_TO_FLOAT(new_data->exceptions_perc[i].cycles, 281 new_data->ecycles_diff[i] * 100, ecycles_total); 282 FRACTION_TO_FLOAT(new_data->exceptions_perc[i].count, 283 new_data->ecount_diff[i] * 100, ecount_total); 284 } 285 } 286 287 static int cmp_data(void *a, void *b, void *arg) 288 { 289 size_t ia = *((size_t *) a); 290 size_t ib = *((size_t *) b); 291 data_t *data = (data_t *) arg; 292 293 uint64_t acycles = data->ucycles_diff[ia] + data->kcycles_diff[ia]; 294 uint64_t bcycles = data->ucycles_diff[ib] + data->kcycles_diff[ib]; 295 296 if (acycles > bcycles) 297 return -1; 298 299 if (acycles < bcycles) 300 return 1; 301 302 return 0; 303 } 304 305 static void sort_data(data_t *data) 306 { 307 size_t i; 308 309 for (i = 0; i < data->tasks_count; i++) 310 data->tasks_map[i] = i; 311 312 qsort((void *) data->tasks_map, data->tasks_count, 313 sizeof(size_t), cmp_data, (void *) data); 203 kcycles_diff[i] * 100, kcycles_total); 204 } 205 206 /* Cleanup */ 207 208 free(ucycles_diff); 209 free(kcycles_diff); 210 211 return NULL; 314 212 } 315 213 … … 334 232 free(target->threads); 335 233 336 if (target->exceptions != NULL)337 free(target->exceptions);338 339 if (target->exceptions_perc != NULL)340 free(target->exceptions_perc);341 342 234 if (target->physmem != NULL) 343 235 free(target->physmem); 344 345 if (target->ucycles_diff != NULL)346 free(target->ucycles_diff);347 348 if (target->kcycles_diff != NULL)349 free(target->kcycles_diff);350 351 if (target->ecycles_diff != NULL)352 free(target->ecycles_diff);353 354 if (target->ecount_diff != NULL)355 free(target->ecount_diff);356 236 } 357 237 … … 369 249 370 250 /* Compute some rubbish to have initialised values */ 371 compute_percentages(&data_prev, &data_prev); 251 if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL) 252 goto out; 372 253 373 254 /* And paint screen until death */ 255 operation_type = OP_TASKS; 374 256 while (true) { 375 257 int c = tgetchar(UPDATE_INTERVAL); … … 380 262 } 381 263 382 compute_percentages(&data_prev, &data); 383 sort_data(&data); 264 if ((ret = compute_percentages(&data_prev, &data)) != NULL) { 265 free_data(&data); 266 goto out; 267 } 268 384 269 print_data(&data); 385 270 free_data(&data_prev); … … 390 275 391 276 switch (c) { 277 case 'q': 278 goto out; 279 case 'i': 280 print_warning("Showing IPC statistics"); 281 operation_type = OP_IPC; 282 break; 392 283 case 't': 393 284 print_warning("Showing task statistics"); 394 op _mode = OP_TASKS;285 operation_type = OP_TASKS; 395 286 break; 396 case 'i':397 print_warning("Showing IPC statistics");398 op_mode = OP_IPC;399 break;400 case 'e':401 print_warning("Showing exception statistics");402 op_mode = OP_EXCS;403 break;404 case 'h':405 print_warning("Showing help");406 op_mode = OP_HELP;407 break;408 case 'q':409 goto out;410 case 'a':411 if (op_mode == OP_EXCS) {412 excs_all = !excs_all;413 if (excs_all)414 print_warning("Showing all exceptions");415 else416 print_warning("Showing only hot exceptions");417 break;418 }419 287 default: 420 print_warning("Unknown command \"%c\", use \"h\" for help", c);288 print_warning("Unknown command: %c", c); 421 289 break; 422 290 }
Note:
See TracChangeset
for help on using the changeset viewer.