浏览代码

Hooks and profiler now runs on linux

banana-cakes
Felix Brendel 6 年前
父节点
当前提交
98aa1450d8
共有 3 个文件被更改,包括 68 次插入21 次删除
  1. +2
    -2
      bucket_allocator.hpp
  2. +8
    -8
      hooks.hpp
  3. +58
    -11
      profiler.hpp

+ 2
- 2
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]);
}


+ 8
- 8
hooks.hpp 查看文件

@@ -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
profiler.hpp 查看文件

@@ -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);
};


正在加载...
取消
保存