2019-10-18 20:54:45 +00:00
|
|
|
/*
|
|
|
|
* 4coder_profile.cpp - Built in self profiling report.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// TOP
|
|
|
|
|
|
|
|
function Profile_Group*
|
|
|
|
make_profile_group__inner(u32 slot_count, u32 stack_size, char *source_location){
|
|
|
|
Arena arena = make_arena_system(KB(4));
|
|
|
|
Profile_Group *group = push_array(&arena, Profile_Group, 1);
|
|
|
|
group->arena = arena;
|
|
|
|
group->thread_id = system_thread_get_id();
|
|
|
|
group->source_location = SCu8(source_location);
|
|
|
|
group->slot_names = push_array_zero(&group->arena, String_Const_u8, slot_count);
|
|
|
|
group->timer_stack = push_array_zero(&group->arena, Profile_Slot, stack_size);
|
|
|
|
group->slot_count = slot_count;
|
|
|
|
group->stack_size = stack_size;
|
|
|
|
group->stack_top = 0;
|
|
|
|
group->first = 0;
|
|
|
|
group->last = 0;
|
|
|
|
return(group);
|
|
|
|
}
|
|
|
|
|
|
|
|
#define make_profile_group(L,T) make_profile_group__inner((L),(T), file_name_line_number)
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_define(Profile_Group *group, u32 slot_index, char *name){
|
|
|
|
if (slot_index < group->slot_count){
|
|
|
|
group->slot_names[slot_index] = SCu8(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile__record(Profile_Group *group, u32 slot_index, u64 time){
|
|
|
|
Profile_Record *record = push_array(&group->arena, Profile_Record, 1);
|
|
|
|
record->slot_index = slot_index;
|
|
|
|
record->time = time;
|
|
|
|
sll_queue_push(group->first, group->last, record);
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_begin_range(Profile_Group *group, u32 slot_index){
|
|
|
|
Assert(group->stack_top < group->stack_size);
|
|
|
|
Profile_Slot *slot = &group->timer_stack[group->stack_top];
|
|
|
|
Profile_Slot *prev = 0;
|
|
|
|
if (group->stack_top > 0){
|
|
|
|
prev = &group->timer_stack[group->stack_top - 1];
|
|
|
|
}
|
|
|
|
slot->slot_index = slot_index;
|
|
|
|
group->stack_top += 1;
|
|
|
|
slot->accumulated_time = 0;
|
|
|
|
u64 time = system_now_time();
|
|
|
|
slot->start_time = time;
|
|
|
|
if (prev != 0){
|
|
|
|
prev->accumulated_time += time - prev->start_time;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_end_range(Profile_Group *group){
|
|
|
|
u64 time = system_now_time();
|
|
|
|
Assert(group->stack_top > 0);
|
|
|
|
group->stack_top -= 1;
|
|
|
|
if (group->stack_top > 0){
|
|
|
|
Profile_Slot *prev = &group->timer_stack[group->stack_top - 1];
|
|
|
|
prev->start_time = time;
|
|
|
|
}
|
|
|
|
Profile_Slot *slot = &group->timer_stack[group->stack_top];
|
|
|
|
u64 accumulated = time - slot->start_time + slot->accumulated_time;
|
|
|
|
profile__record(group, slot->slot_index, accumulated);
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_add_note(Profile_Group *group, u32 slot_index){
|
|
|
|
profile__record(group, slot_index, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_group_post(Profile_Group *group){
|
|
|
|
Assert(group->stack_top == 0);
|
|
|
|
system_mutex_acquire(profile_history.mutex);
|
|
|
|
if (profile_history.disable_bits == 0){
|
|
|
|
sll_queue_push(profile_history.first, profile_history.last, group);
|
|
|
|
}
|
|
|
|
else{
|
2019-10-18 22:25:40 +00:00
|
|
|
Arena arena = group->arena;
|
|
|
|
linalloc_clear(&arena);
|
2019-10-18 20:54:45 +00:00
|
|
|
}
|
|
|
|
system_mutex_release(profile_history.mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_history_set_enabled(b32 value, Profile_Enable_Flag flag){
|
|
|
|
system_mutex_acquire(profile_history.mutex);
|
|
|
|
if (value){
|
|
|
|
RemFlag(profile_history.disable_bits, flag);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
AddFlag(profile_history.disable_bits, flag);
|
|
|
|
}
|
|
|
|
system_mutex_release(profile_history.mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_history_clear(void){
|
|
|
|
system_mutex_acquire(profile_history.mutex);
|
|
|
|
for (Profile_Group *node = profile_history.first, *next = 0;
|
|
|
|
node != 0;
|
|
|
|
node = next){
|
|
|
|
next = node->next;
|
2019-10-18 22:25:40 +00:00
|
|
|
Arena arena = node->arena;
|
|
|
|
linalloc_clear(&arena);
|
2019-10-18 20:54:45 +00:00
|
|
|
}
|
2019-10-19 18:55:56 +00:00
|
|
|
profile_history.first = 0;
|
|
|
|
profile_history.last = 0;
|
2019-10-18 20:54:45 +00:00
|
|
|
system_mutex_release(profile_history.mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
function void
|
|
|
|
profile_history_init(void){
|
|
|
|
profile_history.mutex = system_mutex_make();
|
|
|
|
profile_history.disable_bits = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////
|
|
|
|
|
|
|
|
CUSTOM_COMMAND_SIG(profile_enable)
|
|
|
|
CUSTOM_DOC("Allow 4coder's self profiler to gather new profiling information.")
|
|
|
|
{
|
|
|
|
profile_history_set_enabled(true, ProfileEnable_UserBit);
|
|
|
|
}
|
|
|
|
|
|
|
|
CUSTOM_COMMAND_SIG(profile_disable)
|
|
|
|
CUSTOM_DOC("Prevent 4coder's self profiler from gathering new profiling information.")
|
|
|
|
{
|
|
|
|
profile_history_set_enabled(false, ProfileEnable_UserBit);
|
|
|
|
}
|
|
|
|
|
|
|
|
CUSTOM_COMMAND_SIG(profile_clear)
|
|
|
|
CUSTOM_DOC("Clear all profiling information from 4coder's self profiler.")
|
|
|
|
{
|
|
|
|
profile_history_clear();
|
|
|
|
}
|
|
|
|
|
|
|
|
// BOTTOM
|