You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+18-19Lines changed: 18 additions & 19 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -38,20 +38,6 @@ These design choices are also limitations:
38
38
39
39
Ultra-low-latency applications need just that and nothing more. The minimalism pays off, see the [throughput and latency benchmarks][1].
40
40
41
-
Available containers are:
42
-
*`AtomicQueue` - a fixed size ring-buffer for atomic elements.
43
-
*`OptimistAtomicQueue` - a faster fixed size ring-buffer for atomic elements which busy-waits when empty or full. It is `AtomicQueue` used with `push`/`pop` instead of `try_push`/`try_pop`.
44
-
*`AtomicQueue2` - a fixed size ring-buffer for non-atomic elements.
45
-
*`OptimistAtomicQueue2` - a faster fixed size ring-buffer for non-atomic elements which busy-waits when empty or full. It is `AtomicQueue2` used with `push`/`pop` instead of `try_push`/`try_pop`.
46
-
47
-
These containers have corresponding `AtomicQueueB`, `OptimistAtomicQueueB`, `AtomicQueueB2`, `OptimistAtomicQueueB2` versions where the buffer size is specified as an argument to the constructor.
48
-
49
-
Totally ordered mode is supported. In this mode consumers receive messages in the same FIFO order the messages were posted. This mode is supported for `push` and `pop` functions, but for not the `try_` versions. On Intel x86 the totally ordered mode has 0 cost, as of 2019.
50
-
51
-
Single-producer-single-consumer mode is supported. In this mode, no expensive atomic read-modify-write CPU instructions are necessary, only the cheapest atomic loads and stores. That improves queue throughput significantly.
52
-
53
-
Move-only queue element types are fully supported. For example, a queue of `std::unique_ptr<T>` elements would be `AtomicQueue2B<std::unique_ptr<T>>` or `AtomicQueue2<std::unique_ptr<T>, CAPACITY>`.
54
-
55
41
## Role Models
56
42
Several other well established and popular thread-safe containers are used for reference in the [benchmarks][1]:
57
43
*`std::mutex` - a fixed size ring-buffer with `std::mutex`.
@@ -102,7 +88,22 @@ make -r -j4 run_benchmarks
102
88
103
89
The benchmark also requires Intel TBB library to be available. It assumes that it is installed in `/usr/local/include` and `/usr/local/lib`. If it is installed elsewhere you may like to modify `cppflags.tbb` and `ldlibs.tbb` in `Makefile`.
104
90
105
-
# API
91
+
# Library contemts
92
+
## Available queues
93
+
*`AtomicQueue` - a fixed size ring-buffer for atomic elements.
94
+
*`OptimistAtomicQueue` - a faster fixed size ring-buffer for atomic elements which busy-waits when empty or full. It is `AtomicQueue` used with `push`/`pop` instead of `try_push`/`try_pop`.
95
+
*`AtomicQueue2` - a fixed size ring-buffer for non-atomic elements.
96
+
*`OptimistAtomicQueue2` - a faster fixed size ring-buffer for non-atomic elements which busy-waits when empty or full. It is `AtomicQueue2` used with `push`/`pop` instead of `try_push`/`try_pop`.
97
+
98
+
These containers have corresponding `AtomicQueueB`, `OptimistAtomicQueueB`, `AtomicQueueB2`, `OptimistAtomicQueueB2` versions where the buffer size is specified as an argument to the constructor.
99
+
100
+
Totally ordered mode is supported. In this mode consumers receive messages in the same FIFO order the messages were posted. This mode is supported for `push` and `pop` functions, but for not the `try_` versions. On Intel x86 the totally ordered mode has 0 cost, as of 2019.
101
+
102
+
Single-producer-single-consumer mode is supported. In this mode, no expensive atomic read-modify-write CPU instructions are necessary, only the cheapest atomic loads and stores. That improves queue throughput significantly.
103
+
104
+
Move-only queue element types are fully supported. For example, a queue of `std::unique_ptr<T>` elements would be `AtomicQueue2B<std::unique_ptr<T>>` or `AtomicQueue2<std::unique_ptr<T>, CAPACITY>`.
105
+
106
+
## Queue API
106
107
The queue class templates provide the following member functions:
107
108
*`try_push` - Appends an element to the end of the queue. Returns `false` when the queue is full.
108
109
*`try_pop` - Removes an element from the front of the queue. Returns `false` when the queue is empty.
@@ -121,15 +122,13 @@ Note that _optimism_ is a choice of a queue modification operation control flow,
121
122
122
123
See [example.cc](src/example.cc) for a usage example.
123
124
124
-
TODO: full API reference.
125
-
125
+
# Implementation Notes
126
126
## Memory order of non-atomic loads and stores
127
127
`push` and `try_push` operations _synchronize-with_ (as defined in [`std::memory_order`][17]) with any subsequent `pop` or `try_pop` operation of the same queue object. Meaning that:
128
128
* No non-atomic load/store gets reordered past `push`/`try_push`, which is a `memory_order::release` operation. Same memory order as that of `std::mutex::unlock`.
129
129
* No non-atomic load/store gets reordered prior to `pop`/`try_pop`, which is a `memory_order::acquire` operation. Same memory order as that of `std::mutex::lock`.
130
130
* The effects of a producer thread's non-atomic stores followed by `push`/`try_push` of an element into a queue become visible in the consumer's thread which `pop`/`try_pop` that particular element.
131
131
132
-
# Implementation Notes
133
132
## Ring-buffer capacity
134
133
The available queues here use a ring-buffer array for storing elements. The capacity of the queue is fixed at compile time or construction time.
135
134
@@ -216,7 +215,7 @@ One thread posts an integer to another thread through one queue and waits for a
216
215
Contributions are more than welcome. `.editorconfig` and `.clang-format` can be used to automatically match code formatting.
217
216
218
217
# Reading material
219
-
Some books on the subject of multi-threaded programming I found instructive:
218
+
Some books on the subject of multi-threaded programming I found quite instructive:
220
219
221
220
*_Programming with POSIX Threads_ by David R. Butenhof.
222
221
*_The Art of Multiprocessor Programming_ by Maurice Herlihy, Nir Shavit.
0 commit comments