Hooks and profiler now runs on linux
This commit is contained in:
@@ -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]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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(&tmp_time);
|
||||||
QueryPerformanceFrequency(&pf);
|
#ifdef _MSC_VER
|
||||||
fprintf(out_file, "%lld,,,,\n", pf.QuadPart);
|
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);
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user