163 lines
3.7 KiB
C
163 lines
3.7 KiB
C
|
/*
|
||
|
* Mr. 4th Dimention - Allen Webster
|
||
|
*
|
||
|
* 29.03.2017
|
||
|
*
|
||
|
* Really basic profiling primitives. (not meant to stay for long)
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
// TOP
|
||
|
|
||
|
#if !defined(FRED_PROFILE_H)
|
||
|
#define FRED_PROFILE_H
|
||
|
|
||
|
#if FRED_INTERNAL
|
||
|
|
||
|
#include <intrin.h>
|
||
|
#include <stdio.h>
|
||
|
|
||
|
struct Profile_Group{
|
||
|
char name[104];
|
||
|
u64 cycle_start;
|
||
|
u64 cycle_count;
|
||
|
void *end;
|
||
|
};
|
||
|
|
||
|
struct Profile{
|
||
|
u8 *buffer;
|
||
|
u32 pos, max;
|
||
|
|
||
|
Profile_Group *stack[64];
|
||
|
u32 stack_top;
|
||
|
};
|
||
|
global Profile global_profile = {0};
|
||
|
|
||
|
internal Profile_Group*
|
||
|
push_group(char *name){
|
||
|
Profile_Group *result = 0;
|
||
|
if (global_profile.pos + sizeof(Profile_Group) <= global_profile.max){
|
||
|
result = (Profile_Group*)(global_profile.buffer + global_profile.pos);
|
||
|
global_profile.pos += sizeof(Profile_Group);
|
||
|
u32 i = 0;
|
||
|
for (; name[i] && i < sizeof(result->name)-1; ++i){
|
||
|
result->name[i] = name[i];
|
||
|
}
|
||
|
result->name[i] = 0;
|
||
|
result->cycle_start = __rdtsc();
|
||
|
}
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
profile_init(void *mem, u32 max){
|
||
|
global_profile.buffer = (u8*)mem;
|
||
|
global_profile.max = max;
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
profile_begin_group(char *name){
|
||
|
u32 stack_pos = global_profile.stack_top;
|
||
|
if (stack_pos < ArrayCount(global_profile.stack)){
|
||
|
global_profile.stack[stack_pos] = push_group(name);
|
||
|
Assert(global_profile.stack[stack_pos] != 0);
|
||
|
++global_profile.stack_top;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
profile_end_group(){
|
||
|
Assert(global_profile.stack_top > 0);
|
||
|
u32 stack_pos = --global_profile.stack_top;
|
||
|
if (stack_pos < ArrayCount(global_profile.stack)){
|
||
|
Profile_Group *group = global_profile.stack[stack_pos];
|
||
|
Assert(group != 0);
|
||
|
group->cycle_count = __rdtsc() - group->cycle_start;
|
||
|
group->end = global_profile.buffer + global_profile.pos;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
profile_begin_frame(){
|
||
|
global_profile.pos = 0;
|
||
|
global_profile.stack_top = 0;
|
||
|
profile_begin_group("*frame*");
|
||
|
}
|
||
|
|
||
|
internal void
|
||
|
profile_end_frame(char *filename){
|
||
|
profile_end_group();
|
||
|
Assert(global_profile.stack_top == 0);
|
||
|
|
||
|
FILE *file = fopen(filename, "ab");
|
||
|
Assert(file != 0);
|
||
|
fwrite(&global_profile.buffer, 8, 1, file);
|
||
|
|
||
|
Profile_Group *first_group = (Profile_Group*)global_profile.buffer;
|
||
|
fwrite(&first_group->end, 8, 1, file);
|
||
|
|
||
|
fwrite(global_profile.buffer, 1, global_profile.pos, file);
|
||
|
fclose(file);
|
||
|
}
|
||
|
|
||
|
internal Profile_Group*
|
||
|
profile_begin_resumable(char *name){
|
||
|
Profile_Group *result = push_group(name);
|
||
|
Assert(result != 0);
|
||
|
result->cycle_count = 0;
|
||
|
result->end = result + 1;
|
||
|
return(result);
|
||
|
}
|
||
|
|
||
|
struct profile_scope{
|
||
|
profile_scope(char *name){
|
||
|
profile_begin_group(name);
|
||
|
}
|
||
|
|
||
|
~profile_scope(){
|
||
|
profile_end_group();
|
||
|
}
|
||
|
};
|
||
|
|
||
|
#define PRFL_INIT(m,s) profile_init(m,s)
|
||
|
|
||
|
#define PRFL_BEGIN_FRAME() profile_begin_frame()
|
||
|
#define PRFL_END_FRAME(n) profile_end_frame(n)
|
||
|
|
||
|
#define PRFL_BEGIN_GROUP(n) profile_begin_group(#n)
|
||
|
#define PRFL_END_GROUP() profile_end_group()
|
||
|
#define PRFL_SCOPE_GROUP(n) profile_scope SCOPE_##n(#n)
|
||
|
|
||
|
#define PRFL_FUNC_GROUP() profile_scope SCOPE_FUNC(__FUNCTION__)
|
||
|
|
||
|
#define PRFL_BEGIN_RESUMABLE(n) Profile_Group *PRFLGRP_##n = profile_begin_resumable(#n)
|
||
|
#define PRFL_START_RESUMABLE(n) PRFLGRP_##n->cycle_start = __rdtsc()
|
||
|
#define PRFL_STOP_RESUMABLE(n) PRFLGRP_##n->cycle_count += __rdtsc() - PRFLGRP_##n->cycle_start
|
||
|
#define PRFL_END_RESUMABLE(n)
|
||
|
|
||
|
#else
|
||
|
|
||
|
#define PRFL_INIT(m,s)
|
||
|
|
||
|
#define PRFL_BEGIN_FRAME()
|
||
|
#define PRFL_END_FRAME(n)
|
||
|
|
||
|
#define PRFL_BEGIN_GROUP(n)
|
||
|
#define PRFL_END_GROUP()
|
||
|
#define PRFL_SCOPE_GROUP(n)
|
||
|
|
||
|
#define PRFL_FUNC_GROUP()
|
||
|
|
||
|
#define PRFL_BEGIN_RESUMABLE(n)
|
||
|
#define PRFL_START_RESUMABLE(n)
|
||
|
#define PRFL_STOP_RESUMABLE(n)
|
||
|
#define PRFL_END_RESUMABLE(n)
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
// BOTTOM
|
||
|
|
||
|
|