diff options
-rw-r--r-- | doc/gc.txt | 10 | ||||
-rw-r--r-- | lib/system/gc.nim | 14 | ||||
-rw-r--r-- | lib/system/gc2.nim | 14 |
3 files changed, 34 insertions, 4 deletions
diff --git a/doc/gc.txt b/doc/gc.txt index 4ada88d2f..1c8cb9122 100644 --- a/doc/gc.txt +++ b/doc/gc.txt @@ -56,7 +56,7 @@ file as well). With this switch the GC supports the following operations: .. code-block:: nim proc GC_setMaxPause*(MaxPauseInUs: int) - proc GC_step*(us: int, strongAdvice = false) + proc GC_step*(us: int, strongAdvice = false, stackSize = -1) The unit of the parameters ``MaxPauseInUs`` and ``us`` is microseconds. @@ -75,7 +75,13 @@ These two procs are the two modus operandi of the realtime GC: This allows the GC to perform some work for up to ``us`` time. This is useful to call in a main loop to ensure the GC can do its work. To bind all GC activity to a ``GC_step`` call, deactivate the GC with - ``GC_disable`` at program startup. + ``GC_disable`` at program startup. If ``strongAdvice`` is set to ``true``, + GC will be forced to perform collection cycle. Otherwise, GC may decide not + to do anything, if there is not much garbage to collect. + You may also specify the current stack size via ``stackSize`` parameter. + It can improve performance, when you know that there are no unique Nim + references below certain point on the stack. Make sure the size you specify + is greater than the potential worst case size. These procs provide a "best effort" realtime guarantee; in particular the cycle collector is not aware of deadlines yet. Deactivate it to get more diff --git a/lib/system/gc.nim b/lib/system/gc.nim index 4f461b5c3..5c2170a17 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -980,7 +980,19 @@ when withRealTime: collectCTBody(gch) release(gch) - proc GC_step*(us: int, strongAdvice = false) = GC_step(gch, us, strongAdvice) + proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} = + var stackTop {.volatile.}: pointer + let prevStackBottom = gch.stackBottom + if stackSize >= 0: + stackTop = addr(stackTop) + when stackIncreases: + gch.stackBottom = cast[pointer]( + cast[ByteAddress](stackTop) - sizeof(pointer) * 6 - stackSize) + else: + gch.stackBottom = cast[pointer]( + cast[ByteAddress](stackTop) + sizeof(pointer) * 6 + stackSize) + GC_step(gch, us, strongAdvice) + gch.stackBottom = prevStackBottom when not defined(useNimRtl): proc GC_disable() = diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 6c44d509e..7d54c07be 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -956,7 +956,19 @@ when withRealTime: strongAdvice: collectCTBody(gch) - proc GC_step*(us: int, strongAdvice = false) = GC_step(gch, us, strongAdvice) + proc GC_step*(us: int, strongAdvice = false, stackSize = -1) {.noinline.} = + var stackTop {.volatile.}: pointer + let prevStackBottom = gch.stackBottom + if stackSize >= 0: + stackTop = addr(stackTop) + when stackIncreases: + gch.stackBottom = cast[pointer]( + cast[ByteAddress](stackTop) - sizeof(pointer) * 6 - stackSize) + else: + gch.stackBottom = cast[pointer]( + cast[ByteAddress](stackTop) + sizeof(pointer) * 6 + stackSize) + GC_step(gch, us, strongAdvice) + gch.stackBottom = prevStackBottom when not defined(useNimRtl): proc GC_disable() = |