Optimizations and profiling (fix draw line numbers, coroutines)
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
- What precise workflow do I need for me to be viable to use this?
|
||||
- From a user (novice) point of view, how does it look like?
|
||||
|
||||
- Optimization:
|
||||
- Show what process/coroutines are running and allow to kill (active process buffer?)
|
||||
- ctrl + p like in VSCode (without special buffers)
|
||||
- I THINK WE NEED A SPECIAL VIEW, this is too slow
|
||||
- Move to the top so that it can be progressively expanded using coroutines by appending at the end
|
||||
- Maybe 2 windows?
|
||||
- Database idea: use special buffers to store information
|
||||
- Editing the buffer doesn't seem to be the slow part rather, accessing the data and putting it into the buffer (potentially hitting many different memory locations) I have a crazy idea to use buffers in order to store the names in a serialized format
|
||||
- non editable buffers (raw ops ok, non-raw no op)
|
||||
- Guide on the first page for new users with links to configs, tutorials
|
||||
|
||||
- Why constraint that name of buffer needs to be unique? For Open() and default behavior but is this required?
|
||||
|
||||
@@ -193,6 +193,13 @@ API String GetExeDir(Allocator al) {
|
||||
return result;
|
||||
}
|
||||
|
||||
API uint64_t GetTimeNanos(void) {
|
||||
struct timespec spec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||
uint64_t ts = ((uint64_t)spec.tv_sec * 1000000000ull) + (uint64_t)spec.tv_nsec;
|
||||
return ts;
|
||||
}
|
||||
|
||||
API double GetTimeMicros(void) {
|
||||
struct timespec spec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||
@@ -565,6 +572,19 @@ API FileIter IterateFiles(Allocator alo, String path) {
|
||||
return it;
|
||||
}
|
||||
|
||||
API uint64_t GetTimeNanos(void) {
|
||||
static double invfreq;
|
||||
if (!invfreq) {
|
||||
LARGE_INTEGER frequency;
|
||||
QueryPerformanceFrequency(&frequency);
|
||||
invfreq = 1000000000.0 / frequency.QuadPart;
|
||||
}
|
||||
LARGE_INTEGER counter;
|
||||
QueryPerformanceCounter(&counter);
|
||||
uint64_t ts = (uint64_t)((double)counter.QuadPart * invfreq);
|
||||
return ts;
|
||||
}
|
||||
|
||||
API double GetTimeMicros(void) {
|
||||
static double invfreq;
|
||||
if (!invfreq) {
|
||||
@@ -1047,6 +1067,13 @@ API String GetExeDir(Allocator al) {
|
||||
return result;
|
||||
}
|
||||
|
||||
API uint64_t GetTimeNanos(void) {
|
||||
struct timespec spec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||
uint64_t ts = ((uint64_t)spec.tv_sec * 1000000000ull) + (uint64_t)spec.tv_nsec;
|
||||
return ts;
|
||||
}
|
||||
|
||||
API double GetTimeMicros(void) {
|
||||
struct timespec spec;
|
||||
clock_gettime(CLOCK_MONOTONIC, &spec);
|
||||
|
||||
@@ -674,11 +674,7 @@ void Coro_OpenCode(mco_coro *co) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ((i%32) == 0) {
|
||||
CoYield(co);
|
||||
}
|
||||
i += 1;
|
||||
CoYield(co);
|
||||
}
|
||||
}
|
||||
Release(&arena);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
typedef void CoroutineProc(mco_coro *co);
|
||||
|
||||
mco_coro *CoAdd(CoroutineProc *proc) {
|
||||
#define CoAdd(x) CoAddEx(x, #x)
|
||||
mco_coro *CoAddEx(CoroutineProc *proc, String name) {
|
||||
mco_desc desc = mco_desc_init(proc, 0);
|
||||
|
||||
mco_coro *coro = NULL;
|
||||
@@ -11,32 +12,35 @@ mco_coro *CoAdd(CoroutineProc *proc) {
|
||||
}
|
||||
|
||||
mco_resume(coro);
|
||||
Add(&ActiveCoroutines, coro);
|
||||
Add(&ActiveCoroutines, {coro, name});
|
||||
return coro;
|
||||
}
|
||||
|
||||
void CoUpdate(Event *event) {
|
||||
ProfileFunction();
|
||||
double start = GetTimeSeconds();
|
||||
IterRemove(ActiveCoroutines) {
|
||||
IterRemovePrepare(ActiveCoroutines);
|
||||
for (;ActiveCoroutines.len;) {
|
||||
IterRemove(ActiveCoroutines) {
|
||||
IterRemovePrepare(ActiveCoroutines);
|
||||
ProfileScopeEx(it.name);
|
||||
|
||||
mco_state status = mco_status(it);
|
||||
if (status == MCO_DEAD) {
|
||||
mco_destroy(it);
|
||||
remove_item = true;
|
||||
} else {
|
||||
mco_push(it, &event, sizeof(Event *));
|
||||
mco_result ok = mco_resume(it);
|
||||
if (ok != MCO_SUCCESS) {
|
||||
ReportWarningf("failed to resume coroutine %d", ok);
|
||||
mco_destroy(it);
|
||||
mco_state status = mco_status(it.co);
|
||||
if (status == MCO_DEAD) {
|
||||
mco_destroy(it.co);
|
||||
remove_item = true;
|
||||
} else {
|
||||
mco_push(it.co, &event, sizeof(Event *));
|
||||
mco_result ok = mco_resume(it.co);
|
||||
if (ok != MCO_SUCCESS) {
|
||||
ReportWarningf("failed to resume coroutine %d", ok);
|
||||
mco_destroy(it.co);
|
||||
remove_item = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double took = GetTimeSeconds() - start;
|
||||
if (took > 0.01) {
|
||||
if (took > (0.016666 / 3.0)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -53,7 +57,12 @@ Event *CoYield(mco_coro *co) {
|
||||
return event;
|
||||
}
|
||||
|
||||
void CoRemove(mco_coro *co) {
|
||||
UnorderedRemove(&ActiveCoroutines, co);
|
||||
mco_destroy(co);
|
||||
void CoRemove(String name) {
|
||||
IterRemove(ActiveCoroutines) {
|
||||
IterRemovePrepare(ActiveCoroutines);
|
||||
if (it.name == name) {
|
||||
mco_destroy(it.co);
|
||||
remove_item = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,7 +235,7 @@ void DrawWindow(Window *window, Event &event) {
|
||||
|
||||
// Draw caret "|" markings
|
||||
if (is_active) {
|
||||
BeginProfileScope(draw_carets);
|
||||
ProfileScope(DrawCarets);
|
||||
For(view->carets) {
|
||||
Int front = GetFront(it);
|
||||
XY fxy = PosToXY(buffer, front);
|
||||
@@ -244,17 +244,17 @@ void DrawWindow(Window *window, Event &event) {
|
||||
DrawCaret(window, fxy, 0.3f, main_caret ? color_main_caret : color_sub_caret);
|
||||
}
|
||||
}
|
||||
EndProfileScope();
|
||||
}
|
||||
|
||||
// Draw line numbers
|
||||
if (window->draw_line_numbers) {
|
||||
ProfileScope(DrawLineNumbers);
|
||||
Scratch scratch;
|
||||
SetScissor(window->line_numbers_rect);
|
||||
|
||||
Rect2I vlines = GetVisibleCells(window);
|
||||
for (Int line = vlines.min.y; line <= visible.max.y && line >= 0 && line < buffer->line_starts.len; line += 1) {
|
||||
Scratch scratch;
|
||||
Vec2I pos = {0, line * window->font->line_spacing};
|
||||
Vec2I pos = {0, line * window->font->line_spacing};
|
||||
pos.y -= view->scroll.y;
|
||||
pos += window->line_numbers_rect.min;
|
||||
String s = Format(scratch, "%lld", (long long)line + 1ll);
|
||||
@@ -270,6 +270,7 @@ void DrawWindow(Window *window, Event &event) {
|
||||
|
||||
// Draw scrollbar
|
||||
if (window->draw_scrollbar) {
|
||||
ProfileScope(DrawScrollbar);
|
||||
SetScissor(window->scrollbar_rect);
|
||||
DrawRect(window->scrollbar_rect, ColorScrollbarBackground);
|
||||
Scroller scroller = ComputeScrollerRect(window);
|
||||
@@ -281,12 +282,14 @@ void DrawWindow(Window *window, Event &event) {
|
||||
|
||||
// color the floating object to make it stand out
|
||||
if (window->z >= 1) {
|
||||
ProfileScope(ColorFloating);
|
||||
SetScissor(window->total_rect);
|
||||
DrawRect(window->total_rect, {255, 255, 255, 25});
|
||||
}
|
||||
|
||||
// darken the inactive windows
|
||||
if (!is_active) {
|
||||
ProfileScope(DarkenInactiveRect);
|
||||
SetScissor(screen_rect);
|
||||
DrawRect(window->total_rect, ColorInactiveWindow);
|
||||
}
|
||||
|
||||
@@ -81,7 +81,9 @@ Array<Variable> Variables;
|
||||
|
||||
Array<Process> ActiveProcesses = {};
|
||||
Array<String> ProcessEnviroment = {};
|
||||
Array<mco_coro *> ActiveCoroutines;
|
||||
|
||||
struct CoData { mco_coro *co; String name; };
|
||||
Array<CoData> ActiveCoroutines;
|
||||
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
@@ -364,7 +364,7 @@ SPALL_FN bool spall_buffer_name_process(SpallProfile *ctx, SpallBuffer *wb, cons
|
||||
|
||||
static SpallProfile spall_ctx;
|
||||
static SpallBuffer spall_buffer;
|
||||
double GetTimeMicros(void);
|
||||
uint64_t GetTimeNanos(void);
|
||||
|
||||
void BeginProfiler() {
|
||||
spall_init_file("te.spall", 1, &spall_ctx);
|
||||
@@ -386,14 +386,14 @@ void _BeginProfileScope(const char *name, int len) {
|
||||
spall_buffer_begin(&spall_ctx, &spall_buffer,
|
||||
name, // name of your name
|
||||
len, // name len minus the null terminator
|
||||
(uint64_t)GetTimeMicros() // timestamp in microseconds -- start of your timing block
|
||||
GetTimeNanos() // timestamp in microseconds -- start of your timing block
|
||||
);
|
||||
}
|
||||
#define BeginProfileScope(name) _BeginProfileScope(#name, sizeof(#name) - 1)
|
||||
|
||||
void EndProfileScope() {
|
||||
spall_buffer_end(&spall_ctx, &spall_buffer,
|
||||
(uint64_t)GetTimeMicros() // timestamp in microseconds -- end of your timing block
|
||||
GetTimeNanos() // timestamp in microseconds -- end of your timing block
|
||||
);
|
||||
}
|
||||
#define ProfileScopeEx(name) ProfileScopeClass PROFILE_SCOPE_VAR_((name).data, (int)(name).len)
|
||||
|
||||
Reference in New Issue
Block a user