CoroutineLeakCheck
This commit is contained in:
@@ -47,6 +47,7 @@ struct BlockArena {
|
|||||||
U8 *end;
|
U8 *end;
|
||||||
BlockArenaNode *blocks;
|
BlockArenaNode *blocks;
|
||||||
Allocator allocator;
|
Allocator allocator;
|
||||||
|
int refs; // :CoroutineLeakCheck
|
||||||
|
|
||||||
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
operator Allocator() { return {BlockArenaAllocatorProc, this}; }
|
||||||
};
|
};
|
||||||
@@ -66,6 +67,7 @@ struct VirtualArena {
|
|||||||
size_t reserve;
|
size_t reserve;
|
||||||
size_t commit;
|
size_t commit;
|
||||||
size_t align;
|
size_t align;
|
||||||
|
int refs; // :CoroutineLeakCheck
|
||||||
|
|
||||||
operator Allocator() {
|
operator Allocator() {
|
||||||
void *ArenaAllocatorProc(void *object, int kind, void *p, size_t size);
|
void *ArenaAllocatorProc(void *object, int kind, void *p, size_t size);
|
||||||
@@ -112,28 +114,32 @@ API VirtualArena *GetScratchEx(VirtualArena **conflicts, int conflict_count);
|
|||||||
struct Scratch {
|
struct Scratch {
|
||||||
VirtualArena *arena;
|
VirtualArena *arena;
|
||||||
U64 p;
|
U64 p;
|
||||||
Scratch() {arena = &ScratchArenas[0]; p = arena->len;}
|
Scratch() {arena = &ScratchArenas[0]; p = arena->len; arena->refs += 1;}
|
||||||
Scratch(VirtualArena *conflict) {
|
Scratch(VirtualArena *conflict) {
|
||||||
VirtualArena *conf[] = {conflict};
|
VirtualArena *conf[] = {conflict};
|
||||||
arena = GetScratchEx(conf, Lengthof(conf));
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
p = arena->len;
|
p = arena->len;
|
||||||
|
arena->refs += 1;
|
||||||
}
|
}
|
||||||
Scratch(VirtualArena *c1, VirtualArena *c2) {
|
Scratch(VirtualArena *c1, VirtualArena *c2) {
|
||||||
VirtualArena *conf[] = {c1, c2};
|
VirtualArena *conf[] = {c1, c2};
|
||||||
arena = GetScratchEx(conf, Lengthof(conf));
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
p = arena->len;
|
p = arena->len;
|
||||||
|
arena->refs += 1;
|
||||||
}
|
}
|
||||||
Scratch(Allocator conflict) {
|
Scratch(Allocator conflict) {
|
||||||
VirtualArena *conf[] = {(VirtualArena *)conflict.object};
|
VirtualArena *conf[] = {(VirtualArena *)conflict.object};
|
||||||
arena = GetScratchEx(conf, Lengthof(conf));
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
p = arena->len;
|
p = arena->len;
|
||||||
|
arena->refs += 1;
|
||||||
}
|
}
|
||||||
Scratch(Allocator c1, Allocator c2) {
|
Scratch(Allocator c1, Allocator c2) {
|
||||||
VirtualArena *conf[] = {(VirtualArena *)c1.object, (VirtualArena *)c2.object};
|
VirtualArena *conf[] = {(VirtualArena *)c1.object, (VirtualArena *)c2.object};
|
||||||
arena = GetScratchEx(conf, Lengthof(conf));
|
arena = GetScratchEx(conf, Lengthof(conf));
|
||||||
p = arena->len;
|
p = arena->len;
|
||||||
|
arena->refs += 1;
|
||||||
}
|
}
|
||||||
~Scratch() { SetLen(arena, p); }
|
~Scratch() { SetLen(arena, p); arena->refs -= 1; }
|
||||||
operator VirtualArena *() { return arena; }
|
operator VirtualArena *() { return arena; }
|
||||||
operator Allocator() { return *arena; }
|
operator Allocator() { return *arena; }
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,16 @@ void CoUpdate(Event *event) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG_BUILD
|
||||||
|
//:CoroutineLeakCheck
|
||||||
|
// Make sure we don't leak scratch arenas between coroutine boundaries.
|
||||||
|
// it leads to memory corruption! If you hit Assert here make sure you
|
||||||
|
// don't leak the scratch arena.
|
||||||
|
for (int i = 0; i < Lengthof(ScratchArenas); i += 1) {
|
||||||
|
Assert(ScratchArenas[i].refs == 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
double took = GetTimeSeconds() - start;
|
double took = GetTimeSeconds() - start;
|
||||||
if (took > (0.016666 / 3.0)) {
|
if (took > (0.016666 / 3.0)) {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -472,35 +472,32 @@ inline void AddEvent(Array<Event> *events, Event ev) {
|
|||||||
Add(events, ev);
|
Add(events, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
Array<Event> GetEventsForFrame(Allocator allocator) {
|
void GetEventsForFrame(Array<Event> *events) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
Array<Event> result = {allocator};
|
For (EventPlayback) {
|
||||||
if (EventPlayback.len) {
|
Add(events, it);
|
||||||
result = TightCopy(allocator, EventPlayback);
|
|
||||||
EventPlayback.len = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_Event event;
|
SDL_Event event;
|
||||||
if (WaitForEventsState) {
|
if (WaitForEventsState) {
|
||||||
SDL_WaitEvent(&event);
|
SDL_WaitEvent(&event);
|
||||||
Event ev = TranslateSDLEvent(&event);
|
Event ev = TranslateSDLEvent(&event);
|
||||||
AddEvent(&result, ev);
|
AddEvent(events, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
while (SDL_PollEvent(&event)) {
|
while (SDL_PollEvent(&event)) {
|
||||||
Event ev = TranslateSDLEvent(&event);
|
Event ev = TranslateSDLEvent(&event);
|
||||||
AddEvent(&result, ev);
|
AddEvent(events, ev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result.len == 0) {
|
if (events->len == 0) {
|
||||||
Event event = {};
|
Event event = {};
|
||||||
FillEventWithBasicData(&event);
|
FillEventWithBasicData(&event);
|
||||||
event.kind = EVENT_UPDATE;
|
event.kind = EVENT_UPDATE;
|
||||||
Add(&result, event);
|
Add(events, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert(result.len);
|
Assert(events->len);
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -67,4 +67,18 @@ void CMD_SetProjectHere() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} RegisterCommand(CMD_SetProjectHere, "", "Sets the project directory, opens the project file etc.");
|
} RegisterCommand(CMD_SetProjectHere, "", "Sets the project directory, opens the project file etc.");
|
||||||
|
|
||||||
|
void CO_CreateProject(mco_coro *co) {
|
||||||
|
String16 project_name16 = QueryUserString(co, "Please tell me, how would you like to name your project?");
|
||||||
|
String directory = GetPrimaryDirectory();
|
||||||
|
{
|
||||||
|
Scratch scratch;
|
||||||
|
String project_name = ToString(scratch, project_name16);
|
||||||
|
String name = Format(scratch, "%S/%S", directory, project_name);
|
||||||
|
MakeDir(name);
|
||||||
|
Open(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} RegisterCoroutineCommand(CO_CreateProject, "", "Creates a project in current buffer directory with template files and all that, asks user for input etc.");
|
||||||
@@ -626,15 +626,17 @@ void Update(Event event) {
|
|||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
LayoutWindows(event.xwindow, event.ywindow);
|
LayoutWindows(event.xwindow, event.ywindow);
|
||||||
|
|
||||||
Scratch scratch;
|
{
|
||||||
Array<Window *> order = GetWindowZOrder(scratch);
|
Scratch scratch;
|
||||||
For(order) {
|
Array<Window *> order = GetWindowZOrder(scratch);
|
||||||
if (!it->visible) {
|
For(order) {
|
||||||
continue;
|
if (!it->visible) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
View *view = GetView(it->active_view);
|
||||||
|
view->main_caret_on_begin_frame = view->carets[0];
|
||||||
|
view->update_scroll = true;
|
||||||
}
|
}
|
||||||
View *view = GetView(it->active_view);
|
|
||||||
view->main_caret_on_begin_frame = view->carets[0];
|
|
||||||
view->update_scroll = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
For (Windows) {
|
For (Windows) {
|
||||||
@@ -670,7 +672,7 @@ void Update(Event event) {
|
|||||||
CoUpdate(&event);
|
CoUpdate(&event);
|
||||||
|
|
||||||
|
|
||||||
For(IterateInReverse(&order)) {
|
For (Windows) {
|
||||||
if (!it->visible) continue;
|
if (!it->visible) continue;
|
||||||
View *view = GetView(it->active_view);
|
View *view = GetView(it->active_view);
|
||||||
UpdateScroll(it, !AreEqual(view->main_caret_on_begin_frame, view->carets[0]) && view->update_scroll);
|
UpdateScroll(it, !AreEqual(view->main_caret_on_begin_frame, view->carets[0]) && view->update_scroll);
|
||||||
@@ -783,13 +785,13 @@ void Update(Event event) {
|
|||||||
GarbageCollect();
|
GarbageCollect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Array<Event> FrameEvents;
|
||||||
void MainLoop() {
|
void MainLoop() {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
Scratch scratch;
|
|
||||||
FrameID += 1;
|
FrameID += 1;
|
||||||
Array<Event> frame_events = GetEventsForFrame(scratch);
|
FrameEvents.len = 0;
|
||||||
For(frame_events) {
|
GetEventsForFrame(&FrameEvents);
|
||||||
|
For (FrameEvents) {
|
||||||
#if PLUGIN_RECORD_EVENTS
|
#if PLUGIN_RECORD_EVENTS
|
||||||
if (it.kind != EVENT_UPDATE && !Testing) {
|
if (it.kind != EVENT_UPDATE && !Testing) {
|
||||||
Serialize(EventBuffer, &it);
|
Serialize(EventBuffer, &it);
|
||||||
@@ -823,6 +825,7 @@ void MainLoop() {
|
|||||||
// This shouldn't matter to the state of the program, only appearance for
|
// This shouldn't matter to the state of the program, only appearance for
|
||||||
// the user
|
// the user
|
||||||
{
|
{
|
||||||
|
Scratch scratch;
|
||||||
ProfileScope(SetWindowTitle);
|
ProfileScope(SetWindowTitle);
|
||||||
Window *window = GetActiveWind();
|
Window *window = GetActiveWind();
|
||||||
View *view = GetView(window->active_view);
|
View *view = GetView(window->active_view);
|
||||||
@@ -832,15 +835,18 @@ void MainLoop() {
|
|||||||
SDL_SetWindowTitle(SDLWindow, string.data);
|
SDL_SetWindowTitle(SDLWindow, string.data);
|
||||||
}
|
}
|
||||||
|
|
||||||
Event *event = GetLast(frame_events);
|
Event *event = GetLast(FrameEvents);
|
||||||
SetMouseCursor(*event);
|
SetMouseCursor(*event);
|
||||||
LayoutWindows(event->xwindow, event->ywindow); // This is here to render changes in title bar size without a frame of delay
|
LayoutWindows(event->xwindow, event->ywindow); // This is here to render changes in title bar size without a frame of delay
|
||||||
BeginFrameRender(event->xwindow, event->ywindow);
|
BeginFrameRender(event->xwindow, event->ywindow);
|
||||||
|
|
||||||
Array<Window *> order = GetWindowZOrder(scratch);
|
{
|
||||||
For(IterateInReverse(&order)) {
|
Scratch scratch;
|
||||||
if (!it->visible) continue;
|
Array<Window *> order = GetWindowZOrder(scratch);
|
||||||
DrawWindow(it, *GetLast(frame_events));
|
For(IterateInReverse(&order)) {
|
||||||
|
if (!it->visible) continue;
|
||||||
|
DrawWindow(it, *GetLast(FrameEvents));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EndFrameRender(event->xwindow, event->ywindow, BackgroundColor);
|
EndFrameRender(event->xwindow, event->ywindow, BackgroundColor);
|
||||||
SDL_GL_SwapWindow(SDLWindow);
|
SDL_GL_SwapWindow(SDLWindow);
|
||||||
|
|||||||
Reference in New Issue
Block a user