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/tarray_of_channels.nim26
-rw-r--r--tests/parallel/tconvexhull.nim2
-rw-r--r--tests/parallel/tdont_be_stupid.nim15
-rw-r--r--tests/parallel/tgc_unsafe.nim32
-rw-r--r--tests/parallel/tgc_unsafe2.nim39
-rw-r--r--tests/parallel/tmissing_deepcopy.nim40
-rw-r--r--tests/parallel/tsimple_array_checks.nim41
-rw-r--r--tests/parallel/twrong_refcounts.nim53
8 files changed, 247 insertions, 1 deletions
diff --git a/tests/parallel/tarray_of_channels.nim b/tests/parallel/tarray_of_channels.nim
new file mode 100644
index 000000000..11b523401
--- /dev/null
+++ b/tests/parallel/tarray_of_channels.nim
@@ -0,0 +1,26 @@
+# bug #2257
+import threadpool
+
+type StringChannel = TChannel[string]
+var channels: array[1..3, StringChannel]
+
+type
+  MyObject[T] = object
+    x: T
+
+var global: MyObject[string]
+var globalB: MyObject[float]
+
+proc consumer(ix : int) {.thread.} =
+  echo channels[ix].recv() ###### not GC-safe: 'channels'
+  echo globalB
+
+proc main =
+  for ix in 1..3: channels[ix].open()
+  for ix in 1..3: spawn consumer(ix)
+  for ix in 1..3: channels[ix].send("test")
+  sync()
+  for ix in 1..3: channels[ix].close()
+
+when isMainModule:
+  main()
diff --git a/tests/parallel/tconvexhull.nim b/tests/parallel/tconvexhull.nim
index d7e4f7716..dffe5339b 100644
--- a/tests/parallel/tconvexhull.nim
+++ b/tests/parallel/tconvexhull.nim
@@ -6,7 +6,7 @@ true
 true
 true'''
 
-ccodeCheck: "!'deepcopy('"
+ccodeCheck: "\\i ! @'deepCopy(' .*"
 """
 
 # parallel convex hull for Nim bigbreak
diff --git a/tests/parallel/tdont_be_stupid.nim b/tests/parallel/tdont_be_stupid.nim
new file mode 100644
index 000000000..a7e82466a
--- /dev/null
+++ b/tests/parallel/tdont_be_stupid.nim
@@ -0,0 +1,15 @@
+
+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/tgc_unsafe.nim b/tests/parallel/tgc_unsafe.nim
new file mode 100644
index 000000000..6548bbec8
--- /dev/null
+++ b/tests/parallel/tgc_unsafe.nim
@@ -0,0 +1,32 @@
+discard """
+  errormsg: "'consumer' is not GC-safe"
+  line: 19
+"""
+
+# bug #2257
+import threadpool
+
+type StringChannel = TChannel[string]
+var channels: array[1..3, StringChannel]
+
+type
+  MyObject[T] = object
+    x: T
+
+var global: MyObject[string]
+var globalB: MyObject[float]
+
+proc consumer(ix : int) {.thread.} =
+  echo channels[ix].recv() ###### not GC-safe: 'channels'
+  echo global
+  echo globalB
+
+proc main =
+  for ix in 1..3: channels[ix].open()
+  for ix in 1..3: spawn consumer(ix)
+  for ix in 1..3: channels[ix].send("test")
+  sync()
+  for ix in 1..3: channels[ix].close()
+
+when isMainModule:
+  main()
diff --git a/tests/parallel/tgc_unsafe2.nim b/tests/parallel/tgc_unsafe2.nim
new file mode 100644
index 000000000..ec4605fe9
--- /dev/null
+++ b/tests/parallel/tgc_unsafe2.nim
@@ -0,0 +1,39 @@
+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'"
+"""
+
+import threadpool
+
+type StringChannel = TChannel[string]
+var channels: array[1..3, StringChannel]
+
+type
+  MyObject[T] = object
+    x: T
+
+var global: MyObject[string]
+var globalB: MyObject[float]
+
+proc trick(ix: int) =
+  echo global.x
+  echo channels[ix].recv()
+
+proc track(ix: int) = trick(ix)
+
+proc consumer(ix: int) {.thread.} =
+  track(ix)
+
+proc main =
+  for ix in 1..3: channels[ix].open()
+  for ix in 1..3: spawn consumer(ix)
+  for ix in 1..3: channels[ix].send("test")
+  sync()
+  for ix in 1..3: channels[ix].close()
+
+when isMainModule:
+  main()
diff --git a/tests/parallel/tmissing_deepcopy.nim b/tests/parallel/tmissing_deepcopy.nim
new file mode 100644
index 000000000..53481e4df
--- /dev/null
+++ b/tests/parallel/tmissing_deepcopy.nim
@@ -0,0 +1,40 @@
+discard """
+  ccodeCheck: "\\i @'deepCopy(' .*"
+"""
+
+# bug #2286
+
+import threadPool
+
+type
+  Person = ref object
+    name: string
+    friend: Person
+
+var
+  people: seq[Person] = @[]
+
+proc newPerson(name:string): Person =
+  result.new()
+  result.name = name
+
+proc greet(p:Person) =
+  p.friend.name &= "-MUT" # this line crashes the program
+  echo "Person {",
+    " name:", p.name, "(", cast[int](addr p.name),"),",
+    " friend:", p.friend.name, "(", cast[int](addr p.friend.name),") }"
+
+proc setup =
+  for i in 0 .. <20:
+    people.add newPerson("Person" & $(i + 1))
+  for i in 0 .. <20:
+    people[i].friend = people[19-i]
+
+proc update =
+  parallel:
+    for i in 0 .. people.high:
+      spawn people[i].greet()
+
+when isMainModule:
+  setup()
+  update()
diff --git a/tests/parallel/tsimple_array_checks.nim b/tests/parallel/tsimple_array_checks.nim
new file mode 100644
index 000000000..9874d3299
--- /dev/null
+++ b/tests/parallel/tsimple_array_checks.nim
@@ -0,0 +1,41 @@
+# bug #2287
+
+import threadPool
+
+# If `nums` is an array instead of seq,
+# NONE of the iteration ways below work (including high / len-1)
+let nums = @[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
+
+proc log(n:int) =
+  echo n
+
+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-1: # WORKS!
+    #for i in 0 .. <nums.len: # WORKS!
+    #  spawn log(nums[i])
+
+# Array needs explicit size to work, probably related to issue #2287
+#const a: array[0..5, int] = [1,2,3,4,5,6]
+
+#const a = [1,2,3,4,5,6] # Doesn't work
+const a = @[1,2,3,4,5,6] # Doesn't work
+proc f(n: int) = echo "Hello ", n
+
+proc maino =
+  parallel:
+    # while loop doesn't work:
+    var i = 0
+    while i < a.high:
+      #for i in countup(0, a.high-1, 2):
+      spawn f(a[i])
+      spawn f(a[i+1])
+      i += 2
+
+maino() # Doesn't work outside a proc
+
+when isMainModule:
+  main()
diff --git a/tests/parallel/twrong_refcounts.nim b/tests/parallel/twrong_refcounts.nim
new file mode 100644
index 000000000..db32a96d8
--- /dev/null
+++ b/tests/parallel/twrong_refcounts.nim
@@ -0,0 +1,53 @@
+discard """
+  output: "Success"
+"""
+
+import math, 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()