diff options
author | Ruslan Mustakov <ruslan.mustakov@xored.com> | 2016-05-10 21:51:42 +0600 |
---|---|---|
committer | Ruslan Mustakov <ruslan.mustakov@xored.com> | 2016-05-10 21:52:44 +0600 |
commit | f288eb7543d99651eee58ad9a961c78a737aa0c2 (patch) | |
tree | 1949df67419c1b78f428a4f5604bd958705df9b7 | |
parent | d2cfd71627f38419f0eba31708ca5ec97b8267c6 (diff) | |
download | Nim-f288eb7543d99651eee58ad9a961c78a737aa0c2.tar.gz |
Added ignoreStackAndRegisters parameter to GC_step
-rw-r--r-- | doc/gc.txt | 8 | ||||
-rw-r--r-- | lib/system/gc.nim | 26 | ||||
-rw-r--r-- | lib/system/gc2.nim | 24 |
3 files changed, 33 insertions, 25 deletions
diff --git a/doc/gc.txt b/doc/gc.txt index 4ada88d2f..de010099f 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, ignoreStackAndRegisters = false) The unit of the parameters ``MaxPauseInUs`` and ``us`` is microseconds. @@ -75,7 +75,11 @@ 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. Notice that you may ask GC to not + scan stack and registers for references via ``ignoreStackAndRegisters`` + parameter. This may reduce the step time depending on the stack depth, + but use it only when you are sure that neither the stack nor the registers + contain unique references to objects that must be preserved. 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..85bdf04fe 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -905,19 +905,19 @@ proc unmarkStackAndRegisters(gch: var GcHeap) = #sysAssert c.typ != nil, "unmarkStackAndRegisters 2" gch.decStack.len = 0 -proc collectCTBody(gch: var GcHeap) = +proc collectCTBody(gch: var GcHeap, ignoreStackAndRegisters = false) = when withRealTime: let t0 = getticks() sysAssert(allocInv(gch.region), "collectCT: begin") - - when not defined(nimCoroutines): - gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize()) sysAssert(gch.decStack.len == 0, "collectCT") prepareForInteriorPointerChecking(gch.region) - markStackAndRegisters(gch) - markThreadStacks(gch) - gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len) - inc(gch.stat.stackScans) + if not ignoreStackAndRegisters: + when not defined(nimCoroutines): + gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize()) + markStackAndRegisters(gch) + markThreadStacks(gch) + gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len) + inc(gch.stat.stackScans) if collectZCT(gch): when cycleGC: if getOccupiedMem(gch.region) >= gch.cycleThreshold or alwaysCycleGC: @@ -927,7 +927,8 @@ proc collectCTBody(gch: var GcHeap) = gch.cycleThreshold = max(InitialCycleThreshold, getOccupiedMem() * CycleIncrease) gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold) - unmarkStackAndRegisters(gch) + if not ignoreStackAndRegisters: + unmarkStackAndRegisters(gch) sysAssert(allocInv(gch.region), "collectCT: end") when withRealTime: @@ -971,16 +972,17 @@ when withRealTime: proc GC_setMaxPause*(MaxPauseInUs: int) = gch.maxPause = MaxPauseInUs.toNano - proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool) = + proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool, ignoreStackAndRegisters: bool) = acquire(gch) gch.maxPause = us.toNano if (gch.zct.len >= ZctThreshold or (cycleGC and getOccupiedMem(gch.region)>=gch.cycleThreshold) or alwaysGC) or strongAdvice: - collectCTBody(gch) + collectCTBody(gch, ignoreStackAndRegisters) release(gch) - proc GC_step*(us: int, strongAdvice = false) = GC_step(gch, us, strongAdvice) + proc GC_step*(us: int, strongAdvice, ignoreStackAndRegisters = false) = + GC_step(gch, us, strongAdvice, ignoreStackAndRegisters) when not defined(useNimRtl): proc GC_disable() = diff --git a/lib/system/gc2.nim b/lib/system/gc2.nim index 6c44d509e..f2d1397b4 100644 --- a/lib/system/gc2.nim +++ b/lib/system/gc2.nim @@ -894,18 +894,18 @@ proc unmarkStackAndRegisters(gch: var GcHeap) = decRef(d[i]) gch.decStack.len = 0 -proc collectCTBody(gch: var GcHeap) = +proc collectCTBody(gch: var GcHeap, ignoreStackAndRegisters = false) = when withRealTime: let t0 = getticks() sysAssert(allocInv(gch.region), "collectCT: begin") - - when not defined(nimCoroutines): - gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize()) sysAssert(gch.decStack.len == 0, "collectCT") prepareForInteriorPointerChecking(gch.region) - markStackAndRegisters(gch) - gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len) - inc(gch.stat.stackScans) + if not ignoreStackAndRegisters: + when not defined(nimCoroutines): + gch.stat.maxStackSize = max(gch.stat.maxStackSize, stackSize()) + markStackAndRegisters(gch) + gch.stat.maxStackCells = max(gch.stat.maxStackCells, gch.decStack.len) + inc(gch.stat.stackScans) if collectZCT(gch): when cycleGC: if getOccupiedMem(gch.region) >= gch.cycleThreshold or alwaysCycleGC: @@ -914,7 +914,8 @@ proc collectCTBody(gch: var GcHeap) = gch.cycleThreshold = max(InitialCycleThreshold, getOccupiedMem() * CycleIncrease) gch.stat.maxThreshold = max(gch.stat.maxThreshold, gch.cycleThreshold) - unmarkStackAndRegisters(gch) + if not ignoreStackAndRegisters: + unmarkStackAndRegisters(gch) sysAssert(allocInv(gch.region), "collectCT: end") when withRealTime: @@ -949,14 +950,15 @@ when withRealTime: proc GC_setMaxPause*(MaxPauseInUs: int) = gch.maxPause = MaxPauseInUs.toNano - proc GC_step(gch: var GcHeap, us: int, strongAdvice: bool) = + proc GC_step(gch: var GcHeap, us: int, strongAdvice, ignoreStackAndRegisters: bool) = gch.maxPause = us.toNano if (gch.zct.len >= ZctThreshold or (cycleGC and getOccupiedMem(gch.region)>=gch.cycleThreshold) or alwaysGC) or strongAdvice: - collectCTBody(gch) + collectCTBody(gch, ignoreStackAndRegisters) - proc GC_step*(us: int, strongAdvice = false) = GC_step(gch, us, strongAdvice) + proc GC_step*(us: int, strongAdvice, ignoreStackAndRegisters = false) = + GC_step(gch, us, strongAdvice, ignoreStackAndRegisters) when not defined(useNimRtl): proc GC_disable() = |