Version: (using KDE 4.2.4) Compiler: gcc 4.2.1 OS: FreeBSD Installed from: FreeBSD Ports The memory usage report on FreeBSD is broken because it uses obsolete sysctl nodes and the wrong data types: on a 4GB amd64 system for example the total memory is reported as 17GB. The included patch fixes those problems. However, the cache and buffer statistics are misleading since it's impossible to obtain accurate data from userland on FreeBSD due to the VM architecture. Other applications do report the same data so I've included it too. kdebase-4.2.4/apps/cmake/modules/FindKVM.cmake: # - Try to find the KVM library # Once done this will define # # KVM_FOUND - system has the KVM library # KVM_INCLUDE_DIR - the KVM include directory # KVM_LIBRARIES - The libraries needed to use KVM IF(KVM_LIBRARIES) SET(KVM_FIND_QUIETLY TRUE) ENDIF(KVM_LIBRARIES) # IF(SSL_EAY_DEBUG AND SSL_EAY_RELEASE) # SET(LIB_FOUND 1) # ENDIF(SSL_EAY_DEBUG AND SSL_EAY_RELEASE) FIND_PATH(KVM_INCLUDE_DIR kvm.h ) FIND_LIBRARY(KVM_LIBRARIES NAMES kvm ) IF(KVM_INCLUDE_DIR AND KVM_LIBRARIES) SET(KVM_FOUND TRUE) ELSE(KVM_INCLUDE_DIR AND KVM_LIBRARIES) SET(KVM_FOUND FALSE) ENDIF (KVM_INCLUDE_DIR AND KVM_LIBRARIES) IF (KVM_FOUND) IF (NOT KVM_FIND_QUIETLY) MESSAGE(STATUS "Found libKVM: ${KVM_LIBRARIES}") ENDIF (NOT KVM_FIND_QUIETLY) ELSE (KVM_FOUND) IF (KVM_FIND_REQUIRED) MESSAGE(FATAL_ERROR "Could NOT find libKVM") ENDIF (KVM_FIND_REQUIRED) ENDIF (KVM_FOUND) MARK_AS_ADVANCED(KVM_INCLUDE_DIR KVM_LIBRARIES) kdebase-4.2.4.diff: Only in kdebase4/work/kdebase-4.2.4/apps/cmake/modules: FindKVM.cmake diff -U3 -r kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt kdebase4/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt --- kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt 2009-06-06 21:07:45.000000000 +0100 +++ kdebase4/work/kdebase-4.2.4/apps/kinfocenter/CMakeLists.txt 2009-06-06 21:42:31.000000000 +0100 @@ -57,6 +57,13 @@ kde4_add_kdeinit_executable( kinfocenter ${kinfocenter_SRCS}) +IF (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") + find_package(KVM REQUIRED) + include_directories(${KVM_INCLUDE_DIRS}) + set(LIBS ${LIBS} ${KVM_LIBRARIES}) + target_link_libraries(kinfocenter ${LIBS}) +ENDIF (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") + target_link_libraries(kdeinit_kinfocenter ${KDE4_KIO_LIBS} ${KDE4_KHTML_LIBS} ${KDE4_KUTILS_LIBS} ) install(TARGETS kdeinit_kinfocenter ${INSTALL_TARGETS_DEFAULT_ARGS}) diff -U3 -r kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp kdebase4/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp --- kdebase4_orig/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp 2009-06-06 21:07:45.000000000 +0100 +++ kdebase4/work/kdebase-4.2.4/apps/kinfocenter/memory/memory_fbsd.cpp 2009-06-06 21:42:15.000000000 +0100 @@ -1,90 +1,67 @@ - #include <sys/types.h> #include <sys/sysctl.h> #include <sys/vmmeter.h> #include <vm/vm_param.h> +#include <kvm.h> -#include <stdlib.h> -#include <stdio.h> +#include <fcntl.h> +#include <paths.h> #include <unistd.h> void KCMMemory::fetchValues() { - char blah[10], buf[80], *used_str, *total_str; /* Stuff for sysctl */ - int memory; size_t len; - /* Stuff for swap display */ - int used, total, _free; - FILE *pipe; - len=sizeof(memory); + unsigned long memory; + len = sizeof(memory); sysctlbyname("hw.physmem", &memory, &len, NULL, 0); - snprintf(blah, 10, "%d", memory); // Numerical values // total physical memory (without swap space) memoryInfos[TOTAL_MEM] = MEMORY(memory); + + unsigned int cached; + len = sizeof(cached); + if (sysctlbyname("vm.stats.vm.v_cache_count", &cached, &len, NULL, 0) == -1 || !len) + memoryInfos[CACHED_MEM] = NO_MEMORY_INFO; + else + memoryInfos[CACHED_MEM] = MEMORY(cached) * PAGE_SIZE; + + unsigned int free; + len = sizeof(free); + if (sysctlbyname("vm.stats.vm.v_free_count", &free, &len, NULL, 0) == -1 || !len) + memoryInfos[FREE_MEM] = NO_MEMORY_INFO; + else + memoryInfos[FREE_MEM] = MEMORY(free) * PAGE_SIZE; // added by Brad Hughes bhughes@trolltech.com struct vmtotal vmem; -#ifdef __GNUC__ - #warning "FIXME: memoryInfos[CACHED_MEM]" -#endif - memoryInfos[CACHED_MEM] = NO_MEMORY_INFO; - - // The sysctls don't work in a nice manner under FreeBSD v2.2.x - // so we assume that if sysctlbyname doesn't return what we - // prefer, assume it's the old data types. FreeBSD prior - // to 4.0-R isn't supported by the rest of KDE, so what is - // this code doing here. len = sizeof(vmem); - if (sysctlbyname("vm.vmmeter", &vmem, &len, NULL, 0) == 0) - memoryInfos[SHARED_MEM] = MEMORY(vmem.t_armshr) * PAGE_SIZE; - else - memoryInfos[SHARED_MEM] = NO_MEMORY_INFO; - - int buffers; - len = sizeof (buffers); - if ((sysctlbyname("vfs.bufspace", &buffers, &len, NULL, 0) == -1) || !len) - memoryInfos[BUFFER_MEM] = NO_MEMORY_INFO; + if (sysctlbyname("vm.vmtotal", &vmem, &len, NULL, 0) == -1 || !len) + memoryInfos[SHARED_MEM] = NO_MEMORY_INFO; else - memoryInfos[BUFFER_MEM] = MEMORY(buffers); + memoryInfos[SHARED_MEM] = MEMORY(vmem.t_armshr) * PAGE_SIZE; - // total free physical memory (without swap space) - int free; - len = sizeof (buffers); - if ((sysctlbyname("vm.stats.vm.v_free_count", &free, &len, NULL, 0) == -1) || !len) - memoryInfos[FREE_MEM] = NO_MEMORY_INFO; + long buffers; + len = sizeof(buffers); + if ((sysctlbyname("vfs.bufspace", &buffers, &len, NULL, 0) == -1) || !len) + memoryInfos[BUFFER_MEM] = NO_MEMORY_INFO; else - memoryInfos[FREE_MEM] = MEMORY(free) * getpagesize(); + memoryInfos[BUFFER_MEM] = MEMORY(buffers); - // Q&D hack for swap display. Borrowed from xsysinfo-1.4 - if ((pipe = popen("/usr/sbin/pstat -ks", "r")) == NULL) { - used = total = 1; - return; + struct kvm_swap swap[1]; + kvm_t *kvm_handle; + kvm_handle = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open"); + + if (kvm_handle != NULL && kvm_getswapinfo(kvm_handle, swap, 1, 0) != -1) { + memoryInfos[SWAP_MEM] = MEMORY(swap[0].ksw_total) * PAGE_SIZE; + memoryInfos[FREESWAP_MEM] = MEMORY(swap[0].ksw_total - swap[0].ksw_used) * PAGE_SIZE; } - fgets(buf, sizeof(buf), pipe); - fgets(buf, sizeof(buf), pipe); - fgets(buf, sizeof(buf), pipe); - fgets(buf, sizeof(buf), pipe); - pclose(pipe); - - strtok(buf, " "); - total_str = strtok(NULL, " "); - used_str = strtok(NULL, " "); - used = atoi(used_str); - total = atoi(total_str); - - _free=total-used; - - // total size of all swap-partitions - memoryInfos[SWAP_MEM] = MEMORY(total) * 1024; - - // free memory in swap-partitions - memoryInfos[FREESWAP_MEM] = MEMORY(_free) * 1024; + if (kvm_handle != NULL) + kvm_close(kvm_handle); }
Created attachment 34333 [details] libkvm cmake module
Created attachment 34334 [details] Patch to fix memory report on FreeBSD
Created attachment 40618 [details] Updated patch to kinfocenter to fix memory report on FreeBSD
SVN commit 1087863 by rkcosta: Fix memory usage information on FreeBSD 5.x+. Patch by Bruce Cran from the FreeBSD team. BUG: 195507 M +5 -0 CMakeLists.txt M +35 -58 memory/memory_fbsd.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=1087863
SVN commit 1087867 by rkcosta: Backport r1087863. Fix memory usage information on FreeBSD 5.x+. Patch by Bruce Cran from the FreeBSD team. CCBUG: 195507 M +5 -0 CMakeLists.txt M +35 -58 memory/memory_fbsd.cpp WebSVN link: http://websvn.kde.org/?view=rev&revision=1087867