1/* 2 * Copyright (c) 2012 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22 23#include <stdlib.h> 24#include "libtop.h" 25#include "statistic.h" 26#include "generic.h" 27#include "preferences.h" 28#include "uinteger.h" 29 30extern const libtop_tsamp_t *tsamp; 31 32static bool idlewake_insert_cell(struct statistic *s, const void *sample) { 33 const libtop_psamp_t *psamp = sample; 34 char buf[GENERIC_INT_SIZE]; 35 36 if(top_uinteger_format_result(buf, sizeof(buf), 37 psamp->power.task_platform_idle_wakeups, 38 psamp->p_power.task_platform_idle_wakeups, 39 psamp->b_power.task_platform_idle_wakeups)) { 40 return true; 41 } 42 43 return generic_insert_cell(s, buf); 44} 45 46// cribbed from cpu_insert_cell 47static bool powerscore_insert_cell(struct statistic *s, const void *sample) { 48 const libtop_psamp_t *psamp = sample; 49 struct timeval elapsed, used; 50 char buf[10]; 51 unsigned long long elapsed_us = 0, used_us = 0, idlew = 0, taxed_us = 0; 52 int whole = 0, part = 0; 53 54 if(0 == psamp->p_seq || 0 == psamp->pid) { // kernel gets a free ride 55 whole = 0; 56 part = 0; 57 58 if(-1 == snprintf(buf, sizeof(buf), "%d.%1d", whole, part)) 59 return true; 60 61 return generic_insert_cell(s, buf); 62 } 63 64 65 switch(top_prefs_get_mode()) { 66 case STATMODE_ACCUM: 67 timersub(&tsamp->time, &tsamp->b_time, &elapsed); 68 timersub(&psamp->total_time, &psamp->b_total_time, &used); 69 idlew = psamp->power.task_platform_idle_wakeups - psamp->b_power.task_platform_idle_wakeups; 70 break; 71 72 73 case STATMODE_EVENT: 74 case STATMODE_DELTA: 75 case STATMODE_NON_EVENT: 76 timersub(&tsamp->time, &tsamp->p_time, &elapsed); 77 timersub(&psamp->total_time, &psamp->p_total_time, &used); 78 idlew = psamp->power.task_platform_idle_wakeups - psamp->p_power.task_platform_idle_wakeups; 79 break; 80 81 default: 82 fprintf(stderr, "unhandled STATMOMDE in %s\n", __func__); 83 abort(); 84 } 85 86 elapsed_us = (unsigned long long)elapsed.tv_sec * 1000000ULL 87 + (unsigned long long)elapsed.tv_usec; 88 89 taxed_us = (unsigned long long)idlew * 500ULL; 90 91 used_us = (unsigned long long)used.tv_sec * 1000000ULL 92 + (unsigned long long)used.tv_usec 93 + taxed_us; 94 95 /* Avoid a divide by 0 exception. */ 96 if(elapsed_us > 0) { 97 whole = (used_us * 100ULL) / elapsed_us; 98 part = (((used_us * 100ULL) - (whole * elapsed_us)) * 10ULL) / elapsed_us; 99 } 100 101 //top_log("command %s whole %d part %d\n", psamp->command, whole, part); 102 103 if(-1 == snprintf(buf, sizeof(buf), "%d.%1d", whole, part)) 104 return true; 105 106 return generic_insert_cell(s, buf); 107} 108 109static struct statistic_callbacks idlewake_callbacks = { 110 .draw = generic_draw, 111 .resize_cells = generic_resize_cells, 112 .move_cells = generic_move_cells, 113 .get_request_size = generic_get_request_size, 114 .get_minimum_size = generic_get_minimum_size, 115 .insert_cell = idlewake_insert_cell, 116 .reset_insertion = generic_reset_insertion 117}; 118 119static struct statistic_callbacks powerscore_callbacks = { 120 .draw = generic_draw, 121 .resize_cells = generic_resize_cells, 122 .move_cells = generic_move_cells, 123 .get_request_size = generic_get_request_size, 124 .get_minimum_size = generic_get_minimum_size, 125 .insert_cell = powerscore_insert_cell, 126 .reset_insertion = generic_reset_insertion 127}; 128 129struct statistic *top_idlewake_create(WINDOW *parent, const char *name) { 130 return create_statistic(STATISTIC_PORTS, parent, NULL, &idlewake_callbacks, 131 name); 132} 133 134struct statistic *top_powerscore_create(WINDOW *parent, const char *name) 135{ 136 return create_statistic(STATISTIC_PORTS, parent, NULL, &powerscore_callbacks, 137 name); 138} 139 140