Skip to content

Commit

Permalink
make tsan happy with running(thr: Thread): bool
Browse files Browse the repository at this point in the history
  • Loading branch information
elcritch committed Jan 6, 2025
1 parent 8ed0a63 commit e9b54d9
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 13 deletions.
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

Expand Down Expand Up @@ -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
Expand Down
12 changes: 7 additions & 5 deletions lib/std/typedthreads.nim
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ deinitLock(l)

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

import system/ansi_c

Expand Down Expand Up @@ -151,7 +152,8 @@ else:

proc running*[TArg](t: 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`.
Expand Down Expand Up @@ -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)
Expand All @@ -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],
Expand All @@ -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,
Expand All @@ -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
Expand Down
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):
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand Down Expand Up @@ -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))

0 comments on commit e9b54d9

Please sign in to comment.