/* * $Revision: 2523 $ * * last checkin: * $Author: gutwenger $ * $Date: 2012-07-02 20:59:27 +0200 (Mon, 02 Jul 2012) $ ***************************************************************/ /** \file * \brief Decalration of System class which provides unified * access to system information. * * \author Carsten Gutwenger * * \par License: * This file is part of the Open Graph Drawing Framework (OGDF). * * \par * Copyright (C)
* See README.txt in the root directory of the OGDF installation for details. * * \par * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * Version 2 or 3 as published by the Free Software Foundation; * see the file LICENSE.txt included in the packaging of this file * for details. * * \par * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * \par * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * * \see http://www.gnu.org/copyleft/gpl.html ***************************************************************/ #ifdef _MSC_VER #pragma once #endif #ifndef OGDF_SYSTEM_H #define OGDF_SYSTEM_H #include "basic.h" #if defined(OGDF_SYSTEM_OSX) #include #elif defined(OGDF_SYSTEM_UNIX) || defined(__MINGW32__) #include #endif // detect processor architecture we're compiling for // // OGDF_ARCH_X86 Intel / AMD x86 32-bit processors // OGDF_ARCH_X64 Intel / AMD x86 64-bit processors // OGDF_ARCH_IA64 Intel Itanium // OGDF_ARCH_PPC PowerPC // OGDF_ARCH_SPARC SUN SPARC // OGDF_ARCH_SPARC_V9 SUN SPARC V9 #if defined(_M_X64) || defined(__x86_64__) #define OGDF_ARCH_X64 #elif defined(_M_IX86) || defined(__i386__) #define OGDF_ARCH_X86 #elif defined(_M_IA64) || defined(__ia64__) #define OGDF_ARCH_IA64 #elif defined(_M_MPPC) || defined(_M_PPC) || defined(__powerpc__) #define OGDF_ARCH_PPC #elif defined(__sparc__) #define OGDF_ARCH_SPARC #elif defined(__sparc_v9__) #define OGDF_ARCH_SPARC_V9 #endif // use SSE2 always if x64-platform or compiler option is set #ifndef OGDF_USE_SSE2 #if defined(OGDF_ARCH_X64) #define OGDF_USE_SSE2 #elif defined(_MSC_VER) #if _M_IX86_FP >= 2 #define OGDF_USE_SSE2 #endif #endif #endif // macros to check for using special cpu features // // OGDF_CHECK_SSE2 returns true if SSE2 can be used #ifdef OGDF_USE_SSE2 #define OGDF_CHECK_SSE2 true #elif defined(OGDF_ARCH_X86) #define OGDF_CHECK_SSE2 ogdf::System::cpuSupports(ogdf::cpufSSE2) #else #define OGDF_USE_SSE2 false #endif // work-around for MinGW-w64 #ifdef __MINGW64__ #ifndef _aligned_free #define _aligned_free(a) __mingw_aligned_free(a) #endif #ifndef _aligned_malloc #define _aligned_malloc(a,b) __mingw_aligned_malloc(a,b) #endif #endif namespace ogdf { //! Special features supported by a x86/x64 CPU. /** * This enumeration is used to specify spcial additional features that * are supported by the CPU, in particular extended instruction sets * such as SSE. */ enum CPUFeature { cpufMMX, //!< Intel MMX Technology cpufSSE, //!< Streaming SIMD Extensions (SSE) cpufSSE2, //!< Streaming SIMD Extensions 2 (SSE2) cpufSSE3, //!< Streaming SIMD Extensions 3 (SSE3) cpufSSSE3, //!< Supplemental Streaming SIMD Extensions 3 (SSSE3) cpufSSE4_1, //!< Streaming SIMD Extensions 4.1 (SSE4.1) cpufSSE4_2, //!< Streaming SIMD Extensions 4.2 (SSE4.2) cpufVMX, //!< Virtual Machine Extensions cpufSMX, //!< Safer Mode Extensions cpufEST, //!< Enhanced Intel SpeedStep Technology cpufMONITOR //!< Processor supports MONITOR/MWAIT instructions }; //! Bit mask for CPU features. enum CPUFeatureMask { cpufmMMX = 1 << cpufMMX, //!< Intel MMX Technology cpufmSSE = 1 << cpufSSE, //!< Streaming SIMD Extensions (SSE) cpufmSSE2 = 1 << cpufSSE2, //!< Streaming SIMD Extensions 2 (SSE2) cpufmSSE3 = 1 << cpufSSE3, //!< Streaming SIMD Extensions 3 (SSE3) cpufmSSSE3 = 1 << cpufSSSE3, //!< Supplemental Streaming SIMD Extensions 3 (SSSE3) cpufmSSE4_1 = 1 << cpufSSE4_1, //!< Streaming SIMD Extensions 4.1 (SSE4.1) cpufmSSE4_2 = 1 << cpufSSE4_2, //!< Streaming SIMD Extensions 4.2 (SSE4.2) cpufmVMX = 1 << cpufVMX, //!< Virtual Machine Extensions cpufmSMX = 1 << cpufSMX, //!< Safer Mode Extensions cpufmEST = 1 << cpufEST, //!< Enhanced Intel SpeedStep Technology cpufmMONITOR = 1 << cpufMONITOR //!< Processor supports MONITOR/MWAIT instructions }; //! %System specific functionality. /** * The class System encapsulates system specific functions * providing unified access across different operating systems. * The provided functionality includes: * - Access to file system functionality (listing directories etc.). * - Query memory usage. * - Access to high-perfomance counter under Windows and Cygwin. * - Query CPU specific information. */ class OGDF_EXPORT System { //friend class ::OgdfInitialization; public: /** * @name Memory usage * These methods allow to query the amount of physical memory, as well as the * current memory usage by both the process and OGDF's internal memory manager. */ //@{ static void *alignedMemoryAlloc16(size_t size) { #ifdef OGDF_SYSTEM_WINDOWS size_t alignment = 16; return _aligned_malloc(size,alignment); #elif defined(OGDF_SYSTEM_OSX) // malloc returns 16 byte aligned memory on OS X. return malloc(size); #else size_t alignment = 16; return memalign(alignment,size); #endif } static void alignedMemoryFree(void *p) { #ifdef OGDF_SYSTEM_WINDOWS _aligned_free(p); #else free(p); #endif } //! Returns the page size of virtual memory (in bytes). static int pageSize() { return s_pageSize; } //! Returns the total size of physical memory (in bytes). static long long physicalMemory(); //! Returns the size of available (free) physical memory (in bytes). static long long availablePhysicalMemory(); //! Returns the amount of memory (in bytes) allocated by the process. static size_t memoryUsedByProcess(); #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__) //! Returns the maximal amount of memory (in bytes) used by the process (Windows/Cygwin only). static size_t peakMemoryUsedByProcess(); #endif //! Returns the amount of memory (in bytes) allocated by OGDF's memory manager. /** * The memory manager allocates blocks of a fixed size from the system (via malloc()) * and makes it available in its free lists (for allocating small pieces of memory. * The returned value is the total amount of memory allocated from the system; * the amount of memory currently allocated from the user is * memoryAllocatedByMemoryManager() - memoryInFreelistOfMemoryManager(). * * Keep in mind that the memory manager never releases memory to the system before * its destruction. */ static size_t memoryAllocatedByMemoryManager(); //! Returns the amount of memory (in bytes) contained in the global free list of OGDF's memory manager. static size_t memoryInGlobalFreeListOfMemoryManager(); //! Returns the amount of memory (in bytes) contained in the thread's free list of OGDF's memory manager. static size_t memoryInThreadFreeListOfMemoryManager(); //! Returns the amount of memory (in bytes) allocated on the heap (e.g., with malloc). /** * This refers to dynamically allocated memory, e.g., memory allocated with malloc() * or new. */ static size_t memoryAllocatedByMalloc(); //! Returns the amount of memory (in bytes) contained in free chunks on the heap. /** * This refers to memory that has been deallocated with free() or delete, but has not * yet been returned to the operating system. */ static size_t memoryInFreelistOfMalloc(); #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__) //@} /** * @name Measuring time * These methods provide various ways to measure time. The high-performance * counter (Windows and Cygwin only) can be used to measure real time * periods with a better resolution than the standard system time function. */ //@{ //! Returns the current value of the high-performance counter in \a counter. static void getHPCounter(LARGE_INTEGER &counter); //! Returns the elapsed time (in seconds) between \a startCounter and \a endCounter. static double elapsedSeconds( const LARGE_INTEGER &startCounter, const LARGE_INTEGER &endCounter); #endif //! Returns the elapsed time (in milliseconds) between \a t and now. /** * The functions sets \a t to to the current time. Usually, you first call * usedRealTime(t) to query the start time \a t, and determine the elapsed time * after performing some computation by calling usedRealTime(t) again; this time * the return value gives you the elapsed time in milliseconds. */ static __int64 usedRealTime(__int64 &t); //@} /** * @name Processor information * These methods allow to query information about the current processor such as * supported instruction sets (e.g., SSE extensions), cache size, and number of * installed processors. */ //@{ //! Returns the bit vector describing the CPU features supported on current system. static int cpuFeatures() { return s_cpuFeatures; } //! Returns true if the CPU supports \a feature. static bool cpuSupports(CPUFeature feature) { return (s_cpuFeatures & (1 << feature)) != 0; } //! Returns the L2-cache size (in KBytes). static int cacheSizeKBytes() { return s_cacheSize; } //! Returns the number of bytes in a cache line. static int cacheLineBytes() { return s_cacheLine; } //! Returns the number of processors (cores) available on the current system. static int numberOfProcessors() { return s_numberOfProcessors; } //@} private: static unsigned int s_cpuFeatures; //!< Supported CPU features. static int s_cacheSize; //!< Cache size in KBytes. static int s_cacheLine; //!< Bytes in a cache line. static int s_numberOfProcessors; //!< Number of processors (cores) available. static int s_pageSize; //!< The page size of virtual memory. #if defined(OGDF_SYSTEM_WINDOWS) || defined(__CYGWIN__) static LARGE_INTEGER s_HPCounterFrequency; //!< Frequency of high-performance counter. #endif public: //! Static initilization routine (automatically called). static void init(); }; } // end namespace ogdf #endif