Hooks and profiler now runs on linux

This commit is contained in:
Felix Brendel
2020-03-10 00:28:51 +01:00
parent f82af0b6be
commit 98aa1450d8
3 changed files with 68 additions and 21 deletions
+2 -2
View File
@@ -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]);
}
+8 -8
View File
@@ -5,10 +5,10 @@
#include <type_traits>
template<typename>
struct TransientFunction; // intentionally not defined
struct Lambda; // intentionally not defined
template<typename R, typename ...Args>
struct TransientFunction<R(Args...)>
struct Lambda<R(Args...)>
{
using Dispatcher = R(*)(void*, Args...);
@@ -16,7 +16,7 @@ struct TransientFunction<R(Args...)>
// 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<typename S>
static R Dispatch(void* target, Args... args)
@@ -25,7 +25,7 @@ struct TransientFunction<R(Args...)>
}
template<typename T>
TransientFunction(T&& target)
Lambda(T&& target)
: m_Dispatcher(&Dispatch<typename std::decay<T>::type>)
, m_Target(&target)
{
@@ -34,7 +34,7 @@ struct TransientFunction<R(Args...)>
// 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<TargetFunctionRef>)
{
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() {
alloc();
}
~Hook () {
dealloc();
}
void operator<<(TransientFunction<void()> f) {
void operator<<(Lambda<void()> f) {
// FIXME(Felix): Why can I not call Array_List::append here??? Hallo?
if (next_index == length) {
length *= 2;
data = (TransientFunction<void()>*)realloc(data, length * sizeof(TransientFunction<void()>));
data = (Lambda<void()>*)realloc(data, length * sizeof(Lambda<void()>));
}
data[next_index] = f;
next_index++;
+58 -11
View File
@@ -1,23 +1,57 @@
#pragma once
#ifdef _PROFILING
# include <stdlib.h>
# include <stdio.h>
# include <string.h>
# include <time.h>
// # include <bits/stdc++.h>
// # include <iostream>
// # include <sys/stat.h>
// # include <sys/types.h>
#ifdef _MSC_VER
// if windows
# include <Windows.h>
# include <Windows.h>
#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
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);
};