From 05f8515b0d0aa64c73477af1df721fb171e41b7d Mon Sep 17 00:00:00 2001 From: Araq Date: Wed, 17 Apr 2024 15:03:25 +0200 Subject: [PATCH] added 'activeProducer' feature --- malebolgia.nimble | 10 +++++----- src/malebolgia.nim | 15 +++++++++++---- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/malebolgia.nimble b/malebolgia.nimble index 0007967..97ded92 100644 --- a/malebolgia.nimble +++ b/malebolgia.nimble @@ -1,10 +1,10 @@ # Package -version = "1.3.1" -author = "Araq" -description = "Malebolgia creates new spawns. Experiments with thread pools and related APIs." -license = "MIT" -srcDir = "src" +version = "1.3.2" +author = "Araq" +description = "Malebolgia creates new spawns. Experiments with thread pools and related APIs." +license = "MIT" +srcDir = "src" # Dependencies diff --git a/src/malebolgia.nim b/src/malebolgia.nim index 273309c..c92e9f4 100644 --- a/src/malebolgia.nim +++ b/src/malebolgia.nim @@ -14,7 +14,7 @@ type runningTasks: int stopToken: Atomic[bool] shouldEndAt: Time - usesTimeout: bool + usesTimeout, activeProducer: bool proc `=destroy`(m: var Master) {.inline.} = deinitCond(m.c) @@ -23,13 +23,17 @@ proc `=destroy`(m: var Master) {.inline.} = proc `=copy`(dest: var Master; src: Master) {.error.} proc `=sink`(dest: var Master; src: Master) {.error.} -proc createMaster*(timeout = default(Duration)): Master = +proc createMaster*(timeout = default(Duration); activeProducer = false): Master = + ## Set `activeProducer` to true to prevent the master thread from + ## running a task directly. + ## But beware! This can introduce deadlocks for recursive loads! result = default(Master) initCond(result.c) initLock(result.L) if timeout != default(Duration): result.usesTimeout = true result.shouldEndAt = getTime() + timeout + result.activeProducer = activeProducer proc cancel*(m: var Master) = ## Try to stop all running tasks immediately. @@ -163,9 +167,12 @@ proc panicStop*() = deinitCond(chan.spaceAvailable) deinitLock(chan.L) +proc shouldSend(master: var Master): bool {.inline.} = + master.activeProducer or busyThreads.load(moRelaxed) < ThreadPoolSize-1 + template spawnImplRes[T](master: var Master; fn: typed; res: T) = if stillHaveTime(master): - if busyThreads.load(moRelaxed) < ThreadPoolSize-1: + if shouldSend(master): taskCreated master send PoolTask(m: addr(master), t: toTask(fn), result: addr res) else: @@ -173,7 +180,7 @@ template spawnImplRes[T](master: var Master; fn: typed; res: T) = template spawnImplNoRes(master: var Master; fn: typed) = if stillHaveTime(master): - if busyThreads.load(moRelaxed) < ThreadPoolSize-1: + if shouldSend(master): taskCreated master send PoolTask(m: addr(master), t: toTask(fn), result: nil) else: