1/* 2 * Copyright (c) 2002-2004 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 <mach/boolean.h> 24#include <mach/host_info.h> 25#include <mach/task_info.h> 26#include <mach/vm_types.h> 27#include <stdarg.h> 28#include <sys/time.h> 29#include <sys/sysctl.h> 30 31__BEGIN_DECLS 32 33/* 34 * Flags for determining whether to collect memory region information on a 35 * per-process basis, used byt libtop_preg(). 36 */ 37typedef enum { 38 /* 39 * Collect memory region information iff libtop_sample()'s a_reg 40 * parameter is TRUE. 41 */ 42 LIBTOP_PREG_default = 0, 43 /* Do not collect memory region information. */ 44 LIBTOP_PREG_off, 45 /* Always collect memory region information. */ 46 LIBTOP_PREG_on 47} libtop_preg_t; 48 49typedef struct libtop_i64 { 50 uint64_t accumulator; 51 int last_value; 52} libtop_i64_t; 53 54typedef struct libtop_i64_values { 55 libtop_i64_t i64; 56 uint64_t now; 57 uint64_t began; 58 uint64_t previous; 59} libtop_i64_values_t; 60 61/* 62 * Type used for specifying a printing function that is called when an error 63 * occurs. libtop does not print a '\n' at the end of the string, so it is 64 * up to the printing function to add it if desired. 65 */ 66typedef boolean_t libtop_print_t (void *a_user_data, const char *a_format, ...); 67 68/* 69 * General sample information. 70 * 71 * Fields prefix meanings: 72 * 73 * b_ : Value for first sample. 74 * p_ : Value for previous sample (same as b_ if p_seq is 0). 75 */ 76typedef struct { 77 /* 78 * Sample sequence number, incremented for every sample. The first 79 * sample has a sequence number of 1. 80 */ 81 uint32_t seq; 82 83 /* Number of processes. */ 84 uint32_t nprocs; 85 86 /* CPU loads. */ 87 host_cpu_load_info_data_t cpu; 88 host_cpu_load_info_data_t b_cpu; 89 host_cpu_load_info_data_t p_cpu; 90 91 /* Load averages for 1, 5, and 15 minutes. */ 92 float loadavg[3]; 93 94 /* Start time, previous sample time, and current sample time. */ 95 struct timeval time; 96 struct timeval b_time; 97 struct timeval p_time; 98 99 /* Total number of threads. */ 100 uint32_t threads; 101 102 /* VM page size. */ 103 vm_size_t pagesize; 104 105 /* Physical memory size. */ 106 uint64_t memsize; 107 108 /* VM statistics. */ 109 vm_statistics64_data_t vm_stat; 110 vm_statistics64_data_t b_vm_stat; 111 vm_statistics64_data_t p_vm_stat; 112 113 boolean_t purgeable_is_valid; 114 115 /* Swap usage */ 116 struct xsw_usage xsu; 117 boolean_t xsu_is_valid; 118 119 /* Total number of memory regions. */ 120 uint32_t reg; 121 122 /* Total shared, private, virtual sizes. */ 123 uint64_t rshrd; 124 uint64_t rprvt; 125 uint64_t vsize; 126 127 /* Total private resident memory used by frameworks. */ 128 uint64_t fw_private; 129 130 /* Total virtual memory used by frameworks. */ 131 uint64_t fw_vsize; 132 133 /* Number of frameworks. */ 134 uint32_t fw_count; 135 136 /* Code size of frameworks. */ 137 uint64_t fw_code; 138 139 /* Data size of frameworks. */ 140 uint64_t fw_data; 141 142 /* Linkedit size of frameworks. */ 143 uint64_t fw_linkedit; 144 145#define LIBTOP_STATE_MAX 7 146#define LIBTOP_NSTATES (LIBTOP_STATE_MAX + 1) 147#define LIBTOP_STATE_MAXLEN 8 148 int state_breakdown[LIBTOP_NSTATES]; 149 150 /* Network statistics. */ 151 uint64_t net_ipackets; 152 uint64_t b_net_ipackets; 153 uint64_t p_net_ipackets; 154 155 uint64_t net_opackets; 156 uint64_t b_net_opackets; 157 uint64_t p_net_opackets; 158 159 uint64_t net_ibytes; 160 uint64_t b_net_ibytes; 161 uint64_t p_net_ibytes; 162 163 uint64_t net_obytes; 164 uint64_t b_net_obytes; 165 uint64_t p_net_obytes; 166 167 /* Disk statistics. */ 168 uint64_t disk_rops; 169 uint64_t b_disk_rops; 170 uint64_t p_disk_rops; 171 172 uint64_t disk_wops; 173 uint64_t b_disk_wops; 174 uint64_t p_disk_wops; 175 176 uint64_t disk_rbytes; 177 uint64_t b_disk_rbytes; 178 uint64_t p_disk_rbytes; 179 180 uint64_t disk_wbytes; 181 uint64_t b_disk_wbytes; 182 uint64_t p_disk_wbytes; 183 184 uint64_t pages_stolen; 185} libtop_tsamp_t; 186 187/* 188 * Process sample information. 189 * 190 * Fields prefix meanings: 191 * 192 * b_ : Value for first sample. 193 * p_ : Value for previous sample (invalid if p_seq is 0). 194 */ 195typedef struct libtop_psamp_s libtop_psamp_t; 196struct libtop_psamp_s { 197 uid_t uid; 198 pid_t pid; 199 pid_t ppid; 200 gid_t pgrp; 201 202 /* Memory statistics. */ 203 uint64_t rsize; 204 uint64_t vsize; 205 uint64_t rprvt; 206 uint64_t vprvt; 207 uint64_t rshrd; 208 uint64_t fw_private; 209 uint64_t empty; 210 211 uint32_t reg; 212 uint32_t p_reg; 213 214 uint64_t p_rsize; 215 uint64_t p_vprvt; 216 uint64_t p_vsize; 217 uint64_t p_rprvt; 218 uint64_t p_rshrd; 219 uint64_t p_empty; 220 221 /* Anonymous/purgeable memory statistics. */ 222 uint64_t anonymous; 223 uint64_t purgeable; 224 uint64_t p_anonymous; 225 uint64_t p_purgeable; 226 227 /* Compressed memory statistics. */ 228 uint64_t compressed; 229 uint64_t p_compressed; 230 231 /* Number of threads. */ 232 uint32_t th; 233 uint32_t p_th; 234 235 uint32_t running_th; 236 uint32_t p_running_th; 237 238 239 /* Number of ports. */ 240 uint32_t prt; 241 uint32_t p_prt; 242 243 /* CPU state/usage statistics. */ 244 int state; /* Process state. */ 245 246 /* Total time consumed by process. */ 247 struct timeval total_time; 248 struct timeval b_total_time; 249 struct timeval p_total_time; 250 251 /* Total on behalf cpu time. */ 252 uint64_t cpu_billed_to_me; 253 uint64_t cpu_billed_to_others; 254 uint64_t b_cpu_billed_to_me; 255 uint64_t b_cpu_billed_to_others; 256 uint64_t p_cpu_billed_to_me; 257 uint64_t p_cpu_billed_to_others; 258 259 /* assert counts */ 260 uint64_t assertcnt; 261 uint64_t p_assertcnt; 262 uint64_t b_assertcnt; 263 264 /* boost transition counts */ 265 uint64_t boosts; 266 uint64_t b_boosts; 267 uint64_t p_boosts; 268 269 /* last seq we were boost donating */ 270 boolean_t boost_donating; 271 uint32_t boost_last_donating_seq; 272 273 /* Event counters. */ 274 task_events_info_data_t events; 275 task_events_info_data_t b_events; 276 task_events_info_data_t p_events; 277 278 libtop_i64_values_t faults; 279 libtop_i64_values_t pageins; 280 libtop_i64_values_t cow_faults; 281 libtop_i64_values_t messages_sent; 282 libtop_i64_values_t messages_recv; 283 libtop_i64_values_t syscalls_mach; 284 libtop_i64_values_t syscalls_bsd; 285 libtop_i64_values_t csw; 286 287 uint64_t palloc; 288 uint64_t pfree; 289 uint64_t salloc; 290 uint64_t sfree; 291 292 uint64_t p_palloc; 293 uint64_t p_pfree; 294 uint64_t p_salloc; 295 uint64_t p_sfree; 296 297 /* malloc()ed '\0'-terminated string. */ 298 char *command; 299 300 /* Sequence number, used to detect defunct processes. */ 301 uint32_t seq; 302 303 /* 304 * Previous sequence number, used to detect processes that have only 305 * existed for the current sample (p_seq == 0). 306 */ 307 uint32_t p_seq; 308 309 /* time process was started */ 310 struct timeval started; 311 /* process cpu type */ 312 cpu_type_t cputype; 313 314 uint32_t wq_nthreads; 315 uint32_t wq_run_threads; 316 uint32_t wq_blocked_threads; 317 318 uint32_t p_wq_nthreads; 319 uint32_t p_wq_run_threads; 320 uint32_t p_wq_blocked_threads; 321 322 /* Power info. */ 323 task_power_info_data_t power; 324 task_power_info_data_t b_power; 325 task_power_info_data_t p_power; 326}; 327 328/* 329 * Initialize libtop. If a non-NULL printing function pointer is passed in, 330 * libtop will call the printing function when errors occur. 331 * 332 * Returns zero for success, non-zero for error. 333 */ 334int 335libtop_init(libtop_print_t *a_print, void *a_user_data); 336 337/* Shut down libtop. */ 338void 339libtop_fini(void); 340 341/* 342 * Take a sample. 343 * 344 * If a_reg is FALSE, do not calculate reg, vprvt, rprvt, or rshrd. 345 * 346 * If a_fw is FALSE, do not calculate fw_count, fw_code, fw_data, or 347 * fw_linkedit. 348 * 349 * Returns zero for success, non-zero for error. 350 */ 351int 352libtop_sample(boolean_t a_reg, boolean_t a_fw); 353 354/* 355 * Return a pointer to a structure containing the generic information collected 356 * during the most recent sample. The return value from this function can be 357 * used for the duration of program execution (i.e. the return value does not 358 * change between samples). 359 */ 360const libtop_tsamp_t * 361libtop_tsamp(void); 362 363/* 364 * Type for psamp comparison function. 365 * 366 * Arguments : (void *) : Opaque data pointer. 367 * (libtop_psamp_t *) : psamp. 368 * 369 * Return values : -1 : Second argument less than third argument. 370 * 0 : Second argument equal to third argument. 371 * 1 : Second argument greater than third argument. 372 */ 373typedef int libtop_sort_t (void *, const libtop_psamp_t *, 374 const libtop_psamp_t *); 375 376/* 377 * Sort processes using a_sort(). Pass a_data as the opaque data pointer to 378 * a_sort(). 379 */ 380void 381libtop_psort(libtop_sort_t *a_sort, void *a_data); 382 383/* 384 * Iteratively return a pointer to each process which was in the most recent 385 * sample. If libtop_psort() was called after the most recent libtop_sample() 386 * call, the processes are iterated over in sorted order. Otherwise, they are 387 * iterated over in increasing pid order. 388 * 389 * A NULL return value indicates that there are no more processes to iterate 390 * over. 391 */ 392const libtop_psamp_t * 393libtop_piterate(void); 394 395/* 396 * Set whether to collect memory region information for the process with pid 397 * a_pid. 398 * 399 * Returns zero for success, non-zero for error. 400 */ 401int 402libtop_preg(pid_t a_pid, libtop_preg_t a_preg); 403 404/* 405 * Set the interval between framework updates. 406 * 407 * Returns zero for success, non-zero for error. 408 */ 409int 410libtop_set_interval(uint32_t ival); 411#define LIBTOP_MAX_INTERVAL 100 412 413/* 414 * Return a pointer to a username string (truncated to the first 8 characters), 415 * given a uid. If the uid cannot be matched to a username, NULL is returned. 416 */ 417const char * 418libtop_username(uid_t a_uid); 419 420/* 421 * Return a pointer to a string representation of a process state (names of 422 * states that are contained in libtop_tsamp_t's state_breakdown array). 423 */ 424const char * 425libtop_state_str(uint32_t a_state); 426 427/* 428 * These i64 functions are special functions that operate on an accumulator 429 * and work with overflowing 32-bit integers. So if the value overflows in the kernel 430 * counter, because it is a 32-bit value, they will in most cases capture the 431 * changes overtime to the value. The assumption is that all updates are increments 432 * of 0 or more (based on the deltas) so this doesn't work with values that 433 * potentially go negative. 434 */ 435 436libtop_i64_t 437libtop_i64_init(uint64_t acc, int last_value); 438 439void 440libtop_i64_update(libtop_i64_t *i, int value); 441 442uint64_t 443libtop_i64_value(libtop_i64_t *i); 444 445__END_DECLS 446