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 == '\0') {
                return cpp::nullptr;
            }

            for (char *ptr = (char *)fullname; *ptr != '\0'; ptr++) {
                if (*ptr == splitchar && *(ptr + 1) != '\0') {
                    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 == '\0' || pathname == cpp::nullptr || pathszie < 2) {
                return 0;
            }

            for (char *ptr = (char *)fullname; *ptr != '\0'; ptr++) {
                if (*ptr == splitchar && *(ptr + 1) != '\0') {
                    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, '\0' };

            if (filename == cpp::nullptr || *filename == '\0' || newname == cpp::nullptr || newszie < 2) {
                return 0;
            }

            for (char *ptr = (char *)filename; *ptr != '\0'; ptr++)
            {
                if (*ptr == splitchar && *(ptr + 1) != '\0') {
                    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] = {'\0'};
            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] = { '\0' };
            // 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] = { '\0' };
    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

 

转载于:https://www.cnblogs.com/lsgxeva/p/10907676.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值