Hooks and profiler now runs on linux
This commit is contained in:
@@ -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]);
|
||||
}
|
||||
|
||||
@@ -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++;
|
||||
|
||||
+56
-9
@@ -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>
|
||||
#else
|
||||
# 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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user