Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lib/std/private/threadtypes.nim
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
include system/inclrtl
import std/atomics

const hasSharedHeap* = defined(boehmgc) or defined(gogc) # don't share heaps; every thread has its own

@@ -166,9 +167,9 @@ type
core*: PGcThread
sys*: SysThread
when TArg is void:
dataFn*: proc () {.nimcall, gcsafe.}
dataFn*: Atomic[proc () {.nimcall, gcsafe.}]
else:
dataFn*: proc (m: TArg) {.nimcall, gcsafe.}
dataFn*: Atomic[proc (m: TArg) {.nimcall, gcsafe.}]
data*: TArg
when hasAllocStack:
rawStack*: pointer
14 changes: 8 additions & 6 deletions lib/std/typedthreads.nim
Original file line number Diff line number Diff line change
@@ -78,6 +78,7 @@ deinitLock(l)

import std/private/[threadtypes]
export Thread
import std/atomics

import system/ansi_c

@@ -149,9 +150,10 @@ else:
nimThreadProcWrapperBody(closure)
{.pop.}

proc running*[TArg](t: Thread[TArg]): bool {.inline.} =
proc running*[TArg](t: var Thread[TArg]): bool {.inline.} =
## Returns true if `t` is running.
result = t.dataFn != nil
let dataFn = t.dataFn.load()
result = dataFn != nil

proc handle*[TArg](t: Thread[TArg]): SysThread {.inline.} =
## Returns the thread handle of `t`.
@@ -202,7 +204,7 @@ when false:
else:
discard pthread_cancel(t.sys)
when declared(registerThread): unregisterThread(addr(t))
t.dataFn = nil
t.dataFn.store nil
## if thread `t` already exited, `t.core` will be `null`.
if not isNil(t.core):
deallocThreadStorage(t.core)
@@ -220,7 +222,7 @@ when hostOS == "windows":
t.core = cast[PGcThread](allocThreadStorage(sizeof(GcThread)))

when TArg isnot void: t.data = param
t.dataFn = tp
t.dataFn.store tp
when hasSharedHeap: t.core.stackSize = ThreadStackSize
var dummyThreadId: int32 = 0'i32
t.sys = createThread(nil, ThreadStackSize, threadProcWrapper[TArg],
@@ -245,7 +247,7 @@ elif defined(genode):
t.core = cast[PGcThread](allocThreadStorage(sizeof(GcThread)))

when TArg isnot void: t.data = param
t.dataFn = tp
t.dataFn.store(tp)
when hasSharedHeap: t.stackSize = ThreadStackSize
t.sys.initThread(
runtimeEnv,
@@ -269,7 +271,7 @@ else:
t.core = cast[PGcThread](allocThreadStorage(sizeof(GcThread)))

when TArg isnot void: t.data = param
t.dataFn = tp
t.dataFn.store(tp)
when hasSharedHeap: t.core.stackSize = ThreadStackSize
var a {.noinit.}: Pthread_attr
doAssert pthread_attr_init(a) == 0
16 changes: 10 additions & 6 deletions lib/system/threadimpl.nim
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import std/atomics

var
nimThreadDestructionHandlers* {.rtlThreadVar.}: seq[proc () {.closure, gcsafe, raises: [].}]
when not defined(boehmgc) and not hasSharedHeap and not defined(gogc) and not defined(gcRegions):
@@ -50,10 +52,11 @@ when defined(boehmgc):
boehmGC_register_my_thread(sb)
try:
let thrd = cast[ptr Thread[TArg]](thrd)
let dataFn = thrd.dataFn.load()
when TArg is void:
thrd.dataFn()
dataFn()
else:
thrd.dataFn(thrd.data)
dataFn(thrd.data)
except:
threadTrouble()
finally:
@@ -62,15 +65,16 @@ when defined(boehmgc):
else:
proc threadProcWrapDispatch[TArg](thrd: ptr Thread[TArg]) {.raises: [].} =
try:
let dataFn = thrd.dataFn.load()
when TArg is void:
thrd.dataFn()
dataFn()
else:
when defined(nimV2):
thrd.dataFn(thrd.data)
dataFn(thrd.data)
else:
var x: TArg = default(TArg)
deepCopy(x, thrd.data)
thrd.dataFn(x)
dataFn(x)
except:
threadTrouble()
finally:
@@ -107,5 +111,5 @@ template nimThreadProcWrapperBody*(closure: untyped): untyped =

# mark as not running anymore:
thrd.core = nil
thrd.dataFn = nil
thrd.dataFn.store(nil)
deallocThreadStorage(cast[pointer](core))