summary refs log tree commit diff stats
path: root/tests/parallel
diff options
context:
space:
mode:
Diffstat (limited to 'tests/parallel')
-rw-r--r--tests/parallel/t10913.nim20
-rw-r--r--tests/parallel/t7535.nim11
-rw-r--r--tests/parallel/t9691.nim9
-rw-r--r--tests/parallel/tarray_of_channels.nim15
-rw-r--r--tests/parallel/tblocking_channel.nim39
-rw-r--r--tests/parallel/tconvexhull.nim26
-rw-r--r--tests/parallel/tdeepcopy.nim61
-rw-r--r--tests/parallel/tdeepcopy2.nim9
-rw-r--r--tests/parallel/tdisjoint_slice1.nim58
-rw-r--r--tests/parallel/tdisjoint_slice2.nim33
-rw-r--r--tests/parallel/tdont_be_stupid.nim15
-rw-r--r--tests/parallel/tflowvar.nim2
-rw-r--r--tests/parallel/tgc_unsafe.nim2
-rw-r--r--tests/parallel/tgc_unsafe2.nim11
-rw-r--r--tests/parallel/tguard1.nim8
-rw-r--r--tests/parallel/tguard2.nim2
-rw-r--r--tests/parallel/tinvalid_array_bounds.nim3
-rw-r--r--tests/parallel/tlet_spawn.nim16
-rw-r--r--tests/parallel/tmissing_deepcopy.nim12
-rw-r--r--tests/parallel/tnon_disjoint_slice1.nim3
-rw-r--r--tests/parallel/tparfind.nim3
-rw-r--r--tests/parallel/tpi.nim5
-rw-r--r--tests/parallel/tptr_to_ref.nim6
-rw-r--r--tests/parallel/tsendtwice.nim65
-rw-r--r--tests/parallel/tsimple_array_checks.nim40
-rw-r--r--tests/parallel/tsysspawn.nim37
-rw-r--r--tests/parallel/tsysspawnbadarg.nim2
-rw-r--r--tests/parallel/tuseafterdef.nim5
-rw-r--r--tests/parallel/twaitany.nim34
-rw-r--r--tests/parallel/twrong_refcounts.nim53
30 files changed, 428 insertions, 177 deletions
diff --git a/tests/parallel/t10913.nim b/tests/parallel/t10913.nim
new file mode 100644
index 000000000..191939100
--- /dev/null
+++ b/tests/parallel/t10913.nim
@@ -0,0 +1,20 @@
+discard """
+  matrix: "--mm:refc; --mm:orc"
+  errormsg: "'spawn'ed function cannot have a 'typed' or 'untyped' parameter"
+"""
+
+# bug #10913
+
+import threadpool
+
+proc useParallel*[T](unused: T) =
+  # use a generic T here to show the problem.
+  {.push experimental: "parallel".}
+  parallel:
+    for i in 0..4:
+      spawn echo "echo in parallel"
+  sync()
+  
+  {.pop.}
+
+useParallel(1)
diff --git a/tests/parallel/t7535.nim b/tests/parallel/t7535.nim
new file mode 100644
index 000000000..7817a1c9e
--- /dev/null
+++ b/tests/parallel/t7535.nim
@@ -0,0 +1,11 @@
+discard """
+  matrix: "--mm:refc; --mm:orc"
+  errormsg: "'spawn' takes a call expression; got: proc (x: uint32) = echo [x]"
+"""
+
+import threadpool
+
+# bug #7535
+proc print_parallel_nok(r: uint32) =
+  for x in 0..r:
+    spawn (proc (x: uint32) = echo x)
diff --git a/tests/parallel/t9691.nim b/tests/parallel/t9691.nim
new file mode 100644
index 000000000..254f03416
--- /dev/null
+++ b/tests/parallel/t9691.nim
@@ -0,0 +1,9 @@
+discard """
+  matrix: "--mm:refc; --mm:orc"
+  errormsg: "'spawn'ed function cannot have a 'typed' or 'untyped' parameter"
+"""
+
+# bug #9691
+
+import threadpool
+spawn echo()
diff --git a/tests/parallel/tarray_of_channels.nim b/tests/parallel/tarray_of_channels.nim
index 90ae8369c..9479227aa 100644
--- a/tests/parallel/tarray_of_channels.nim
+++ b/tests/parallel/tarray_of_channels.nim
@@ -1,3 +1,16 @@
+discard """
+sortoutput: true
+output: '''
+(x: 0.0)
+(x: 0.0)
+(x: 0.0)
+test
+test
+test
+'''
+disabled: "openbsd"
+"""
+
 # bug #2257
 import threadpool
 
@@ -22,5 +35,5 @@ proc main =
   sync()
   for ix in 1..3: channels[ix].close()
 
-when isMainModule:
+when true:
   main()
diff --git a/tests/parallel/tblocking_channel.nim b/tests/parallel/tblocking_channel.nim
new file mode 100644
index 000000000..f3ccd166a
--- /dev/null
+++ b/tests/parallel/tblocking_channel.nim
@@ -0,0 +1,39 @@
+discard """
+output: ""
+disabled: "freebsd" # see #15725
+"""
+
+import threadpool, os
+
+var chan: Channel[int]
+
+chan.open(2)
+chan.send(1)
+chan.send(2)
+doAssert(not chan.trySend(3)) # At this point chan is at max capacity
+
+proc receiver() =
+    doAssert(chan.recv() == 1)
+    doAssert(chan.recv() == 2)
+    doAssert(chan.recv() == 3)
+    doAssert(chan.recv() == 4)
+    doAssert(chan.recv() == 5)
+
+var msgSent = false
+
+proc emitter() =
+    chan.send(3)
+    msgSent = true
+
+spawn emitter()
+# At this point emitter should be stuck in `send`
+sleep(50) # Sleep a bit to ensure that it is still stuck
+doAssert(not msgSent)
+
+spawn receiver()
+sleep(50) # Sleep a bit to let receicer consume the messages
+doAssert(msgSent) # Sender should be unblocked
+
+doAssert(chan.trySend(4))
+chan.send(5)
+sync()
diff --git a/tests/parallel/tconvexhull.nim b/tests/parallel/tconvexhull.nim
index dffe5339b..a89aa910b 100644
--- a/tests/parallel/tconvexhull.nim
+++ b/tests/parallel/tconvexhull.nim
@@ -1,12 +1,7 @@
 discard """
-  output: '''true
-true
-true
-true
-true
-true'''
-
-ccodeCheck: "\\i ! @'deepCopy(' .*"
+  matrix: "--mm:refc"
+  output: '''
+'''
 """
 
 # parallel convex hull for Nim bigbreak
@@ -20,10 +15,10 @@ proc cmpPoint(a, b: Point): int =
   if result == 0:
     result = cmp(a.y, b.y)
 
-template cross[T](o, a, b: T): expr =
+template cross[T](o, a, b: T): untyped =
   (a.x - o.x) * (b.y - o.y) - (a.y - o.y) * (b.x - o.x)
 
-template pro(): expr =
+template pro(): untyped =
   while lr1 > 0 and cross(result[lr1 - 1], result[lr1], p[i]) <= 0:
     discard result.pop
     lr1 -= 1
@@ -55,10 +50,11 @@ proc convex_hull[T](points: var seq[T], cmp: proc(x, y: T): int {.closure.}) : s
       ul[k] = spawn half[T](points, k == 0)
   result = concat(^ul[0], ^ul[1])
 
-var s = map(toSeq(0..999999), proc(x: int): Point = (float(x div 1000), float(x mod 1000)))
+var s = map(toSeq(0..9999), proc(x: int): Point = (float(x div 100), float(x mod 100)))
+# On some runs, this pool size reduction will set the "shutdown" attribute on the
+# worker thread that executes our spawned task, before we can read the flowvars.
 setMaxPoolSize 2
 
-#echo convex_hull[Point](s, cmpPoint)
-for i in 0..5:
-  echo convex_hull[Point](s, cmpPoint) ==
-      @[(0.0, 0.0), (999.0, 0.0), (999.0, 999.0), (0.0, 999.0)]
+for i in 0..2:
+  doAssert convex_hull[Point](s, cmpPoint) ==
+      @[(0.0, 0.0), (99.0, 0.0), (99.0, 99.0), (0.0, 99.0)]
diff --git a/tests/parallel/tdeepcopy.nim b/tests/parallel/tdeepcopy.nim
index 84e2edf3f..96ca15ca3 100644
--- a/tests/parallel/tdeepcopy.nim
+++ b/tests/parallel/tdeepcopy.nim
@@ -1,18 +1,55 @@
 discard """
-  output: '''13 abc'''
+  matrix: "--mm:refc"
+  output: '''
+13 abc
+called deepCopy for int
+called deepCopy for int
+done999 999
+'''
 """
 
-type
-  PBinaryTree = ref object
-    le, ri: PBinaryTree
-    value: int
+import threadpool
 
+block one:
+  type
+    PBinaryTree = ref object
+      le, ri: PBinaryTree
+      value: int
 
-proc main =
-  var x: PBinaryTree
-  deepCopy(x, PBinaryTree(ri: PBinaryTree(le: PBinaryTree(value: 13))))
-  var y: string
-  deepCopy y, "abc"
-  echo x.ri.le.value, " ", y
+  proc main =
+    var x: PBinaryTree
+    deepCopy(x, PBinaryTree(ri: PBinaryTree(le: PBinaryTree(value: 13))))
+    var y: string
+    deepCopy y, "abc"
+    echo x.ri.le.value, " ", y
 
-main()
+  main()
+
+
+block two:
+  type
+    Bar[T] = object
+      x: T
+
+  proc `=deepCopy`[T](b: ref Bar[T]): ref Bar[T] =
+    result.new
+    result.x = b.x
+    when T is int:
+      echo "called deepCopy for int"
+    else:
+      echo "called deepCopy for something else"
+
+  proc foo(b: ref Bar[int]): int = 999
+
+# test that the disjoint checker deals with 'a = spawn f(); g = spawn f()':
+
+  proc main =
+    var dummy: ref Bar[int]
+    new(dummy)
+    dummy.x = 44
+    #parallel:
+    let f = spawn foo(dummy)
+    let b = spawn foo(dummy)
+    echo "done", ^f, " ", ^b
+
+  main()
diff --git a/tests/parallel/tdeepcopy2.nim b/tests/parallel/tdeepcopy2.nim
index 8ffdcc5f2..e8305173d 100644
--- a/tests/parallel/tdeepcopy2.nim
+++ b/tests/parallel/tdeepcopy2.nim
@@ -1,7 +1,10 @@
 discard """
-  output: '''called deepCopy for int
+  matrix: "--mm:refc"
+  output: '''
 called deepCopy for int
-done999 999'''
+called deepCopy for int
+done999 999
+'''
 """
 
 import threadpool
@@ -11,7 +14,7 @@ type
   Bar[T] = object
     x: T
 
-proc deepCopy[T](b: ref Bar[T]): ref Bar[T] {.override.} =
+proc `=deepCopy`[T](b: ref Bar[T]): ref Bar[T] =
   result.new
   result.x = b.x
   when T is int:
diff --git a/tests/parallel/tdisjoint_slice1.nim b/tests/parallel/tdisjoint_slice1.nim
index c1d0e52f8..6892e7383 100644
--- a/tests/parallel/tdisjoint_slice1.nim
+++ b/tests/parallel/tdisjoint_slice1.nim
@@ -1,21 +1,51 @@
 discard """
+  matrix: "--mm:refc"
   outputsub: "EVEN 28"
 """
 
-import threadpool
+import threadpool, locks
 
-proc odd(a: int) =  echo "ODD  ", a
-proc even(a: int) = echo "EVEN ", a
+block one:
+  proc odd(a: int) =  echo "ODD  ", a
+  proc even(a: int) = echo "EVEN ", a
 
-proc main() =
-  var a: array[0..30, int]
-  for i in low(a)..high(a): a[i] = i
-  parallel:
-    var i = 0
-    while i <= 29:
-      spawn even(a[i])
-      spawn odd(a[i+1])
-      inc i, 2
-      # is correct here
+  proc main() =
+    var a: array[0..30, int]
+    for i in low(a)..high(a): a[i] = i
+    parallel:
+      var i = 0
+      while i <= 29:
+        spawn even(a[i])
+        spawn odd(a[i+1])
+        inc i, 2
+        # is correct here
 
-main()
+  main()
+
+
+block two:
+  var echoLock: Lock
+  initLock echoLock
+
+  proc f(a: openArray[int]) =
+    for x in a:
+      withLock echoLock:
+        echo x
+
+  proc f(a: int) =
+    withLock echoLock:
+      echo a
+
+  proc main() =
+    var a: array[0..9, int] = [0,1,2,3,4,5,6,7,8,9]
+    parallel:
+      spawn f(a[0..2])
+      #spawn f(a[16..30])
+      var i = 3
+      while i <= 8:
+        spawn f(a[i])
+        spawn f(a[i+1])
+        inc i, 2
+        # is correct here
+
+  main()
diff --git a/tests/parallel/tdisjoint_slice2.nim b/tests/parallel/tdisjoint_slice2.nim
deleted file mode 100644
index 1e86ea644..000000000
--- a/tests/parallel/tdisjoint_slice2.nim
+++ /dev/null
@@ -1,33 +0,0 @@
-discard """
-  output: '''0
-1
-2
-3
-4
-5
-6
-7
-8'''
-  sortoutput: true
-"""
-
-import threadpool
-
-proc f(a: openArray[int]) =
-  for x in a: echo x
-
-proc f(a: int) = echo a
-
-proc main() =
-  var a: array[0..9, int] = [0,1,2,3,4,5,6,7,8,9]
-  parallel:
-    spawn f(a[0..2])
-    #spawn f(a[16..30])
-    var i = 3
-    while i <= 8:
-      spawn f(a[i])
-      spawn f(a[i+1])
-      inc i, 2
-      # is correct here
-
-main()
diff --git a/tests/parallel/tdont_be_stupid.nim b/tests/parallel/tdont_be_stupid.nim
deleted file mode 100644
index a7e82466a..000000000
--- a/tests/parallel/tdont_be_stupid.nim
+++ /dev/null
@@ -1,15 +0,0 @@
-
-import threadpool, os
-
-proc single(time: int) =
-  sleep time
-  echo time
-
-proc sleepsort(nums: openArray[int]) =
-  parallel:
-    var i = 0
-    while i <= len(nums) + -1:
-      spawn single(nums[i])
-      i += 1
-
-sleepsort([50,3,40,25])
diff --git a/tests/parallel/tflowvar.nim b/tests/parallel/tflowvar.nim
index fd3aa326e..e44b29a87 100644
--- a/tests/parallel/tflowvar.nim
+++ b/tests/parallel/tflowvar.nim
@@ -1,9 +1,11 @@
 discard """
+  matrix: "--mm:refc"
   output: '''foobarfoobar
 bazbearbazbear
 
 1'''
   cmd: "nim $target --threads:on $options $file"
+  disabled: "openbsd"
 """
 
 import threadpool
diff --git a/tests/parallel/tgc_unsafe.nim b/tests/parallel/tgc_unsafe.nim
index a4d96cd73..baf0dc24a 100644
--- a/tests/parallel/tgc_unsafe.nim
+++ b/tests/parallel/tgc_unsafe.nim
@@ -28,5 +28,5 @@ proc main =
   sync()
   for ix in 1..3: channels[ix].close()
 
-when isMainModule:
+when true:
   main()
diff --git a/tests/parallel/tgc_unsafe2.nim b/tests/parallel/tgc_unsafe2.nim
index 4a5f36f6d..7d98dafcb 100644
--- a/tests/parallel/tgc_unsafe2.nim
+++ b/tests/parallel/tgc_unsafe2.nim
@@ -1,10 +1,9 @@
 discard """
-  line: 28
-  nimout: '''tgc_unsafe2.nim(22, 5) Warning: 'trick' is not GC-safe as it accesses 'global' which is a global using GC'ed memory
-tgc_unsafe2.nim(26, 5) Warning: 'track' is not GC-safe as it calls 'trick'
-tgc_unsafe2.nim(28, 5) Error: 'consumer' is not GC-safe as it calls 'track'
-'''
   errormsg: "'consumer' is not GC-safe as it calls 'track'"
+  nimout: '''tgc_unsafe2.nim(21, 6) Warning: 'trick' is not GC-safe as it accesses 'global' which is a global using GC'ed memory [GcUnsafe2]
+tgc_unsafe2.nim(25, 6) Warning: 'track' is not GC-safe as it calls 'trick' [GcUnsafe2]
+tgc_unsafe2.nim(27, 6) Error: 'consumer' is not GC-safe as it calls 'track'
+'''
 """
 
 import threadpool
@@ -35,5 +34,5 @@ proc main =
   sync()
   for ix in 1..3: channels[ix].close()
 
-when isMainModule:
+when true:
   main()
diff --git a/tests/parallel/tguard1.nim b/tests/parallel/tguard1.nim
index 3e0c131c5..f4c92319b 100644
--- a/tests/parallel/tguard1.nim
+++ b/tests/parallel/tguard1.nim
@@ -1,7 +1,11 @@
+discard """
+output: "90"
+"""
+
 
 when false:
   template lock(a, b: ptr Lock; body: stmt) =
-    if cast[ByteAddress](a) < cast[ByteAddress](b):
+    if cast[int](a) < cast[int](b):
       pthread_mutex_lock(a)
       pthread_mutex_lock(b)
     else:
@@ -24,7 +28,7 @@ var
 
 c.i = 89
 
-template atomicRead(L, x): expr =
+template atomicRead(L, x): untyped =
   {.locks: [L].}:
     x
 
diff --git a/tests/parallel/tguard2.nim b/tests/parallel/tguard2.nim
index b69ea3371..661893bb5 100644
--- a/tests/parallel/tguard2.nim
+++ b/tests/parallel/tguard2.nim
@@ -13,7 +13,7 @@ var
 
 c.i = 89
 
-template atomicRead(L, x): expr =
+template atomicRead(L, x): untyped =
   {.locks: [L].}:
     x
 
diff --git a/tests/parallel/tinvalid_array_bounds.nim b/tests/parallel/tinvalid_array_bounds.nim
index 4c6065fd6..8dc93c33f 100644
--- a/tests/parallel/tinvalid_array_bounds.nim
+++ b/tests/parallel/tinvalid_array_bounds.nim
@@ -1,5 +1,6 @@
 discard """
-  errormsg: "can prove: i + 1 > 30"
+  matrix: "--mm:refc"
+  errormsg: "cannot prove (i)..(i) disjoint from (i + 1)..(i + 1)"
   line: 21
 """
 
diff --git a/tests/parallel/tlet_spawn.nim b/tests/parallel/tlet_spawn.nim
index 463ee1a47..853ffc443 100644
--- a/tests/parallel/tlet_spawn.nim
+++ b/tests/parallel/tlet_spawn.nim
@@ -1,5 +1,10 @@
+discard """
+output: '''
+done999 999
+'''
+"""
 
-import threadpool
+import std/[threadpool, os]
 
 proc foo(): int = 999
 
@@ -12,3 +17,12 @@ proc main =
   echo "done", f, " ", b
 
 main()
+
+# bug #13781
+proc thread(): string =
+  os.sleep(1000)
+  return "ok"
+
+var fv = spawn thread()
+sync()
+doAssert ^fv == "ok"
diff --git a/tests/parallel/tmissing_deepcopy.nim b/tests/parallel/tmissing_deepcopy.nim
index 53481e4df..ea77936ad 100644
--- a/tests/parallel/tmissing_deepcopy.nim
+++ b/tests/parallel/tmissing_deepcopy.nim
@@ -1,5 +1,7 @@
 discard """
-  ccodeCheck: "\\i @'deepCopy(' .*"
+  matrix: "--mm:refc"
+  ccodeCheck: "@'genericDeepCopy(' .*"
+  action: compile
 """
 
 # bug #2286
@@ -25,16 +27,16 @@ proc greet(p:Person) =
     " friend:", p.friend.name, "(", cast[int](addr p.friend.name),") }"
 
 proc setup =
-  for i in 0 .. <20:
+  for i in 0 ..< 10:
     people.add newPerson("Person" & $(i + 1))
-  for i in 0 .. <20:
-    people[i].friend = people[19-i]
+  for i in 0 ..< 10:
+    people[i].friend = people[9-i]
 
 proc update =
   parallel:
     for i in 0 .. people.high:
       spawn people[i].greet()
 
-when isMainModule:
+when true:
   setup()
   update()
diff --git a/tests/parallel/tnon_disjoint_slice1.nim b/tests/parallel/tnon_disjoint_slice1.nim
index 72d008bbd..51762187d 100644
--- a/tests/parallel/tnon_disjoint_slice1.nim
+++ b/tests/parallel/tnon_disjoint_slice1.nim
@@ -1,6 +1,7 @@
 discard """
+  matrix: "--mm:refc"
   errormsg: "cannot prove (i)..(i) disjoint from (i + 1)..(i + 1)"
-  line: 20
+  line: 21
 """
 
 import threadpool
diff --git a/tests/parallel/tparfind.nim b/tests/parallel/tparfind.nim
index 9de5012f5..cf1bc9336 100644
--- a/tests/parallel/tparfind.nim
+++ b/tests/parallel/tparfind.nim
@@ -1,10 +1,11 @@
 discard """
+  matrix: "--mm:refc"
   output: "500"
 """
 
 import threadpool, sequtils
 
-{.experimental.}
+{.experimental: "parallel".}
 
 proc linearFind(a: openArray[int]; x, offset: int): int =
   for i, y in a:
diff --git a/tests/parallel/tpi.nim b/tests/parallel/tpi.nim
index dcb9b8fc5..cd965d585 100644
--- a/tests/parallel/tpi.nim
+++ b/tests/parallel/tpi.nim
@@ -1,4 +1,5 @@
 discard """
+  matrix: "--mm:refc"
   output: '''3.141792613595791
 3.141792613595791'''
 """
@@ -9,9 +10,9 @@ proc term(k: float): float = 4 * math.pow(-1, k) / (2*k + 1)
 
 proc piU(n: int): float =
   var ch = newSeq[FlowVar[float]](n+1)
-  for k in 0..n:
+  for k in 0..ch.high:
     ch[k] = spawn term(float(k))
-  for k in 0..n:
+  for k in 0..ch.high:
     result += ^ch[k]
 
 proc piS(n: int): float =
diff --git a/tests/parallel/tptr_to_ref.nim b/tests/parallel/tptr_to_ref.nim
index 229c247ce..ae02c16e5 100644
--- a/tests/parallel/tptr_to_ref.nim
+++ b/tests/parallel/tptr_to_ref.nim
@@ -11,10 +11,10 @@ type
   Killer* = object
     lock:                      Lock
     bailed    {.guard: lock.}: bool
-    processes {.guard: lock.}: array[0..MAX_WORKERS-1, foreign ptr Process]
+    processes {.guard: lock.}: array[0..MAX_WORKERS-1, ptr Process]
 
 # Hold a lock for a statement.
-template hold(lock: Lock, body: stmt) =
+template hold(lock: Lock, body: untyped) =
   lock.acquire
   defer: lock.release
   {.locks: [lock].}:
@@ -32,7 +32,7 @@ proc initKiller*(): Killer =
 var killer = initKiller()
 
 # remember that a process has been launched, killing it if we have bailed.
-proc launched*(process: foreign ptr Process): int {.gcsafe.} =
+proc launched*(process: ptr Process): int {.gcsafe.} =
   result = killer.processes.high + 1
   killer.lock.hold:
     if killer.bailed:
diff --git a/tests/parallel/tsendtwice.nim b/tests/parallel/tsendtwice.nim
new file mode 100644
index 000000000..9f4a2e06e
--- /dev/null
+++ b/tests/parallel/tsendtwice.nim
@@ -0,0 +1,65 @@
+discard """
+  matrix: "--mm:refc"
+"""
+
+# bug #4776
+
+import tables, algorithm
+
+type
+  Base* = ref object of RootObj
+    someSeq: seq[int]
+    baseData: array[40000, byte]
+  Derived* = ref object of Base
+    data: array[40000, byte]
+
+type
+  ThreadPool = ref object
+    threads: seq[ptr Thread[ThreadArg]]
+    channels: seq[ThreadArg]
+  TableChannel = Channel[TableRef[string, Base]]
+  ThreadArg = ptr TableChannel
+
+var globalTable {.threadvar.}: TableRef[string, Base]
+globalTable = newTable[string, Base]()
+let d = new(Derived)
+globalTable.add("ob", d)
+globalTable.add("ob2", d)
+globalTable.add("ob3", d)
+
+proc `<`(x, y: seq[int]): bool = x.len < y.len
+proc kvs(t: TableRef[string, Base]): seq[(string, seq[int])] =
+  for k, v in t.pairs: result.add (k, v.someSeq)
+  result.sort
+
+proc testThread(channel: ptr TableChannel) {.thread.} =
+  globalTable = channel[].recv()
+  var myObj: Base
+  deepCopy(myObj, globalTable["ob"])
+  myObj.someSeq = newSeq[int](100)
+  let table = channel[].recv() # same table
+  assert(table.contains("ob")) # fails!
+  assert(table.contains("ob2")) # fails!
+  assert(table.contains("ob3")) # fails!
+  assert table.kvs == globalTable.kvs # Last to see above spot checks first
+
+var channel: TableChannel
+
+proc newThreadPool(threadCount: int) = #: ThreadPool =
+  #new(result)
+  #result.threads = newSeq[ptr Thread[ThreadArg]](threadCount)
+  #var channel = cast[ptr TableChannel](allocShared0(sizeof(TableChannel)))
+  channel.open()
+  channel.send(globalTable)
+  channel.send(globalTable)
+  #createThread(threadPtr[], testThread, addr channel)
+  testThread(addr channel)
+  #result.threads[i] = threadPtr
+
+proc stop(p: ThreadPool) =
+  for t in p.threads:
+    joinThread(t[])
+    dealloc(t)
+
+
+newThreadPool(1)#.stop()
diff --git a/tests/parallel/tsimple_array_checks.nim b/tests/parallel/tsimple_array_checks.nim
index 9874d3299..ab292f935 100644
--- a/tests/parallel/tsimple_array_checks.nim
+++ b/tests/parallel/tsimple_array_checks.nim
@@ -1,3 +1,25 @@
+discard """
+sortoutput: true
+output: '''
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+Hello 1
+Hello 2
+Hello 3
+Hello 4
+Hello 5
+Hello 6
+'''
+"""
+
 # bug #2287
 
 import threadPool
@@ -13,9 +35,9 @@ proc main =
   parallel:
     for n in nums: # Error: cannot prove: i <= len(nums) + -1
       spawn log(n)
-    #for i in 0 .. <nums.len: # Error: cannot prove: i <= len(nums) + -1
+    #for i in 0 ..< nums.len: # Error: cannot prove: i <= len(nums) + -1
     #for i in 0 .. nums.len-1: # WORKS!
-    #for i in 0 .. <nums.len: # WORKS!
+    #for i in 0 ..< nums.len: # WORKS!
     #  spawn log(nums[i])
 
 # Array needs explicit size to work, probably related to issue #2287
@@ -37,5 +59,17 @@ proc maino =
 
 maino() # Doesn't work outside a proc
 
-when isMainModule:
+when true:
   main()
+
+block two:
+  proc f(a: openArray[int]) =
+    discard
+
+  proc main() =
+    var a: array[0..9, int] = [0,1,2,3,4,5,6,7,8,9]
+    parallel:
+      spawn f(a[0..2])
+
+
+  main()
\ No newline at end of file
diff --git a/tests/parallel/tsysspawn.nim b/tests/parallel/tsysspawn.nim
index 7244a5ee6..b7ecd1264 100644
--- a/tests/parallel/tsysspawn.nim
+++ b/tests/parallel/tsysspawn.nim
@@ -1,7 +1,11 @@
 discard """
   output: '''4
-8'''
-  cmd: "nim $target --threads:on $options $file"
+8
+(a: 1)
+2
+2
+'''
+  matrix: "--mm:refc"
 """
 
 import threadpool
@@ -29,3 +33,32 @@ sync()
 
 echo x
 echo y
+
+
+#--------------------------------------------------------
+# issue #14014
+
+import threadpool
+
+type A = object
+    a: int
+
+proc f(t: typedesc): t =
+  t(a:1)
+
+let r = spawn f(A)
+echo ^r
+
+proc f2(x: static[int]): int =
+  x
+
+let r2 = spawn f2(2)
+echo ^r2
+
+type statint = static[int]
+
+proc f3(x: statint): int =
+  x
+
+let r3 = spawn f3(2)
+echo ^r3
diff --git a/tests/parallel/tsysspawnbadarg.nim b/tests/parallel/tsysspawnbadarg.nim
index 2d3ffd241..a8f1ed401 100644
--- a/tests/parallel/tsysspawnbadarg.nim
+++ b/tests/parallel/tsysspawnbadarg.nim
@@ -1,6 +1,6 @@
 discard """
-  line: 9
   errormsg: "'spawn' takes a call expression"
+  line: 9
   cmd: "nim $target --threads:on $options $file"
 """
 
diff --git a/tests/parallel/tuseafterdef.nim b/tests/parallel/tuseafterdef.nim
index 833c72a0a..64f835a1b 100644
--- a/tests/parallel/tuseafterdef.nim
+++ b/tests/parallel/tuseafterdef.nim
@@ -1,6 +1,9 @@
 discard """
+  matrix: "--mm:refc"
+  disabled: true
   errormsg: "(k)..(k) not disjoint from (k)..(k)"
-  line: 23
+  line: 24
+  action: compile
 """
 
 # bug #1597
diff --git a/tests/parallel/twaitany.nim b/tests/parallel/twaitany.nim
new file mode 100644
index 000000000..d57c5f40f
--- /dev/null
+++ b/tests/parallel/twaitany.nim
@@ -0,0 +1,34 @@
+discard """
+  matrix: "--mm:refc"
+  output: '''true'''
+"""
+
+# bug #7638
+import threadpool, os
+
+proc timer(d: int): int =
+  #echo fmt"sleeping {d}"
+  sleep(d)
+  #echo fmt"done {d}"
+  return d
+
+var durations = [1000, 1500, 2000]
+var tasks: seq[FlowVarBase] = @[]
+var results: seq[int] = @[]
+
+for i in 0 .. durations.high:
+  tasks.add spawn timer(durations[i])
+
+var index = blockUntilAny(tasks)
+while index != -1:
+  results.add ^cast[FlowVar[int]](tasks[index])
+  tasks.del(index)
+  #echo repr results
+  index = blockUntilAny(tasks)
+
+doAssert results.len == 3
+doAssert 1000 in results
+doAssert 1500 in results
+doAssert 2000 in results
+sync()
+echo "true"
diff --git a/tests/parallel/twrong_refcounts.nim b/tests/parallel/twrong_refcounts.nim
deleted file mode 100644
index 57e0588a0..000000000
--- a/tests/parallel/twrong_refcounts.nim
+++ /dev/null
@@ -1,53 +0,0 @@
-discard """
-  output: "Success"
-"""
-
-import math, random, threadPool
-
-# ---
-
-type
-  Person = object
-    age: int
-    friend: ref Person
-
-var
-  people: seq[ref Person] = @[]
-
-proc newPerson(age:int): ref Person =
-  result.new()
-  result.age = age
-
-proc greet(p:Person) =
-  #echo p.age, ", ", p.friend.age
-  p.friend.age += 1
-
-# ---
-
-proc setup =
-  for i in 0 .. <20:
-    people.add newPerson(i + 1)
-  for i in 0 .. <20:
-    people[i].friend = people[random(20)]
-
-proc update =
-  var countA: array[20, int]
-  var countB: array[20, int]
-
-  for i, p in people:
-    countA[i] = getRefCount(p)
-  parallel:
-    for i in 0 .. people.high:
-      spawn greet(people[i][])
-  for i, p in people:
-    countB[i] = getRefCount(p)
-
-  for i in 0 .. <20:
-    doAssert countA[i] == countB[i]
-  echo "Success"
-
-# ---
-
-when isMainModule:
-  setup()
-  update()