discard """ output: ''' Hello from thread Hello from thread Hello from thread Hello from thread ''' cmd: "nim $target --hints:on --threads:on --tlsEmulation:off $options $file" """ # Copied from stdlib import strutils const StackGuardSize = 4096 ThreadStackMask = 1024*256*sizeof(int)-1 ThreadStackSize = ThreadStackMask+1 - StackGuardSize type ThreadFunc = proc() {.thread.} when defined(posix): import posix proc runInForeignThread(f: ThreadFunc) = proc wrapper(p: pointer): pointer {.noconv.} = let thr = cast[ThreadFunc](p) setupForeignThreadGc() thr() tearDownForeignThreadGc() setupForeignThreadGc() thr() tearDownForeignThreadGc() result = nil var attrs {.noinit.}: PthreadAttr doAssert pthread_attr_init(addr attrs) == 0 doAssert pthread_attr_setstacksize(addr attrs, ThreadStackSize) == 0 var tid: Pthread doAssert pthread_create(addr tid, addr attrs, wrapper, f) == 0 doAssert pthread_join(tid, nil) == 0 elif defined(windows): import winlean type WinThreadProc = proc (x: pointer): int32 {.stdcall.} proc createThread(lpThreadAttributes: pointer, dwStackSize: DWORD, lpStartAddress: WinThreadProc, lpParameter: pointer, dwCreationFlags: DWORD, lpThreadId: var DWORD): Handle {. stdcall, dynlib: "kernel32", importc: "CreateThread".} proc wrapper(p: pointer): int32 {.stdcall.} = let thr = cast[ThreadFunc](p) setupForeignThreadGc() thr() tearDownForeignThreadGc() setupForeignThreadGc() thr() tearDownForeignThreadGc() result = 0'i32 proc runInForeignThread(f: ThreadFunc) = var dummyThreadId: DWORD var h = createThread(nil, ThreadStackSize.int32, wrapper.WinThreadProc, cast[pointer](f), 0, dummyThreadId) doAssert h != 0.Handle doAssert waitForSingleObject(h, -1'i32) == 0.DWORD else: {.fatal: "Unknown system".} proc runInNativeThread(f: ThreadFunc) = proc wrapper(f: ThreadFunc) {.thread.} = # These operations must be NOP setupForeignThreadGc() tearDownForeignThreadGc() f() f() var thr: Thread[ThreadFunc] createThread(thr, wrapper, f) joinThread(thr) proc f {.thread.} = var msg = "Hello " & "from thread" echo msg runInForeignThread(f) runInNativeThread(f)