make tests green
This commit is contained in:
parent
3ba34f1762
commit
30823c1ce3
44 changed files with 415 additions and 403 deletions
|
|
@ -31,7 +31,7 @@ when someGcc and hasThreadSupport:
|
|||
## with acquire loads
|
||||
## and release stores in all threads.
|
||||
|
||||
TAtomType* = TNumber|pointer|ptr|char
|
||||
TAtomType* = SomeNumber|pointer|ptr|char
|
||||
## Type Class representing valid types for use with atomic procs
|
||||
|
||||
proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {.
|
||||
|
|
|
|||
|
|
@ -53,8 +53,8 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
|
|||
proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
|
||||
mode: TLoadStoreMode) {.gcsafe.} =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
s = cast[TAddress](src)
|
||||
d = cast[ByteAddress](dest)
|
||||
s = cast[ByteAddress](src)
|
||||
case n.kind
|
||||
of nkSlot: storeAux(cast[pointer](d +% n.offset),
|
||||
cast[pointer](s +% n.offset), n.typ, t, mode)
|
||||
|
|
@ -70,8 +70,8 @@ proc storeAux(dest, src: pointer, n: ptr TNimNode, t: PRawChannel,
|
|||
proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
|
||||
mode: TLoadStoreMode) =
|
||||
var
|
||||
d = cast[TAddress](dest)
|
||||
s = cast[TAddress](src)
|
||||
d = cast[ByteAddress](dest)
|
||||
s = cast[ByteAddress](src)
|
||||
sysAssert(mt != nil, "mt == nil")
|
||||
case mt.kind
|
||||
of tyString:
|
||||
|
|
@ -108,11 +108,11 @@ proc storeAux(dest, src: pointer, mt: PNimType, t: PRawChannel,
|
|||
x[] = alloc(t.region, seq.len *% mt.base.size +% GenericSeqSize)
|
||||
else:
|
||||
unsureAsgnRef(x, newObj(mt, seq.len * mt.base.size + GenericSeqSize))
|
||||
var dst = cast[TAddress](cast[PPointer](dest)[])
|
||||
var dst = cast[ByteAddress](cast[PPointer](dest)[])
|
||||
for i in 0..seq.len-1:
|
||||
storeAux(
|
||||
cast[pointer](dst +% i*% mt.base.size +% GenericSeqSize),
|
||||
cast[pointer](cast[TAddress](s2) +% i *% mt.base.size +%
|
||||
cast[pointer](cast[ByteAddress](s2) +% i *% mt.base.size +%
|
||||
GenericSeqSize),
|
||||
mt.base, t, mode)
|
||||
var dstseq = cast[PGenericSeq](dst)
|
||||
|
|
@ -192,7 +192,7 @@ template lockChannel(q: expr, action: stmt) {.immediate.} =
|
|||
|
||||
template sendImpl(q: expr) {.immediate.} =
|
||||
if q.mask == ChannelDeadMask:
|
||||
sysFatal(EDeadThread, "cannot send message; thread died")
|
||||
sysFatal(DeadThreadError, "cannot send message; thread died")
|
||||
acquireSys(q.lock)
|
||||
var m: TMsg
|
||||
shallowCopy(m, msg)
|
||||
|
|
@ -215,7 +215,7 @@ proc llRecv(q: PRawChannel, res: pointer, typ: PNimType) =
|
|||
q.ready = false
|
||||
if typ != q.elemType:
|
||||
releaseSys(q.lock)
|
||||
sysFatal(EInvalidValue, "cannot receive message of wrong type")
|
||||
sysFatal(ValueError, "cannot receive message of wrong type")
|
||||
rawRecv(q, res, typ)
|
||||
|
||||
proc recv*[TMsg](c: var TChannel[TMsg]): TMsg =
|
||||
|
|
|
|||
|
|
@ -80,11 +80,11 @@ template gcAssert(cond: bool, msg: string) =
|
|||
|
||||
proc cellToUsr(cell: PCell): pointer {.inline.} =
|
||||
# convert object (=pointer to refcount) to pointer to userdata
|
||||
result = cast[pointer](cast[TAddress](cell)+%TAddress(sizeof(TCell)))
|
||||
result = cast[pointer](cast[ByteAddress](cell)+%ByteAddress(sizeof(TCell)))
|
||||
|
||||
proc usrToCell(usr: pointer): PCell {.inline.} =
|
||||
# convert pointer to userdata to object (=pointer to refcount)
|
||||
result = cast[PCell](cast[TAddress](usr)-%TAddress(sizeof(TCell)))
|
||||
result = cast[PCell](cast[ByteAddress](usr)-%ByteAddress(sizeof(TCell)))
|
||||
|
||||
proc canbeCycleRoot(c: PCell): bool {.inline.} =
|
||||
result = ntfAcyclic notin c.typ.flags
|
||||
|
|
@ -169,7 +169,7 @@ proc initGC() =
|
|||
init(gch.marked)
|
||||
|
||||
proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
|
||||
var d = cast[TAddress](dest)
|
||||
var d = cast[ByteAddress](dest)
|
||||
case n.kind
|
||||
of nkSlot: forAllChildrenAux(cast[pointer](d +% n.offset), n.typ, op)
|
||||
of nkList:
|
||||
|
|
@ -181,7 +181,7 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) {.gcsafe.} =
|
|||
of nkNone: sysAssert(false, "forAllSlotsAux")
|
||||
|
||||
proc forAllChildrenAux(dest: pointer, mt: PNimType, op: TWalkOp) =
|
||||
var d = cast[TAddress](dest)
|
||||
var d = cast[ByteAddress](dest)
|
||||
if dest == nil: return # nothing to do
|
||||
if ntfNoRefs notin mt.flags:
|
||||
case mt.kind
|
||||
|
|
@ -206,7 +206,7 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
|||
of tyRef: # common case
|
||||
forAllChildrenAux(cellToUsr(cell), cell.typ.base, op)
|
||||
of tySequence:
|
||||
var d = cast[TAddress](cellToUsr(cell))
|
||||
var d = cast[ByteAddress](cellToUsr(cell))
|
||||
var s = cast[PGenericSeq](d)
|
||||
if s != nil:
|
||||
for i in 0..s.len-1:
|
||||
|
|
@ -220,7 +220,7 @@ proc rawNewObj(typ: PNimType, size: int, gch: var TGcHeap): pointer =
|
|||
gcAssert(typ.kind in {tyRef, tyString, tySequence}, "newObj: 1")
|
||||
collectCT(gch)
|
||||
var res = cast[PCell](rawAlloc(gch.region, size + sizeof(TCell)))
|
||||
gcAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
|
||||
gcAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "newObj: 2")
|
||||
# now it is buffered in the ZCT
|
||||
res.typ = typ
|
||||
when leakDetector and not hasThreadSupport:
|
||||
|
|
@ -280,9 +280,9 @@ proc growObj(old: pointer, newsize: int, gch: var TGcHeap): pointer =
|
|||
|
||||
var oldsize = cast[PGenericSeq](old).len*elemSize + GenericSeqSize
|
||||
copyMem(res, ol, oldsize + sizeof(TCell))
|
||||
zeroMem(cast[pointer](cast[TAddress](res)+% oldsize +% sizeof(TCell)),
|
||||
zeroMem(cast[pointer](cast[ByteAddress](res)+% oldsize +% sizeof(TCell)),
|
||||
newsize-oldsize)
|
||||
sysAssert((cast[TAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||
sysAssert((cast[ByteAddress](res) and (MemAlign-1)) == 0, "growObj: 3")
|
||||
when withBitvectors: excl(gch.allocated, ol)
|
||||
when reallyDealloc: rawDealloc(gch.region, ol)
|
||||
else:
|
||||
|
|
@ -379,7 +379,7 @@ proc markGlobals(gch: var TGcHeap) =
|
|||
proc gcMark(gch: var TGcHeap, p: pointer) {.inline.} =
|
||||
# the addresses are not as cells on the stack, so turn them to cells:
|
||||
var cell = usrToCell(p)
|
||||
var c = cast[TAddress](cell)
|
||||
var c = cast[ByteAddress](cell)
|
||||
if c >% PageSize:
|
||||
# fast check: does it look like a cell?
|
||||
var objStart = cast[PCell](interiorAllocatedPtr(gch.region, cell))
|
||||
|
|
@ -404,8 +404,8 @@ when not defined(useNimRtl):
|
|||
# the first init must be the one that defines the stack bottom:
|
||||
if gch.stackBottom == nil: gch.stackBottom = theStackBottom
|
||||
else:
|
||||
var a = cast[TAddress](theStackBottom) # and not PageMask - PageSize*2
|
||||
var b = cast[TAddress](gch.stackBottom)
|
||||
var a = cast[ByteAddress](theStackBottom) # and not PageMask - PageSize*2
|
||||
var b = cast[ByteAddress](gch.stackBottom)
|
||||
#c_fprintf(c_stdout, "old: %p new: %p;\n",gch.stackBottom,theStackBottom)
|
||||
when stackIncreases:
|
||||
gch.stackBottom = cast[pointer](min(a, b))
|
||||
|
|
@ -421,9 +421,9 @@ when defined(sparc): # For SPARC architecture.
|
|||
proc isOnStack(p: pointer): bool =
|
||||
var stackTop {.volatile.}: pointer
|
||||
stackTop = addr(stackTop)
|
||||
var b = cast[TAddress](gch.stackBottom)
|
||||
var a = cast[TAddress](stackTop)
|
||||
var x = cast[TAddress](p)
|
||||
var b = cast[ByteAddress](gch.stackBottom)
|
||||
var a = cast[ByteAddress](stackTop)
|
||||
var x = cast[ByteAddress](p)
|
||||
result = a <=% x and x <=% b
|
||||
|
||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||
|
|
@ -440,7 +440,7 @@ when defined(sparc): # For SPARC architecture.
|
|||
# Addresses decrease as the stack grows.
|
||||
while sp <= max:
|
||||
gcMark(gch, sp[])
|
||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
||||
sp = cast[ppointer](cast[ByteAddress](sp) +% sizeof(pointer))
|
||||
|
||||
elif defined(ELATE):
|
||||
{.error: "stack marking code is to be written for this architecture".}
|
||||
|
|
@ -452,9 +452,9 @@ elif stackIncreases:
|
|||
proc isOnStack(p: pointer): bool =
|
||||
var stackTop {.volatile.}: pointer
|
||||
stackTop = addr(stackTop)
|
||||
var a = cast[TAddress](gch.stackBottom)
|
||||
var b = cast[TAddress](stackTop)
|
||||
var x = cast[TAddress](p)
|
||||
var a = cast[ByteAddress](gch.stackBottom)
|
||||
var b = cast[ByteAddress](stackTop)
|
||||
var x = cast[ByteAddress](p)
|
||||
result = a <=% x and x <=% b
|
||||
|
||||
var
|
||||
|
|
@ -465,8 +465,8 @@ elif stackIncreases:
|
|||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||
var registers: C_JmpBuf
|
||||
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||
var max = cast[TAddress](gch.stackBottom)
|
||||
var sp = cast[TAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
|
||||
var max = cast[ByteAddress](gch.stackBottom)
|
||||
var sp = cast[ByteAddress](addr(registers)) +% jmpbufSize -% sizeof(pointer)
|
||||
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
||||
# otherwise sp would be below the registers structure).
|
||||
while sp >=% max:
|
||||
|
|
@ -480,9 +480,9 @@ else:
|
|||
proc isOnStack(p: pointer): bool =
|
||||
var stackTop {.volatile.}: pointer
|
||||
stackTop = addr(stackTop)
|
||||
var b = cast[TAddress](gch.stackBottom)
|
||||
var a = cast[TAddress](stackTop)
|
||||
var x = cast[TAddress](p)
|
||||
var b = cast[ByteAddress](gch.stackBottom)
|
||||
var a = cast[ByteAddress](stackTop)
|
||||
var x = cast[ByteAddress](p)
|
||||
result = a <=% x and x <=% b
|
||||
|
||||
proc markStackAndRegisters(gch: var TGcHeap) {.noinline, cdecl.} =
|
||||
|
|
@ -492,8 +492,8 @@ else:
|
|||
type PStackSlice = ptr array [0..7, pointer]
|
||||
var registers {.noinit.}: C_JmpBuf
|
||||
if c_setjmp(registers) == 0'i32: # To fill the C stack with registers.
|
||||
var max = cast[TAddress](gch.stackBottom)
|
||||
var sp = cast[TAddress](addr(registers))
|
||||
var max = cast[ByteAddress](gch.stackBottom)
|
||||
var sp = cast[ByteAddress](addr(registers))
|
||||
# loop unrolled:
|
||||
while sp <% max - 8*sizeof(pointer):
|
||||
gcMark(gch, cast[PStackSlice](sp)[0])
|
||||
|
|
@ -546,7 +546,7 @@ when not defined(useNimRtl):
|
|||
else:
|
||||
dec(gch.recGcLock)
|
||||
|
||||
proc GC_setStrategy(strategy: TGC_Strategy) = discard
|
||||
proc GC_setStrategy(strategy: GC_Strategy) = discard
|
||||
|
||||
proc GC_enableMarkAndSweep() =
|
||||
gch.cycleThreshold = InitialThreshold
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ type
|
|||
PSafePoint = ptr TSafePoint
|
||||
TSafePoint {.compilerproc, final.} = object
|
||||
prev: PSafePoint # points to next safe point
|
||||
exc: ref E_Base
|
||||
exc: ref Exception
|
||||
|
||||
PCallFrame = ptr TCallFrame
|
||||
TCallFrame {.importc, nodecl, final.} = object
|
||||
|
|
@ -97,7 +97,7 @@ proc rawWriteStackTrace(): string =
|
|||
else:
|
||||
result = "No stack traceback available\n"
|
||||
|
||||
proc raiseException(e: ref E_Base, ename: cstring) {.
|
||||
proc raiseException(e: ref Exception, ename: cstring) {.
|
||||
compilerproc, asmNoStackFrame.} =
|
||||
e.name = ename
|
||||
if excHandler != nil:
|
||||
|
|
@ -120,24 +120,24 @@ proc raiseException(e: ref E_Base, ename: cstring) {.
|
|||
|
||||
proc reraiseException() {.compilerproc, asmNoStackFrame.} =
|
||||
if excHandler == nil:
|
||||
raise newException(ENoExceptionToReraise, "no exception to reraise")
|
||||
raise newException(ReraiseError, "no exception to reraise")
|
||||
else:
|
||||
asm """throw excHandler.exc;"""
|
||||
|
||||
proc raiseOverflow {.exportc: "raiseOverflow", noreturn.} =
|
||||
raise newException(EOverflow, "over- or underflow")
|
||||
raise newException(OverflowError, "over- or underflow")
|
||||
|
||||
proc raiseDivByZero {.exportc: "raiseDivByZero", noreturn.} =
|
||||
raise newException(EDivByZero, "divison by zero")
|
||||
raise newException(DivByZeroError, "divison by zero")
|
||||
|
||||
proc raiseRangeError() {.compilerproc, noreturn.} =
|
||||
raise newException(EOutOfRange, "value out of range")
|
||||
raise newException(RangeError, "value out of range")
|
||||
|
||||
proc raiseIndexError() {.compilerproc, noreturn.} =
|
||||
raise newException(EInvalidIndex, "index out of bounds")
|
||||
raise newException(IndexError, "index out of bounds")
|
||||
|
||||
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
|
||||
raise newException(EInvalidField, f & " is not accessible")
|
||||
raise newException(FieldError, f & " is not accessible")
|
||||
|
||||
proc SetConstr() {.varargs, asmNoStackFrame, compilerproc.} =
|
||||
asm """
|
||||
|
|
@ -260,7 +260,7 @@ proc eqStrings(a, b: string): bool {.asmNoStackFrame, compilerProc.} =
|
|||
"""
|
||||
|
||||
type
|
||||
TDocument {.importc.} = object of TObject
|
||||
TDocument {.importc.} = object of RootObj
|
||||
write: proc (text: cstring) {.nimcall.}
|
||||
writeln: proc (text: cstring) {.nimcall.}
|
||||
createAttribute: proc (identifier: cstring): ref TNode {.nimcall.}
|
||||
|
|
@ -283,7 +283,7 @@ type
|
|||
DocumentTypeNode,
|
||||
DocumentFragmentNode,
|
||||
NotationNode
|
||||
TNode* {.importc.} = object of TObject
|
||||
TNode* {.importc.} = object of RootObj
|
||||
attributes*: seq[ref TNode]
|
||||
childNodes*: seq[ref TNode]
|
||||
data*: cstring
|
||||
|
|
@ -515,7 +515,7 @@ proc isFatPointer(ti: PNimType): bool =
|
|||
|
||||
proc nimCopy(x: pointer, ti: PNimType): pointer {.compilerproc.}
|
||||
|
||||
proc nimCopyAux(dest, src: Pointer, n: ptr TNimNode) {.compilerproc.} =
|
||||
proc nimCopyAux(dest, src: pointer, n: ptr TNimNode) {.compilerproc.} =
|
||||
case n.kind
|
||||
of nkNone: sysAssert(false, "nimCopyAux")
|
||||
of nkSlot:
|
||||
|
|
@ -566,7 +566,7 @@ proc nimCopy(x: pointer, ti: PNimType): pointer =
|
|||
else:
|
||||
result = x
|
||||
|
||||
proc genericReset(x: Pointer, ti: PNimType): pointer {.compilerproc.} =
|
||||
proc genericReset(x: pointer, ti: PNimType): pointer {.compilerproc.} =
|
||||
case ti.kind
|
||||
of tyPtr, tyRef, tyVar, tyNil:
|
||||
if not isFatPointer(ti):
|
||||
|
|
@ -621,7 +621,7 @@ proc chckObj(obj, subclass: PNimType) {.compilerproc.} =
|
|||
if x == subclass: return # optimized fast path
|
||||
while x != subclass:
|
||||
if x == nil:
|
||||
raise newException(EInvalidObjectConversion, "invalid object conversion")
|
||||
raise newException(ObjectConversionError, "invalid object conversion")
|
||||
x = x.base
|
||||
|
||||
proc isObj(obj, subclass: PNimType): bool {.compilerproc.} =
|
||||
|
|
|
|||
|
|
@ -305,22 +305,26 @@ proc running*[TArg](t: TThread[TArg]): bool {.inline.} =
|
|||
## returns true if `t` is running.
|
||||
result = t.dataFn != nil
|
||||
|
||||
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
|
||||
## waits for the thread `t` to finish.
|
||||
when hostOS == "windows":
|
||||
when hostOS == "windows":
|
||||
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
|
||||
## waits for the thread `t` to finish.
|
||||
discard waitForSingleObject(t.sys, -1'i32)
|
||||
else:
|
||||
discard pthread_join(t.sys, nil)
|
||||
|
||||
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
|
||||
## waits for every thread in `t` to finish.
|
||||
when hostOS == "windows":
|
||||
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
|
||||
## waits for every thread in `t` to finish.
|
||||
var a: array[0..255, TSysThread]
|
||||
sysAssert a.len >= t.len, "a.len >= t.len"
|
||||
for i in 0..t.high: a[i] = t[i].sys
|
||||
discard waitForMultipleObjects(t.len.int32,
|
||||
discard waitForMultipleObjects(t.len.int32,
|
||||
cast[ptr TSysThread](addr(a)), 1, -1)
|
||||
else:
|
||||
|
||||
else:
|
||||
proc joinThread*[TArg](t: TThread[TArg]) {.inline.} =
|
||||
## waits for the thread `t` to finish.
|
||||
discard pthread_join(t.sys, nil)
|
||||
|
||||
proc joinThreads*[TArg](t: varargs[TThread[TArg]]) =
|
||||
## waits for every thread in `t` to finish.
|
||||
for i in 0..t.high: joinThread(t[i])
|
||||
|
||||
when false:
|
||||
|
|
@ -335,27 +339,37 @@ when false:
|
|||
when declared(registerThread): unregisterThread(addr(t))
|
||||
t.dataFn = nil
|
||||
|
||||
proc createThread*[TArg](t: var TThread[TArg],
|
||||
tp: proc (arg: TArg) {.thread.},
|
||||
param: TArg) =
|
||||
## creates a new thread `t` and starts its execution. Entry point is the
|
||||
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
|
||||
## don't need to pass any data to the thread.
|
||||
when TArg isnot void: t.data = param
|
||||
t.dataFn = tp
|
||||
when hasSharedHeap: t.stackSize = ThreadStackSize
|
||||
when hostOS == "windows":
|
||||
when hostOS == "windows":
|
||||
proc createThread*[TArg](t: var TThread[TArg],
|
||||
tp: proc (arg: TArg) {.thread.},
|
||||
param: TArg) =
|
||||
## creates a new thread `t` and starts its execution. Entry point is the
|
||||
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
|
||||
## don't need to pass any data to the thread.
|
||||
when TArg isnot void: t.data = param
|
||||
t.dataFn = tp
|
||||
when hasSharedHeap: t.stackSize = ThreadStackSize
|
||||
var dummyThreadId: int32
|
||||
t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg],
|
||||
addr(t), 0'i32, dummyThreadId)
|
||||
if t.sys <= 0:
|
||||
raise newException(EResourceExhausted, "cannot create thread")
|
||||
else:
|
||||
raise newException(ResourceExhaustedError, "cannot create thread")
|
||||
|
||||
else:
|
||||
proc createThread*[TArg](t: var TThread[TArg],
|
||||
tp: proc (arg: TArg) {.thread.},
|
||||
param: TArg) =
|
||||
## creates a new thread `t` and starts its execution. Entry point is the
|
||||
## proc `tp`. `param` is passed to `tp`. `TArg` can be ``void`` if you
|
||||
## don't need to pass any data to the thread.
|
||||
when TArg isnot void: t.data = param
|
||||
t.dataFn = tp
|
||||
when hasSharedHeap: t.stackSize = ThreadStackSize
|
||||
var a {.noinit.}: Tpthread_attr
|
||||
pthread_attr_init(a)
|
||||
pthread_attr_setstacksize(a, ThreadStackSize)
|
||||
if pthread_create(t.sys, a, threadProcWrapper[TArg], addr(t)) != 0:
|
||||
raise newException(EResourceExhausted, "cannot create thread")
|
||||
raise newException(ResourceExhaustedError, "cannot create thread")
|
||||
|
||||
proc threadId*[TArg](t: var TThread[TArg]): TThreadId[TArg] {.inline.} =
|
||||
## returns the thread ID of `t`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue