| @@ -0,0 +1,13 @@ | |||
| TIMEFORMAT=%3lR | |||
| SCRIPTPATH="$( cd "$(dirname "$0")" ; pwd -P )" | |||
| pushd $SCRIPTPATH > /dev/null | |||
| # _DEBUG | |||
| # time g++ -fpermissive src/main.cpp -g -o ./bin/slime --std=c++17 || exit 1 | |||
| time clang++ -D_DEBUG -D_PROFILING -fpermissive test.cpp -g -o ./ftb --std=c++17 || exit 1 | |||
| echo "" | |||
| time ./ftb | |||
| popd > /dev/null | |||
| unset TIMEFORMAT | |||
| @@ -1,54 +0,0 @@ | |||
| #pragma once | |||
| #include <functional> | |||
| #define proc auto | |||
| #ifdef _DEBUG | |||
| # define if_debug if constexpr (true) | |||
| #else | |||
| # define if_debug if constexpr (false) | |||
| #endif | |||
| #ifdef _MSC_VER | |||
| # define debug_break() if_debug __debugbreak() | |||
| # define if_windows if constexpr (true) | |||
| # define if_linux if constexpr (false) | |||
| #else | |||
| # define debug_break() if_debug raise(SIGTRAP) | |||
| # define if_windows if constexpr (false) | |||
| # define if_linux if constexpr (true) | |||
| #endif | |||
| /** | |||
| * Defer * | |||
| */ | |||
| template<typename F> | |||
| class defer_finalizer { | |||
| F f; | |||
| bool moved; | |||
| public: | |||
| template<typename T> | |||
| defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { } | |||
| defer_finalizer(const defer_finalizer &) = delete; | |||
| defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) { | |||
| other.moved = true; | |||
| } | |||
| ~defer_finalizer() { | |||
| if (!moved) f(); | |||
| } | |||
| }; | |||
| struct { | |||
| template<typename F> | |||
| defer_finalizer<F> operator<<(F && f) { | |||
| return defer_finalizer<F>(std::forward<F>(f)); | |||
| } | |||
| } deferrer; | |||
| #define TOKENPASTE(x, y) x ## y | |||
| #define TOKENPASTE2(x, y) TOKENPASTE(x, y) | |||
| #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&] | |||
| @@ -0,0 +1,77 @@ | |||
| #pragma once | |||
| #include <functional> | |||
| #define proc auto | |||
| #ifdef _DEBUG | |||
| # define if_debug if constexpr (true) | |||
| #else | |||
| # define if_debug if constexpr (false) | |||
| #endif | |||
| #ifdef _MSC_VER | |||
| # define debug_break() if_debug __debugbreak() | |||
| # define if_windows if constexpr (true) | |||
| # define if_linux if constexpr (false) | |||
| #else | |||
| # define debug_break() if_debug raise(SIGTRAP) | |||
| # define if_windows if constexpr (false) | |||
| # define if_linux if constexpr (true) | |||
| #endif | |||
| #define TOKENPASTE(x, y) x ## y | |||
| #define TOKENPASTE2(x, y) TOKENPASTE(x, y) | |||
| /** | |||
| * Defer * | |||
| */ | |||
| template<typename F> | |||
| class defer_finalizer { | |||
| F f; | |||
| bool moved; | |||
| public: | |||
| template<typename T> | |||
| defer_finalizer(T && f_) : f(std::forward<T>(f_)), moved(false) { } | |||
| defer_finalizer(const defer_finalizer &) = delete; | |||
| defer_finalizer(defer_finalizer && other) : f(std::move(other.f)), moved(other.moved) { | |||
| other.moved = true; | |||
| } | |||
| ~defer_finalizer() { | |||
| if (!moved) f(); | |||
| } | |||
| }; | |||
| struct { | |||
| template<typename F> | |||
| defer_finalizer<F> operator<<(F && f) { | |||
| return defer_finalizer<F>(std::forward<F>(f)); | |||
| } | |||
| } deferrer; | |||
| #define defer auto TOKENPASTE2(__deferred_lambda_call, __COUNTER__) = deferrer << [&] | |||
| /** | |||
| * fluid-let * | |||
| */ | |||
| #define fluid_let(var, val) \ | |||
| if (0) \ | |||
| TOKENPASTE2(finished,__LINE__): ; \ | |||
| else \ | |||
| for (auto TOKENPASTE2(fluid_let_, __LINE__) = var;;) \ | |||
| for(var = val;;) \ | |||
| if (1) { \ | |||
| goto TOKENPASTE2(body,__LINE__); \ | |||
| } \ | |||
| else \ | |||
| while (1) \ | |||
| if (1) { \ | |||
| var = TOKENPASTE2(fluid_let_, __LINE__); \ | |||
| goto TOKENPASTE2(finished, __LINE__); \ | |||
| } \ | |||
| else TOKENPASTE2(body,__LINE__): | |||
| @@ -1,40 +0,0 @@ | |||
| #pragma once | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| #include <time.h> | |||
| struct Profiler { | |||
| inline thread_local static int thread_id = 0; | |||
| inline thread_local static FILE* out_file = nullptr; | |||
| inline static char file_template[40] = "\0"; | |||
| Profiler(const char* file, const char* func, const int line) { | |||
| if (!out_file) { | |||
| time_t t = time(NULL); | |||
| tm tm_i; | |||
| localtime_s(&tm_i, &t); | |||
| if (!file_template[0]) { | |||
| sprintf(file_template, "%02d.%02d.%04d-%02d.%02d.%02d-%%02d-profiler.report", | |||
| tm_i.tm_mday, tm_i.tm_mon+1, tm_i.tm_year+1900, | |||
| tm_i.tm_hour, tm_i.tm_min, tm_i.tm_sec); | |||
| } | |||
| char file_name[38]; | |||
| sprintf(file_name, file_template, thread_id); | |||
| fopen_s(&out_file, file_name, "w"); | |||
| if (!out_file) { | |||
| printf("could not open %s\n", file_name); | |||
| } | |||
| } | |||
| fprintf(out_file, "-> %s %s %d\n", func, file, line); | |||
| }; | |||
| ~Profiler() { | |||
| fprintf(out_file, "<-\n"); | |||
| }; | |||
| }; | |||
| #define profile_this Profiler profiler(__FILE__, __FUNCTION__, __LINE__) | |||
| @@ -0,0 +1,61 @@ | |||
| #pragma once | |||
| #ifdef _PROFILING | |||
| # include <stdlib.h> | |||
| # include <stdio.h> | |||
| # include <string.h> | |||
| # include <time.h> | |||
| // for syscall: | |||
| # include <unistd.h> | |||
| # include <sys/syscall.h> | |||
| struct Profiler { | |||
| // same for all threads | |||
| inline static char file_template[40] = "\0"; | |||
| // thread local | |||
| inline thread_local static bool is_initialized = false; | |||
| inline thread_local static int thread_id = -1; | |||
| inline thread_local static int call_depth = 0; | |||
| inline thread_local static FILE* out_file = nullptr; | |||
| Profiler(const char* file, const char* func, const int line) { | |||
| call_depth += 1; | |||
| // if we never used this thread before | |||
| if (!is_initialized) { | |||
| thread_id = syscall(__NR_gettid); | |||
| printf("Hello I am %d\n", thread_id); | |||
| time_t t = time(NULL); | |||
| tm* tm_i = localtime(&t); | |||
| // if we never even created the shared file name template | |||
| if (!file_template[0]) { | |||
| sprintf(file_template, "%02d.%02d.%04d-%02d.%02d.%02d-%%02d-profiler.report", | |||
| tm_i->tm_mday, tm_i->tm_mon+1, tm_i->tm_year+1900, | |||
| tm_i->tm_hour, tm_i->tm_min, tm_i->tm_sec); | |||
| } | |||
| char file_name[38]; | |||
| sprintf(file_name, file_template, thread_id); | |||
| out_file = fopen(file_name, "w"); | |||
| if (!out_file) { | |||
| printf("could not open %s\n", file_name); | |||
| } | |||
| is_initialized = true; | |||
| } | |||
| fprintf(out_file, "-> %s %s %d\n", func, file, line); | |||
| }; | |||
| ~Profiler() { | |||
| call_depth -= 1; | |||
| fprintf(out_file, "<-\n"); | |||
| if (call_depth == 0) | |||
| fflush(out_file); | |||
| }; | |||
| }; | |||
| # define profile_this Profiler profiler(__FILE__, __FUNCTION__, __LINE__) | |||
| #else | |||
| # define profile_this enum {} | |||
| #endif | |||
| @@ -1,20 +1,25 @@ | |||
| #define _CRT_SECURE_NO_WARNINGS | |||
| #include <windows.h> | |||
| #include "profiler.h" | |||
| #include "profiler.hpp" | |||
| #include "macros.h" | |||
| int var = 100; | |||
| void test() { | |||
| profile_this; | |||
| printf("var is %d\n", var); | |||
| fluid_let (var, 200) { | |||
| printf("var is %d\n", var); | |||
| } | |||
| printf("doing more work!\n"); | |||
| printf("var is %d\n", var); | |||
| } | |||
| int main(int argc, char* argv[]) { | |||
| profile_this; | |||
| printf("doing some work and sleeping!\n"); | |||
| Sleep(1000); // Sleep a seconds | |||
| test(); | |||
| return 0; | |||