diff options
-rw-r--r-- | lib/system/alloc.nim | 30 | ||||
-rw-r--r-- | lib/system/avltree.nim | 2 | ||||
-rw-r--r-- | lib/system/memtracker.nim | 7 | ||||
-rw-r--r-- | lib/system/threads.nim | 32 | ||||
-rw-r--r-- | tests/threads/threadex.nim | 5 |
5 files changed, 58 insertions, 18 deletions
diff --git a/lib/system/alloc.nim b/lib/system/alloc.nim index 95566129d..6f11941a0 100644 --- a/lib/system/alloc.nim +++ b/lib/system/alloc.nim @@ -103,19 +103,12 @@ type root, deleted, last, freeAvlNodes: PAvlNode locked, blockChunkSizeIncrease: bool # if locked, we cannot free pages. nextChunkSize: int -{.deprecated: [TMemRegion: MemRegion].} + bottomData: AvlNode -# shared: -var - bottomData {.threadvar.}: AvlNode - bottom {.threadvar.}: PAvlNode +{.deprecated: [TMemRegion: MemRegion].} {.push stack_trace: off.} -proc initAllocator() = - when not defined(useNimRtl): - bottom = addr(bottomData) - bottom.link[0] = bottom - bottom.link[1] = bottom +proc initAllocator() = discard "nothing to do anymore" {.pop.} proc incCurrMem(a: var MemRegion, bytes: int) {.inline.} = @@ -152,6 +145,12 @@ proc llAlloc(a: var MemRegion, size: int): pointer = inc(a.llmem.acc, size) zeroMem(result, size) +proc getBottom(a: var MemRegion): PAvlNode = + result = addr(a.bottomData) + if result.link[0] == nil: + result.link[0] = result + result.link[1] = result + proc allocAvlNode(a: var MemRegion, key, upperBound: int): PAvlNode = if a.freeAvlNodes != nil: result = a.freeAvlNodes @@ -162,12 +161,13 @@ proc allocAvlNode(a: var MemRegion, key, upperBound: int): PAvlNode = cprintf("tracking location: %p\n", result) result.key = key result.upperBound = upperBound + let bottom = getBottom(a) result.link[0] = bottom result.link[1] = bottom result.level = 1 - when defined(avlcorruption): - track("allocAvlNode", result, sizeof(AvlNode)) - sysAssert(bottom == addr(bottomData), "bottom data") + #when defined(avlcorruption): + # track("allocAvlNode", result, sizeof(AvlNode)) + sysAssert(bottom == addr(a.bottomData), "bottom data") sysAssert(bottom.link[0] == bottom, "bottom link[0]") sysAssert(bottom.link[1] == bottom, "bottom link[1]") @@ -565,7 +565,7 @@ proc rawAlloc(a: var MemRegion, requestedSize: int): pointer = sysAssert c.size == size, "rawAlloc 12" result = addr(c.data) sysAssert((cast[ByteAddress](result) and (MemAlign-1)) == 0, "rawAlloc 13") - if a.root == nil: a.root = bottom + if a.root == nil: a.root = getBottom(a) add(a, a.root, cast[ByteAddress](result), cast[ByteAddress](result)+%size) sysAssert(isAccessible(a, result), "rawAlloc 14") sysAssert(allocInv(a), "rawAlloc: end") @@ -613,7 +613,7 @@ proc rawDealloc(a: var MemRegion, p: pointer) = when overwriteFree: c_memset(p, -1'i32, c.size -% bigChunkOverhead()) # free big chunk var c = cast[PBigChunk](c) - a.deleted = bottom + a.deleted = getBottom(a) del(a, a.root, cast[int](addr(c.data))) freeBigChunk(a, c) sysAssert(allocInv(a), "rawDealloc: end") diff --git a/lib/system/avltree.nim b/lib/system/avltree.nim index 96c187841..8d4b7e897 100644 --- a/lib/system/avltree.nim +++ b/lib/system/avltree.nim @@ -81,7 +81,7 @@ proc del(a: var MemRegion, t: var PAvlNode, x: int) {.benign.} = if t == a.last and not isBottom(a.deleted) and x == a.deleted.key: a.deleted.key = t.key a.deleted.upperBound = t.upperBound - a.deleted = bottom + a.deleted = getBottom(a) t = t.link[1] deallocAvlNode(a, a.last) elif t.link[0].level < t.level-1 or diff --git a/lib/system/memtracker.nim b/lib/system/memtracker.nim index 0e33e0ec0..219956012 100644 --- a/lib/system/memtracker.nim +++ b/lib/system/memtracker.nim @@ -62,12 +62,17 @@ proc addEntry(entry: LogEntry) = interesting = true break if interesting: - cprintf("interesting %s:%ld\n", entry.file, entry.line) + gLog.disabled = true + cprintf("interesting %s:%ld %s\n", entry.file, entry.line, entry.op) + let x = cast[proc() {.nimcall, tags: [], gcsafe, locks: 0.}](writeStackTrace) + x() + quit 1 if gLog.count > high(gLog.data): gLogger(gLog) gLog.count = 0 gLog.data[gLog.count] = entry inc gLog.count + gLog.disabled = false proc memTrackerWrite(address: pointer; size: int; file: cstring; line: int) {.compilerProc.} = addEntry LogEntry(op: "write", address: address, diff --git a/lib/system/threads.nim b/lib/system/threads.nim index f72395fd2..7886fdcdf 100644 --- a/lib/system/threads.nim +++ b/lib/system/threads.nim @@ -53,7 +53,7 @@ when defined(windows): type SysThread* = Handle WinThreadProc = proc (x: pointer): int32 {.stdcall.} - {.deprecated: [TSysThread: SysThread, TWinThreadProc: WinThreadProc].} + {.deprecated: [TSysThread: SysThread].} proc createThread(lpThreadAttributes: pointer, dwStackSize: int32, lpStartAddress: WinThreadProc, @@ -77,6 +77,9 @@ when defined(windows): proc terminateThread(hThread: SysThread, dwExitCode: int32): int32 {. stdcall, dynlib: "kernel32", importc: "TerminateThread".} + proc getCurrentThreadId(): int32 {. + stdcall, dynlib: "kernel32", importc: "GetCurrentThreadId".} + type ThreadVarSlot = distinct int32 @@ -108,6 +111,10 @@ when defined(windows): proc setThreadAffinityMask(hThread: SysThread, dwThreadAffinityMask: uint) {. importc: "SetThreadAffinityMask", stdcall, header: "<windows.h>".} + proc getThreadId*(): int = + ## get the ID of the currently running thread. + result = int(getCurrentThreadId()) + else: when not defined(macosx): {.passL: "-pthread".} @@ -187,6 +194,29 @@ else: proc setAffinity(thread: SysThread; setsize: csize; s: var CpuSet) {. importc: "pthread_setaffinity_np", header: pthreadh.} + when defined(linux): + type Pid {.importc: "pid_t", header: "<sys/types.h>".} = distinct int + proc gettid(): Pid {.importc, header: "<sys/types.h>".} + + proc getThreadId*(): int = + ## get the ID of the currently running thread. + result = int(gettid()) + elif defined(macosx) or defined(bsd): + proc pthread_main_np(): cint {.importc, header: "pthread.h".} + + proc getThreadId*(): int = + ## get the ID of the currently running thread. + result = int(pthread_main_np()) + elif defined(solaris): + # just a guess really: + type thread_t {.importc: "thread_t", header: "<thread.h>".} = distinct int + proc thr_self(): thread_t {.importc, header: "<thread.h>".} + + proc getThreadId*(): int = + ## get the ID of the currently running thread. + result = int(thr_self()) + + const emulatedThreadVars = compileOption("tlsEmulation") diff --git a/tests/threads/threadex.nim b/tests/threads/threadex.nim index 442e80189..fb03cbfa8 100644 --- a/tests/threads/threadex.nim +++ b/tests/threads/threadex.nim @@ -14,8 +14,11 @@ var producer, consumer: Thread[void] chan: Channel[TMsg] printedLines = 0 + prodId: int + consId: int proc consume() {.thread.} = + consId = getThreadId() while true: var x = recv(chan) if x.k == mEof: break @@ -23,6 +26,7 @@ proc consume() {.thread.} = atomicInc(printedLines) proc produce() {.thread.} = + prodId = getThreadId() var m: TMsg var input = open("readme.txt") var line = "" @@ -40,5 +44,6 @@ joinThread(consumer) joinThread(producer) close(chan) +doAssert prodId != consId echo printedLines |