From bc9f8babaa905dac910090979dd968278a07ff9f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Uwe=20Kr=C3=BCger?=
<45282134+UweKrueger@users.noreply.github.com>
Date: Sun, 28 Jun 2020 13:58:08 +0200
Subject: [PATCH] docs: describe upcoming concurrency
---
doc/upcoming.md | 106 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 106 insertions(+)
create mode 100644 doc/upcoming.md
diff --git a/doc/upcoming.md b/doc/upcoming.md
new file mode 100644
index 0000000000..38ec2b3823
--- /dev/null
+++ b/doc/upcoming.md
@@ -0,0 +1,106 @@
+# V Work In Progress
+
+***This document describes features that are not implemented, yet.
+Please refer to [docs.md](https://github.com/vlang/v/blob/master/doc/docs.md)
+for the current state of V***
+
+## Table of Contents
+
+* [Concurrency](#concurrency)
+ * [Variable Declarations](#concurrency-variable-declarations)
+
+## Concurrency
+
+### Variable Declarations
+
+Objects that are supposed to be used to exchange data between
+coroutines have to be declared with special care. Exactly one of the following
+4 kinds of declaration has to be chosen:
+
+```v
+a := ...
+mut b := ...
+shared c := ...
+atomic d := ...
+```
+
+- `a` is declared as *constant* that can be passed to
+ other coroutines and read without limitations. However
+ it cannot be changed.
+- `b` can be accessed reading and writing but only from one
+ coroutine. That coroutine *owns* the object. A `mut` variable can
+ be passed to another coroutine (as receiver or function argument in
+ the `go` statement or via a channel) but then ownership is passed,
+ too, and only the other coroutine can access the object.1
+- `c` can be passed to coroutines an accessed
+ *concurrently*.2 In order to avoid data races it has to
+ be locked before access can occur and unlocked to allow access to
+ other coroutines. This is done by the following block structure:
+ ```v
+ lock c {
+ // read, modify, write c
+ ...
+ }
+ ```
+ Several variables may be specified: `lock x, y, z { ... }`.
+ They are unlocked in the opposite order.
+- `d` can be passed to coroutines and accessed *concurrently*,
+ too.3 No lock is needed in this case, however
+ `atomic` variables can only be 32/64 bit integers (or pointers)
+ and access is limited to a small set of predefined idioms that have
+ native hardware support.
+
+To help making the correct decision the following table summarizes the
+different capabilities:
+
+| | *default* | `mut` | `shared` | `atomic` |
+| :--- | :---: | :---: | :---: | :---: |
+| write access | | + | + | + |
+| concurrent access | + | | + | + |
+| performance | ++ | ++ | | + |
+| sophisticated operations | + | + | + | |
+| structured data types | + | + | + | |
+
+### Strengths
+#### default
+- very fast
+- unlimited access from different coroutines
+- easy to handle
+
+#### `mut`
+- very fast
+- easy to handle
+
+#### `shared`
+- concurrent access from different coroutines
+- data type may be complex structure
+- sophisticated access possible (several statements within one `lock`
+ block)
+
+#### `atomic`
+- concurrent access from different coroutines
+- reasonably fast
+
+### Weaknesses
+#### default
+- read only
+
+#### `mut`
+- access only from one coroutine at a time
+
+#### `shared`
+- lock/unlock are slow
+- moderately difficult to handle (needs `lock` block)
+
+#### `atomic`
+- limited to single (max. 64 bit) integers (and pointers)
+- only a small set of predefined operations possible
+- very difficult to handle correctly
+
+1 The owning coroutine will also free the memory space used
+for the object when it is no longer needed.
+2 For `shared` objects the compiler adds code for reference
+counting. Once the counter reaches 0 the object is automatically freed.
+3 Since an `atomic` variable is only a few bytes in size
+allocation would be an unnecessary overhead. Instead the compiler
+creates a global.