mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-22 23:35:22 +00:00
case consistency part 1
This commit is contained in:
@@ -59,15 +59,16 @@ elif defined(windows):
|
||||
MEM_DECOMMIT = 0x4000
|
||||
MEM_RELEASE = 0x8000
|
||||
|
||||
proc VirtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType,
|
||||
proc virtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType,
|
||||
flProtect: int32): pointer {.
|
||||
header: "<windows.h>", stdcall.}
|
||||
header: "<windows.h>", stdcall, importc: "VirtualAlloc".}
|
||||
|
||||
proc VirtualFree(lpAddress: pointer, dwSize: int,
|
||||
dwFreeType: int32) {.header: "<windows.h>", stdcall.}
|
||||
proc virtualFree(lpAddress: pointer, dwSize: int,
|
||||
dwFreeType: int32) {.header: "<windows.h>", stdcall,
|
||||
importc: "VirtualFree".}
|
||||
|
||||
proc osAllocPages(size: int): pointer {.inline.} =
|
||||
result = VirtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT,
|
||||
result = virtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT,
|
||||
PAGE_READWRITE)
|
||||
if result == nil: raiseOutOfMem()
|
||||
|
||||
@@ -78,7 +79,7 @@ elif defined(windows):
|
||||
# Windows :-(. We have to live with MEM_DECOMMIT instead.
|
||||
# Well that used to be the case but MEM_DECOMMIT fragments the address
|
||||
# space heavily, so we now treat Windows as a strange unmap target.
|
||||
when reallyOsDealloc: VirtualFree(p, 0, MEM_RELEASE)
|
||||
when reallyOsDealloc: virtualFree(p, 0, MEM_RELEASE)
|
||||
#VirtualFree(p, size, MEM_DECOMMIT)
|
||||
|
||||
else:
|
||||
@@ -251,14 +252,14 @@ proc llDeallocAll(a: var TMemRegion) =
|
||||
osDeallocPages(it, PageSize)
|
||||
it = next
|
||||
|
||||
proc IntSetGet(t: TIntSet, key: int): PTrunk =
|
||||
proc intSetGet(t: TIntSet, key: int): PTrunk =
|
||||
var it = t.data[key and high(t.data)]
|
||||
while it != nil:
|
||||
if it.key == key: return it
|
||||
it = it.next
|
||||
result = nil
|
||||
|
||||
proc IntSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk =
|
||||
proc intSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk =
|
||||
result = IntSetGet(t, key)
|
||||
if result == nil:
|
||||
result = cast[PTrunk](llAlloc(a, sizeof(result[])))
|
||||
@@ -266,7 +267,7 @@ proc IntSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk =
|
||||
t.data[key and high(t.data)] = result
|
||||
result.key = key
|
||||
|
||||
proc Contains(s: TIntSet, key: int): bool =
|
||||
proc contains(s: TIntSet, key: int): bool =
|
||||
var t = IntSetGet(s, key shr TrunkShift)
|
||||
if t != nil:
|
||||
var u = key and TrunkMask
|
||||
@@ -274,12 +275,12 @@ proc Contains(s: TIntSet, key: int): bool =
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc Incl(a: var TMemRegion, s: var TIntSet, key: int) =
|
||||
proc incl(a: var TMemRegion, s: var TIntSet, key: int) =
|
||||
var t = IntSetPut(a, s, key shr TrunkShift)
|
||||
var u = key and TrunkMask
|
||||
t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask))
|
||||
|
||||
proc Excl(s: var TIntSet, key: int) =
|
||||
proc excl(s: var TIntSet, key: int) =
|
||||
var t = IntSetGet(s, key shr TrunkShift)
|
||||
if t != nil:
|
||||
var u = key and TrunkMask
|
||||
@@ -387,7 +388,7 @@ proc freeOsChunks(a: var TMemRegion, p: pointer, size: int) =
|
||||
#c_fprintf(c_stdout, "[Alloc] back to OS: %ld\n", size)
|
||||
|
||||
proc isAccessible(a: TMemRegion, p: pointer): bool {.inline.} =
|
||||
result = Contains(a.chunkStarts, pageIndex(p))
|
||||
result = contains(a.chunkStarts, pageIndex(p))
|
||||
|
||||
proc contains[T](list, x: T): bool =
|
||||
var it = list
|
||||
@@ -403,7 +404,7 @@ proc writeFreeList(a: TMemRegion) =
|
||||
it, it.next, it.prev)
|
||||
it = it.next
|
||||
|
||||
proc ListAdd[T](head: var T, c: T) {.inline.} =
|
||||
proc listAdd[T](head: var T, c: T) {.inline.} =
|
||||
sysAssert(c notin head, "listAdd 1")
|
||||
sysAssert c.prev == nil, "listAdd 2"
|
||||
sysAssert c.next == nil, "listAdd 3"
|
||||
@@ -413,7 +414,7 @@ proc ListAdd[T](head: var T, c: T) {.inline.} =
|
||||
head.prev = c
|
||||
head = c
|
||||
|
||||
proc ListRemove[T](head: var T, c: T) {.inline.} =
|
||||
proc listRemove[T](head: var T, c: T) {.inline.} =
|
||||
sysAssert(c in head, "listRemove")
|
||||
if c == head:
|
||||
head = c.next
|
||||
@@ -759,7 +760,7 @@ proc getOccupiedMem(a: TMemRegion): int {.inline.} =
|
||||
|
||||
# ---------------------- thread memory region -------------------------------
|
||||
|
||||
template InstantiateForRegion(allocator: expr) =
|
||||
template instantiateForRegion(allocator: expr) =
|
||||
when defined(fulldebug):
|
||||
proc interiorAllocatedPtr*(p: pointer): pointer =
|
||||
result = interiorAllocatedPtr(allocator, p)
|
||||
@@ -801,13 +802,13 @@ template InstantiateForRegion(allocator: expr) =
|
||||
when hasThreadSupport:
|
||||
var sharedHeap: TMemRegion
|
||||
var heapLock: TSysLock
|
||||
InitSysLock(HeapLock)
|
||||
initSysLock(HeapLock)
|
||||
|
||||
proc allocShared(size: int): pointer =
|
||||
when hasThreadSupport:
|
||||
AcquireSys(HeapLock)
|
||||
acquireSys(HeapLock)
|
||||
result = alloc(sharedHeap, size)
|
||||
ReleaseSys(HeapLock)
|
||||
releaseSys(HeapLock)
|
||||
else:
|
||||
result = alloc(size)
|
||||
|
||||
@@ -817,17 +818,17 @@ template InstantiateForRegion(allocator: expr) =
|
||||
|
||||
proc deallocShared(p: pointer) =
|
||||
when hasThreadSupport:
|
||||
AcquireSys(HeapLock)
|
||||
acquireSys(HeapLock)
|
||||
dealloc(sharedHeap, p)
|
||||
ReleaseSys(HeapLock)
|
||||
releaseSys(HeapLock)
|
||||
else:
|
||||
dealloc(p)
|
||||
|
||||
proc reallocShared(p: pointer, newsize: int): pointer =
|
||||
when hasThreadSupport:
|
||||
AcquireSys(HeapLock)
|
||||
acquireSys(HeapLock)
|
||||
result = realloc(sharedHeap, p, newsize)
|
||||
ReleaseSys(HeapLock)
|
||||
releaseSys(HeapLock)
|
||||
else:
|
||||
result = realloc(p, newsize)
|
||||
|
||||
|
||||
@@ -168,12 +168,12 @@ proc objectInit(dest: Pointer, typ: PNimType) =
|
||||
of tyArray, tyArrayConstr:
|
||||
for i in 0..(typ.size div typ.base.size)-1:
|
||||
objectInit(cast[pointer](d +% i * typ.base.size), typ.base)
|
||||
else: nil # nothing to do
|
||||
else: discard # nothing to do
|
||||
|
||||
# ---------------------- assign zero -----------------------------------------
|
||||
|
||||
when not defined(nimmixin):
|
||||
proc destroy(x: int) = nil
|
||||
proc destroy(x: int) = discard
|
||||
proc nimDestroyRange*[T](r: T) =
|
||||
# internal proc used for destroying sequences and arrays
|
||||
for i in countup(0, r.len - 1): destroy(r[i])
|
||||
|
||||
@@ -7,62 +7,60 @@
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
# Atomic operations for Nimrod.
|
||||
## Atomic operations for Nimrod.
|
||||
|
||||
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
|
||||
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
type
|
||||
AtomMemModel* = enum
|
||||
ATOMIC_RELAXED,
|
||||
## No barriers or synchronization.
|
||||
ATOMIC_CONSUME,
|
||||
## Data dependency only for both barrier and synchronization with another thread.
|
||||
ATOMIC_ACQUIRE,
|
||||
## Barrier to hoisting of code and synchronizes with release (or stronger)
|
||||
## semantic stores from another thread.
|
||||
ATOMIC_RELEASE,
|
||||
## Barrier to sinking of code and synchronizes with acquire (or stronger)
|
||||
## semantic loads from another thread.
|
||||
ATOMIC_ACQ_REL,
|
||||
## Full barrier in both directions and synchronizes with acquire loads
|
||||
## and release stores in another thread.
|
||||
ATOMIC_SEQ_CST
|
||||
## Full barrier in both directions and synchronizes with acquire loads
|
||||
## and release stores in all threads.
|
||||
ATOMIC_RELAXED, ## No barriers or synchronization.
|
||||
ATOMIC_CONSUME, ## Data dependency only for both barrier and
|
||||
## synchronization with another thread.
|
||||
ATOMIC_ACQUIRE, ## Barrier to hoisting of code and synchronizes with
|
||||
## release (or stronger)
|
||||
## semantic stores from another thread.
|
||||
ATOMIC_RELEASE, ## Barrier to sinking of code and synchronizes with
|
||||
## acquire (or stronger)
|
||||
## semantic loads from another thread.
|
||||
ATOMIC_ACQ_REL, ## Full barrier in both directions and synchronizes
|
||||
## with acquire loads
|
||||
## and release stores in another thread.
|
||||
ATOMIC_SEQ_CST ## Full barrier in both directions and synchronizes
|
||||
## with acquire loads
|
||||
## and release stores in all threads.
|
||||
|
||||
TAtomType* = TNumber|pointer|ptr|char
|
||||
## Type Class representing valid types for use with atomic procs
|
||||
## Type Class representing valid types for use with atomic procs
|
||||
|
||||
proc atomic_load_n*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {.
|
||||
proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_load_n", nodecl.}
|
||||
## This proc implements an atomic load operation. It returns the contents at p.
|
||||
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_CONSUME.
|
||||
|
||||
proc atomic_load*[T: TAtomType](p: ptr T, ret: ptr T, mem: AtomMemModel) {.
|
||||
proc atomicLoad*[T: TAtomType](p: ptr T, ret: ptr T, mem: AtomMemModel) {.
|
||||
importc: "__atomic_load", nodecl.}
|
||||
## This is the generic version of an atomic load. It returns the contents at p in ret.
|
||||
|
||||
proc atomic_store_n*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel) {.
|
||||
proc atomicStoreN*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel) {.
|
||||
importc: "__atomic_store_n", nodecl.}
|
||||
## This proc implements an atomic store operation. It writes val at p.
|
||||
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, and ATOMIC_RELEASE.
|
||||
|
||||
proc atomic_store*[T: TAtomType](p: ptr T, val: ptr T, mem: AtomMemModel) {.
|
||||
proc atomicStore*[T: TAtomType](p: ptr T, val: ptr T, mem: AtomMemModel) {.
|
||||
importc: "__atomic_store", nodecl.}
|
||||
## This is the generic version of an atomic store. It stores the value of val at p
|
||||
|
||||
proc atomic_exchange_n*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicExchangeN*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_exchange_n", nodecl.}
|
||||
## This proc implements an atomic exchange operation. It writes val at p,
|
||||
## and returns the previous contents at p.
|
||||
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_RELEASE, ATOMIC_ACQ_REL
|
||||
|
||||
proc atomic_exchange*[T: TAtomType](p: ptr T, val: ptr T, ret: ptr T, mem: AtomMemModel) {.
|
||||
proc atomicExchange*[T: TAtomType](p: ptr T, val: ptr T, ret: ptr T, mem: AtomMemModel) {.
|
||||
importc: "__atomic_exchange", nodecl.}
|
||||
## This is the generic version of an atomic exchange. It stores the contents at val at p.
|
||||
## The original value at p is copied into ret.
|
||||
|
||||
proc atomic_compare_exchange_n*[T: TAtomType](p: ptr T, expected: ptr T, desired: T,
|
||||
proc atomicCompareExchangeN*[T: TAtomType](p: ptr T, expected: ptr T, desired: T,
|
||||
weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {.
|
||||
importc: "__atomic_compare_exchange_n ", nodecl.}
|
||||
## This proc implements an atomic compare and exchange operation. This compares the
|
||||
@@ -78,7 +76,7 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
## cannot be __ATOMIC_RELEASE nor __ATOMIC_ACQ_REL. It also cannot be a stronger model
|
||||
## than that specified by success_memmodel.
|
||||
|
||||
proc atomic_compare_exchange*[T: TAtomType](p: ptr T, expected: ptr T, desired: ptr T,
|
||||
proc atomicCompareExchange*[T: TAtomType](p: ptr T, expected: ptr T, desired: ptr T,
|
||||
weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {.
|
||||
importc: "__atomic_compare_exchange_n ", nodecl.}
|
||||
## This proc implements the generic version of atomic_compare_exchange.
|
||||
@@ -86,58 +84,58 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
## value is also a pointer.
|
||||
|
||||
## Perform the operation return the new value, all memory models are valid
|
||||
proc atomic_add_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicAddFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_add_fetch", nodecl.}
|
||||
proc atomic_sub_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicSubFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_sub_fetch", nodecl.}
|
||||
proc atomic_or_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicOrFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_or_fetch ", nodecl.}
|
||||
proc atomic_and_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicAndFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_and_fetch", nodecl.}
|
||||
proc atomic_xor_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicXorFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_xor_fetch", nodecl.}
|
||||
proc atomic_nand_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicNandFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_nand_fetch ", nodecl.}
|
||||
|
||||
## Perform the operation return the old value, all memory models are valid
|
||||
proc atomic_fetch_add*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_add ", nodecl.}
|
||||
proc atomic_fetch_sub*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_sub ", nodecl.}
|
||||
proc atomic_fetch_or*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_or ", nodecl.}
|
||||
proc atomic_fetch_and*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_and ", nodecl.}
|
||||
proc atomic_fetch_xor*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_xor ", nodecl.}
|
||||
proc atomic_fetch_nand*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
proc atomicFetchAdd*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_add", nodecl.}
|
||||
proc atomicFetchSub*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_sub", nodecl.}
|
||||
proc atomicFetchOr*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_or", nodecl.}
|
||||
proc atomicFetchAnd*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_and", nodecl.}
|
||||
proc atomicFetchXor*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_xor", nodecl.}
|
||||
proc atomicFetchAand*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
|
||||
importc: "__atomic_fetch_nand", nodecl.}
|
||||
|
||||
proc atomic_test_and_set*(p: pointer, mem: AtomMemModel): bool {.
|
||||
importc: "__atomic_test_and_set ", nodecl.}
|
||||
proc atomicTestAndSet*(p: pointer, mem: AtomMemModel): bool {.
|
||||
importc: "__atomic_test_and_set", nodecl.}
|
||||
## This built-in function performs an atomic test-and-set operation on the byte at p.
|
||||
## The byte is set to some implementation defined nonzero “set” value and the return
|
||||
## value is true if and only if the previous contents were “set”.
|
||||
## All memory models are valid.
|
||||
|
||||
proc atomic_clear*(p: pointer, mem: AtomMemModel) {.
|
||||
proc atomicClear*(p: pointer, mem: AtomMemModel) {.
|
||||
importc: "__atomic_clear", nodecl.}
|
||||
## This built-in function performs an atomic clear operation at p.
|
||||
## After the operation, at p contains 0.
|
||||
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_RELEASE
|
||||
|
||||
proc atomic_thread_fence*(mem: AtomMemModel) {.
|
||||
importc: "__atomic_thread_fence ", nodecl.}
|
||||
proc atomicThreadFence*(mem: AtomMemModel) {.
|
||||
importc: "__atomic_thread_fence", nodecl.}
|
||||
## This built-in function acts as a synchronization fence between threads based
|
||||
## on the specified memory model. All memory orders are valid.
|
||||
|
||||
proc atomic_signal_fence*(mem: AtomMemModel) {.
|
||||
importc: "__atomic_signal_fence ", nodecl.}
|
||||
proc atomicSignalFence*(mem: AtomMemModel) {.
|
||||
importc: "__atomic_signal_fence", nodecl.}
|
||||
## This built-in function acts as a synchronization fence between a thread and
|
||||
## signal handlers based in the same thread. All memory orders are valid.
|
||||
|
||||
proc atomic_always_lock_free*(size: int, p: pointer): bool {.
|
||||
importc: "__atomic_always_lock_free ", nodecl.}
|
||||
proc atomicAlwaysLockFree*(size: int, p: pointer): bool {.
|
||||
importc: "__atomic_always_lock_free", nodecl.}
|
||||
## This built-in function returns true if objects of size bytes always generate
|
||||
## lock free atomic instructions for the target architecture. size must resolve
|
||||
## to a compile-time constant and the result also resolves to a compile-time constant.
|
||||
@@ -145,8 +143,8 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
## A value of 0 indicates typical alignment should be used. The compiler may also
|
||||
## ignore this parameter.
|
||||
|
||||
proc atomic_is_lock_free*(size: int, p: pointer): bool {.
|
||||
importc: "__atomic_is_lock_free ", nodecl.}
|
||||
proc atomicIsLockFree*(size: int, p: pointer): bool {.
|
||||
importc: "__atomic_is_lock_free", nodecl.}
|
||||
## This built-in function returns true if objects of size bytes always generate
|
||||
## lock free atomic instructions for the target architecture. If it is not known
|
||||
## to be lock free a call is made to a runtime routine named __atomic_is_lock_free.
|
||||
@@ -154,19 +152,14 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
|
||||
## A value of 0 indicates typical alignment should be used. The compiler may also
|
||||
## ignore this parameter.
|
||||
|
||||
|
||||
|
||||
elif defined(vcc) and hasThreadSupport:
|
||||
proc add_and_fetch*(p: ptr int, val: int): int {.
|
||||
proc addAndFetch*(p: ptr int, val: int): int {.
|
||||
importc: "NimXadd", nodecl.}
|
||||
else:
|
||||
proc add_and_fetch*(p: ptr int, val: int): int {.inline.} =
|
||||
proc addAndFetch*(p: ptr int, val: int): int {.inline.} =
|
||||
inc(p[], val)
|
||||
result = p[]
|
||||
|
||||
|
||||
|
||||
|
||||
# atomic compare and swap (CAS) funcitons to implement lock-free algorithms
|
||||
|
||||
#if defined(windows) and not defined(gcc) and hasThreadSupport:
|
||||
@@ -210,6 +203,3 @@ proc atomicDec*(memLoc: var int, x: int = 1): int =
|
||||
else:
|
||||
dec(memLoc, x)
|
||||
result = memLoc
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -9,30 +9,30 @@
|
||||
|
||||
# not really an AVL tree anymore, but still balanced ...
|
||||
|
||||
template IsBottom(n: PAvlNode): bool = n == bottom
|
||||
template isBottom(n: PAvlNode): bool = n == bottom
|
||||
|
||||
proc lowGauge(n: PAvlNode): int =
|
||||
var it = n
|
||||
while not IsBottom(it):
|
||||
while not isBottom(it):
|
||||
result = it.key
|
||||
it = it.link[0]
|
||||
|
||||
proc highGauge(n: PAvlNode): int =
|
||||
result = -1
|
||||
var it = n
|
||||
while not IsBottom(it):
|
||||
while not isBottom(it):
|
||||
result = it.upperBound
|
||||
it = it.link[1]
|
||||
|
||||
proc find(root: PAvlNode, key: int): PAvlNode =
|
||||
var it = root
|
||||
while not IsBottom(it):
|
||||
while not isBottom(it):
|
||||
if it.key == key: return it
|
||||
it = it.link[ord(it.key <% key)]
|
||||
|
||||
proc inRange(root: PAvlNode, key: int): PAvlNode =
|
||||
var it = root
|
||||
while not IsBottom(it):
|
||||
while not isBottom(it):
|
||||
if it.key <=% key and key <% it.upperBound: return it
|
||||
it = it.link[ord(it.key <% key)]
|
||||
|
||||
|
||||
@@ -43,15 +43,15 @@ type
|
||||
|
||||
proc contains(s: TCellSeq, c: PCell): bool {.inline.} =
|
||||
for i in 0 .. s.len-1:
|
||||
if s.d[i] == c: return True
|
||||
return False
|
||||
if s.d[i] == c: return true
|
||||
return false
|
||||
|
||||
proc add(s: var TCellSeq, c: PCell) {.inline.} =
|
||||
if s.len >= s.cap:
|
||||
s.cap = s.cap * 3 div 2
|
||||
var d = cast[PCellArray](Alloc(s.cap * sizeof(PCell)))
|
||||
var d = cast[PCellArray](alloc(s.cap * sizeof(PCell)))
|
||||
copyMem(d, s.d, s.len * sizeof(PCell))
|
||||
Dealloc(s.d)
|
||||
dealloc(s.d)
|
||||
s.d = d
|
||||
# XXX: realloc?
|
||||
s.d[s.len] = c
|
||||
@@ -60,10 +60,10 @@ proc add(s: var TCellSeq, c: PCell) {.inline.} =
|
||||
proc init(s: var TCellSeq, cap: int = 1024) =
|
||||
s.len = 0
|
||||
s.cap = cap
|
||||
s.d = cast[PCellArray](Alloc0(cap * sizeof(PCell)))
|
||||
s.d = cast[PCellArray](alloc0(cap * sizeof(PCell)))
|
||||
|
||||
proc deinit(s: var TCellSeq) =
|
||||
Dealloc(s.d)
|
||||
dealloc(s.d)
|
||||
s.d = nil
|
||||
s.len = 0
|
||||
s.cap = 0
|
||||
@@ -73,20 +73,20 @@ proc deinit(s: var TCellSeq) =
|
||||
const
|
||||
InitCellSetSize = 1024 # must be a power of two!
|
||||
|
||||
proc Init(s: var TCellSet) =
|
||||
s.data = cast[PPageDescArray](Alloc0(InitCellSetSize * sizeof(PPageDesc)))
|
||||
proc init(s: var TCellSet) =
|
||||
s.data = cast[PPageDescArray](alloc0(InitCellSetSize * sizeof(PPageDesc)))
|
||||
s.max = InitCellSetSize-1
|
||||
s.counter = 0
|
||||
s.head = nil
|
||||
|
||||
proc Deinit(s: var TCellSet) =
|
||||
proc deinit(s: var TCellSet) =
|
||||
var it = s.head
|
||||
while it != nil:
|
||||
var n = it.next
|
||||
Dealloc(it)
|
||||
dealloc(it)
|
||||
it = n
|
||||
s.head = nil # play it safe here
|
||||
Dealloc(s.data)
|
||||
dealloc(s.data)
|
||||
s.data = nil
|
||||
s.counter = 0
|
||||
|
||||
@@ -96,14 +96,14 @@ proc nextTry(h, maxHash: int): int {.inline.} =
|
||||
# generates each int in range(maxHash) exactly once (see any text on
|
||||
# random-number generation for proof).
|
||||
|
||||
proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc =
|
||||
proc cellSetGet(t: TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while t.data[h] != nil:
|
||||
if t.data[h].key == key: return t.data[h]
|
||||
h = nextTry(h, t.max)
|
||||
return nil
|
||||
|
||||
proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
|
||||
proc cellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
|
||||
var h = cast[int](desc.key) and t.max
|
||||
while data[h] != nil:
|
||||
sysAssert(data[h] != desc, "CellSetRawInsert 1")
|
||||
@@ -111,17 +111,17 @@ proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
|
||||
sysAssert(data[h] == nil, "CellSetRawInsert 2")
|
||||
data[h] = desc
|
||||
|
||||
proc CellSetEnlarge(t: var TCellSet) =
|
||||
proc cellSetEnlarge(t: var TCellSet) =
|
||||
var oldMax = t.max
|
||||
t.max = ((t.max+1)*2)-1
|
||||
var n = cast[PPageDescArray](Alloc0((t.max + 1) * sizeof(PPageDesc)))
|
||||
var n = cast[PPageDescArray](alloc0((t.max + 1) * sizeof(PPageDesc)))
|
||||
for i in 0 .. oldmax:
|
||||
if t.data[i] != nil:
|
||||
CellSetRawInsert(t, n, t.data[i])
|
||||
Dealloc(t.data)
|
||||
cellSetRawInsert(t, n, t.data[i])
|
||||
dealloc(t.data)
|
||||
t.data = n
|
||||
|
||||
proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
var h = cast[int](key) and t.max
|
||||
while true:
|
||||
var x = t.data[h]
|
||||
@@ -130,13 +130,13 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
h = nextTry(h, t.max)
|
||||
|
||||
if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4):
|
||||
CellSetEnlarge(t)
|
||||
cellSetEnlarge(t)
|
||||
inc(t.counter)
|
||||
h = cast[int](key) and t.max
|
||||
while t.data[h] != nil: h = nextTry(h, t.max)
|
||||
sysAssert(t.data[h] == nil, "CellSetPut")
|
||||
# the new page descriptor goes into result
|
||||
result = cast[PPageDesc](Alloc0(sizeof(TPageDesc)))
|
||||
result = cast[PPageDesc](alloc0(sizeof(TPageDesc)))
|
||||
result.next = t.head
|
||||
result.key = key
|
||||
t.head = result
|
||||
@@ -146,7 +146,7 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||
|
||||
proc contains(s: TCellSet, cell: PCell): bool =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetGet(s, u shr PageShift)
|
||||
var t = cellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0
|
||||
@@ -155,13 +155,13 @@ proc contains(s: TCellSet, cell: PCell): bool =
|
||||
|
||||
proc incl(s: var TCellSet, cell: PCell) {.noinline.} =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetPut(s, u shr PageShift)
|
||||
var t = cellSetPut(s, u shr PageShift)
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask))
|
||||
|
||||
proc excl(s: var TCellSet, cell: PCell) =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetGet(s, u shr PageShift)
|
||||
var t = cellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
t.bits[u shr IntShift] = (t.bits[u shr IntShift] and
|
||||
@@ -169,7 +169,7 @@ proc excl(s: var TCellSet, cell: PCell) =
|
||||
|
||||
proc containsOrIncl(s: var TCellSet, cell: PCell): bool =
|
||||
var u = cast[TAddress](cell)
|
||||
var t = CellSetGet(s, u shr PageShift)
|
||||
var t = cellSetGet(s, u shr PageShift)
|
||||
if t != nil:
|
||||
u = (u %% PageSize) /% MemAlign
|
||||
result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0
|
||||
@@ -177,7 +177,7 @@ proc containsOrIncl(s: var TCellSet, cell: PCell): bool =
|
||||
t.bits[u shr IntShift] = t.bits[u shr IntShift] or
|
||||
(1 shl (u and IntMask))
|
||||
else:
|
||||
Incl(s, cell)
|
||||
incl(s, cell)
|
||||
result = false
|
||||
|
||||
iterator elements(t: TCellSet): PCell {.inline.} =
|
||||
|
||||
@@ -28,7 +28,7 @@ proc nimLoadLibraryError(path: string) =
|
||||
stdout.rawWrite("\n")
|
||||
quit(1)
|
||||
|
||||
proc ProcAddrError(name: cstring) {.noinline.} =
|
||||
proc procAddrError(name: cstring) {.noinline.} =
|
||||
# carefully written to avoid memory allocation:
|
||||
stdout.rawWrite("could not import: ")
|
||||
stdout.write(name)
|
||||
@@ -83,21 +83,22 @@ elif defined(windows) or defined(dos):
|
||||
type
|
||||
THINSTANCE {.importc: "HINSTANCE".} = pointer
|
||||
|
||||
proc FreeLibrary(lib: THINSTANCE) {.importc, header: "<windows.h>", stdcall.}
|
||||
proc freeLibrary(lib: THINSTANCE) {.
|
||||
importc: "FreeLibrary", header: "<windows.h>", stdcall.}
|
||||
proc winLoadLibrary(path: cstring): THINSTANCE {.
|
||||
importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
|
||||
proc GetProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
|
||||
proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
|
||||
importc: "GetProcAddress", header: "<windows.h>", stdcall.}
|
||||
|
||||
proc nimUnloadLibrary(lib: TLibHandle) =
|
||||
FreeLibrary(cast[THINSTANCE](lib))
|
||||
freeLibrary(cast[THINSTANCE](lib))
|
||||
|
||||
proc nimLoadLibrary(path: string): TLibHandle =
|
||||
result = cast[TLibHandle](winLoadLibrary(path))
|
||||
|
||||
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
|
||||
result = GetProcAddress(cast[THINSTANCE](lib), name)
|
||||
if result == nil: ProcAddrError(name)
|
||||
result = getProcAddress(cast[THINSTANCE](lib), name)
|
||||
if result == nil: procAddrError(name)
|
||||
|
||||
elif defined(mac):
|
||||
#
|
||||
|
||||
@@ -151,7 +151,7 @@ template gcTrace(cell, state: expr): stmt {.immediate.} =
|
||||
|
||||
# forward declarations:
|
||||
proc collectCT(gch: var TGcHeap)
|
||||
proc IsOnStack*(p: pointer): bool {.noinline.}
|
||||
proc isOnStack*(p: pointer): bool {.noinline.}
|
||||
proc forAllChildren(cell: PCell, op: TWalkOp)
|
||||
proc doOperation(p: pointer, op: TWalkOp)
|
||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp)
|
||||
@@ -669,7 +669,7 @@ proc doOperation(p: pointer, op: TWalkOp) =
|
||||
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
|
||||
doOperation(d, TWalkOp(op))
|
||||
|
||||
proc CollectZCT(gch: var TGcHeap): bool
|
||||
proc collectZCT(gch: var TGcHeap): bool
|
||||
|
||||
when useMarkForDebug or useBackupGc:
|
||||
proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl.}
|
||||
|
||||
@@ -72,7 +72,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
|
||||
result = $e & " (invalid data!)"
|
||||
|
||||
type
|
||||
pbyteArray = ptr array[0.. 0xffff, int8]
|
||||
PByteArray = ptr array[0.. 0xffff, int8]
|
||||
|
||||
proc addSetElem(result: var string, elem: int, typ: PNimType) =
|
||||
case typ.kind
|
||||
|
||||
@@ -22,48 +22,48 @@ when defined(Windows):
|
||||
|
||||
TSysCond = THandle
|
||||
|
||||
proc InitSysLock(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
proc initSysLock(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "InitializeCriticalSection".}
|
||||
## Initializes the lock `L`.
|
||||
|
||||
proc TryAcquireSysAux(L: var TSysLock): int32 {.stdcall, noSideEffect,
|
||||
proc tryAcquireSysAux(L: var TSysLock): int32 {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "TryEnterCriticalSection".}
|
||||
## Tries to acquire the lock `L`.
|
||||
|
||||
proc TryAcquireSys(L: var TSysLock): bool {.inline.} =
|
||||
proc tryAcquireSys(L: var TSysLock): bool {.inline.} =
|
||||
result = TryAcquireSysAux(L) != 0'i32
|
||||
|
||||
proc AcquireSys(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
proc acquireSys(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "EnterCriticalSection".}
|
||||
## Acquires the lock `L`.
|
||||
|
||||
proc ReleaseSys(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
proc releaseSys(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "LeaveCriticalSection".}
|
||||
## Releases the lock `L`.
|
||||
|
||||
proc DeinitSys(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
proc deinitSys(L: var TSysLock) {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "DeleteCriticalSection".}
|
||||
|
||||
proc CreateEvent(lpEventAttributes: pointer,
|
||||
proc createEvent(lpEventAttributes: pointer,
|
||||
bManualReset, bInitialState: int32,
|
||||
lpName: cstring): TSysCond {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "CreateEventA".}
|
||||
|
||||
proc CloseHandle(hObject: THandle) {.stdcall, noSideEffect,
|
||||
proc closeHandle(hObject: THandle) {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "CloseHandle".}
|
||||
proc WaitForSingleObject(hHandle: THandle, dwMilliseconds: int32): int32 {.
|
||||
proc waitForSingleObject(hHandle: THandle, dwMilliseconds: int32): int32 {.
|
||||
stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".}
|
||||
|
||||
proc SignalSysCond(hEvent: TSysCond) {.stdcall, noSideEffect,
|
||||
proc signalSysCond(hEvent: TSysCond) {.stdcall, noSideEffect,
|
||||
dynlib: "kernel32", importc: "SetEvent".}
|
||||
|
||||
proc InitSysCond(cond: var TSysCond) {.inline.} =
|
||||
cond = CreateEvent(nil, 0'i32, 0'i32, nil)
|
||||
proc DeinitSysCond(cond: var TSysCond) {.inline.} =
|
||||
CloseHandle(cond)
|
||||
proc WaitSysCond(cond: var TSysCond, lock: var TSysLock) =
|
||||
proc initSysCond(cond: var TSysCond) {.inline.} =
|
||||
cond = createEvent(nil, 0'i32, 0'i32, nil)
|
||||
proc deinitSysCond(cond: var TSysCond) {.inline.} =
|
||||
closeHandle(cond)
|
||||
proc waitSysCond(cond: var TSysCond, lock: var TSysLock) =
|
||||
releaseSys(lock)
|
||||
discard WaitForSingleObject(cond, -1'i32)
|
||||
discard waitForSingleObject(cond, -1'i32)
|
||||
acquireSys(lock)
|
||||
|
||||
else:
|
||||
@@ -73,29 +73,29 @@ else:
|
||||
TSysCond {.importc: "pthread_cond_t", pure, final,
|
||||
header: "<sys/types.h>".} = object
|
||||
|
||||
proc InitSysLock(L: var TSysLock, attr: pointer = nil) {.
|
||||
proc initSysLock(L: var TSysLock, attr: pointer = nil) {.
|
||||
importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
|
||||
|
||||
proc AcquireSys(L: var TSysLock) {.noSideEffect,
|
||||
proc acquireSys(L: var TSysLock) {.noSideEffect,
|
||||
importc: "pthread_mutex_lock", header: "<pthread.h>".}
|
||||
proc TryAcquireSysAux(L: var TSysLock): cint {.noSideEffect,
|
||||
proc tryAcquireSysAux(L: var TSysLock): cint {.noSideEffect,
|
||||
importc: "pthread_mutex_trylock", header: "<pthread.h>".}
|
||||
|
||||
proc TryAcquireSys(L: var TSysLock): bool {.inline.} =
|
||||
result = TryAcquireSysAux(L) == 0'i32
|
||||
proc tryAcquireSys(L: var TSysLock): bool {.inline.} =
|
||||
result = tryAcquireSysAux(L) == 0'i32
|
||||
|
||||
proc ReleaseSys(L: var TSysLock) {.noSideEffect,
|
||||
proc releaseSys(L: var TSysLock) {.noSideEffect,
|
||||
importc: "pthread_mutex_unlock", header: "<pthread.h>".}
|
||||
proc DeinitSys(L: var TSysLock) {.
|
||||
proc deinitSys(L: var TSysLock) {.
|
||||
importc: "pthread_mutex_destroy", header: "<pthread.h>".}
|
||||
|
||||
proc InitSysCond(cond: var TSysCond, cond_attr: pointer = nil) {.
|
||||
proc initSysCond(cond: var TSysCond, cond_attr: pointer = nil) {.
|
||||
importc: "pthread_cond_init", header: "<pthread.h>".}
|
||||
proc WaitSysCond(cond: var TSysCond, lock: var TSysLock) {.
|
||||
proc waitSysCond(cond: var TSysCond, lock: var TSysLock) {.
|
||||
importc: "pthread_cond_wait", header: "<pthread.h>".}
|
||||
proc SignalSysCond(cond: var TSysCond) {.
|
||||
proc signalSysCond(cond: var TSysCond) {.
|
||||
importc: "pthread_cond_signal", header: "<pthread.h>".}
|
||||
|
||||
proc DeinitSysCond(cond: var TSysCond) {.
|
||||
proc deinitSysCond(cond: var TSysCond) {.
|
||||
importc: "pthread_cond_destroy", header: "<pthread.h>".}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user