Skip to content

Commit

Permalink
Add CAS article (#20)
Browse files Browse the repository at this point in the history
![grafik](https://github.com/jeremy-rifkin/wheatley-mirror/assets/22040976/43486c95-e0fa-4e60-ad8a-82758d90f7da)

---------

Co-authored-by: Jeremy Rifkin <51220084+jeremy-rifkin@users.noreply.github.com>
  • Loading branch information
Eisenwave and jeremy-rifkin committed Jul 30, 2023
1 parent d20083c commit 2aa8e83
Showing 1 changed file with 36 additions and 0 deletions.
36 changes: 36 additions & 0 deletions wiki_articles/cas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# What Is an Atomic Compare-And-Swap (CAS)?

[CAS](https://en.wikipedia.org/wiki/Compare-and-swap)
allows
*[read-modify-write operations](https://en.wikipedia.org/wiki/Read%E2%80%93modify%E2%80%93write)*
for atomics.
It's often the foundation of
*[lock-free algorithms](https://en.wikipedia.org/wiki/Non-blocking_algorithm)*.
In C++, this takes the form of
**[std::atomic::compare_exchange_xxx](https://en.cppreference.com/w/cpp/atomic/atomic/compare_exchange)**:
```cpp
bool atomic<T>::compare_exchange(T& expected, T desired) {
T old = load(); // All of this happens atomically.
// For weak exchanges, this test can fail spuriously:
if (old == expected) { store(desired); return true; }
else { expected = old; return false; }
}
```

## Example - Lock-Free Singly Linked List Stack Push
```cpp
struct node { int val; std::atomic<node*> next; };
std::atomic<node*> top;

void push(int val) {
node* element = new node{ val, nullptr };
node* old_top = top;
do {
element->next = old_top;
} while(!top.compare_exchange_weak(old_top, element));
}
```
Each iteration, `old_top` is loaded from `top`.
In the time that we set `element->next = old_top` another thread might have updated `top`,
which makes the exchange fail.
We keep retrying until we *safely* exchange `top` with the `element`.

0 comments on commit 2aa8e83

Please sign in to comment.