summary refs log tree commit diff stats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rwxr-xr-xlib/core/typeinfo.nim16
-rw-r--r--lib/pure/actors.nim45
-rwxr-xr-xlib/pure/parsecfg.nim1
-rwxr-xr-xlib/system/threads.nim8
4 files changed, 39 insertions, 31 deletions
diff --git a/lib/core/typeinfo.nim b/lib/core/typeinfo.nim
index 32042695d..b5e9e1a0f 100755
--- a/lib/core/typeinfo.nim
+++ b/lib/core/typeinfo.nim
@@ -104,13 +104,17 @@ proc toAny*[T](x: var T): TAny {.inline.} =
 proc kind*(x: TAny): TAnyKind {.inline.} = 
   ## get the type kind
   result = TAnyKind(ord(x.rawType.kind))
+
+proc size*(x: TAny): int {.inline.} =
+  ## returns the size of `x`'s type.
+  result = x.rawType.size
   
 proc baseTypeKind*(x: TAny): TAnyKind {.inline.} = 
   ## get the base type's kind; ``akNone`` is returned if `x` has no base type.
   if x.rawType.base != nil:
     result = TAnyKind(ord(x.rawType.base.kind))
 
-proc baseTypeSize*(x: TAny): int =
+proc baseTypeSize*(x: TAny): int {.inline.} =
   ## returns the size of `x`'s basetype.
   if x.rawType.base != nil:
     result = x.rawType.base.size
@@ -339,8 +343,8 @@ proc getInt64*(x: TAny): int64 =
 
 proc getBiggestInt*(x: TAny): biggestInt =
   ## retrieve the integer value out of `x`. `x` needs to represent
-  ## some integer, a bool, a char or an enum. The value might be
-  ## sign-extended to ``biggestInt``.
+  ## some integer, a bool, a char, an enum or a small enough bit set.
+  ## The value might be sign-extended to ``biggestInt``.
   var t = skipRange(x.rawtype)
   case t.kind
   of tyInt: result = biggestInt(cast[ptr int](x.value)[])
@@ -350,7 +354,7 @@ proc getBiggestInt*(x: TAny): biggestInt =
   of tyInt64: result = biggestInt(cast[ptr int64](x.value)[])
   of tyBool: result = biggestInt(cast[ptr bool](x.value)[])
   of tyChar: result = biggestInt(cast[ptr char](x.value)[])
-  of tyEnum:
+  of tyEnum, tySet:
     case t.size
     of 1: result = ze64(cast[ptr int8](x.value)[])
     of 2: result = ze64(cast[ptr int16](x.value)[])
@@ -361,7 +365,7 @@ proc getBiggestInt*(x: TAny): biggestInt =
 
 proc setBiggestInt*(x: TAny, y: biggestInt) =
   ## sets the integer value of `x`. `x` needs to represent
-  ## some integer, a bool, a char or an enum.
+  ## some integer, a bool, a char, an enum or a small enough bit set.
   var t = skipRange(x.rawtype)
   case t.kind
   of tyInt: cast[ptr int](x.value)[] = int(y)
@@ -371,7 +375,7 @@ proc setBiggestInt*(x: TAny, y: biggestInt) =
   of tyInt64: cast[ptr int64](x.value)[] = int64(y)
   of tyBool: cast[ptr bool](x.value)[] = y != 0
   of tyChar: cast[ptr char](x.value)[] = chr(y.int)
-  of tyEnum:
+  of tyEnum, tySet:
     case t.size
     of 1: cast[ptr int8](x.value)[] = toU8(y.int)
     of 2: cast[ptr int16](x.value)[] = toU16(y.int)
diff --git a/lib/pure/actors.nim b/lib/pure/actors.nim
index 285e3241d..4576cb602 100644
--- a/lib/pure/actors.nim
+++ b/lib/pure/actors.nim
@@ -30,7 +30,7 @@ proc spawn*[TIn, TOut](action: proc(
     self: PActor[TIn, TOut]){.thread.}): PActor[TIn, TOut] =
   ## creates an actor; that is a thread with an inbox. The caller MUST call
   ## ``join`` because that also frees the associated resources with the actor.
-  result = allocShared0(sizeof(result[]))
+  result = cast[PActor[TIn, TOut]](allocShared0(sizeof(result[])))
   open(result.i)
   createThread(result.t, action, result)
 
@@ -52,8 +52,8 @@ proc recv*[TIn, TOut](a: PActor[TIn, TOut]): TTask[TIn, TOut] =
   ## receives a task from `a`'s inbox.
   result = recv(a.i)
 
-proc send*[TIn, TOut, X, Y](sender: PActor[X, Z], 
-                            receiver: PActor[TIn, TOut], msg: TIn) =
+proc send*[TIn, TOut, X, Y](receiver: PActor[TIn, TOut], msg: TIn,
+                            sender: PActor[X, Y]) =
   ## sends a message to `a`'s inbox.
   var t: TTask[TIn, TOut]
   t.receiver = addr(sender.i)
@@ -99,9 +99,9 @@ proc poolWorker[TIn, TOut](self: PActor[TIn, TOut]) {.thread.} =
     var m = self.recv
     if m.shutDown: break
     when TOut is void:
-      action(m.data)
+      m.action(m.data)
     else:
-      self.repy(action(m.data))
+      self.repy(m.action(m.data))
 
 proc createActorPool*[TIn, TOut](a: var TActorPool[TIn, TOut], poolSize = 4) =
   ## creates an actor pool.
@@ -109,21 +109,20 @@ proc createActorPool*[TIn, TOut](a: var TActorPool[TIn, TOut], poolSize = 4) =
   when TOut isnot void:
     open(a.outputs)
   for i in 0 .. < a.actors.len:
-    a.actors[i] = spawn(poolWorker)
+    a.actors[i] = spawn(poolWorker[TIn, TOut])
 
 proc join*[TIn, TOut](a: var TActorPool[TIn, TOut]) =
   ## waits for each actor in the actor pool `a` to finish and frees the
   ## resources attached to `a`.
   var t: TTask[TIn, TOut]
   t.shutdown = true
-  for i in 0 .. < a.actors.len: send(a.actors[i], t)
+  for i in 0 .. < a.actors.len: send(a.actors[i].i, t)
   for i in 0 .. < a.actors.len: join(a.actors[i])
   when TOut isnot void:
     close(a.outputs)
   a.actors = nil
 
 template setupTask =
-  var t: TTask[TIn, TOut]
   t.action = action
   shallowCopy(t.data, input)
 
@@ -132,7 +131,7 @@ template schedule =
   # it remains 'hot' ;-). Round-robin hurts for keeping threads hot.
   for i in 0..high(a.actors):
     if a.actors[i].i.ready:
-      a.actors[i].send(t)
+      a.actors[i].i.send(t)
       return
   # no thread ready :-( --> send message to the thread which has the least
   # messages pending:
@@ -142,27 +141,29 @@ template schedule =
     var curr = a.actors[i].i.peek
     if curr == 0:
       # ok, is ready now:
-      a.actors[i].send(t)
+      a.actors[i].i.send(t)
       return
     if curr < minVal:
       minVal = curr
       minIdx = i
-  a.actors[minIdx].send(t)
+  a.actors[minIdx].i.send(t)
 
-proc spawn*[TIn, TOut](p: var TActorPool[TIn, TOut],
-                       action: proc (input: TIn): TOut {.thread.}, 
-                       input: TIn): ptr TChannel[TOut] =
-  ## uses the actor pool to run `action` concurrently. `spawn` is guaranteed
-  ## to not block.
+proc spawn*[TIn, TOut](p: var TActorPool[TIn, TOut], input: TIn,
+                       action: proc (input: TIn): TOut {.thread.}
+                       ): ptr TChannel[TOut] =
+  ## uses the actor pool to run ``action(input)`` concurrently.
+  ## `spawn` is guaranteed to not block.
+  var t: TTask[TIn, TOut]
   setupTask()
   result = addr(p.outputs)
+  t.receiver = result
   schedule()
 
-proc spawn*[TIn](p: var TActorPool[TIn, void],
-                 action: proc (input: TIn) {.thread.}, 
-                 input: TIn) =
-  ## uses the actor pool to run `action` concurrently. `spawn` is guaranteed
-  ## to not block.
+proc spawn*[TIn](p: var TActorPool[TIn, void], input: TIn,
+                 action: proc (input: TIn) {.thread.}) =
+  ## uses the actor pool to run ``action(input)`` concurrently.
+  ## `spawn` is guaranteed to not block.
+  var t: TTask[TIn, void]
   setupTask()
   schedule()
   
@@ -171,7 +172,7 @@ when isMainModule:
     a: TActorPool[int, void]
   createActorPool(a)
   for i in 0 .. < 300:
-    a.spawn(proc (x: int) {.thread.} = echo x)
+    a.spawn(i, proc (x: int) {.thread.} = echo x)
 
   when false:
     proc treeDepth(n: PNode): int {.thread.} =
diff --git a/lib/pure/parsecfg.nim b/lib/pure/parsecfg.nim
index 67644e156..3e85a9ee6 100755
--- a/lib/pure/parsecfg.nim
+++ b/lib/pure/parsecfg.nim
@@ -323,6 +323,7 @@ proc getKeyValPair(c: var TCfgParser, kind: TCfgEventKind): TCfgEvent =
       if c.tok.kind == tkSymbol: 
         result.value = c.tok.literal
       else: 
+        reset result
         result.kind = cfgError
         result.msg = errorStr(c, "symbol expected, but found: " & c.tok.literal)
       rawGetTok(c, c.tok)
diff --git a/lib/system/threads.nim b/lib/system/threads.nim
index 2079762f8..9fbea2e1a 100755
--- a/lib/system/threads.nim
+++ b/lib/system/threads.nim
@@ -252,8 +252,10 @@ type
       object of TGcThread ## Nimrod thread. A thread is a heavy object (~14K)
                           ## that **must not** be part of a message! Use
                           ## a ``TThreadId`` for that.
-    dataFn: proc (m: TArg)
-    when TArg isnot void:
+    when TArg is void:
+      dataFn: proc ()
+    else:
+      dataFn: proc (m: TArg)
       data: TArg
   TThreadId*[TArg] = ptr TThread[TArg] ## the current implementation uses
                                        ## a pointer as a thread ID.
@@ -273,7 +275,7 @@ template ThreadProcWrapperBody(closure: expr) =
   when defined(registerThread):
     t.stackBottom = addr(t)
     registerThread(t)
-  if TArg is void: t.dataFn()
+  when TArg is void: t.dataFn()
   else: t.dataFn(t.data)
   when defined(registerThread): unregisterThread(t)
   when defined(deallocOsPages): deallocOsPages()