From 98aa1450d8e63046d3260ea7fb4ff12c9c7e2629 Mon Sep 17 00:00:00 2001 From: Felix Brendel Date: Tue, 10 Mar 2020 00:28:51 +0100 Subject: [PATCH] Hooks and profiler now runs on linux --- bucket_allocator.hpp | 4 +-- hooks.hpp | 16 +++++----- profiler.hpp | 69 +++++++++++++++++++++++++++++++++++++------- 3 files changed, 68 insertions(+), 21 deletions(-) diff --git a/bucket_allocator.hpp b/bucket_allocator.hpp index 83a9924..3988f88 100644 --- a/bucket_allocator.hpp +++ b/bucket_allocator.hpp @@ -34,7 +34,7 @@ class Bucket_Allocator { } public: - Bucket_Allocator(unsigned int bucket_size, unsigned int initial_bucket_count) { + void alloc(unsigned int bucket_size, unsigned int initial_bucket_count) { this->free_list.alloc(); this->bucket_size = bucket_size; next_index_in_latest_bucket = 0; @@ -45,7 +45,7 @@ public: buckets[0] = (type*)malloc(bucket_size * sizeof(type)); } - ~Bucket_Allocator() { + void dealloc() { for (unsigned int i = 0; i <= next_bucket_index; ++i) { free(buckets[i]); } diff --git a/hooks.hpp b/hooks.hpp index 773b9ac..08d8b19 100644 --- a/hooks.hpp +++ b/hooks.hpp @@ -5,10 +5,10 @@ #include template -struct TransientFunction; // intentionally not defined +struct Lambda; // intentionally not defined template -struct TransientFunction +struct Lambda { using Dispatcher = R(*)(void*, Args...); @@ -16,7 +16,7 @@ struct TransientFunction // wrapped invokable object void* m_Target; // A pointer to the invokable object - // Dispatch() is instantiated by the TransientFunction constructor, + // Dispatch() is instantiated by the Lambda constructor, // which will store a pointer to the function in m_Dispatcher. template static R Dispatch(void* target, Args... args) @@ -25,7 +25,7 @@ struct TransientFunction } template - TransientFunction(T&& target) + Lambda(T&& target) : m_Dispatcher(&Dispatch::type>) , m_Target(&target) { @@ -34,7 +34,7 @@ struct TransientFunction // Specialize for reference-to-function, to ensure that a valid pointer is // stored. using TargetFunctionRef = R(Args...); - TransientFunction(TargetFunctionRef target) + Lambda(TargetFunctionRef target) : m_Dispatcher(Dispatch) { static_assert(sizeof(void*) == sizeof target, @@ -50,18 +50,18 @@ struct TransientFunction }; -struct Hook : Array_List> { +struct Hook : Array_List> { Hook() { alloc(); } ~Hook () { dealloc(); } - void operator<<(TransientFunction f) { + void operator<<(Lambda f) { // FIXME(Felix): Why can I not call Array_List::append here??? Hallo? if (next_index == length) { length *= 2; - data = (TransientFunction*)realloc(data, length * sizeof(TransientFunction)); + data = (Lambda*)realloc(data, length * sizeof(Lambda)); } data[next_index] = f; next_index++; diff --git a/profiler.hpp b/profiler.hpp index bceb04c..4ffcee3 100644 --- a/profiler.hpp +++ b/profiler.hpp @@ -1,23 +1,57 @@ #pragma once #ifdef _PROFILING + # include # include # include # include -// # include -// # include -// # include -// # include + #ifdef _MSC_VER -// if windows -# include +# include #else -# include +# include +# include +# include +# include +# include +# include +# include + +/* Helpful conversion constants. */ +static const unsigned usec_per_sec = 1000000; +static const unsigned usec_per_msec = 1000; + +/* These functions are written to match the win32 + signatures and behavior as closely as possible. +*/ +bool QueryPerformanceFrequency(int64_t *frequency) +{ + /* gettimeofday reports to microsecond accuracy. */ + *frequency = usec_per_sec; + + return true; +} + +bool QueryPerformanceCounter(int64_t *performance_count) +{ + struct timeval time; + + /* Grab the current time. */ + gettimeofday(&time, NULL); + *performance_count = time.tv_usec + /* Microseconds. */ + time.tv_sec * usec_per_sec; /* Seconds. */ + + return true; +} #endif struct Profiler { +#ifdef _MSC_VER LARGE_INTEGER tmp_time; +#else + int64_t tmp_time; +#endif // same for all threads inline static char file_template[40] = "\0"; @@ -62,22 +96,35 @@ struct Profiler { } // initially write the performance frequency - LARGE_INTEGER pf; - QueryPerformanceFrequency(&pf); - fprintf(out_file, "%lld,,,,\n", pf.QuadPart); - + QueryPerformanceFrequency(&tmp_time); +#ifdef _MSC_VER + fprintf(out_file, "%lld,,,,\n", tmp_time.QuadPart); +#else + fprintf(out_file, "%ld,,,,\n", tmp_time); +#endif is_initialized = true; } + QueryPerformanceCounter(&tmp_time); +#ifdef _MSC_VER fprintf(out_file, "->,%lld,%s,%s,%d,%s,%s\n", tmp_time.QuadPart, name, file, line, comment1, comment2); +#else + fprintf(out_file, "->,%ld,%s,%s,%d,%s,%s\n", + tmp_time, name, file, + line, comment1, comment2); +#endif }; ~Profiler() { call_depth -= 1; QueryPerformanceCounter(&tmp_time); +#ifdef _MSC_VER fprintf(out_file, "<-,%lld,,,,,\n", tmp_time.QuadPart); +#else + fprintf(out_file, "<-,%ld,,,,,\n", tmp_time); +#endif if (call_depth == 0) fflush(out_file); };