Created
March 18, 2017 21:34
-
-
Save cheatfate/2b53411b12e5c52c1088683babd0828f to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
when hostOS == "windows": | |
const | |
MAXIMUM_WAIT_OBJECTS = 64 | |
MAXIMUM_WAIT_THREADS = MAXIMUM_WAIT_OBJECTS * MAXIMUM_WAIT_OBJECTS | |
type | |
WaitChunk = object | |
events: array[MAXIMUM_WAIT_OBJECTS, SysThread] | |
count: int | |
proc createThread*[TArg](t: var Thread[TArg], | |
tp: proc (arg: TArg) {.thread, nimcall.}, | |
param: TArg) | |
proc threadWait(chunk: WaitChunk) {.thread.} = | |
echo "threadWait(" & $chunk.count & ")" | |
discard waitForMultipleObjects(int32(chunk.count), | |
cast[ptr SysThread](unsafeAddr chunk.events[0]), | |
1, -1); | |
proc joinThread*[TArg](t: Thread[TArg]) {.inline.} = | |
## waits for the thread `t` to finish. | |
discard waitForSingleObject(t.sys, -1'i32) | |
proc joinThreads*[TArg](t: varargs[Thread[TArg]]) = | |
## waits for every thread in `t` to finish. | |
sysAssert(len(t) <= MAXIMUM_WAIT_THREADS, | |
"Maximum number of threads reached") | |
if len(t) > MAXIMUM_WAIT_OBJECTS: | |
var count = 0 | |
var thrs: array[MAXIMUM_WAIT_OBJECTS, SysThread] | |
var thread: Thread[WaitChunk] | |
var s = 0 | |
var chunk = WaitChunk() | |
while true: | |
var e = min(t.len, s + MAXIMUM_WAIT_OBJECTS) | |
var k = 0 | |
echo "s = " & $s | |
echo "e = " & $e | |
for i in s..(e - 1): | |
echo "put " & $i & " thread " & $t[i].sys & " to wait chunk" | |
chunk.events[k] = t[i].sys | |
inc(k) | |
chunk.count = k | |
echo "running wait thread with " & $chunk.count & " events" | |
createThread(thread, threadWait, chunk) | |
thrs[count] = thread.sys | |
inc(count) | |
if e == t.len: break | |
inc(s, MAXIMUM_WAIT_OBJECTS) | |
echo "wait for " & $count & " threads..." | |
echo repr thrs | |
discard waitForMultipleObjects(int32(count), | |
cast[ptr SysThread](addr thrs[0]), | |
1, -1) | |
echo "wait completed!" | |
else: | |
var a: array[MAXIMUM_WAIT_OBJECTS, SysThread] | |
for i in 0..t.high: a[i] = t[i].sys | |
discard waitForMultipleObjects(t.len.int32, | |
cast[ptr SysThread](addr(a)), 1, -1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment