* Implemented a (private for now) get_system_info_etc() call, that can retrieve
various system information. * Implemented retrieving some VM stats via this call. * The VM now maintains a page fault counter, and sets system_info::page_faults accordingly. * Added a (pretty simple) "vmstat" command line app. * Minor cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@27597 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
b0a63e7a2a
commit
ca7cb625b9
@ -50,7 +50,7 @@ BEOS_BIN = "[" addattr alert arp base64 basename bc beep bootman bzip2 cal cat
|
||||
traceroute translate true tsort tty
|
||||
uname unchop unexpand unmount uniq unrar unshar unzip unzipsfx <bin>updatedb
|
||||
uptime urlwrapper usb_dev_info useradd uudecode uuencode
|
||||
vdir version vim waitfor wc wget whoami xargs xres yes
|
||||
vdir version vim vmstat waitfor wc wget whoami xargs xres yes
|
||||
zdiff zforce zgrep zip zipcloak <bin>zipgrep zipnote zipsplit zmore znew
|
||||
;
|
||||
|
||||
@ -138,7 +138,7 @@ BEOS_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com etherpci $(X86_ONLY)ipro1000
|
||||
;
|
||||
#BEOS_ADD_ONS_DRIVERS_ACPI = $(X86_ONLY)acpi_button ;
|
||||
BEOS_ADD_ONS_BUS_MANAGERS = pci $(X86_ONLY)ps2 $(X86_ONLY)isa ide scsi
|
||||
config_manager agp_gart usb firewire
|
||||
config_manager agp_gart usb firewire #acpi
|
||||
;
|
||||
BEOS_ADD_ONS_FILE_SYSTEMS = bfs cdda ext2 fat iso9660 $(GPL_ONLY)reiserfs ;
|
||||
#googlefs nfs $(GPL_ONLY)ntfs ;
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2004-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _KERNEL_SYSTEM_INFO_H
|
||||
@ -16,12 +16,14 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
extern status_t system_info_init(struct kernel_args *args);
|
||||
extern uint32 get_haiku_revision(void);
|
||||
extern uint32 get_haiku_revision(void);
|
||||
|
||||
extern status_t _user_get_system_info(system_info *userInfo, size_t size);
|
||||
extern status_t _user_get_system_info_etc(int32 id, void *buffer,
|
||||
size_t bufferSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _KRENEL_SYSTEM_INFO_H */
|
||||
#endif /* _KERNEL_SYSTEM_INFO_H */
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||
@ -16,6 +16,7 @@
|
||||
|
||||
struct kernel_args;
|
||||
struct team;
|
||||
struct system_memory_info;
|
||||
struct vm_page;
|
||||
struct VMCache;
|
||||
struct vm_area;
|
||||
@ -93,6 +94,8 @@ status_t vm_map_page(struct vm_area *area, struct vm_page *page, addr_t address,
|
||||
status_t vm_get_physical_page(addr_t paddr, addr_t *vaddr, uint32 flags);
|
||||
status_t vm_put_physical_page(addr_t vaddr);
|
||||
|
||||
void vm_get_info(struct system_memory_info *info);
|
||||
uint32 vm_num_page_faults(void);
|
||||
off_t vm_available_memory(void);
|
||||
off_t vm_available_not_needed_memory(void);
|
||||
|
||||
|
@ -406,6 +406,8 @@ extern int64 _kern_atomic_get64(vint64 *value);
|
||||
|
||||
/* System informations */
|
||||
extern status_t _kern_get_system_info(system_info *info, size_t size);
|
||||
extern status_t _kern_get_system_info_etc(int32 id, void *buffer,
|
||||
size_t bufferSize);
|
||||
extern status_t _kern_analyze_scheduling(bigtime_t from, bigtime_t until,
|
||||
void* buffer, size_t size,
|
||||
struct scheduling_analysis* analysis);
|
||||
|
37
headers/private/system/system_info.h
Normal file
37
headers/private/system/system_info.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2008 Haiku, Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _SYSTEM_INFO_H
|
||||
#define _SYSTEM_INFO_H
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
#define B_MEMORY_INFO 'memo'
|
||||
|
||||
struct system_memory_info {
|
||||
uint64 max_memory;
|
||||
uint64 free_memory;
|
||||
uint64 needed_memory;
|
||||
uint64 max_swap_space;
|
||||
uint64 free_swap_space;
|
||||
uint64 block_cache_memory;
|
||||
uint32 page_faults;
|
||||
|
||||
// TODO: add active/inactive page counts, swap in/out, ...
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern status_t get_system_info_etc(int32 id, void *buffer, size_t bufferSize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _SYSTEM_INFO_H */
|
@ -2,10 +2,7 @@ SubDir HAIKU_TOP src bin ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
UsePrivateHeaders app ;
|
||||
UsePrivateHeaders shared ;
|
||||
UsePrivateHeaders storage ;
|
||||
UseLibraryHeaders usb ;
|
||||
UsePrivateHeaders app shared storage usb ;
|
||||
UsePrivateSystemHeaders ;
|
||||
SubDirHdrs $(HAIKU_TOP) src add-ons kernel file_cache ;
|
||||
|
||||
@ -46,6 +43,7 @@ StdBinCommands
|
||||
sysinfo.c
|
||||
unchop.c
|
||||
uptime.cpp
|
||||
vmstat.cpp
|
||||
waitfor.c
|
||||
# whoami.c
|
||||
: : $(haiku-utils_rsrc) ;
|
||||
|
109
src/bin/vmstat.cpp
Normal file
109
src/bin/vmstat.cpp
Normal file
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <system_info.h>
|
||||
|
||||
|
||||
static struct option const kLongOptions[] = {
|
||||
{"periodic", no_argument, 0, 'p'},
|
||||
{"rate", required_argument, 0, 'r'},
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{NULL}
|
||||
};
|
||||
|
||||
extern const char *__progname;
|
||||
static const char *kProgramName = __progname;
|
||||
|
||||
|
||||
void
|
||||
usage(int status)
|
||||
{
|
||||
fprintf(stderr, "usage: %s [-p] [-r <time>]\n"
|
||||
" -p,--periodic\tDumps changes periodically every second.\n",
|
||||
" -r,--rate\tDumps changes periodically every <time> milli seconds.\n",
|
||||
kProgramName);
|
||||
|
||||
exit(status);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
bool periodically = false;
|
||||
bigtime_t rate = 1000000LL;
|
||||
|
||||
int c;
|
||||
while ((c = getopt_long(argc, argv, "pr:h", kLongOptions, NULL)) != -1) {
|
||||
switch (c) {
|
||||
case 0:
|
||||
break;
|
||||
case 'p':
|
||||
periodically = true;
|
||||
break;
|
||||
case 'r':
|
||||
rate = atoi(optarg) * 1000LL;
|
||||
if (rate <= 0) {
|
||||
fprintf(stderr, "%s: Invalid rate: %s\n",
|
||||
kProgramName, optarg);
|
||||
return 1;
|
||||
}
|
||||
periodically = true;
|
||||
break;
|
||||
case 'h':
|
||||
usage(0);
|
||||
break;
|
||||
default:
|
||||
usage(1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
system_memory_info info;
|
||||
status_t status = get_system_info_etc(B_MEMORY_INFO, &info,
|
||||
sizeof(system_memory_info));
|
||||
if (status != B_OK) {
|
||||
fprintf(stderr, "%s: cannot get system info: %s\n", kProgramName,
|
||||
strerror(status));
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf("max memory:\t\t%Lu\n", info.max_memory);
|
||||
printf("free memory:\t\t%Lu\n", info.free_memory);
|
||||
printf("needed memory:\t\t%Lu\n", info.needed_memory);
|
||||
printf("block cache memory:\t%Lu\n", info.block_cache_memory);
|
||||
printf("max swap space:\t\t%Lu\n", info.max_swap_space);
|
||||
printf("free swap space:\t%Lu\n", info.free_swap_space);
|
||||
printf("page faults:\t\t%lu\n", info.page_faults);
|
||||
|
||||
if (periodically) {
|
||||
puts("\npage faults used memory used swap block cache");
|
||||
system_memory_info lastInfo = info;
|
||||
|
||||
while (true) {
|
||||
snooze(rate);
|
||||
|
||||
get_system_info_etc(B_MEMORY_INFO, &info,
|
||||
sizeof(system_memory_info));
|
||||
|
||||
printf("%11ld %11Ld %11Ld %11Ld\n",
|
||||
(int32)info.page_faults - lastInfo.page_faults,
|
||||
(info.max_memory - info.free_memory)
|
||||
- (lastInfo.max_memory - lastInfo.free_memory),
|
||||
(info.max_swap_space - info.free_swap_space)
|
||||
- (lastInfo.max_swap_space - lastInfo.free_swap_space),
|
||||
info.block_cache_memory - lastInfo.block_cache_memory);
|
||||
|
||||
lastInfo = info;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -16,8 +16,8 @@
|
||||
#include <frame_buffer_console.h>
|
||||
#include <int.h>
|
||||
#include <kernel.h>
|
||||
#include <ksystem_info.h>
|
||||
#include <smp.h>
|
||||
#include <system_info.h>
|
||||
#include <thread.h>
|
||||
#include <tracing.h>
|
||||
#include <vm.h>
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <kmodule.h>
|
||||
#include <kscheduler.h>
|
||||
#include <ksyscalls.h>
|
||||
#include <ksystem_info.h>
|
||||
#include <lock.h>
|
||||
#include <low_resource_manager.h>
|
||||
#include <messaging.h>
|
||||
@ -44,7 +45,6 @@
|
||||
#include <real_time_clock.h>
|
||||
#include <sem.h>
|
||||
#include <smp.h>
|
||||
#include <system_info.h>
|
||||
#include <team.h>
|
||||
#include <timer.h>
|
||||
#include <user_debugger.h>
|
||||
|
@ -4,45 +4,45 @@
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
/* Big case statement for dispatching syscalls */
|
||||
/*! Big case statement for dispatching syscalls */
|
||||
|
||||
#include <kernel.h>
|
||||
#include <ksyscalls.h>
|
||||
#include <syscalls.h>
|
||||
#include <generic_syscall.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <arch_config.h>
|
||||
#include <arch/system_info.h>
|
||||
#include <cpu.h>
|
||||
#include <debug.h>
|
||||
#include <int.h>
|
||||
#include <disk_device_manager/ddm_userland_interface.h>
|
||||
#include <elf.h>
|
||||
#include <vfs.h>
|
||||
#include <vm.h>
|
||||
#include <thread.h>
|
||||
#include <frame_buffer_console.h>
|
||||
#include <fs/fd.h>
|
||||
#include <fs/node_monitor.h>
|
||||
#include <generic_syscall.h>
|
||||
#include <int.h>
|
||||
#include <kernel.h>
|
||||
#include <kimage.h>
|
||||
#include <ksignal.h>
|
||||
#include <ksyscalls.h>
|
||||
#include <ksystem_info.h>
|
||||
#include <messaging.h>
|
||||
#include <port.h>
|
||||
#include <posix/realtime_sem.h>
|
||||
#include <posix/xsi_message_queue.h>
|
||||
#include <posix/xsi_semaphore.h>
|
||||
#include <sem.h>
|
||||
#include <port.h>
|
||||
#include <cpu.h>
|
||||
#include <arch_config.h>
|
||||
#include <disk_device_manager/ddm_userland_interface.h>
|
||||
#include <sys/resource.h>
|
||||
#include <fs/fd.h>
|
||||
#include <fs/node_monitor.h>
|
||||
#include <kimage.h>
|
||||
#include <ksignal.h>
|
||||
#include <real_time_clock.h>
|
||||
#include <safemode.h>
|
||||
#include <system_info.h>
|
||||
#include <sem.h>
|
||||
#include <sys/resource.h>
|
||||
#include <syscalls.h>
|
||||
#include <thread.h>
|
||||
#include <tracing.h>
|
||||
#include <user_atomic.h>
|
||||
#include <arch/system_info.h>
|
||||
#include <messaging.h>
|
||||
#include <frame_buffer_console.h>
|
||||
#include <usergroup.h>
|
||||
#include <vfs.h>
|
||||
#include <vm.h>
|
||||
#include <wait_for_objects.h>
|
||||
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "syscall_numbers.h"
|
||||
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <ksystem_info.h>
|
||||
#include <system_info.h>
|
||||
#include <arch/system_info.h>
|
||||
|
||||
@ -16,6 +17,7 @@
|
||||
#include <OS.h>
|
||||
#include <KernelExport.h>
|
||||
|
||||
#include <block_cache.h>
|
||||
#include <cpu.h>
|
||||
#include <debug.h>
|
||||
#include <kernel.h>
|
||||
@ -137,3 +139,29 @@ _user_get_system_info(system_info *userInfo, size_t size)
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
_user_get_system_info_etc(int32 id, void* userInfo, size_t size)
|
||||
{
|
||||
if (userInfo == NULL || !IS_USER_ADDRESS(userInfo))
|
||||
return B_BAD_ADDRESS;
|
||||
|
||||
switch (id) {
|
||||
case B_MEMORY_INFO:
|
||||
{
|
||||
if (size < sizeof(system_memory_info))
|
||||
return B_BAD_VALUE;
|
||||
|
||||
system_memory_info info;
|
||||
vm_get_info(&info);
|
||||
|
||||
info.block_cache_memory = block_cache_used_memory();
|
||||
|
||||
return user_memcpy(userInfo, &info, sizeof(system_memory_info));
|
||||
}
|
||||
|
||||
default:
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <kernel_daemon.h>
|
||||
#include <slab/Slab.h>
|
||||
#include <syscalls.h>
|
||||
#include <system_info.h>
|
||||
#include <tracing.h>
|
||||
#include <util/AutoLock.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
@ -1248,3 +1249,16 @@ swap_total_swap_pages()
|
||||
}
|
||||
|
||||
#endif // ENABLE_SWAP_SUPPORT
|
||||
|
||||
void
|
||||
swap_get_info(struct system_memory_info *info)
|
||||
{
|
||||
#if ENABLE_SWAP_SUPPORT
|
||||
info->max_swap_space = swap_total_swap_pages() * B_PAGE_SIZE;
|
||||
info->free_swap_space = swap_available_pages() * B_PAGE_SIZE;
|
||||
#else
|
||||
info->max_swap_space = 0;
|
||||
info->free_swap_space = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@
|
||||
|
||||
typedef page_num_t swap_addr_t;
|
||||
struct swap_block;
|
||||
struct system_memory_info;
|
||||
|
||||
|
||||
extern "C" {
|
||||
void swap_init(void);
|
||||
@ -23,6 +25,7 @@ extern "C" {
|
||||
bool swap_free_page_swap_space(vm_page *page);
|
||||
uint32 swap_available_pages(void);
|
||||
uint32 swap_total_swap_pages(void);
|
||||
void swap_get_info(struct system_memory_info *info);
|
||||
}
|
||||
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <lock.h>
|
||||
#include <low_resource_manager.h>
|
||||
#include <smp.h>
|
||||
#include <system_info.h>
|
||||
#include <thread.h>
|
||||
#include <team.h>
|
||||
#include <util/AutoLock.h>
|
||||
@ -43,6 +44,8 @@
|
||||
#include <vm_page.h>
|
||||
#include <vm_priv.h>
|
||||
|
||||
#include "VMAnonymousCache.h"
|
||||
|
||||
|
||||
//#define TRACE_VM
|
||||
//#define TRACE_FAULTS
|
||||
@ -194,6 +197,7 @@ static mutex sAreaCacheLock = MUTEX_INITIALIZER("area->cache");
|
||||
static off_t sAvailableMemory;
|
||||
static off_t sNeededMemory;
|
||||
static mutex sAvailableMemoryLock = MUTEX_INITIALIZER("available memory lock");
|
||||
static uint32 sPageFaults;
|
||||
|
||||
#if DEBUG_CACHE_LIST
|
||||
|
||||
@ -4158,15 +4162,15 @@ status_t
|
||||
vm_page_fault(addr_t address, addr_t faultAddress, bool isWrite, bool isUser,
|
||||
addr_t *newIP)
|
||||
{
|
||||
FTRACE(("vm_page_fault: page fault at 0x%lx, ip 0x%lx\n", address, faultAddress));
|
||||
|
||||
*newIP = 0;
|
||||
FTRACE(("vm_page_fault: page fault at 0x%lx, ip 0x%lx\n", address,
|
||||
faultAddress));
|
||||
|
||||
addr_t pageAddress = ROUNDOWN(address, B_PAGE_SIZE);
|
||||
vm_address_space *addressSpace = NULL;
|
||||
|
||||
status_t status = B_OK;
|
||||
|
||||
vm_address_space *addressSpace;
|
||||
*newIP = 0;
|
||||
atomic_add((int32*)&sPageFaults, 1);
|
||||
|
||||
if (IS_KERNEL_ADDRESS(pageAddress)) {
|
||||
addressSpace = vm_get_kernel_address_space();
|
||||
@ -4850,6 +4854,27 @@ vm_get_physical_page(addr_t paddr, addr_t *_vaddr, uint32 flags)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
vm_get_info(system_memory_info* info)
|
||||
{
|
||||
swap_get_info(info);
|
||||
|
||||
info->max_memory = vm_page_num_pages() * B_PAGE_SIZE;
|
||||
info->page_faults = sPageFaults;
|
||||
|
||||
MutexLocker locker(sAvailableMemoryLock);
|
||||
info->free_memory = sAvailableMemory;
|
||||
info->needed_memory = sNeededMemory;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
vm_num_page_faults(void)
|
||||
{
|
||||
return sPageFaults;
|
||||
}
|
||||
|
||||
|
||||
off_t
|
||||
vm_available_memory(void)
|
||||
{
|
||||
|
@ -2122,6 +2122,7 @@ vm_page_get_stats(system_info *info)
|
||||
info->used_pages = gMappedPagesCount - blockCachePages;
|
||||
info->cached_pages = sNumPages >= free + info->used_pages
|
||||
? sNumPages - free - info->used_pages : 0;
|
||||
info->page_faults = vm_num_page_faults();
|
||||
|
||||
// TODO: We don't consider pages used for page directories/tables yet.
|
||||
}
|
||||
|
@ -1,11 +1,13 @@
|
||||
/*
|
||||
** Copyright 2002-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
||||
** Distributed under the terms of the OpenBeOS License.
|
||||
*/
|
||||
/*
|
||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include "syscalls.h"
|
||||
|
||||
#include <syscalls.h>
|
||||
#include <system_info.h>
|
||||
|
||||
|
||||
status_t
|
||||
@ -18,6 +20,16 @@ _get_system_info(system_info *info, size_t size)
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
get_system_info_etc(int32 id, void *info, size_t size)
|
||||
{
|
||||
if (info == NULL || size == 0 || id < 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
return _kern_get_system_info_etc(id, info, size);
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
is_computer_on(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user