1/* 2 * Copyright (c) 2009 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23/* 24cc alloccount.c -o alloccount -Wall -framework IOKit 25 */ 26 27#include <sysexits.h> 28#include <malloc/malloc.h> 29#include <CoreFoundation/CoreFoundation.h> 30#include <IOKit/IOKitLib.h> 31#include <IOKit/IOKitKeys.h> 32 33/********************************************************************* 34*********************************************************************/ 35static Boolean printNumber( 36 CFDictionaryRef dict, 37 CFStringRef name, 38 char ** nameCString) 39{ 40 int result = FALSE; 41 CFIndex nameLength = 0; 42 static char * nameBuffer = NULL; // free if nameCString is NULL 43 CFNumberRef num = NULL; // do not release 44 SInt32 num32 = 0; 45 Boolean gotName = FALSE; 46 Boolean gotNum = FALSE; 47 48 /* Note that errors displaying the name and value are not considered 49 * fatal and do not affect the exit status of the program. 50 */ 51 num = (CFNumberRef)CFDictionaryGetValue(dict, name); 52 if (num) { 53 nameLength = CFStringGetMaximumSizeForEncoding(CFStringGetLength(name), 54 kCFStringEncodingUTF8); 55 if (!nameCString || !*nameCString) { 56 nameBuffer = (char *)malloc((1 + nameLength) * sizeof(char)); 57 } else if ((1 + nameLength) > malloc_size(nameBuffer)) { 58 nameBuffer = (char *)realloc(*nameCString, 59 (1 + nameLength) * sizeof(char)); 60 } 61 if (nameBuffer) { 62 gotName = CFStringGetCString(name, nameBuffer, 1 + nameLength, 63 kCFStringEncodingUTF8); 64 } else { 65 fprintf(stderr, "Memory allocation failure.\n"); 66 goto finish; 67 } 68 printf("%22s = ", gotName ? nameBuffer : "??"); 69 70 if (CFNumberGetTypeID() == CFGetTypeID(num)) { 71 gotNum = CFNumberGetValue(num, kCFNumberSInt32Type, &num32); 72 } 73 if (gotNum) { 74 printf("0x%08lx = %4lu K\n", 75 (unsigned long)num32, 76 (unsigned long)(num32 / 1024)); 77 } else { 78 printf("?? (error reading/converting value)\n"); 79 } 80 } 81 82 result = TRUE; 83 84finish: 85 if (nameCString) { 86 *nameCString = nameBuffer; 87 } else { 88 if (nameBuffer) free(nameBuffer); 89 } 90 return result; 91} 92 93/********************************************************************* 94*********************************************************************/ 95int main(int argc, char ** argv) 96{ 97 int result = EX_OSERR; 98 io_registry_entry_t root = IO_OBJECT_NULL; // must IOObjectRelease() 99 CFDictionaryRef rootProps = NULL; // must release 100 CFDictionaryRef allocInfo = NULL; // do not release 101 kern_return_t status = KERN_FAILURE; 102 char * nameCString = NULL; // must free 103 104 // Obtain the registry root entry. 105 106 root = IORegistryGetRootEntry(kIOMasterPortDefault); 107 if (!root) { 108 fprintf(stderr, "Error: Can't get registry root.\n"); 109 goto finish; 110 } 111 112 status = IORegistryEntryCreateCFProperties(root, 113 (CFMutableDictionaryRef *)&rootProps, 114 kCFAllocatorDefault, kNilOptions ); 115 if (KERN_SUCCESS != status) { 116 fprintf(stderr, "Error: Can't read registry root properties.\n"); 117 goto finish; 118 } 119 if (CFDictionaryGetTypeID() != CFGetTypeID(rootProps)) { 120 fprintf(stderr, "Error: Registry root properties not a dictionary.\n"); 121 goto finish; 122 } 123 124 allocInfo = (CFDictionaryRef)CFDictionaryGetValue(rootProps, 125 CFSTR(kIOKitDiagnosticsKey)); 126 if (!allocInfo) { 127 fprintf(stderr, "Error: Allocation information missing.\n"); 128 goto finish; 129 } 130 if (CFDictionaryGetTypeID() != CFGetTypeID(allocInfo)) { 131 fprintf(stderr, "Error: Allocation information not a dictionary.\n"); 132 goto finish; 133 } 134 135 if (!(printNumber(allocInfo, CFSTR("Instance allocation"), &nameCString) && 136 printNumber(allocInfo, CFSTR("Container allocation"), &nameCString) && 137 printNumber(allocInfo, CFSTR("IOMalloc allocation"), &nameCString) && 138 printNumber(allocInfo, CFSTR("Pageable allocation"), &nameCString) )) { 139 140 goto finish; 141 } 142 143 result = EX_OK; 144 145finish: 146 if (nameCString) free(nameCString); 147 if (rootProps) CFRelease(rootProps); 148 if (root != IO_OBJECT_NULL) IOObjectRelease(root); 149 150 return result; 151} 152 153