diff options
Diffstat (limited to 'doc')
-rw-r--r-- | doc/advopt.txt | 1 | ||||
-rw-r--r-- | doc/keywords.txt | 2 | ||||
-rw-r--r-- | doc/lib.txt | 3 | ||||
-rw-r--r-- | doc/manual.txt | 104 |
4 files changed, 31 insertions, 79 deletions
diff --git a/doc/advopt.txt b/doc/advopt.txt index 0ebc85370..f5ff90791 100644 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -4,6 +4,7 @@ Advanced commands: //compileToOC, objc compile project to Objective C code //rst2html convert a reStructuredText file to HTML //rst2tex convert a reStructuredText file to TeX + //jsondoc extract the documentation to a json file //buildIndex build an index for the whole documentation //run run the project (with Tiny C backend; buggy!) //genDepend generate a DOT file containing the diff --git a/doc/keywords.txt b/doc/keywords.txt index 2d18d7969..60b100398 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -12,7 +12,7 @@ nil not notin object of or out proc ptr raise ref return -shared shl shr static +shl shr static template try tuple type using var diff --git a/doc/lib.txt b/doc/lib.txt index a209357f7..3ca519c9e 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -373,6 +373,9 @@ Miscellaneous * `logging <logging.html>`_ This module implements a simple logger. +* `future <future.html>`_ + This module implements new experimental features. Currently the syntax + sugar for anonymous procedures. Database support ---------------- diff --git a/doc/manual.txt b/doc/manual.txt index c0d4f2627..d6b9f296e 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -5616,7 +5616,6 @@ Memory allocation requires no lock at all! This design easily scales to massive multicore processors that will become the norm in the future. - Thread pragma ------------- @@ -5626,12 +5625,32 @@ violations of the `no heap sharing restriction`:idx:\: This restriction implies that it is invalid to construct a data structure that consists of memory allocated from different (thread local) heaps. -Since the semantic checking of threads requires whole program analysis, -it is quite expensive and can be turned off with ``--threadanalysis:off`` to -improve compile times. +A thread proc is passed to ``createThread`` or ``spawn`` and invoked +indirectly; so the ``thread`` pragma implies ``procvar``. + + +GC safety +--------- + +We call a proc ``p`` `GC safe`:idx: when it doesn't access any global variable +that contains GC'ed memory (``string``, ``seq``, ``ref`` or a closure) either +directly or indirectly through a call to a GC unsafe proc. + +The `gcsafe`:idx: annotation can be used to mark a proc to be gcsafe +otherwise this property is inferred by the compiler. Note that ``noSideEfect`` +implies ``gcsafe``. The only way to create a thread is via ``spawn`` or +``createThead``. ``spawn`` is usually the preferable method. Either way +the invoked proc must not use ``var`` parameters nor must any of its parameters +contain a ``ref`` or ``closure`` type. This enforces +the *no heap sharing restriction*. + +Routines that are imported from C are always assumed to be ``gcsafe``. + +Future directions: -A thread proc is passed to ``createThread`` and invoked indirectly; so the -``thread`` pragma implies ``procvar``. +- For structured fork&join parallelism more efficient parameter passing can + be performed and much more can be proven safe. +- A shared GC'ed heap is planned. Threadvar pragma @@ -5648,78 +5667,6 @@ initialized within the ``var`` section. (Every thread local variable needs to be replicated at thread creation.) -Actor model ------------ - -**Caution**: This section is already outdated! XXX - -Nimrod supports the `actor model`:idx: of concurrency natively: - -.. code-block:: nimrod - type - TMsgKind = enum - mLine, mEof - TMsg = object - case k: TMsgKind - of mEof: nil - of mLine: data: string - - var - thr: TThread[TMsg] - printedLines = 0 - m: TMsg - - proc print() {.thread.} = - while true: - var x = recv[TMsg]() - if x.k == mEof: break - echo x.data - discard atomicInc(printedLines) - - createThread(thr, print) - - var input = open("readme.txt") - while not endOfFile(input): - m.data = input.readLine() - thr.send(m) - close(input) - m.k = mEof - thr.send(m) - joinThread(thr) - - echo printedLines - -In the actor model threads communicate only over sending messages (`send`:idx: -and `recv`:idx: built-ins), not by sharing memory. Every thread has -an `inbox`:idx: that keeps incoming messages until the thread requests a new -message via the ``recv`` operation. The inbox is an unlimited FIFO queue. - -In the above example the ``print`` thread also communicates with its -parent thread over the ``printedLines`` global variable. In general, it is -highly advisable to only read from globals, but not to write to them. In fact -a write to a global that contains GC'ed memory is always wrong, because it -violates the *no heap sharing restriction*: - -.. code-block:: nimrod - var - global: string - t: TThread[string] - - proc horrible() {.thread.} = - global = "string in thread local heap!" - - createThread(t, horrible) - joinThread(t) - -For the above code the compiler produces "Warning: write to foreign heap". This -warning might become an error message in future versions of the compiler. - -Creating a thread is an expensive operation, because a new stack and heap needs -to be created for the thread. It is therefore highly advisable that a thread -handles a large amount of work. Nimrod prefers *coarse grained* -over *fine grained* concurrency. - - Threads and exceptions ---------------------- @@ -5727,6 +5674,7 @@ The interaction between threads and exceptions is simple: A *handled* exception in one thread cannot affect any other thread. However, an *unhandled* exception in one thread terminates the whole *process*! + Taint mode ========== |