From 1a2d4dd1336767f8f0f3390d728ec2f3b6fcca2f Mon Sep 17 00:00:00 2001 From: Jaremy Creechley Date: Tue, 27 Feb 2024 22:07:14 -0700 Subject: [PATCH] more experiments --- tests/exampleGcFailures/exFailureSeqSeq.nim | 26 ++++---- .../exFailureSeqSeqCursor.nim | 63 +++++++++++++++++++ tests/exampleGcFailures/test.nim | 25 ++++++++ 3 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 tests/exampleGcFailures/exFailureSeqSeqCursor.nim create mode 100644 tests/exampleGcFailures/test.nim diff --git a/tests/exampleGcFailures/exFailureSeqSeq.nim b/tests/exampleGcFailures/exFailureSeqSeq.nim index beffd08..599bc81 100644 --- a/tests/exampleGcFailures/exFailureSeqSeq.nim +++ b/tests/exampleGcFailures/exFailureSeqSeq.nim @@ -29,13 +29,14 @@ proc toSeqDataPtr*[T](data: seq[T]): SeqDataPtr[T] = data: cast[ptr UncheckedArray[T]](unsafeAddr(data[0])), size: data.len() ) -proc worker(data: ptr seq[seq[char]], sig: ThreadSignalPtr) = - os.sleep(10) +proc worker(data: seq[seq[char]], sig: ThreadSignalPtr) = + # os.sleep(10) echo "running worker: " - echo "worker: ", data[] - for i, d in data[]: - for j, c in d: - data[i][j] = char(c.uint8 + 10) + echo "worker: ", data + # for i, d in data: + # for j, c in d: + # d[j] = char(c.uint8 + 10) + GC_fullCollect() discard sig.fireSync() proc runTest(tp: TaskPool, sig: ThreadSignalPtr) {.async.} = @@ -45,27 +46,28 @@ proc runTest(tp: TaskPool, sig: ThreadSignalPtr) {.async.} = var data = @[obj1, obj2] # echo "spawn worker" - tp.spawn worker(addr data, sig) + tp.spawn worker(data, sig) ## adding fut.wait(100.milliseconds) creates memory issue - await wait(sig).wait(1.milliseconds) + await wait(sig) ## just doing the wait is fine: # await wait(sig) + echo "data: ", data proc runTests(tp: TaskPool, sig: ThreadSignalPtr) {.async.} = - for i in 1..30_000: + for i in 1..10_000: try: await runTest(tp, sig) except AsyncTimeoutError: # os.sleep(1) # echo "looping..." - # GC_fullCollect() discard + GC_fullCollect() suite "async tests": - var tp = Taskpool.new(num_threads = 2) # Default to the number of hardware threads. + var tp = Taskpool.new(num_threads = 8) # Default to the number of hardware threads. let sig = ThreadSignalPtr.new().get() asyncTest "test": await runTests(tp, sig) - os.sleep(10_000) + # os.sleep(10_000) diff --git a/tests/exampleGcFailures/exFailureSeqSeqCursor.nim b/tests/exampleGcFailures/exFailureSeqSeqCursor.nim new file mode 100644 index 0000000..8b21d99 --- /dev/null +++ b/tests/exampleGcFailures/exFailureSeqSeqCursor.nim @@ -0,0 +1,63 @@ +import std/os +import std/sequtils +import chronos +import chronos/threadsync +import chronos/unittest2/asynctests +import taskpools + +## create a probablistically likely failure of +## using sequence memory from another thread +## with refc. +## +## However, unlike `exFailure.nim`, this can take +## a while to run. +## +## It may not always produce an error either, but +## generally does so in a few seconds of running. +## + +type + SeqCursor* = object + data* {.cursor.}: seq[seq[char]] + +proc worker(data: SeqCursor, sig: ThreadSignalPtr) = + os.sleep(10) + echo "running worker: " + echo "worker: ", data.data + # for i, d in data.data: + # for j, c in d: + # data.data[i][j] = char(c.uint8 + 10) + discard sig.fireSync() + +proc runTest(tp: TaskPool, sig: ThreadSignalPtr) {.async.} = + ## init + var obj1 = "hello world!".toSeq() + var obj2 = "goodbye denver!".toSeq() + var data = @[obj1, obj2] + var cur = SeqCursor(data: data) + + # echo "spawn worker" + tp.spawn worker(cur, sig) + + ## adding fut.wait(100.milliseconds) creates memory issue + await wait(sig) + ## just doing the wait is fine: + # await wait(sig) + +proc runTests(tp: TaskPool, sig: ThreadSignalPtr) {.async.} = + for i in 1..3_000: + try: + await runTest(tp, sig) + except AsyncTimeoutError: + # os.sleep(1) + # echo "looping..." + # GC_fullCollect() + discard + +suite "async tests": + var tp = Taskpool.new(num_threads = 2) # Default to the number of hardware threads. + let sig = ThreadSignalPtr.new().get() + + asyncTest "test": + await runTests(tp, sig) + os.sleep(10_000) diff --git a/tests/exampleGcFailures/test.nim b/tests/exampleGcFailures/test.nim new file mode 100644 index 0000000..91ab044 --- /dev/null +++ b/tests/exampleGcFailures/test.nim @@ -0,0 +1,25 @@ + +when false: + type AnObject* = object of RootObj + value*: int + + proc mutate(a: sink AnObject) = + a.value = 1 + + var obj = AnObject(value: 42) + mutate(obj) + doAssert obj.value == 42 + +else: + type AnObject = object of RootObj + value*: int + + proc `=destroy`(x: var AnObject) = + echo "DEST" + + proc mutate(a: sink AnObject) = + a.value = 1 + + var obj = AnObject(value: 42) + mutate(obj) + doAssert obj.value == 42