Felix Brendel преди 6 години
родител
ревизия
63f8554200
променени са 7 файла, в които са добавени 161 реда и са изтрити 99 реда
  1. +13
    -0
      build.sh
  2. +0
    -54
      macros.h
  3. +77
    -0
      macros.hpp
  4. +0
    -40
      profiler.h
  5. +61
    -0
      profiler.hpp
  6. +10
    -5
      test.cpp
  7. +0
    -0
      types.hpp

+ 13
- 0
build.sh Целия файл

@@ -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

+ 0
- 54
macros.h Целия файл

@@ -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 << [&]

+ 77
- 0
macros.hpp Целия файл

@@ -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__):

+ 0
- 40
profiler.h Целия файл

@@ -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__)

+ 61
- 0
profiler.hpp Целия файл

@@ -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

+ 10
- 5
test.cpp Целия файл

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


types.h → types.hpp Целия файл


Зареждане…
Отказ
Запис