Profiler as plugin
This commit is contained in:
@@ -463,11 +463,3 @@ void CMD_OpenLogs() {
|
|||||||
void CMD_Errors() {
|
void CMD_Errors() {
|
||||||
CMD_OpenLogs();
|
CMD_OpenLogs();
|
||||||
} RegisterCommand(CMD_Errors, "", "Opens the text editor logs and clear error counter");
|
} RegisterCommand(CMD_Errors, "", "Opens the text editor logs and clear error counter");
|
||||||
|
|
||||||
void CMD_BeginProfile() {
|
|
||||||
BeginProfiler();
|
|
||||||
} RegisterCommand(CMD_BeginProfile, "", "Start gathering profile data");
|
|
||||||
|
|
||||||
void CMD_EndProfile() {
|
|
||||||
EndProfiler();
|
|
||||||
} RegisterCommand(CMD_EndProfile, "", "Stop gathering profile data and write to disk");
|
|
||||||
31
src/text_editor/plugin_profiler.cpp
Normal file
31
src/text_editor/plugin_profiler.cpp
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
#if PLUGIN_PROFILER
|
||||||
|
|
||||||
|
void CMD_BeginProfile() {
|
||||||
|
BeginProfiler();
|
||||||
|
} RegisterCommand(CMD_BeginProfile, "", "Start gathering profile data");
|
||||||
|
|
||||||
|
void CMD_EndProfile() {
|
||||||
|
EndProfiler();
|
||||||
|
} RegisterCommand(CMD_EndProfile, "", "Stop gathering profile data and write to disk");
|
||||||
|
|
||||||
|
SPALL_FN void BeginProfiler() {
|
||||||
|
ActivelyProfiling = true;
|
||||||
|
Scratch scratch;
|
||||||
|
String filename = Format(scratch, "te%llu.spall", (unsigned long long)GetTimeNanos());
|
||||||
|
spall_init_file(filename.data, 1, &spall_ctx);
|
||||||
|
|
||||||
|
int buffer_size = 1 * 1024 * 1024;
|
||||||
|
unsigned char *buffer = (unsigned char *)malloc(buffer_size);
|
||||||
|
spall_buffer = {buffer, (size_t)buffer_size};
|
||||||
|
|
||||||
|
spall_buffer_init(&spall_ctx, &spall_buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SPALL_FN void EndProfiler() {
|
||||||
|
ActivelyProfiling = false;
|
||||||
|
spall_buffer_quit(&spall_ctx, &spall_buffer);
|
||||||
|
free(spall_buffer.data);
|
||||||
|
spall_quit(&spall_ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#if BUILD_DEBUG
|
#if PLUGIN_PROFILER
|
||||||
// SPDX-FileCopyrightText: © 2023 Phillip Trudeau-Tavara <pmttavara@protonmail.com>
|
// SPDX-FileCopyrightText: © 2023 Phillip Trudeau-Tavara <pmttavara@protonmail.com>
|
||||||
// SPDX-License-Identifier: MIT
|
// SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
@@ -21,9 +21,6 @@ TODO: Optional Helper APIs:
|
|||||||
spall_ring_flush
|
spall_ring_flush
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef SPALL_H
|
|
||||||
#define SPALL_H
|
|
||||||
|
|
||||||
#if !defined(_MSC_VER) || defined(__clang__)
|
#if !defined(_MSC_VER) || defined(__clang__)
|
||||||
#define SPALL_NOINSTRUMENT __attribute__((no_instrument_function))
|
#define SPALL_NOINSTRUMENT __attribute__((no_instrument_function))
|
||||||
#define SPALL_FORCEINLINE __attribute__((always_inline))
|
#define SPALL_FORCEINLINE __attribute__((always_inline))
|
||||||
@@ -140,9 +137,10 @@ typedef struct SpallBuffer {
|
|||||||
uint64_t first_ts;
|
uint64_t first_ts;
|
||||||
} SpallBuffer;
|
} SpallBuffer;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
static SpallProfile spall_ctx;
|
||||||
extern "C" {
|
static SpallBuffer spall_buffer;
|
||||||
#endif
|
uint64_t GetTimeNanos(void);
|
||||||
|
bool ActivelyProfiling = false;
|
||||||
|
|
||||||
SPALL_FN SPALL_FORCEINLINE bool spall__file_write(SpallProfile *ctx, const void *p, size_t n) {
|
SPALL_FN SPALL_FORCEINLINE bool spall__file_write(SpallProfile *ctx, const void *p, size_t n) {
|
||||||
if (fwrite(p, n, 1, (FILE *)ctx->data) != 1) return false;
|
if (fwrite(p, n, 1, (FILE *)ctx->data) != 1) return false;
|
||||||
@@ -307,6 +305,7 @@ SPALL_FN bool spall_buffer_init(SpallProfile *ctx, SpallBuffer *wb) {
|
|||||||
|
|
||||||
|
|
||||||
SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, SpallBuffer *wb, const char *name, int32_t name_len, const char *args, int32_t args_len, uint64_t when) {
|
SPALL_FN SPALL_FORCEINLINE bool spall_buffer_begin_args(SpallProfile *ctx, SpallBuffer *wb, const char *name, int32_t name_len, const char *args, int32_t args_len, uint64_t when) {
|
||||||
|
if (!ActivelyProfiling) return false;
|
||||||
if ((wb->head + sizeof(SpallBeginEventMax)) > wb->length) {
|
if ((wb->head + sizeof(SpallBeginEventMax)) > wb->length) {
|
||||||
if (!spall__buffer_flush(ctx, wb, when)) {
|
if (!spall__buffer_flush(ctx, wb, when)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -323,6 +322,7 @@ SPALL_FN bool spall_buffer_begin(SpallProfile *ctx, SpallBuffer *wb, const char
|
|||||||
}
|
}
|
||||||
|
|
||||||
SPALL_FN bool spall_buffer_end(SpallProfile *ctx, SpallBuffer *wb, uint64_t when) {
|
SPALL_FN bool spall_buffer_end(SpallProfile *ctx, SpallBuffer *wb, uint64_t when) {
|
||||||
|
if (!ActivelyProfiling) return false;
|
||||||
if ((wb->head + sizeof(SpallEndEvent)) > wb->length) {
|
if ((wb->head + sizeof(SpallEndEvent)) > wb->length) {
|
||||||
if (!spall__buffer_flush(ctx, wb, when)) {
|
if (!spall__buffer_flush(ctx, wb, when)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -355,67 +355,27 @@ SPALL_FN bool spall_buffer_name_process(SpallProfile *ctx, SpallBuffer *wb, cons
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // SPALL_H
|
#define BeginProfileScopeEx(name, len) spall_buffer_begin(&spall_ctx, &spall_buffer, (name), (len), GetTimeNanos())
|
||||||
|
#define BeginProfileScope(name) BeginProfileScopeEx(#name, sizeof(#name) - 1)
|
||||||
|
#define EndProfileScope() spall_buffer_end(&spall_ctx, &spall_buffer, GetTimeNanos())
|
||||||
static SpallProfile spall_ctx;
|
#define ProfileScopeEx(name) ProfileScopeClass PROFILE_SCOPE_VAR_((name).data, (int)(name).len)
|
||||||
static SpallBuffer spall_buffer;
|
#define ProfileScope(name) ProfileScopeClass PROFILE_SCOPE_VAR_##name(#name, sizeof(#name) - 1)
|
||||||
uint64_t GetTimeNanos(void);
|
#define ProfileFunction() ProfileScopeClass PROFILE_SCOPE_FUNCTION(__FUNCTION__, sizeof(__FUNCTION__) - 1)
|
||||||
bool ActivelyProfiling = false;
|
|
||||||
|
|
||||||
void BeginProfiler() {
|
|
||||||
Scratch scratch;
|
|
||||||
String filename = Format(scratch, "te%llu.spall", (unsigned long long)GetTimeNanos());
|
|
||||||
spall_init_file(filename.data, 1, &spall_ctx);
|
|
||||||
|
|
||||||
int buffer_size = 1 * 1024 * 1024;
|
|
||||||
unsigned char *buffer = (unsigned char *)malloc(buffer_size);
|
|
||||||
spall_buffer = {buffer, (size_t)buffer_size};
|
|
||||||
|
|
||||||
spall_buffer_init(&spall_ctx, &spall_buffer);
|
|
||||||
ActivelyProfiling = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EndProfiler() {
|
|
||||||
spall_buffer_quit(&spall_ctx, &spall_buffer);
|
|
||||||
free(spall_buffer.data);
|
|
||||||
spall_quit(&spall_ctx);
|
|
||||||
ActivelyProfiling = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void _BeginProfileScope(const char *name, int len) {
|
|
||||||
if (!ActivelyProfiling) return;
|
|
||||||
spall_buffer_begin(&spall_ctx, &spall_buffer,
|
|
||||||
name, // name of your name
|
|
||||||
len, // name len minus the null terminator
|
|
||||||
GetTimeNanos() // timestamp in microseconds -- start of your timing block
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#define BeginProfileScope(name) _BeginProfileScope(#name, sizeof(#name) - 1)
|
|
||||||
|
|
||||||
void EndProfileScope() {
|
|
||||||
if (!ActivelyProfiling) return;
|
|
||||||
spall_buffer_end(&spall_ctx, &spall_buffer,
|
|
||||||
GetTimeNanos() // timestamp in microseconds -- end of your timing block
|
|
||||||
);
|
|
||||||
}
|
|
||||||
#define ProfileScopeEx(name) ProfileScopeClass PROFILE_SCOPE_VAR_((name).data, (int)(name).len)
|
|
||||||
#define ProfileScope(name) ProfileScopeClass PROFILE_SCOPE_VAR_##name(#name, sizeof(#name) - 1)
|
|
||||||
#define ProfileFunction() ProfileScopeClass PROFILE_SCOPE_FUNCTION(__FUNCTION__, sizeof(__FUNCTION__) - 1)
|
|
||||||
struct ProfileScopeClass {
|
struct ProfileScopeClass {
|
||||||
ProfileScopeClass(const char *name, int len) { _BeginProfileScope(name, len); }
|
ProfileScopeClass(const char *name, int len) { BeginProfileScopeEx(name, len); }
|
||||||
~ProfileScopeClass() { EndProfileScope(); }
|
~ProfileScopeClass() { EndProfileScope(); }
|
||||||
};
|
};
|
||||||
|
SPALL_FN void BeginProfiler();
|
||||||
|
SPALL_FN void EndProfiler();
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#define ProfileScopeEx(name)
|
#define ProfileScopeEx(name)
|
||||||
#define ProfileScope(name)
|
#define ProfileScope(name)
|
||||||
#define ProfileFunction()
|
#define ProfileFunction()
|
||||||
#define BeginProfiler()
|
#define BeginProfiler()
|
||||||
#define EndProfiler()
|
#define EndProfiler()
|
||||||
|
#define BeginProfileScopeEx(name, len)
|
||||||
#define BeginProfileScope(name)
|
#define BeginProfileScope(name)
|
||||||
#define EndProfileScope()
|
#define EndProfileScope()
|
||||||
#endif
|
#endif
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
|
#define PLUGIN_PROFILER 1
|
||||||
|
|
||||||
|
#include "plugin_profiler.h"
|
||||||
#include "basic/basic.h"
|
#include "basic/basic.h"
|
||||||
#include "basic/basic.cpp"
|
#include "basic/basic.cpp"
|
||||||
#include "profiler.h"
|
|
||||||
#include "SDL3/SDL.h"
|
#include "SDL3/SDL.h"
|
||||||
#include "external/glad/glad.c"
|
#include "external/glad/glad.c"
|
||||||
#include "external/glad/glad.h"
|
#include "external/glad/glad.h"
|
||||||
@@ -69,6 +71,7 @@
|
|||||||
#include "plugin_record_events.cpp"
|
#include "plugin_record_events.cpp"
|
||||||
#include "plugin_load_vcvars.cpp"
|
#include "plugin_load_vcvars.cpp"
|
||||||
#include "plugin_remedybg.cpp"
|
#include "plugin_remedybg.cpp"
|
||||||
|
#include "plugin_profiler.cpp"
|
||||||
|
|
||||||
#if OS_WASM
|
#if OS_WASM
|
||||||
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
|
EM_JS(void, JS_SetMouseCursor, (const char *cursor_str), {
|
||||||
|
|||||||
Reference in New Issue
Block a user