From 5fd83771641d15c418f747bd343ba6738d3875f7 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 9 May 2021 14:20:58 -0400 Subject: Import macOS userland adv_cmds-176 basic_cmds-55 bootstrap_cmds-116.100.1 developer_cmds-66 diskdev_cmds-667.40.1 doc_cmds-53.60.1 file_cmds-321.40.3 mail_cmds-35 misc_cmds-34 network_cmds-606.40.1 patch_cmds-17 remote_cmds-63 shell_cmds-216.60.1 system_cmds-880.60.2 text_cmds-106 --- .../vm_purgeable_stat.tproj/entitlements.plist | 8 + .../vm_purgeable_stat.tproj/vm_purgeable_stat.1 | 35 +++ .../vm_purgeable_stat.tproj/vm_purgeable_stat.c | 250 +++++++++++++++++++++ 3 files changed, 293 insertions(+) create mode 100644 system_cmds/vm_purgeable_stat.tproj/entitlements.plist create mode 100644 system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.1 create mode 100644 system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.c (limited to 'system_cmds/vm_purgeable_stat.tproj') diff --git a/system_cmds/vm_purgeable_stat.tproj/entitlements.plist b/system_cmds/vm_purgeable_stat.tproj/entitlements.plist new file mode 100644 index 0000000..b21dbd8 --- /dev/null +++ b/system_cmds/vm_purgeable_stat.tproj/entitlements.plist @@ -0,0 +1,8 @@ + + + + + task_for_pid-allow + + + diff --git a/system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.1 b/system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.1 new file mode 100644 index 0000000..af01185 --- /dev/null +++ b/system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.1 @@ -0,0 +1,35 @@ +.\" Copyright (c) 2013, Apple Inc. All rights reserved. +.\" +.Dd Jan 16, 2013 +.Dt VM_PURGEABLE_STAT 1 +.Os "Mac OS X" +.Sh NAME +.Nm vm_purgeable_stat +.Nd Display purgeable memory information for processes on the system +.Sh SYNOPSIS +.Pp +.Nm vm_purgeable_stat +.Ar -s +Show summary view for system-wide purgeable memory use. The specifies the refresh interval in secs. +.Pp +.Nm vm_purgeable_stat +.Ar -p +Show purgeable memory information for process +.Pp +.Nm vm_purgeable_stat +.Ar -a +Show purgeable memory information for all processes in the system +.Sh DESCRIPTION +The +.Nm vm_purgeable_stat +command prints information about the purgeable memory usage in the system. It shows the counts and sizes of purgeable objects in the system. +.P +.nf +Following is an explanation of columns: +Process-Name: Name of the process +FIFO-PX : FIFO Purgeable objects at priority X. Each entry is of the form / +OBSOLETE : Obselete Purgeable Objects. Each entry is of the form / +LIFO-PX : LIFO Purgeable objects at priority X. Each entry is of the form / +.fi +.Sh SEE ALSO +.Xr vm_stat 1 diff --git a/system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.c b/system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.c new file mode 100644 index 0000000..bfef539 --- /dev/null +++ b/system_cmds/vm_purgeable_stat.tproj/vm_purgeable_stat.c @@ -0,0 +1,250 @@ +/* + * Copyright (c) 1999-2016 Apple Inc. All rights reserved. + * + * @APPLE_LICENSE_HEADER_START@ + * + * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights + * Reserved. This file contains Original Code and/or Modifications of + * Original Code as defined in and that are subject to the Apple Public + * Source License Version 1.0 (the 'License'). You may not use this file + * except in compliance with the License. Please obtain a copy of the + * License at http://www.apple.com/publicsource and read it before using + * this file. + * + * The Original Code and all software distributed under the License are + * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER + * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the + * License for the specific language governing rights and limitations + * under the License." + * + * @APPLE_LICENSE_HEADER_END@ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define USAGE "Usage: vm_purgeable_stat [-a | -p | -s ]\n" +#define PRIV_ERR_MSG "The option specified needs root priveleges." +#define PROC_NAME_LEN 256 +#define KB 1024 +#define PURGEABLE_PRIO_LEVELS VM_VOLATILE_GROUP_SHIFT + +static inline int purge_info_size_adjust(uint64_t size); +static inline char purge_info_unit(uint64_t size); +void print_header(int summary_view); +int get_system_tasks(task_array_t *tasks, mach_msg_type_number_t *count); +int get_task_from_pid(int pid, task_t *task); +void print_purge_info_task(task_t task, int pid); +void print_purge_info_task_array(task_array_t tasks, mach_msg_type_number_t count); +void print_purge_info_summary(int sleep_duration); + +static inline int purge_info_size_adjust(uint64_t size) +{ + while(size > KB) + size /= KB; + return (int)size; +} + +static inline char purge_info_unit(uint64_t size) +{ + char sizes[] = {'B', 'K', 'M', 'G', 'T'}; + int index = 0; + + while(size > KB) { + index++; + size /= KB; + } + return sizes[index]; +} + +void print_header(int summary_view) +{ + if (!summary_view) + printf("%20s ", "Process-Name"); + + printf("%9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s %9s\n", + "FIFO-P0", "FIFO-P1", "FIFO-P2", "FIFO-P3", + "FIFO-P4", "FIFO-P5", "FIFO-P6", "FIFO-P7", + "OBSOLETE", + "LIFO-P0", "LIFO-P1", "LIFO-P2", "LIFO-P3", + "LIFO-P4", "LIFO-P5", "LIFO-P6", "LIFO-P7" + ); +} + +int get_task_from_pid(int pid, task_t *task) +{ + kern_return_t kr; + if (geteuid() != 0) { + fprintf(stderr, "%s\n", PRIV_ERR_MSG); + return -1; + } + kr = task_for_pid(mach_task_self(), pid, task); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "Failed to get task port for pid: %d\n", pid); + return -1; + } + return 0; +} + +int get_system_tasks(task_array_t *tasks, mach_msg_type_number_t *count) +{ + processor_set_name_array_t psets; + mach_msg_type_number_t psetCount; + mach_port_t pset_priv; + kern_return_t ret; + + if (geteuid() != 0) { + fprintf(stderr, "%s\n", PRIV_ERR_MSG); + return -1; + } + + ret = host_processor_sets(mach_host_self(), &psets, &psetCount); + if (ret != KERN_SUCCESS) { + fprintf(stderr, "host_processor_sets() failed: %s\n", mach_error_string(ret)); + return -1; + } + if (psetCount != 1) { + fprintf(stderr, "Assertion Failure: pset count greater than one (%d)\n", psetCount); + return -1; + } + + /* convert the processor-set-name port to a privileged port */ + ret = host_processor_set_priv(mach_host_self(), psets[0], &pset_priv); + if (ret != KERN_SUCCESS) { + fprintf(stderr, "host_processor_set_priv() failed: %s\n", mach_error_string(ret)); + return -1; + } + mach_port_deallocate(mach_task_self(), psets[0]); + vm_deallocate(mach_task_self(), (vm_address_t)psets, (vm_size_t)psetCount * sizeof(mach_port_t)); + + /* convert the processor-set-priv to a list of tasks for the processor set */ + ret = processor_set_tasks(pset_priv, tasks, count); + if (ret != KERN_SUCCESS) { + fprintf(stderr, "processor_set_tasks() failed: %s\n", mach_error_string(ret)); + return -1; + } + mach_port_deallocate(mach_task_self(), pset_priv); + return 0; +} + +void print_purge_info_task(task_t task, int pid) +{ + task_purgable_info_t info; + kern_return_t kr; + int i; + char pname[PROC_NAME_LEN]; + + kr = task_purgable_info(task, &info); + if (kr != KERN_SUCCESS) { + fprintf(stderr, "(pid: %d) task_purgable_info() failed: %s\n", pid, mach_error_string(kr)); + return; + } + if (0 == proc_name(pid, pname, PROC_NAME_LEN)) + strncpy(pname, "Unknown", 7); + pname[20] = 0; + printf("%20s ", pname); + for (i=0; i