From 45dbe09cff4b095fb366d98c191da7c687aa86ef Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Wed, 6 May 2020 01:38:01 +0200 Subject: [PATCH] minimize D GC from main thread directly in the widgets calling D in threads D memory allocated in the threads was never released --- dexed-d/src/common.d | 19 +++++++++++++++++++ dexed-d/src/todos.d | 4 ++-- src/u_dexed_d.pas | 7 +++++++ src/u_symlist.pas | 1 + src/u_todolist.pas | 1 + 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/dexed-d/src/common.d b/dexed-d/src/common.d index ea3c3278..37a8ffe5 100644 --- a/dexed-d/src/common.d +++ b/dexed-d/src/common.d @@ -9,6 +9,25 @@ import import iz.memory; + +extern(C) void setRtOptions() +{ + import core.gc.config : config; + config.gc = "precise"; +} + +extern(C) void minimizeGcHeap() +{ + import core.memory : GC; + __gshared ubyte c; + if (c++ > 96) + { + GC.collect(); + GC.minimize(); + c = 0; + } +} + enum ErrorType: ubyte { warning, diff --git a/dexed-d/src/todos.d b/dexed-d/src/todos.d index 1cfbb4fa..31cb7ea7 100644 --- a/dexed-d/src/todos.d +++ b/dexed-d/src/todos.d @@ -11,14 +11,14 @@ import extern(C) const(char)* todoItems(const(char)* joinedFiles) { scope Appender!string stream; + scope LexerConfig config = LexerConfig("", StringBehavior.source); + scope StringCache cache = StringCache(4096); stream.reserve(32); stream.put("object TTodoItems\ritems=<"); foreach (fname; joinedFilesToFiles(joinedFiles)) { stream.reserve(256); - scope LexerConfig config = LexerConfig("", StringBehavior.source); scope source = cast(ubyte[]) std.file.read(fname); - scope StringCache cache = StringCache(optimalBucketCount(source.length)); DLexer(source, config, &cache) .filter!(a => a.type == tok!"comment") .each!(t => analyze(t, fname, stream)); diff --git a/src/u_dexed_d.pas b/src/u_dexed_d.pas index 8b0798ff..0a7f69ee 100644 --- a/src/u_dexed_d.pas +++ b/src/u_dexed_d.pas @@ -49,6 +49,12 @@ const {$ENDIF} +// Used to release memroy allocated in external D functions that are called in a thread. +// because managing the GC only work from the main thread. +// memory is released every 96 calls. +procedure minimizeGcHeap(); cdecl; external libdexedd_name; +// Select the precise GC +procedure setRtOptions(); cdecl; external libdexedd_name; // Necessary to start the GC, run the static constructors, etc procedure rt_init(); cdecl; external libdexedd_name; // Cleanup @@ -125,6 +131,7 @@ begin end; initialization + setRtOptions(); rt_init(); finalization rt_term(); diff --git a/src/u_symlist.pas b/src/u_symlist.pas index f2619984..8e250550 100644 --- a/src/u_symlist.pas +++ b/src/u_symlist.pas @@ -874,6 +874,7 @@ begin tree.EndUpdate; if f.isNotEmpty then TreeFilterEdit1.Text := f; + minimizeGcHeap(); end; procedure TSymbolListWidget.smartExpand; diff --git a/src/u_todolist.pas b/src/u_todolist.pas index ea356dbb..f8eb2c39 100644 --- a/src/u_todolist.pas +++ b/src/u_todolist.pas @@ -489,6 +489,7 @@ begin fillTodoList; finally txt.free; + minimizeGcHeap(); end; end;