/*  Program to print out memory usage information in bytes.
 *
 *  Based on the source of top (available in the Darwin project system_cmds-230).
 *  
 *  Author: Eric Carlson, carl0240@tc.umn.edu, 11/9/2002
 *  
 *  This software is supplied 'as is', with no warranty. 
 *  You are free to use and/or redistribute this source, modified or unmodified,
 *  in any form.
 */

#include <stdio.h>
#include <stdlib.h>
#include <mach/mach.h>
#include <mach/bootstrap.h>
#include <mach/host_info.h>
#include <mach/mach_error.h>
#include <mach/mach_types.h>
#include <mach/message.h>
#include <mach/vm_region.h>
#include <mach/vm_map.h>
#include <mach/vm_types.h>
#include <mach/vm_prot.h>
#include <mach/shared_memory_server.h>

int main(int argc, char* argv[]) {
    mach_port_t host_priv_port;
    vm_size_t pagesize;
    int host_count;
    kern_return_t error;
    vm_statistics_data_t vm_stat;
    unsigned long long  total_resident_size,
                        active_resident_size,
                        inactive_resident_size,
                        wire_resident_size,
                        free_size;
    
    //get a mach port
    host_priv_port = mach_host_self();
    
    //get the page size (in bytes)
    (void) host_page_size(host_priv_port, &pagesize);

    /* get total - systemwide main memory usage structure */
    host_count = HOST_VM_INFO_COUNT;
    error = host_statistics(host_priv_port, HOST_VM_INFO,
                (host_info_t)&vm_stat, &host_count);
    if (error != KERN_SUCCESS) {
        mach_error("host_info", error);
        exit(EXIT_FAILURE);
    }
    
    /* display main memory statistics */
    active_resident_size = vm_stat.active_count * pagesize;
    inactive_resident_size = vm_stat.inactive_count * pagesize;
    wire_resident_size = vm_stat.wire_count * pagesize;
    total_resident_size = (vm_stat.active_count + vm_stat.inactive_count + vm_stat.wire_count) * pagesize;
    free_size = vm_stat.free_count * pagesize;

    printf("%llu wired, ", wire_resident_size);
    printf("%llu active, ", active_resident_size);
    printf("%llu inactive, ", inactive_resident_size);
    printf("%llu used, ", total_resident_size);
    printf("%llu free\n", free_size);

    exit(EXIT_SUCCESS);
}
