• gperftools cpp wrapper


    gperftools cpp wrapper

    // Compile command : ${CXX} -o test_profiler.elf -DUSE_GPERFTOOLS -DDEBUG -D_DEBUG ${CXXFLAGS} -O0 -g -Wall ${LIBS} -lprofiler ${BUILD_LDFLAGS} test_profiler.cpp
    // Bash Command : kill -s SIGUSR1 <PID>
    // CPU Profiler command : gperftools/bin/pprof -text test_profiler.elf test_profiler.prof
    // see https://github.com/gperftools/gperftools/wiki

    Source filename: test_profiler.cpp

    /* Start of test_profiler.cpp */
    
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    // Start of config_arch.h
    
    #include <climits>
    
    /* Whether or not the compiler supports long long and unsigned long long
    */
    #ifndef HAS_LONG_LONG
    #if __cplusplus >= 201103L
    #define HAS_LONG_LONG
    #else
    #ifdef __GNUG__
    #ifdef __SIZEOF_LONG_LONG__
    #define HAS_LONG_LONG
    #endif
    #endif
    #endif
    #endif
    
    /* The character type that char matches (i.e., signed or unsigned)
    */
    #if CHAR_MIN < 0
    typedef signed char underlying_char_type;
    #else
    typedef unsigned char underlying_char_type;
    #endif
    
    // End of config_arch.h
    // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    // Start of config_os.h
    
    // =============================================================================
    // Determine the platform. Ex., Windows or POSIX. Define feature macros
    
    #if ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ )  ) )
    #include <unistd.h>
    
    #ifdef _POSIX_VERSION
    // ISO POSIX.1 aka IEEE 1003.1
    
    /// OS_POSIX - unistd.h is included and _POSIX_VERSION is defined
    #define OS_POSIX
    
    #if _POSIX_VERSION >= 199506L
    // ISO POSIX.1-1996 aka IEEE 1003.1-1996
    #define POSIX_THREADS
    
    #if ( _POSIX_VERSION >= 200112L )
    // ISO POSIX.1-2001 aka IEEE 1003.1-2001, aka Issue 6, aka SUSv3
    #define POSIX_ISSUE_6
    
    #if ( _POSIX_VERSION >= 200809L )
    // ISO POSIX.1-2008, aka IEEE 1003.1-2008, aka Issue 7, aka SUSv4
    #define POSIX_ISSUE_7
    #endif // 2008
    #endif // 2001
    #endif // 1996
    #endif // ifdef _POSIX_VERSION
    #endif // if ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ )))
    
    #if defined( _WIN64 ) || defined( _WIN32 )
    #include <windows.h> /* MS Windows operating systems */
    #define OS_WINDOWS
    #endif
    
    // =============================================================================
    // Determine basic types
    
    #ifdef OS_POSIX
    #include <sys/types.h>
    namespace stdbp
    {
        namespace os
        {
            // Identifies a user
            typedef uid_t user_id_type;
    
            // Identifies a process
            typedef pid_t pid_type;
        }
    }
    #else
    #ifdef OS_WINDOWS
    namespace stdbp
    {
        namespace os
        {
            typedef DWORD pid_type;
        }
    }
    #endif // Windows
    #endif // ifdef OS_POSIX
    
    // =============================================================================
    // Determine multithreading types
    
    #ifdef POSIX_THREADS
    #include <pthread.h>
    namespace stdbp
    {
        namespace os
        {
            typedef pthread_t thread_type;
            typedef pthread_mutex_t mutex_type;
            typedef pthread_rwlock_t shared_mutex_type;
            typedef pthread_cond_t condition_variable_type;
        }
    }
    #else
    #ifdef OS_WINDOWS
    namespace stdbp
    {
        namespace os
        {
            typedef HANDLE thread_type;
            typedef CRITICAL_SECTION mutex_type;
        }
    }
    #endif
    #endif // ifdef POSIX_THREADS
    
    // End of config_os.h
    // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
    // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    // Start of version.h
    
    #include <cstddef>
    
    #if __cplusplus >= 201703L
    #define CPP17
    #endif
    #if __cplusplus >= 201402L
    #define CPP14
    #endif
    #if __cplusplus >= 201103L
    #define CPP11
    #endif
    
    #ifdef CPP17
    #define CPP17_NAMESPACE std
    #else
    #define CPP17_NAMESPACE cpp17
    #endif
    
    #ifdef CPP14
    #define CPP14_NAMESPACE std
    #else
    #define CPP14_NAMESPACE cpp14
    #endif
    
    #ifdef CPP11
    #define CPP11_NAMESPACE std
    #else
    #define CPP11_NAMESPACE cpp11
    #endif
    
    namespace cpp11 {}
    
    #ifndef CPP11
    namespace cpp11 {
    
        class nullptr_t {
        public:
            nullptr_t() : _pad(0) {}
    
            template< class T >
            operator T *() const { // 定义类型转换操作符,使nullptr_t 可转为任意非类成员指针类型。
                return 0;
            }
    
            template< class C, class T >
            operator T C::*() const { // 重载类型转换操作符,使 nullptr_t 可以转换为类 C 中任意的指针类型(数据成员指针/函数成员指针)。
                return 0;
            }
        private:
            void *_pad; // std requires : sizeof(nullptr_t) == sizeof(void*)
            void operator &() const; // 不允许取地址操作。
        };
    
        const nullptr_t nullptr; // 定义 nullptr_t 类型的变量 nullptr
    
    } // namespace cpp11
    
    #endif // #ifndef CPP11
    
    namespace cpp14 {}
    namespace cpp17 {}
    
    namespace cpp {
        using namespace ::std;
        using namespace ::CPP11_NAMESPACE;
        using namespace ::CPP14_NAMESPACE;
        using namespace ::CPP17_NAMESPACE;
    } // namespace cpp
    
      // End of version.h
      // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
      // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      // Start of cstdint.h
    
    #include <string>
      //#include "version.h"
    
    #ifdef CPP11
      // Provided by C++11
    #include <cstdint>
    #else
    
    #include <climits>
    
      // Steal some types from the implementation, if we can
    #if !defined( _WIN32 ) && ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ )))
    #include <unistd.h>
    #if ( _POSIX_C_SOURCE >= 200112L )
      // Provided by POSIX
    #include <stdint.h>
    
    namespace cpp11 {
        using ::intptr_t;
        using ::uintptr_t;
    }
    #endif // POSIX
    #endif // UNIX-LIKE
    
    namespace cpp11 {
    #define AT_LEAST_16_BITS_S(x) ((x) >= 32767)
    #define AT_LEAST_32_BITS_S(x) ((x) >= 2147483647)
    #define AT_LEAST_64_BITS_S(x) ((((((x) >> 15) >> 15) >> 15) >> 15) >= 7)
    #define AT_LEAST_16_BITS_U(x) ((x) >= 65535)
    #define AT_LEAST_32_BITS_U(x) (((x) >> 1) >= 2147483647)
    #define AT_LEAST_64_BITS_U(x) ((((((x) >> 15) >> 15) >> 15) >> 15) >= 15)
    
    #define EXACTLY_8_BITS_S(x) ((x) == 127)
    #define EXACTLY_16_BITS_S(x) ((x) == 32767)
    #define EXACTLY_32_BITS_S(x) ((x) == 2147483647)
    #define EXACTLY_64_BITS_S(x) ((((((x) >> 15) >> 15) >> 15) >> 15) == 7)
    #define EXACTLY_8_BITS_U(x) ((x) == 255)
    #define EXACTLY_16_BITS_U(x) ((x) == 65535)
    #define EXACTLY_32_BITS_U(x) (((x) >> 1) == 2147483647)
    #define EXACTLY_64_BITS_U(x) ((((((x) >> 15) >> 15) >> 15) >> 15) == 15)
    
        // int_least8_t
        typedef signed char int_least8_t;
    #ifndef INT8_C
    #define INT8_C(x) x
    #endif
    #ifndef INT_LEAST8_MIN
    #define INT_LEAST8_MIN SCHAR_MIN
    #endif
    #ifndef INT_LEAST8_MAX
    #define INT_LEAST8_MAX SCHAR_MAX
    #endif
    
        // int8_t
    #if EXACTLY_8_BITS_S(INT_LEAST8_MAX)
    #ifndef INT8_MIN
    #define INT8_MIN INT_LEAST8_MIN
    #endif
    #ifndef INT8_MAX
    #define INT8_MAX INT_LEAST8_MAX
    #endif
        typedef int_least8_t int8_t;
    #endif
    
        // int_least16_t
    #if AT_LEAST_16_BITS_S(SCHAR_MAX)
        typedef signed char int_least16_t;
    #ifndef INT_LEAST16_MIN
    #define INT_LEAST16_MIN SCHAR_MIN
    #endif
    #ifndef INT_LEAST16_MAX
    #define INT_LEAST16_MAX SCHAR_MAX
    #endif
    #else
        typedef short int int_least16_t;
    #ifndef INT_LEAST16_MIN
    #define INT_LEAST16_MIN SHRT_MIN
    #endif
    #ifndef INT_LEAST16_MAX
    #define INT_LEAST16_MAX SHRT_MAX
    #endif
    #endif
    #ifndef INT16_C
    #define INT16_C(x) x
    #endif
    
        // int16_t
    #if EXACTLY_16_BITS_S(INT_LEAST8_MAX)
    #ifndef INT16_MIN
    #define INT16_MIN INT_LEAST16_MIN
    #endif
    #ifndef INT16_MAX
    #define INT16_MAX INT_LEAST16_MAX
    #endif
        typedef int_least16_t int16_t;
    #endif
    
        // int_least32_t
    #if AT_LEAST_32_BITS_S(SCHAR_MAX)
        typedef signed char int_least32_t
    #ifndef INT_LEAST32_MIN
    #define INT_LEAST32_MIN SCHAR_MIN
    #endif
    #ifndef INT_LEAST32_MAX
    #define INT_LEAST32_MAX SCHAR_MAX
    #endif
    #ifndef INT32_C
    #define INT32_C(x) x
    #endif
    #elif AT_LEAST_32_BITS_S(SHRT_MAX)
        typedef short int int_least32_t
    #ifndef INT_LEAST32_MIN
    #define INT_LEAST32_MIN SHRT_MIN
    #endif
    #ifndef INT_LEAST32_MAX
    #define INT_LEAST32_MAX SHRT_MAX
    #endif
    #ifndef INT32_C
    #define INT32_C(x) x
    #endif
    #elif AT_LEAST_32_BITS_S(INT_MAX)
        typedef int int_least32_t;
    #ifndef INT_LEAST32_MIN
    #define INT_LEAST32_MIN INT_MIN
    #endif
    #ifndef INT_LEAST32_MAX
    #define INT_LEAST32_MAX INT_MAX
    #endif
    #ifndef INT32_C
    #define INT32_C(x) x
    #endif
    #else
        typedef long int_least32_t;
    #ifndef INT_LEAST32_MIN
    #define INT_LEAST32_MIN LONG_MIN
    #endif
    #ifndef INT_LEAST32_MAX
    #define INT_LEAST32_MAX LONG_MAX
    #endif
    #ifndef INT32_C
    #define INT32_C(x) x##l
    #endif
    #endif // if AT_LEAST_32_BITS_S(SCHAR_MAX)
    
        // int32_t
    #if EXACTLY_32_BITS_S(INT_LEAST32_MAX)
    #ifndef INT32_MIN
    #define INT32_MIN INT_LEAST32_MIN
    #endif
    #ifndef INT32_MAX
    #define INT32_MAX INT_LEAST32_MAX
    #endif
        typedef int_least32_t int32_t;
    #endif
    
        // int_least64_t
    #if AT_LEAST_64_BITS_S(SCHAR_MAX)
        typedef signed char int_least64_t
    #ifndef INT_LEAST64_MIN
    #define INT_LEAST64_MIN SCHAR_MIN
    #endif
    #ifndef INT_LEAST64_MAX
    #define INT_LEAST64_MAX SCHAR_MAX
    #endif
    #ifndef INT64_C
    #define INT64_C(x) x
    #endif
    #elif AT_LEAST_64_BITS_S(SHRT_MAX)
        typedef short int_least64_t
    #ifndef INT_LEAST64_MIN
    #define INT_LEAST64_MIN SHRT_MIN
    #endif
    #ifndef INT_LEAST64_MAX
    #define INT_LEAST64_MAX SHRT_MAX
    #endif
    #ifndef INT64_C
    #define INT64_C(x) x
    #endif
    #elif AT_LEAST_64_BITS_S(INT_MAX)
        typedef int int_least64_t;
    #ifndef INT_LEAST64_MIN
    #define INT_LEAST64_MIN INT_MIN
    #endif
    #ifndef INT_LEAST64_MAX
    #define INT_LEAST64_MAX INT_MAX
    #endif
    #ifndef INT64_C
    #define INT64_C(x) x
    #endif
    #elif AT_LEAST_64_BITS_S(LONG_MAX)
        typedef long int_least64_t;
    #ifndef INT_LEAST64_MIN
    #define INT_LEAST64_MIN LONG_MIN
    #endif
    #ifndef INT_LEAST64_MAX
    #define INT_LEAST64_MAX LONG_MAX
    #endif
    #ifndef INT64_C
    #define INT64_C(x) x##l
    #endif
    #else
    #ifdef LLONG_MAX
        typedef long long int_least64_t;
    #ifndef INT_LEAST64_MIN
    #define INT_LEAST64_MIN LLONG_MIN
    #endif
    #ifndef INT_LEAST64_MAX
    #define INT_LEAST64_MAX LLONG_MAX
    #endif
    #ifndef INT64_C
    #define INT64_C(x) x##ll
    #endif
    #endif
    #endif // if AT_LEAST_64_BITS_S(SCHAR_MAX)
    
        // int64_t
    #if EXACTLY_64_BITS_S(INT_LEAST64_MAX)
    #ifndef INT64_MIN
    #define INT64_MIN INT_LEAST64_MIN
    #endif
    #ifndef INT64_MAX
    #define INT64_MAX INT_LEAST64_MAX
    #endif
        typedef int_least64_t int64_t;
    #endif
    
        // uint_least8_t
        typedef unsigned char uint_least8_t;
    #ifndef UINT8_C
    #define UINT8_C(x) x
    #endif
    #ifndef UINT_LEAST8_MAX
    #define UINT_LEAST8_MAX UCHAR_MAX
    #endif
    
        // uint8_t
    #if EXACTLY_8_BITS_U(UINT_LEAST8_MAX)
    #ifndef UINT8_MAX
    #define UINT8_MAX UINT_LEAST8_MAX
    #endif
        typedef uint_least8_t uint8_t;
    #endif
    
        // uint_least16_t
    #if AT_LEAST_16_BITS_U(UCHAR_MAX)
        typedef unsigned char uint_least16_t;
    #ifndef UINT_LEAST16_MAX
    #define UINT_LEAST16_MAX UCHAR_MAX
    #endif
    #else
        typedef unsigned short uint_least16_t;
    #ifndef UINT_LEAST16_MAX
    #define UINT_LEAST16_MAX USHRT_MAX
    #endif
    #endif
    #ifndef UINT16_C
    #define UINT16_C(x) x
    #endif
    
        // uint16_t
    #if EXACTLY_16_BITS_U(UINT_LEAST16_MAX)
    #ifndef UINT16_MAX
    #define UINT16_MAX UINT_LEAST16_MAX
    #endif
        typedef uint_least16_t uint16_t;
    #endif
    
        // uint_least32_t
    #if AT_LEAST_32_BITS_U(UCHAR_MAX)
        typedef unsigned char uint_least32_t
    #ifndef UINT_LEAST32_MAX
    #define UINT_LEAST32_MAX UCHAR_MAX
    #endif
    #ifndef UINT32_C
    #define UINT32_C(x) x
    #endif
    #elif AT_LEAST_32_BITS_U(USHRT_MAX)
        typedef unsigned short uint_least32_t
    #ifndef UINT_LEAST32_MAX
    #define UINT_LEAST32_MAX USHRT_MAX
    #endif
    #ifndef UINT32_C
    #define UINT32_C(x) x
    #endif
    #elif AT_LEAST_32_BITS_U(UINT_MAX)
        typedef unsigned uint_least32_t;
    #ifndef UINT_LEAST32_MAX
    #define UINT_LEAST32_MAX UINT_MAX
    #endif
    #ifndef UINT32_C
    #define UINT32_C(x) x
    #endif
    #else
        typedef unsigned long uint_least32_t;
    #ifndef UINT_LEAST32_MAX
    #define UINT_LEAST32_MAX ULONG_MAX
    #endif
    #ifndef UINT32_C
    #define UINT32_C(x) x##ul
    #endif
    #endif // if AT_LEAST_32_BITS_U(UCHAR_MAX)
    
        // uint32_t
    #if EXACTLY_32_BITS_U(UINT_LEAST32_MAX)
    #ifndef UINT32_MAX
    #define UINT32_MAX UINT_LEAST32_MAX
    #endif
        typedef uint_least32_t uint32_t;
    #endif
    
        // uint_least64_t
    #if AT_LEAST_64_BITS_U(UCHAR_MAX)
        typedef unsigned char uint_least64_t
    #ifndef UINT64_C
    #define UINT64_C(x) x
    #endif
    #ifndef UINT_LEAST64_MAX
    #define UINT_LEAST64_MAX UCHAR_MAX
    #endif
    #elif AT_LEAST_64_BITS_U(USHRT_MAX)
        typedef unsigned short uint_least64_t
    #ifndef UINT64_C
    #define UINT64_C(x) x
    #endif
    #ifndef UINT_LEAST64_MAX
    #define UINT_LEAST64_MAX USHRT_MAX
    #endif
    #elif AT_LEAST_64_BITS_U(UINT_MAX)
        typedef unsigned uint_least64_t;
    #ifndef UINT64_C
    #define UINT64_C(x) x
    #endif
    #ifndef UINT_LEAST64_MAX
    #define UINT_LEAST64_MAX UINT_MAX
    #endif
    #elif AT_LEAST_64_BITS_U(LONG_MAX)
        typedef unsigned long uint_least64_t;
    #ifndef UINT64_C
    #define UINT64_C(x) x##ul
    #endif
    #ifndef UINT_LEAST64_MAX
    #define UINT_LEAST64_MAX ULONG_MAX
    #endif
    #else
    #ifdef ULLONG_MAX
        typedef unsigned long long uint_least64_t;
    #ifndef UINT64_C
    #define UINT64_C(x) x##ull
    #endif
    #ifndef UINT_LEAST64_MAX
    #define UINT_LEAST64_MAX ULLONG_MAX
    #endif
    #endif
    #endif // if AT_LEAST_64_BITS_U(UCHAR_MAX)
    
        // uint64_t
    #if EXACTLY_64_BITS_U(UINT_LEAST64_MAX)
    #ifndef UINT64_MAX
    #define UINT64_MAX UINT_LEAST64_MAX
    #endif
        typedef uint_least64_t uint64_t;
    #endif
    
        typedef signed char int_fast8_t;
        typedef int int_fast16_t;
        typedef long int_fast32_t;
        typedef int_least64_t int_fast64_t;
    
        typedef unsigned char uint_fast8_t;
        typedef unsigned uint_fast16_t;
        typedef unsigned long uint_fast32_t;
        typedef uint_least64_t uint_fast64_t;
    
    #ifdef LLONG_MAX
        typedef long long intmax_t;
    #ifndef INTMAX_C
    #define INTMAX_C(x) x##ll
    #endif
    #ifndef INTMAX_MAX
    #define INTMAX_MAX LLONG_MAX
    #endif
    #else
        typedef long intmax_t;
    #ifndef INTMAX_C
    #define INTMAX_C(x) x##l
    #endif
    #ifndef INTMAX_MAX
    #define INTMAX_MAX LONG_MAX
    #endif
    #endif
    
    #ifdef ULLONG_MAX
        typedef unsigned long long uintmax_t;
    #ifndef UINTMAX_C
    #define UINTMAX_C(x) x##ull
    #endif
    #ifndef UINTMAX_MAX
    #define UINTMAX_MAX ULLONG_MAX
    #endif
    #else
        typedef unsigned long uintmax_t;
    #ifndef UINTMAX_C
    #define UINTMAX_C(x) x##ul
    #endif
    #ifndef UINTMAX_MAX
    #define UINTMAX_MAX ULONG_MAX
    #endif
    #endif
    
    #undef EXACTLY_8_BITS_S
    #undef EXACTLY_16_BITS_S
    #undef EXACTLY_32_BITS_S
    #undef EXACTLY_64_BITS_S
    #undef EXACTLY_8_BITS_U
    #undef EXACTLY_16_BITS_U
    #undef EXACTLY_32_BITS_U
    #undef EXACTLY_64_BITS_U
    
    #undef AT_LEAST_16_BITS_S
    #undef AT_LEAST_32_BITS_S
    #undef AT_LEAST_64_BITS_S
    #undef AT_LEAST_16_BITS_U
    #undef AT_LEAST_32_BITS_U
    #undef AT_LEAST_64_BITS_U
    } // namespace cpp11
    
    #endif // #ifdef CPP11
    
      // End of cstdint.h
      // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
      // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
      // Start of string.h
    
    #include <string>
      //#include "version.h"
    
    #ifndef CPP11
    #include <cstdlib>
    #include <iostream>
    #include <sstream>
      //#include "config_arch.h"
    namespace cpp11 {
        namespace detail {
            template< typename I >
            std::string arithmetic_to_string(I x) {
                std::ostringstream ss;
                ss << x;
                return ss.str();
            }
    
            template< typename I >
            std::wstring arithmetic_to_wstring(I x) {
                std::wostringstream ss;
                ss << x;
                return ss.str();
            }
        } // namespace detail
    
        inline unsigned long stoul(
            const std::string &s,
            std::size_t *pos = 0,
            int base = 10) {
            char *ptr;
            const char *s_ = s.c_str();
            const long res = std::strtoul(s_, &ptr, base);
            if (pos) {
                *pos = ptr - s_;
            }
            return res;
        }
    
        /// @todo Should throw if not convertible, or result is too large
        inline long stol(
            const std::string &s,
            std::size_t *pos = 0,
            int base = 10) {
            char * ptr;
            const char *s_ = s.c_str();
            const long res = std::strtol(s_, &ptr, base);
            if (pos) {
                *pos = ptr - s_;
            }
            return res;
        }
    
        /// @todo Should throw if not convertible, or result is too large
        inline int stoi(
            const std::string &s,
            std::size_t *pos = 0,
            int base = 10) {
            return static_cast< int >(stol(s, pos, base));
        }
    
        /** @brief Get the string representation of an int
        * @param n An integer
        * @returns lexical_cast<std::string>(n)
        */
        inline std::string to_string(int n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::string to_string(long n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::string to_string(unsigned n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::string to_string(unsigned long  n) {
            return detail::arithmetic_to_string(n);
        }
    
    #ifdef HAS_LONG_LONG
        inline std::string to_string(long long n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::string to_string(unsigned long long n) {
            return detail::arithmetic_to_string(n);
        }
    #endif // #ifdef HAS_LONG_LONG
    
        inline std::string to_string(float n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::string to_string(double n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::string to_string(long double n) {
            return detail::arithmetic_to_string(n);
        }
    
        inline std::wstring to_wstring(int n) {
            return detail::arithmetic_to_wstring(n);
        }
    
        inline std::wstring to_wstring(unsigned n) {
            return detail::arithmetic_to_wstring(n);
        }
    
        inline std::wstring to_wstring(long n) {
            return detail::arithmetic_to_wstring(n);
        }
    
        inline std::wstring to_wstring(unsigned long n) {
            return detail::arithmetic_to_wstring(n);
        }
    
    #ifdef HAS_LONG_LONG
        inline std::wstring to_wstring(long long n) {
            return detail::arithmetic_to_wstring(n);
        }
    
        inline std::wstring to_wstring(unsigned long long n) {
            return detail::arithmetic_to_wstring(n);
        }
    #endif // #ifdef HAS_LONG_LONG
    
        inline std::wstring to_wstring(float n) {
            return detail::arithmetic_to_wstring(n);
        }
    
        inline std::wstring to_wstring(double n) {
            return detail::arithmetic_to_wstring(n);
        }
    
        inline std::wstring to_wstring(long double n) {
            return detail::arithmetic_to_wstring(n);
        }
    
    } // namespace cpp11
    #endif // #ifndef CPP11
    
      // End of string.h
      // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    
      //#include "version.h"
      //#include "config_arch.h"
      //#include "config_os.h"
      //#include "cstdint.h"
      //#include "string.h.h"
    
    #include <cstdio>
    #include <cstdlib>
    #include <cerrno>
    #include <csignal>
    #include <ctime>
    #include <cstring>
    #include <sstream>
    
    namespace lse_ns_util {
    
        namespace common {
    
            char *GetFilename(const char *fullname) {
                char *name = cpp::nullptr;
    #if ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ )  ) )
                const char splitchar = '/';
    #elif defined( _WIN64 ) || defined( _WIN32 )
                const char splitchar = '\';
    #else
                const char splitchar = ' ';
    #endif
                if (fullname == cpp::nullptr || *fullname == '') {
                    return cpp::nullptr;
                }
    
                for (char *ptr = (char *)fullname; *ptr != ''; ptr++) {
                    if (*ptr == splitchar && *(ptr + 1) != '') {
                        name = ptr;
                    }
                }
    
                // eg: fullname == "/"
                if (name == cpp::nullptr && *fullname == splitchar) {
                    return cpp::nullptr;
                }
                // eg: fullname == "xxx.elf/"
                if (name == cpp::nullptr && (*(fullname + strlen(fullname) - 1) == splitchar) ) {
                    return cpp::nullptr;
                }
                // eg: fullname == "/yyy/xxx.elf/"
                if (name != cpp::nullptr && (*(fullname + strlen(fullname) - 1) == splitchar)) {
                    return cpp::nullptr;
                }
                // eg: fullname == "xxx.elf"
                if (name == cpp::nullptr && *fullname != splitchar) {
                    return (char *)fullname;
                }
                // eg: fullname == "/xxx.elf"
                if ((name != cpp::nullptr && name == fullname)) {
                    return (name + 1);
                }
                // eg: fullname == "/yyy/xxx.elf"
                if (name != cpp::nullptr && name != fullname) {
                    return (name + 1);
                }
    
                return cpp::nullptr;
            }
    
            size_t GetPathname(const char *fullname, char *pathname, const size_t pathszie) {
                char *name = cpp::nullptr;
    #if ( defined( __unix__ ) || defined( __unix ) || ( defined( __APPLE__ ) && defined( __MACH__ )  ) )
                const char splitchar = '/';
                const char *splitstr = "/";
    #elif defined( _WIN64 ) || defined( _WIN32 )
                const char splitchar = '\';
                const char *splitstr = "\";
    #else
                const char splitchar = ' ';
                const char *splitstr = " ";
    #endif
                if (fullname == cpp::nullptr || *fullname == '' || pathname == cpp::nullptr || pathszie < 2) {
                    return 0;
                }
    
                for (char *ptr = (char *)fullname; *ptr != ''; ptr++) {
                    if (*ptr == splitchar && *(ptr + 1) != '') {
                        name = ptr;
                    }
                }
    
                // eg: fullname == "/"
                if (name == cpp::nullptr && *fullname == splitchar) {
                    strncpy(pathname, splitstr, strlen(splitstr));
                    return strlen(pathname);
                }
                // eg: fullname == "xxx.elf/"
                if (name == cpp::nullptr && (*(fullname + strlen(fullname) - 1) == splitchar)) {
                    strncpy(pathname, ".", strlen("."));
                    return strlen(pathname);
                }
                // eg: fullname == "/yyy/xxx.elf/"
                if (name != cpp::nullptr && (*(fullname + strlen(fullname) - 1) == splitchar)) {
                    if (pathszie > (size_t)(name - fullname)) {
                        strncpy(pathname, fullname, (size_t)(name - fullname));
                        return strlen(pathname);
                    }
                    else {
                        return 0;
                    }
                }
                // eg: fullname == "xxx.elf"
                if (name == cpp::nullptr && *fullname != splitchar) {
                    strncpy(pathname, ".", strlen("."));
                    return strlen(pathname);
                }
                // eg: fullname == "/xxx.elf"
                if ((name != cpp::nullptr && name == fullname)) {
                    strncpy(pathname, splitstr, strlen(splitstr));
                    return strlen(pathname);
                }
                // eg: fullname == "/yyy/xxx.elf"
                if (name != cpp::nullptr && name != fullname) {
                    if (pathszie > (size_t)(name - fullname)) {
                        strncpy(pathname, fullname, (size_t)(name - fullname));
                        return strlen(pathname);
                    }
                    else {
                        return 0;
                    }
                }
    
                return 0;
            }
    
            size_t DelLastSuffix(const char *filename, const char splitchar, char *newname, const size_t newszie) {
                char *name = cpp::nullptr;
                const char splitstr[] = { splitchar, '' };
    
                if (filename == cpp::nullptr || *filename == '' || newname == cpp::nullptr || newszie < 2) {
                    return 0;
                }
    
                for (char *ptr = (char *)filename; *ptr != ''; ptr++)
                {
                    if (*ptr == splitchar && *(ptr + 1) != '') {
                        name = ptr;
                    }
                }
    
                // eg: filename == "."
                if (name == cpp::nullptr && *filename == splitchar) {
                    strncpy(newname, splitstr, strlen(splitstr));
                    return strlen(newname);
                }
                // eg;  filename == "xxx."
                if (name == cpp::nullptr && (*(filename + strlen(filename) - 1) == splitchar)) {
                    if (newszie > strlen(filename) - 1) {
                        strncpy(newname, filename, strlen(filename) - 1);
                        return strlen(newname);
                    }
                    else {
                        return 0;
                    }
                }
                // eg;  filename == "yyy.xxx."
                if (name != cpp::nullptr && (*(filename + strlen(filename) - 1) == splitchar)) {
                    if (newszie > (size_t)(name - filename)) {
                        strncpy(newname, filename, (size_t)(name - filename));
                        return strlen(newname);
                    }
                    else {
                        return 0;
                    }
                }
                // eg: filename == "xxx"
                if (name == cpp::nullptr && *filename != splitchar) {
                    if (newszie > strlen(filename)) {
                        strncpy(newname, filename, strlen(filename));
                        return strlen(newname);
                    }
                    else {
                        return 0;
                    }
                }
                // eg: filename == ".xxx"
                if ((name != cpp::nullptr && name == filename)) {
                    strncpy(newname, splitstr, strlen(splitstr));
                    return strlen(newname);
                }
                // eg: filename == "xxx.yyy.zzz"
                if (name != cpp::nullptr && name != filename) {
                    if (newszie > (size_t)(name - filename)) {
                        strncpy(newname, filename, (size_t)(name - filename));
                        return strlen(newname);
                    }
                    else {
                        return 0;
                    }
                }
    
                return 0;
            }
    
            int setupSignal(int signum, void(*handler) (int)) {
                const size_t MAX_BUF_LEN = 1024;
                char strbuf[MAX_BUF_LEN] = {''};
                struct sigaction s_sigAction;
                s_sigAction.sa_handler = handler;
                s_sigAction.sa_flags = 0;
                sigemptyset(&s_sigAction.sa_mask);
                sigaddset(&s_sigAction.sa_mask, signum);
                if (sigaction(signum, &s_sigAction, cpp::nullptr) < 0) {
                    strerror_r(errno, strbuf, MAX_BUF_LEN);
                    fprintf(stderr, "error: %d - %s", errno, strbuf);
                    return errno;
                }
                else {
                    return 0;
                }
            }
    
            std::string TimeToTimestampStr(time_t t) {
                tm dTm;
                tm* aTm = localtime_r(&t, &dTm);
                const size_t MAX_BUF_LEN = 20;
                char strbuf[MAX_BUF_LEN] = { '' };
                // YYYY    year
                // MM      month (2 digits 01-12)
                // DD      day (2 digits 01-31)
                // HH      hour (2 digits 00-23)
                // MM      minutes (2 digits 00-59)
                // SS      seconds (2 digits 00-59)
                snprintf(strbuf, MAX_BUF_LEN, "%04d-%02d-%02d_%02d:%02d:%02d", aTm->tm_year + 1900, aTm->tm_mon + 1, aTm->tm_mday, aTm->tm_hour, aTm->tm_min, aTm->tm_sec);
                return std::string(strbuf);
            }
    
            uint32_t CreatePIDFile(std::string filename) {
                FILE * pid_file = fopen(filename.c_str(), "w");
                if (pid_file == cpp::nullptr) {
                    return 0;
                }
    
    #ifdef WIN32
                DWORD pid = GetCurrentProcessId();
    #else
                pid_t pid = getpid();
    #endif
    
                fprintf(pid_file, "%d", pid);
                fclose(pid_file);
    
                return (uint32_t)pid;
            }
    
        }
    
        namespace prof {
    
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
    #include <gperftools/profiler.h>
    #endif
    
            class Profiler {
            public:
                static Profiler *getInstance() {
                    return instance;
                }
    
                static Profiler *FreeInstance() {
                    if (instance != cpp::nullptr) {
                        delete instance;
                        instance = cpp::nullptr;
                    }
                    return instance;
                }
    
                bool IsRunning() const {
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
                    ProfilerState state;
                    ProfilerGetCurrentState(&state);
                    return state.enabled;
    #else
                    return false;
    #endif
                }
    
                void Flush() {
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
                    ProfilerFlush();
    #endif
                }
    
                void RegisterThread() {
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
                    ProfilerRegisterThread();
    #endif
                }
    
                bool Start(std::string filename, std::string &failureReason) {
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
                    if (IsRunning()) {
                        failureReason = "Already running";
                        return false;
                    }
    
                    if (ProfilerStart(filename.c_str()) == 0) {
                        failureReason = "ProfilerStart returned an error";
                        return false;
                    }
    
                    return true;
    #else
                    failureReason = "Not compiled with gperftools";
                    return false;
    #endif
                }
                bool Stop(std::string &failureReason) {
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
                    if (!IsRunning()) {
                        failureReason = "Not running";
                        return false;
                    }
                    ProfilerStop();
                    return true;
    #else
                    failureReason = "Not compiled with gperftools";
                    return false;
    #endif
                }
    
                std::string GetInfos() const {
    #if (defined(__linux__) || defined(__FreeBSD__)) && defined(USE_GPERFTOOLS)
                    bool enabledForAllThreads = ProfilingIsEnabledForAllThreads();
                    ProfilerState state;
                    ProfilerGetCurrentState(&state);
    
                    std::stringstream infos;
                    infos.str("");
                    infos.clear();
    
                    infos << "Profiling is " << std::endl;
                    infos << "- " << (state.enabled ? "enabled" : "disabled") << std::endl;
                    if (!IsRunning()) {
                        return infos.str();
                    }
    
                    infos << "- " << (enabledForAllThreads ? "" : "not ") << "enabled for all threads" << std::endl;
                    infos << "- Started at timestamp(" << cpp::to_string(state.start_time) << ") / localtime(" << ::lse_ns_util::common::TimeToTimestampStr(state.start_time) << ")" << std::endl;
                    infos << "- Writing to filename(" << state.profile_name << ")" << std::endl;
                    infos << "- Has currently gathered " << cpp::to_string(state.samples_gathered) << " samples" << std::endl;
                    return infos.str();
    #else
                    return "Not compiled with gperftools";
    #endif
                }
    
            private:
                static Profiler *instance; // 声明的静态成员变量 instance 
                Profiler() {}
            };
            // 定义 Profiler 类的静态成员变量 instance 
            Profiler *Profiler::instance = new Profiler();
    
        } // namespace prof
    
        namespace util {
            using namespace ::lse_ns_util::common;
            using namespace ::lse_ns_util::prof;
        }
    
    } // namespace lse_ns_util
    
    #include <csignal>
    #include <iostream>
    
    void profilerSignalHandler(int signum) {
        static bool isRunning = false;
    
        if (signum != SIGUSR1) {
            return;
        }
        
        const char *profilerDefaultname = "test";
        const char *profilerSuffix = ".prof";
        const size_t MAX_FILENAME_LEN = 256;
        char profilerFilename[MAX_FILENAME_LEN] = { '' };
        std::string strTemp;
        std::string strFilename;
    
        strFilename.erase();
        strFilename.clear();
        if (lse_ns_util::util::DelLastSuffix(lse_ns_util::util::GetFilename(__FILE__), '.', profilerFilename, MAX_FILENAME_LEN) != 0) {
            strFilename.append(profilerFilename).append(profilerSuffix);
        }
        else {
            strFilename.append(profilerDefaultname).append(profilerSuffix);
        }
    
        strTemp.erase();
        strTemp.clear();
        lse_ns_util::util::Profiler * profiler = lse_ns_util::util::Profiler::getInstance();
        isRunning = profiler->IsRunning();
        if (!isRunning) {
            profiler->Start(strFilename, strTemp);
            isRunning = profiler->IsRunning();
            if (isRunning) {
                std::cout << profiler->GetInfos() << std::endl;
                std::cout << "Notice: Profiler Start successfully." << std::endl;
            }
            else {
                std::cout << "Notice: Profiler Start failed." << std::endl;
            }
        }
        else {
            profiler->Stop(strTemp);
            isRunning = profiler->IsRunning();
            if (!isRunning) {
                lse_ns_util::util::Profiler::FreeInstance();
                std::cout << "Notice: Profiler Stop successfully." << std::endl;
            }
            else {
                std::cout << "Notice: Profiler Stop failed." << std::endl;
            }
        }
    }
    
    void loopop() {
        int n = 0;
        while (1) {
            for (int i = 0; i < 10000; i++) {
                for (int j = 0; j < 10000; j++) {
                    n |= i % 100 + j / 100;
                }
            }
            std::cout << lse_ns_util::common::TimeToTimestampStr(time(cpp::nullptr)) << " - result: " << n << std::endl;
        }
        return;
    }
    
    // Compile command : ${CXX} -o test_profiler.elf -DUSE_GPERFTOOLS -DDEBUG -D_DEBUG ${CXXFLAGS} -O0 -g -Wall ${LIBS} -lprofiler ${BUILD_LDFLAGS} test_profiler.cpp
    // Bash Command : kill -s SIGUSR1 <PID>
    // CPU Profiler command : gperftools/bin/pprof -text test_profiler.elf test_profiler.prof
    // see https://github.com/gperftools/gperftools/wiki
    
    int main(int argc, char *argv[]) {
        
        if (lse_ns_util::util::setupSignal(SIGUSR1, profilerSignalHandler) != 0) {
            return -1;
        }
        else {
            loopop();
            return 0;
        }
    
    }
    
    /* End of test_profiler.cpp */

    ==================== End

  • 相关阅读:
    自定义WordPress文件上传路径
    PHP Warning: preg_match(): JIT compilation failed: no more memory in
    Mac下PHP7.1+Nginx安装和配置
    bootstrap modal插件弹出窗口如何限制最大高度,并且在内容过多时可以滚动显示
    Language Tool ,a plugin for TeXStudio
    平均值mean,众数mode,中值median 和 标准差stddev
    LaTeX Software & Manuals
    MAFFT多重序列比对--(附比对彩标方法)
    Markdown语法 (中文版)
    在64位系统上不能安装Matlab notebook的解决方案
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/10907676.html
Copyright © 2020-2023  润新知