Changes in uspace/app/top/top.c [9e05055:172aad6] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/top/top.c
r9e05055 r172aad6 44 44 #include <arch/barrier.h> 45 45 #include <errno.h> 46 #include <sort.h> 46 47 #include "screen.h" 47 48 #include "input.h" … … 56 57 #define MINUTE 60 57 58 58 int operation_type; 59 op_mode_t op_mode = OP_TASKS; 60 sort_mode_t sort_mode = SORT_TASK_CYCLES; 61 bool excs_all = false; 59 62 60 63 static const char *read_data(data_t *target) … … 66 69 target->tasks = NULL; 67 70 target->tasks_perc = NULL; 71 target->tasks_map = NULL; 68 72 target->threads = NULL; 73 target->exceptions = NULL; 74 target->exceptions_perc = NULL; 69 75 target->physmem = NULL; 76 target->ucycles_diff = NULL; 77 target->kcycles_diff = NULL; 78 target->ecycles_diff = NULL; 79 target->ecount_diff = NULL; 70 80 71 81 /* Get current time */ … … 110 120 return "Not enough memory for task utilization"; 111 121 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 112 127 /* Get threads */ 113 128 target->threads = stats_get_threads(&(target->threads_count)); … … 115 130 return "Cannot get threads"; 116 131 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 117 142 /* Get physical memory */ 118 143 target->physmem = stats_get_physmem(); 119 144 if (target->physmem == NULL) 120 145 return "Cannot get physical memory"; 146 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"; 121 167 122 168 return NULL; … … 129 175 * 130 176 */ 131 static const char *compute_percentages(data_t *old_data, data_t *new_data) 132 { 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 177 static void compute_percentages(data_t *old_data, data_t *new_data) 178 { 179 /* For each CPU: Compute total cycles and divide it between 146 180 user and kernel */ 147 181 … … 149 183 for (i = 0; i < new_data->cpus_count; i++) { 150 184 uint64_t idle = 151 new_data->cpus[i].idle_ ticks - old_data->cpus[i].idle_ticks;185 new_data->cpus[i].idle_cycles - old_data->cpus[i].idle_cycles; 152 186 uint64_t busy = 153 new_data->cpus[i].busy_ ticks - old_data->cpus[i].busy_ticks;187 new_data->cpus[i].busy_cycles - old_data->cpus[i].busy_cycles; 154 188 uint64_t sum = idle + busy; 155 189 … … 160 194 /* For all tasks compute sum and differencies of all cycles */ 161 195 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 */196 uint64_t virtmem_total = 0; 197 uint64_t ucycles_total = 0; 198 uint64_t kcycles_total = 0; 165 199 166 200 for (i = 0; i < new_data->tasks_count; i++) { … … 178 212 if (!found) { 179 213 /* This is newly borned task, ignore it */ 180 ucycles_diff[i] = 0;181 kcycles_diff[i] = 0;214 new_data->ucycles_diff[i] = 0; 215 new_data->kcycles_diff[i] = 0; 182 216 continue; 183 217 } 184 218 185 ucycles_diff[i] =219 new_data->ucycles_diff[i] = 186 220 new_data->tasks[i].ucycles - old_data->tasks[j].ucycles; 187 kcycles_diff[i] =221 new_data->kcycles_diff[i] = 188 222 new_data->tasks[i].kcycles - old_data->tasks[j].kcycles; 189 223 190 224 virtmem_total += new_data->tasks[i].virtmem; 191 ucycles_total += ucycles_diff[i];192 kcycles_total += kcycles_diff[i];193 } 194 195 /* For each task : Compute percential change */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 */ 196 230 197 231 for (i = 0; i < new_data->tasks_count; i++) { … … 199 233 new_data->tasks[i].virtmem * 100, virtmem_total); 200 234 FRACTION_TO_FLOAT(new_data->tasks_perc[i].ucycles, 201 ucycles_diff[i] * 100, ucycles_total);235 new_data->ucycles_diff[i] * 100, ucycles_total); 202 236 FRACTION_TO_FLOAT(new_data->tasks_perc[i].kcycles, 203 kcycles_diff[i] * 100, kcycles_total); 204 } 205 206 /* Cleanup */ 207 208 free(ucycles_diff); 209 free(kcycles_diff); 210 211 return NULL; 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); 212 314 } 213 315 … … 232 334 free(target->threads); 233 335 336 if (target->exceptions != NULL) 337 free(target->exceptions); 338 339 if (target->exceptions_perc != NULL) 340 free(target->exceptions_perc); 341 234 342 if (target->physmem != NULL) 235 343 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); 236 356 } 237 357 … … 249 369 250 370 /* Compute some rubbish to have initialised values */ 251 if ((ret = compute_percentages(&data_prev, &data_prev)) != NULL) 252 goto out; 371 compute_percentages(&data_prev, &data_prev); 253 372 254 373 /* And paint screen until death */ 255 operation_type = OP_TASKS;256 374 while (true) { 257 375 int c = tgetchar(UPDATE_INTERVAL); … … 262 380 } 263 381 264 if ((ret = compute_percentages(&data_prev, &data)) != NULL) { 265 free_data(&data); 266 goto out; 267 } 268 382 compute_percentages(&data_prev, &data); 383 sort_data(&data); 269 384 print_data(&data); 270 385 free_data(&data_prev); … … 275 390 276 391 switch (c) { 392 case 't': 393 print_warning("Showing task statistics"); 394 op_mode = OP_TASKS; 395 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; 277 408 case 'q': 278 409 goto out; 279 case 'i': 280 print_warning("Showing IPC statistics"); 281 operation_type = OP_IPC; 282 break; 283 case 't': 284 print_warning("Showing task statistics"); 285 operation_type = OP_TASKS; 286 break; 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 else 416 print_warning("Showing only hot exceptions"); 417 break; 418 } 287 419 default: 288 print_warning("Unknown command : %c", c);420 print_warning("Unknown command \"%c\", use \"h\" for help", c); 289 421 break; 290 422 }
Note:
See TracChangeset
for help on using the changeset viewer.