diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2016-01-25 03:14:22 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2016-03-28 02:15:08 +0200 |
commit | c11487b339018f01e72ff17fc919f2e3974de658 (patch) | |
tree | 7bbb82180da26dd9174b79c07899d345f8b3f9e0 /lib/system | |
parent | 3a95a0bba4e9251f8ce4ff08678af368345e9218 (diff) | |
download | Nim-c11487b339018f01e72ff17fc919f2e3974de658.tar.gz |
GCs support ForeignCells
Diffstat (limited to 'lib/system')
-rw-r--r-- | lib/system/gc.nim | 11 | ||||
-rw-r--r-- | lib/system/gc_common.nim | 25 | ||||
-rw-r--r-- | lib/system/gc_ms.nim | 7 | ||||
-rw-r--r-- | lib/system/syslocks.nim | 4 |
4 files changed, 47 insertions, 0 deletions
diff --git a/lib/system/gc.nim b/lib/system/gc.nim index d8390ca14..4f461b5c3 100644 --- a/lib/system/gc.nim +++ b/lib/system/gc.nim @@ -39,6 +39,9 @@ when withRealTime and not declared(getTicks): when defined(memProfiler): proc nimProfile(requestedSize: int) {.benign.} +when hasThreadSupport: + import sharedlist + const rcIncrement = 0b1000 # so that lowest 3 bits are not touched rcBlack = 0b000 # cell is colored black; in use or free @@ -93,6 +96,9 @@ type stat: GcStat when useMarkForDebug or useBackupGc: marked: CellSet + when hasThreadSupport: + toDispose: SharedList[pointer] + {.deprecated: [TWalkOp: WalkOp, TFinalizer: Finalizer, TGcHeap: GcHeap, TGcStat: GcStat].} var @@ -304,6 +310,8 @@ proc initGC() = init(gch.decStack) when useMarkForDebug or useBackupGc: init(gch.marked) + when hasThreadSupport: + gch.toDispose = initSharedList[pointer]() when useMarkForDebug or useBackupGc: type @@ -749,6 +757,9 @@ proc collectRoots(gch: var GcHeap) = collectWhite(s) proc collectCycles(gch: var GcHeap) = + when hasThreadSupport: + for c in gch.toDispose: + nimGCunref(c) # ensure the ZCT 'color' is not used: while gch.zct.len > 0: discard collectZCT(gch) when useBackupGc: diff --git a/lib/system/gc_common.nim b/lib/system/gc_common.nim index a4676d26e..4807bb6f8 100644 --- a/lib/system/gc_common.nim +++ b/lib/system/gc_common.nim @@ -7,6 +7,31 @@ # distribution, for details about the copyright. # +type + ForeignCell* = object + data*: pointer + owner: ptr GcHeap + +proc protect*(x: pointer): ForeignCell = + nimGCref(x) + result.data = x + result.owner = addr(gch) + +proc dispose*(x: ForeignCell) = + when hasThreadSupport: + # if we own it we can free it directly: + if x.owner == addr(gch): + nimGCunref(x.data) + else: + x.owner.toDispose.add(x.data) + else: + nimGCunref(x.data) + +proc isNotForeign*(x: ForeignCell): bool = + ## returns true if 'x' belongs to the calling thread. + ## No deep copy has to be performed then. + x.owner == addr(gch) + proc len(stack: ptr GcStack): int = if stack == nil: return 0 diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index d1aecb7a2..c764571b1 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -68,6 +68,8 @@ type recGcLock: int # prevent recursion via finalizers; no thread lock region: MemRegion # garbage collected region stat: GcStat + when hasThreadSupport: + toDispose: SharedList[pointer] additionalRoots: CellSeq # dummy roots for GC_ref/unref {.deprecated: [TWalkOp: WalkOp, TFinalizer: Finalizer, TGcStat: GcStat, TGlobalMarkerProc: GlobalMarkerProc, TGcHeap: GcHeap].} @@ -179,6 +181,8 @@ proc initGC() = when withBitvectors: init(gch.allocated) init(gch.marked) + when hasThreadSupport: + gch.toDispose = initSharedList[pointer]() proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: WalkOp) {.benign.} = var d = cast[ByteAddress](dest) @@ -321,6 +325,9 @@ proc growObj(old: pointer, newsize: int): pointer {.rtl.} = # ----------------- collector ----------------------------------------------- proc mark(gch: var GcHeap, c: PCell) = + when hasThreadSupport: + for c in gch.toDispose: + nimGCunref(c) when withBitvectors: incl(gch.marked, c) gcAssert gch.tempStack.len == 0, "stack not empty!" diff --git a/lib/system/syslocks.nim b/lib/system/syslocks.nim index 1551a4121..6dcdfff0d 100644 --- a/lib/system/syslocks.nim +++ b/lib/system/syslocks.nim @@ -9,6 +9,8 @@ # Low level system locks and condition vars. +{.push stackTrace: off.} + when defined(Windows): type Handle = int @@ -118,3 +120,5 @@ else: proc deinitSysCond(cond: var SysCond) {.noSideEffect, importc: "pthread_cond_destroy", header: "<pthread.h>".} + +{.pop.} |