Browse Source

Hooks and profiler now runs on linux

banana-cakes
Felix Brendel 6 years ago
parent
commit
98aa1450d8
3 changed files with 68 additions and 21 deletions
  1. +2
    -2
      bucket_allocator.hpp
  2. +8
    -8
      hooks.hpp
  3. +58
    -11
      profiler.hpp

+ 2
- 2
bucket_allocator.hpp View File

@@ -34,7 +34,7 @@ class Bucket_Allocator {
} }


public: 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->free_list.alloc();
this->bucket_size = bucket_size; this->bucket_size = bucket_size;
next_index_in_latest_bucket = 0; next_index_in_latest_bucket = 0;
@@ -45,7 +45,7 @@ public:
buckets[0] = (type*)malloc(bucket_size * sizeof(type)); buckets[0] = (type*)malloc(bucket_size * sizeof(type));
} }


~Bucket_Allocator() {
void dealloc() {
for (unsigned int i = 0; i <= next_bucket_index; ++i) { for (unsigned int i = 0; i <= next_bucket_index; ++i) {
free(buckets[i]); free(buckets[i]);
} }


+ 8
- 8
hooks.hpp View File

@@ -5,10 +5,10 @@
#include <type_traits> #include <type_traits>


template<typename> template<typename>
struct TransientFunction; // intentionally not defined
struct Lambda; // intentionally not defined


template<typename R, typename ...Args> template<typename R, typename ...Args>
struct TransientFunction<R(Args...)>
struct Lambda<R(Args...)>
{ {
using Dispatcher = R(*)(void*, Args...); using Dispatcher = R(*)(void*, Args...);


@@ -16,7 +16,7 @@ struct TransientFunction<R(Args...)>
// wrapped invokable object // wrapped invokable object
void* m_Target; // A pointer to the 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. // which will store a pointer to the function in m_Dispatcher.
template<typename S> template<typename S>
static R Dispatch(void* target, Args... args) static R Dispatch(void* target, Args... args)
@@ -25,7 +25,7 @@ struct TransientFunction<R(Args...)>
} }


template<typename T> template<typename T>
TransientFunction(T&& target)
Lambda(T&& target)
: m_Dispatcher(&Dispatch<typename std::decay<T>::type>) : m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
, m_Target(&target) , m_Target(&target)
{ {
@@ -34,7 +34,7 @@ struct TransientFunction<R(Args...)>
// Specialize for reference-to-function, to ensure that a valid pointer is // Specialize for reference-to-function, to ensure that a valid pointer is
// stored. // stored.
using TargetFunctionRef = R(Args...); using TargetFunctionRef = R(Args...);
TransientFunction(TargetFunctionRef target)
Lambda(TargetFunctionRef target)
: m_Dispatcher(Dispatch<TargetFunctionRef>) : m_Dispatcher(Dispatch<TargetFunctionRef>)
{ {
static_assert(sizeof(void*) == sizeof target, static_assert(sizeof(void*) == sizeof target,
@@ -50,18 +50,18 @@ struct TransientFunction<R(Args...)>
}; };




struct Hook : Array_List<TransientFunction<void()>> {
struct Hook : Array_List<Lambda<void()>> {
Hook() { Hook() {
alloc(); alloc();
} }
~Hook () { ~Hook () {
dealloc(); dealloc();
} }
void operator<<(TransientFunction<void()> f) {
void operator<<(Lambda<void()> f) {
// FIXME(Felix): Why can I not call Array_List::append here??? Hallo? // FIXME(Felix): Why can I not call Array_List::append here??? Hallo?
if (next_index == length) { if (next_index == length) {
length *= 2; length *= 2;
data = (TransientFunction<void()>*)realloc(data, length * sizeof(TransientFunction<void()>));
data = (Lambda<void()>*)realloc(data, length * sizeof(Lambda<void()>));
} }
data[next_index] = f; data[next_index] = f;
next_index++; next_index++;


+ 58
- 11
profiler.hpp View File

@@ -1,23 +1,57 @@
#pragma once #pragma once
#ifdef _PROFILING #ifdef _PROFILING

# include <stdlib.h> # include <stdlib.h>
# include <stdio.h> # include <stdio.h>
# include <string.h> # include <string.h>
# include <time.h> # include <time.h>
// # include <bits/stdc++.h>
// # include <iostream>
// # include <sys/stat.h>
// # include <sys/types.h>

#ifdef _MSC_VER #ifdef _MSC_VER
// if windows
# include <Windows.h>
# include <Windows.h>
#else #else
# include <sys/time.h>
# include <fcntl.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <sys/time.h>
# include <stdint.h>
# include <stdbool.h>
# include <stddef.h>

/* 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 #endif




struct Profiler { struct Profiler {
#ifdef _MSC_VER
LARGE_INTEGER tmp_time; LARGE_INTEGER tmp_time;
#else
int64_t tmp_time;
#endif


// same for all threads // same for all threads
inline static char file_template[40] = "\0"; inline static char file_template[40] = "\0";
@@ -62,22 +96,35 @@ struct Profiler {
} }


// initially write the performance frequency // 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; is_initialized = true;
} }

QueryPerformanceCounter(&tmp_time); QueryPerformanceCounter(&tmp_time);
#ifdef _MSC_VER
fprintf(out_file, "->,%lld,%s,%s,%d,%s,%s\n", fprintf(out_file, "->,%lld,%s,%s,%d,%s,%s\n",
tmp_time.QuadPart, name, file, tmp_time.QuadPart, name, file,
line, comment1, comment2); line, comment1, comment2);
#else
fprintf(out_file, "->,%ld,%s,%s,%d,%s,%s\n",
tmp_time, name, file,
line, comment1, comment2);
#endif
}; };


~Profiler() { ~Profiler() {
call_depth -= 1; call_depth -= 1;
QueryPerformanceCounter(&tmp_time); QueryPerformanceCounter(&tmp_time);
#ifdef _MSC_VER
fprintf(out_file, "<-,%lld,,,,,\n", tmp_time.QuadPart); fprintf(out_file, "<-,%lld,,,,,\n", tmp_time.QuadPart);
#else
fprintf(out_file, "<-,%ld,,,,,\n", tmp_time);
#endif
if (call_depth == 0) if (call_depth == 0)
fflush(out_file); fflush(out_file);
}; };


Loading…
Cancel
Save