Skip to content

Commit ab3479d

Browse files
committed
update guide and readme
1 parent fbd30c2 commit ab3479d

File tree

3 files changed

+118
-135
lines changed

3 files changed

+118
-135
lines changed

README.md

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,51 @@
44
[<img alt="github" src="https://img.shields.io/badge/github-seize-blue?style=for-the-badge" height="25">](https://github.com/ibraheemdev/seize)
55
[<img alt="docs.rs" src="https://img.shields.io/docsrs/seize?style=for-the-badge" height="25">](https://docs.rs/seize)
66

7-
Fast, efficient, and robust memory reclamation for concurrent data structures.
7+
Fast, efficient, and predictable memory reclamation for concurrent data
8+
structures.
89

9-
See the [quick-start guide] to get started.
10+
Refer to the [quick-start guide] to get started.
1011

1112
## Background
1213

1314
Concurrent data structures are faced with the problem of deciding when it is
14-
safe to free memory. Although an object might have been logically removed, other
15-
threads that previously loaded it may still be accessing it, and thus it is
15+
safe to free memory. Despite an object being logically removed, it may still be
16+
accessible by other threads that are holding references to it, and thus it is
1617
not safe to free immediately. Over the years, many algorithms have been devised
1718
to solve this problem. However, most traditional memory reclamation schemes make
18-
the tradeoff between performance, efficiency, and robustness. For example,
19-
[epoch based reclamation] is fast and lightweight but lacks robustness in that a
20-
stalled thread can prevent the reclamation of _all_ retired objects. [Hazard
21-
pointers], another popular scheme, tracks individual pointers, making it efficient
22-
and robust but generally much slower.
19+
a tradeoff between performance and efficiency.
2320

24-
Another problem that is often not considered is workload balancing. In most
25-
reclamation schemes, the thread that retires an object is the one that reclaims
26-
it. This leads to unbalanced reclamation in read-dominated workloads; parallelism
27-
is reduced when only a fraction of threads are writing, degrading memory efficiency.
21+
For example, [hazard pointers] track individual pointers, making them very
22+
memory efficient but also relatively slow. On the other hand, [epoch based
23+
reclamation] is fast and lightweight, but lacks predictability, requiring
24+
periodic checks to determine when it is safe to free memory. This can cause
25+
reclamation to trigger unpredictably, leading to poor latency distributions.
2826

29-
## Implementation
27+
Alternative epoch-based schemes forgo workload balancing, relying on the thread
28+
that retires an object always being the one that frees it. While this can avoid
29+
synchronization costs, it also leads to unbalanced reclamation in read-dominated
30+
workloads; parallelism is reduced when only a fraction of threads are writing,
31+
degrading memory efficiency as well as performance.
3032

31-
seize is based on the [hyaline reclamation scheme], which uses reference counting
32-
to determine when it is safe to free memory. However, reference counters are only
33-
used for already retired objects, allowing it to avoid the high overhead incurred
34-
by traditional reference counting schemes where every memory access requires modifying
35-
shared memory. Reclamation is naturally balanced as the thread with the last reference
36-
to an object is the one that frees it. This removes the need to check whether other
37-
threads have made progress, leading to predictable latency without sacrificing performance.
38-
Epochs can also be tracked to protect against stalled threads, making reclamation truly
39-
lock-free.
33+
## Implementation
4034

41-
seize provides performance competitive with that of epoch based schemes, while memory efficiency
42-
is similar to that of hazard pointers. seize is compatible with all modern hardware that
43-
supports single-word atomic operations such as FAA and CAS.
35+
`seize` is based on the [hyaline reclamation scheme], which uses reference
36+
counting to determine when it is safe to free memory. However, unlike
37+
traditional reference counting schemes where every memory access requires
38+
modifying shared memory, reference counters are only used for retired objects.
39+
When a batch of objects is retired, a reference counter is initialized and
40+
propagated to all active threads. Threads cooperate to decrement the reference
41+
counter as they exit, eventually freeing the batch. Reclamation is naturally
42+
balanced as the thread with the last reference to an object is the one that
43+
frees it. This also removes the need to check whether other threads have made
44+
progress, leading to predictable latency without sacrificing performance.
45+
46+
`seize` provides performance competitive with that of epoch based schemes, while
47+
memory efficiency is similar to that of hazard pointers. `seize` is compatible
48+
with all modern hardware that supports single-word atomic operations such as FAA
49+
and CAS.
4450

4551
[quick-start guide]: https://docs.rs/seize/latest/seize/guide/index.html
46-
[tokio]: https://github.com/tokio-rs/tokio
4752
[hazard pointers]:
4853
https://www.cs.otago.ac.nz/cosc440/readings/hazard-pointers.pdf
4954
[hyaline reclamation scheme]: https://arxiv.org/pdf/1905.07903.pdf

benches/stack.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,8 +138,7 @@ mod seize_stack {
138138
}
139139

140140
fn is_empty(&self) -> bool {
141-
let guard = self.collector.enter();
142-
guard.protect(&self.head, Ordering::Relaxed).is_null()
141+
self.head.load(Ordering::Relaxed).is_null()
143142
}
144143
}
145144

0 commit comments

Comments
 (0)