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 /* Event counters. */ 252 task_events_info_data_t events; 253 task_events_info_data_t b_events; 254 task_events_info_data_t p_events; 255 256 libtop_i64_values_t faults; 257 libtop_i64_values_t pageins; 258 libtop_i64_values_t cow_faults; 259 libtop_i64_values_t messages_sent; 260 libtop_i64_values_t messages_recv; 261 libtop_i64_values_t syscalls_mach; 262 libtop_i64_values_t syscalls_bsd; 263 libtop_i64_values_t csw; 264 265 uint64_t palloc; 266 uint64_t pfree; 267 uint64_t salloc; 268 uint64_t sfree; 269 270 uint64_t p_palloc; 271 uint64_t p_pfree; 272 uint64_t p_salloc; 273 uint64_t p_sfree; 274 275 /* malloc()ed '\0'-terminated string. */ 276 char *command; 277 278 /* Sequence number, used to detect defunct processes. */ 279 uint32_t seq; 280 281 /* 282 * Previous sequence number, used to detect processes that have only 283 * existed for the current sample (p_seq == 0). 284 */ 285 uint32_t p_seq; 286 287 /* time process was started */ 288 struct timeval started; 289 /* process cpu type */ 290 cpu_type_t cputype; 291 292 uint32_t wq_nthreads; 293 uint32_t wq_run_threads; 294 uint32_t wq_blocked_threads; 295 296 uint32_t p_wq_nthreads; 297 uint32_t p_wq_run_threads; 298 uint32_t p_wq_blocked_threads; 299 300 /* Power info. */ 301 task_power_info_data_t power; 302 task_power_info_data_t b_power; 303 task_power_info_data_t p_power; 304}; 305 306/* 307 * Initialize libtop. If a non-NULL printing function pointer is passed in, 308 * libtop will call the printing function when errors occur. 309 * 310 * Returns zero for success, non-zero for error. 311 */ 312int 313libtop_init(libtop_print_t *a_print, void *a_user_data); 314 315/* Shut down libtop. */ 316void 317libtop_fini(void); 318 319/* 320 * Take a sample. 321 * 322 * If a_reg is FALSE, do not calculate reg, vprvt, rprvt, or rshrd. 323 * 324 * If a_fw is FALSE, do not calculate fw_count, fw_code, fw_data, or 325 * fw_linkedit. 326 * 327 * Returns zero for success, non-zero for error. 328 */ 329int 330libtop_sample(boolean_t a_reg, boolean_t a_fw); 331 332/* 333 * Return a pointer to a structure containing the generic information collected 334 * during the most recent sample. The return value from this function can be 335 * used for the duration of program execution (i.e. the return value does not 336 * change between samples). 337 */ 338const libtop_tsamp_t * 339libtop_tsamp(void); 340 341/* 342 * Type for psamp comparison function. 343 * 344 * Arguments : (void *) : Opaque data pointer. 345 * (libtop_psamp_t *) : psamp. 346 * 347 * Return values : -1 : Second argument less than third argument. 348 * 0 : Second argument equal to third argument. 349 * 1 : Second argument greater than third argument. 350 */ 351typedef int libtop_sort_t (void *, const libtop_psamp_t *, 352 const libtop_psamp_t *); 353 354/* 355 * Sort processes using a_sort(). Pass a_data as the opaque data pointer to 356 * a_sort(). 357 */ 358void 359libtop_psort(libtop_sort_t *a_sort, void *a_data); 360 361/* 362 * Iteratively return a pointer to each process which was in the most recent 363 * sample. If libtop_psort() was called after the most recent libtop_sample() 364 * call, the processes are iterated over in sorted order. Otherwise, they are 365 * iterated over in increasing pid order. 366 * 367 * A NULL return value indicates that there are no more processes to iterate 368 * over. 369 */ 370const libtop_psamp_t * 371libtop_piterate(void); 372 373/* 374 * Set whether to collect memory region information for the process with pid 375 * a_pid. 376 * 377 * Returns zero for success, non-zero for error. 378 */ 379int 380libtop_preg(pid_t a_pid, libtop_preg_t a_preg); 381 382/* 383 * Set the interval between framework updates. 384 * 385 * Returns zero for success, non-zero for error. 386 */ 387int 388libtop_set_interval(uint32_t ival); 389#define LIBTOP_MAX_INTERVAL 100 390 391/* 392 * Return a pointer to a username string (truncated to the first 8 characters), 393 * given a uid. If the uid cannot be matched to a username, NULL is returned. 394 */ 395const char * 396libtop_username(uid_t a_uid); 397 398/* 399 * Return a pointer to a string representation of a process state (names of 400 * states that are contained in libtop_tsamp_t's state_breakdown array). 401 */ 402const char * 403libtop_state_str(uint32_t a_state); 404 405/* 406 * These i64 functions are special functions that operate on an accumulator 407 * and work with overflowing 32-bit integers. So if the value overflows in the kernel 408 * counter, because it is a 32-bit value, they will in most cases capture the 409 * changes overtime to the value. The assumption is that all updates are increments 410 * of 0 or more (based on the deltas) so this doesn't work with values that 411 * potentially go negative. 412 */ 413 414libtop_i64_t 415libtop_i64_init(uint64_t acc, int last_value); 416 417void 418libtop_i64_update(libtop_i64_t *i, int value); 419 420uint64_t 421libtop_i64_value(libtop_i64_t *i); 422 423__END_DECLS 424