dqn: Fix DQN_ASAN_POISON 0 breaking arenas, improve profiler API

This commit is contained in:
doyle 2023-09-01 00:18:53 +10:00
parent 04b5e26ff3
commit b46b44f11c
4 changed files with 63 additions and 28 deletions

View File

@ -2,8 +2,8 @@
#define DQN_ASAN_POISON 0
#endif
#if !defined(DQN_ASAN_POISON_VET)
#define DQN_ASAN_POISON_VET 0
#if !defined(DQN_ASAN_VET_POISON)
#define DQN_ASAN_VET_POISON 0
#endif
#define DQN_ASAN_POISON_ALIGNMENT 8

View File

@ -952,9 +952,9 @@ DQN_API void Dqn_Library_DumpThreadContextArenaStat(Dqn_String8 file_path)
#if !defined(DQN_NO_PROFILER)
// NOTE: [$PROF] Dqn_Profiler ======================================================================
Dqn_ProfilerZoneScope::Dqn_ProfilerZoneScope(uint16_t label)
Dqn_ProfilerZoneScope::Dqn_ProfilerZoneScope(Dqn_String8 name, uint16_t anchor_index)
{
zone = Dqn_Profiler_BeginZone(label);
zone = Dqn_Profiler_BeginZoneWithIndex(name, anchor_index);
}
Dqn_ProfilerZoneScope::~Dqn_ProfilerZoneScope()
@ -962,15 +962,16 @@ Dqn_ProfilerZoneScope::~Dqn_ProfilerZoneScope()
Dqn_Profiler_EndZone(zone);
}
Dqn_ProfilerZone Dqn_Profiler_BeginZone(uint16_t label)
Dqn_ProfilerZone Dqn_Profiler_BeginZoneWithIndex(Dqn_String8 name, uint16_t anchor_index)
{
Dqn_ProfilerAnchor *anchor = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back) + label;
Dqn_ProfilerAnchor *anchor = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back) + anchor_index;
anchor->name = name;
Dqn_ProfilerZone result = {};
result.begin_tsc = Dqn_CPU_TSC();
result.label = label;
result.anchor_index = anchor_index;
result.parent_zone = g_dqn_library->profiler->parent_zone;
result.elapsed_tsc_at_zone_start = anchor->tsc_inclusive;
g_dqn_library->profiler->parent_zone = label;
g_dqn_library->profiler->parent_zone = anchor_index;
return result;
}
@ -978,15 +979,15 @@ void Dqn_Profiler_EndZone(Dqn_ProfilerZone zone)
{
uint64_t elapsed_tsc = Dqn_CPU_TSC() - zone.begin_tsc;
Dqn_ProfilerAnchor *anchor_buffer = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back);
Dqn_ProfilerAnchor *anchor = anchor_buffer + zone.label;
Dqn_ProfilerAnchor *anchor = anchor_buffer + zone.anchor_index;
anchor->hit_count++;
anchor->tsc_inclusive = zone.elapsed_tsc_at_zone_start + elapsed_tsc;
anchor->tsc_exclusive += elapsed_tsc;
Dqn_ProfilerAnchor *parent_anchor = anchor_buffer + zone.parent_zone;
parent_anchor->tsc_exclusive -= elapsed_tsc;
g_dqn_library->profiler->parent_zone = zone.parent_zone;
Dqn_ProfilerAnchor *parent_anchor = anchor_buffer + zone.parent_zone;
parent_anchor->tsc_exclusive -= elapsed_tsc;
g_dqn_library->profiler->parent_zone = zone.parent_zone;
}
Dqn_ProfilerAnchor *Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer buffer)
@ -1003,4 +1004,31 @@ void Dqn_Profiler_SwapAnchorBuffer(uint32_t anchor_count)
Dqn_ProfilerAnchor *anchors = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back);
DQN_MEMSET(anchors, 0, anchor_count * sizeof(g_dqn_library->profiler->anchors[0][0]));
}
void Dqn_Profiler_Dump(uint64_t tsc_per_second)
{
Dqn_ProfilerAnchor *anchors = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back);
for (size_t anchor_index = 1; anchor_index < DQN_PROFILER_ANCHOR_BUFFER_SIZE; anchor_index++) {
Dqn_ProfilerAnchor const *anchor = anchors + anchor_index;
if (!anchor->hit_count)
continue;
uint64_t tsc_exclusive = anchor->tsc_exclusive;
uint64_t tsc_inclusive = anchor->tsc_inclusive;
Dqn_f64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DQN_CAST(Dqn_f64)tsc_per_second;
if (tsc_exclusive == tsc_inclusive) {
Dqn_Print_LnF("%.*s[%u]: %.1fms",
DQN_STRING_FMT(anchor->name),
anchor->hit_count,
tsc_exclusive_milliseconds);
} else {
Dqn_f64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DQN_CAST(Dqn_f64)tsc_per_second;
Dqn_Print_LnF("%.*s[%u]: %.1f/%.1fms",
DQN_STRING_FMT(anchor->name),
anchor->hit_count,
tsc_exclusive_milliseconds,
tsc_inclusive_milliseconds);
}
}
}
#endif // !defined(DQN_NO_PROFILER)

View File

@ -489,7 +489,7 @@ DQN_API Dqn_U64String Dqn_U64ToString (uint64_t val, char separator);
for (size_t index = 0; index < Zone_Count; index++) {
Dqn_ProfilerAnchor *anchor = anchors + index;
printf("%.*s[%u] %zu cycles (%.1fms)\n",
DQN_STRING_FMT(anchor->label),
DQN_STRING_FMT(anchor->anchor_index),
anchor->hit_count,
anchor->tsc_inclusive,
anchor->tsc_inclusive * tsc_per_seconds * 1000.f);
@ -524,27 +524,29 @@ struct Dqn_ProfilerAnchor
// time spent in children functions that we call that are also being
// profiled. If we recursively call into ourselves, the time we spent in
// our function is accumulated.
uint64_t tsc_inclusive;
uint64_t tsc_exclusive;
uint16_t hit_count;
uint64_t tsc_inclusive;
uint64_t tsc_exclusive;
uint16_t hit_count;
Dqn_String8 name;
};
struct Dqn_ProfilerZone
{
uint16_t label;
uint64_t begin_tsc;
uint16_t parent_zone;
uint64_t elapsed_tsc_at_zone_start;
uint16_t anchor_index;
uint64_t begin_tsc;
uint16_t parent_zone;
uint64_t elapsed_tsc_at_zone_start;
};
#if defined(__cplusplus)
struct Dqn_ProfilerZoneScope
{
Dqn_ProfilerZoneScope(uint16_t label);
Dqn_ProfilerZoneScope(Dqn_String8 name, uint16_t anchor_index);
~Dqn_ProfilerZoneScope();
Dqn_ProfilerZone zone;
};
#define Dqn_Profiler_ZoneScope(label) auto DQN_UNIQUE_NAME(profile_zone_##label_) = Dqn_ProfilerZoneScope(label)
#define Dqn_Profiler_ZoneScope(name) auto DQN_UNIQUE_NAME(profile_zone_) = Dqn_ProfilerZoneScope(DQN_STRING8(name), __COUNTER__ + 1)
#define Dqn_Profiler_ZoneScopeWithIndex(name, anchor_index) auto DQN_UNIQUE_NAME(profile_zone_) = Dqn_ProfilerZoneScope(DQN_STRING8(name), anchor_index)
#endif
enum Dqn_ProfilerAnchorBuffer
@ -560,10 +562,15 @@ struct Dqn_Profiler
uint16_t parent_zone;
};
Dqn_ProfilerZone Dqn_Profiler_BeginZone (uint16_t label);
void Dqn_Profiler_EndZone (Dqn_ProfilerZone zone);
Dqn_ProfilerAnchor *Dqn_Profiler_AnchorBuffer (Dqn_ProfilerAnchorBuffer buffer);
void Dqn_Profiler_SwapAnchorBuffer (uint32_t anchor_count);
// NOTE: Macros ====================================================================================
#define Dqn_Profiler_BeginZone(name) Dqn_Profiler_BeginZoneWithIndex(DQN_STRING8(name), __COUNTER__ + 1)
// NOTE: API =======================================================================================
Dqn_ProfilerZone Dqn_Profiler_BeginZoneWithIndex(Dqn_String8 name, uint16_t anchor_index);
void Dqn_Profiler_EndZone (Dqn_ProfilerZone zone);
Dqn_ProfilerAnchor *Dqn_Profiler_AnchorBuffer (Dqn_ProfilerAnchorBuffer buffer);
void Dqn_Profiler_SwapAnchorBuffer (uint32_t anchor_count);
void Dqn_Profiler_Dump (uint64_t tsc_per_second);
#endif // !defined(DQN_NO_PROFILER)
// NOTE: [$DLIB] Dqn_Library =======================================================================

View File

@ -179,8 +179,8 @@ DQN_API Dqn_MemBlockSizeRequiredResult Dqn_MemBlock_SizeRequired(Dqn_MemBlock co
Dqn_usize Dqn_MemBlock_MetadataSize()
{
Dqn_usize init_poison_page = DQN_ASAN_POISON ? DQN_ASAN_POISON_GUARD_SIZE : 0;
Dqn_usize poison_alignment = DQN_ASAN_POISON ? DQN_ASAN_POISON_ALIGNMENT : 0;
Dqn_usize result = Dqn_AlignUpPowerOfTwo(sizeof(Dqn_MemBlock), poison_alignment) + init_poison_page;
Dqn_usize alignment = DQN_ASAN_POISON ? DQN_ASAN_POISON_ALIGNMENT : alignof(Dqn_MemBlock);
Dqn_usize result = Dqn_AlignUpPowerOfTwo(sizeof(Dqn_MemBlock), alignment) + init_poison_page;
return result;
}