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