# Lock-Free

Published articles for Lock-Free.

This is one page of public article previews, not the complete archive. Follow Next page to continue. Summaries are not the original full articles.

## Security Baked Into the JVM: why fork Apache River and OpenJDK?

DevFeed: [Security Baked Into the JVM: why fork Apache River and OpenJDK?](<https://devfeed.tech/articles/security-baked-into-the-jvm-why-fork-apache-river-and-openjdk-18928.md>)

Original publisher: [Read original article](<https://blog.frankel.ch/security-baked-into-jvm/1/>)

Author: Peter Firmstone

Published: 2026-06-28T00:00:00Z

Content type: opinion

Language: en

Sources: [Nicolas Fränkel](<https://devfeed.tech/sources/nicolas-frankel.md>)

Topics: [Security](<https://devfeed.tech/topics/security.md>), [Java](<https://devfeed.tech/topics/java.md>), [openjdk](<https://devfeed.tech/topics/openjdk.md>), [Architecture & Design](<https://devfeed.tech/topics/architecture-design.md>), [Remote Procedure Call (RPC)](<https://devfeed.tech/topics/rpc.md>), [Networks](<https://devfeed.tech/topics/networks.md>)

Tags: [authorization](<https://devfeed.tech/tags/authorization.md>), [dirtychai](<https://devfeed.tech/tags/dirtychai.md>), [discovery](<https://devfeed.tech/tags/discovery.md>), [distributed](<https://devfeed.tech/tags/distributed.md>), [ipv6](<https://devfeed.tech/tags/ipv6.md>), [java](<https://devfeed.tech/tags/java.md>), [jgdms](<https://devfeed.tech/tags/jgdms.md>), [jini](<https://devfeed.tech/tags/jini.md>), [jvm](<https://devfeed.tech/tags/jvm.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [microservices](<https://devfeed.tech/tags/microservices.md>), [openjdk](<https://devfeed.tech/tags/openjdk.md>), [rpc](<https://devfeed.tech/tags/rpc.md>), [security](<https://devfeed.tech/tags/security.md>), [self-healing](<https://devfeed.tech/tags/self-healing.md>), [technical](<https://devfeed.tech/tags/technical.md>)

### AI overview

This article introduces DirtyChai, a community fork of OpenJDK that restores Java authorization infrastructure, and JGDMS, a security-hardened fork of Apache River for dynamically discoverable microservices over IPv6. It argues that distributed systems require security beyond network firewalls and outlines the projects' complementary roles, including authorization, service discovery, hardened deserialization, transport security, proxy trust verification, and codebase safety checks.

### Source excerpt

The more distributed a system, the harder it is to secure. Code crosses JVM boundaries. Objects are serialized across trust boundaries. Third-party proxies run inside your process. The usual answer is a network firewall. It helps, but it operates at the wrong level. Java 17 deprecated the SecurityManager, Java 24 put the final nail in its coffin. Most developers didn't notice.

## BitFields API: Type-Safe Bit Packing for Lock-Free Data Structures

DevFeed: [BitFields API: Type-Safe Bit Packing for Lock-Free Data Structures](<https://devfeed.tech/articles/bitfields-api-type-safe-bit-packing-for-lock-free-data-structures-22396.md>)

Original publisher: [Read original article](<http://rocksdb.org/blog/2025/12/31/bit-fields-api.html>)

Author: Peter Dillinger

Published: 2025-12-31T00:00:00Z

Content type: tutorial

Language: en

Sources: [RocksDB](<https://devfeed.tech/sources/rocksdb.md>)

Topics: [rocksdb](<https://devfeed.tech/topics/rocksdb.md>), [C++](<https://devfeed.tech/topics/c-plus-plus.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Cache](<https://devfeed.tech/topics/cache.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [blog](<https://devfeed.tech/tags/blog.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [cache](<https://devfeed.tech/tags/cache.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [efficiency](<https://devfeed.tech/tags/efficiency.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>)

### AI overview

This article introduces RocksDB's BitFields API, a type-safe, zero-overhead C++ abstraction for packing multiple logical fields into atomic variables. It explains how the API helps manage packed state and describes its use in the essentially lock-free HyperClockCache.

### Source excerpt

Modern concurrent data structures increasingly rely on atomic operations to avoid the overhead of locking. A valuable but under-utilized technique for maximizing the effectiveness of atomic operations is bit packing--fitting multiple logical fields into a single atomic variable for algorithmic simplicity and efficiency. However, language support for bit packing does not guarantee dense packing, and manually managing bit manipulation quickly becomes error-prone, especially when dealing with complex state machines. To address this in RocksDB, we have developed a reusable BitFields API, a type-safe, zero-overhead abstraction for bit packing in C++. This works in conjunction with clean wrappers for std::atomic for powerful and relatively safe bit-packing of atomic data. For broader use, a variant of the code has been proposed for adding to folly. The Problem: Managing Packed Bit Fields Consider HyperClockCache, an essentially lock-free cache implementation in RocksDB, which was refactored to use this BitFields API. It is a hash table built on slots that can each hold a cache entry and relevant metadata. For atomic simplicity and efficiency, all the essential metadata for each slot is packed into a single 64-bit value: The reference count and eviction metadata are together encoded into acquire and release counters, 30 bits each. The possible states of {empty, under construction/destruction, occupied+visible, and occupied+invisible} are encoded into three state bits (instead of two, for easier decoding and manipulation). A hit bit is used for secondary cache integration. Traditionally, you might write code like this: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 // Old approach: manual bit manipulation constexpr uint64_t kAcquireCounterShift = 0; constexpr uint64_t kReleaseCounterShift = 30; constexpr uint64_t kCounterMask = 0x3FFFFFFF; constexpr uint64_t kHitBitShift = 60; constexpr uint64_t k

## Parallel Compression Revamp: Dramatically Reduced CPU Overhead

DevFeed: [Parallel Compression Revamp: Dramatically Reduced CPU Overhead](<https://devfeed.tech/articles/parallel-compression-revamp-dramatically-reduced-cpu-overhead-22395.md>)

Original publisher: [Read original article](<http://rocksdb.org/blog/2025/10/08/parallel-compression-revamp.html>)

Author: Peter Dillinger

Published: 2025-10-08T00:00:00Z

Content type: release

Language: en

Sources: [RocksDB](<https://devfeed.tech/sources/rocksdb.md>)

Topics: [Compression](<https://devfeed.tech/topics/compression.md>), [rocksdb](<https://devfeed.tech/topics/rocksdb.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [Pull Request](<https://devfeed.tech/topics/pull-request.md>)

Tags: [architecture](<https://devfeed.tech/tags/architecture.md>), [blog](<https://devfeed.tech/tags/blog.md>), [compression](<https://devfeed.tech/tags/compression.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [parallel](<https://devfeed.tech/tags/parallel.md>), [pull-request](<https://devfeed.tech/tags/pull-request.md>), [rocksdb](<https://devfeed.tech/tags/rocksdb.md>), [storage](<https://devfeed.tech/tags/storage.md>), [synchronization](<https://devfeed.tech/tags/synchronization.md>)

### AI overview

RocksDB 10.7 is expected to include a reimplementation of parallel compression that reduces CPU overhead by up to 65% while maintaining or improving throughput for compression-heavy workloads. The redesign uses a ring buffer, work-stealing-style thread participation, automatic thread scaling, and primarily atomic, lock-free synchronization.

### Source excerpt

The upcoming RocksDB 10.7 release includes a major revamp of parallel compression that dramatically reduces the feature's CPU overhead by up to 65% while maintaining or improving throughput for compression-heavy workloads. We expect this to broaden the set of workloads that could benefit from parallel compression, especially for bulk SST generation and remote compaction use cases that are less sensitive to CPU responsiveness. Background Parallel compression in RocksDB (CompressionOptions::parallel_threads > 1) allows multiple threads to compress different blocks simultaneously during SST file generation, which can significantly improve compaction throughput for workloads where compression is a bottleneck. However, the original implementation had substantial CPU overhead that often outweighed the benefits, limiting its practical adoption. What's New: A Complete Reimplementation The parallel compression framework has been completely rewritten from the ground up in pull request #13910 to address the core inefficiencies: Ring Buffer Architecture Instead of separate compression and write queues with complex thread coordination, the new implementation uses a ring buffer of blocks-in-progress that enables efficient work distribution across threads. This bounds working memory while enabling high throughput with minimal cross-thread synchronization. Work-Stealing Design Previously, the calling thread could only generate uncompressed blocks, dedicated compression threads could only compress, and a writer thread could only write the SST file to storage. Now, all threads can participate in compression work in a quasi-work-stealing manner, dramatically reducing the need for threads to block waiting for work. While only one thread (the calling thread or "emit thread") can generate uncompressed SST blocks in the new implementation, feeding compression work to other threads and itself, all other threads are compatible with writing compressed blocks to storage. Auto-Scaling Thread M

## Fearless Concurrency Ep.7: Lock-Free Structures and Channels for Scalable Rust Code

DevFeed: [Fearless Concurrency Ep.7: Lock-Free Structures and Channels for Scalable Rust Code](<https://devfeed.tech/articles/fearless-concurrency-ep-7-lock-free-structures-and-channels-for-scalable-rust-code-22272.md>)

Original publisher: [Read original article](<https://www.ardanlabs.com/blog/2024/12/fearless-concurrency-ep7-lock-free-structures-and-channels-for-scalable-rust-code.html>)

Published: 2024-12-05T00:00:00Z

Content type: tutorial

Language: en

Sources: [William Kennedy](<https://devfeed.tech/sources/william-kennedy.md>)

Topics: [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Rust](<https://devfeed.tech/topics/rust.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Code](<https://devfeed.tech/topics/code.md>), [systems](<https://devfeed.tech/topics/systems.md>)

Tags: [advanced-rust-concurrency](<https://devfeed.tech/tags/advanced-rust-concurrency.md>), [alternatives](<https://devfeed.tech/tags/alternatives.md>), [backpressure](<https://devfeed.tech/tags/backpressure.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [concurrency-in-rust](<https://devfeed.tech/tags/concurrency-in-rust.md>), [crossbeam-crate-rust](<https://devfeed.tech/tags/crossbeam-crate-rust.md>), [efficient-multithreading-rust](<https://devfeed.tech/tags/efficient-multithreading-rust.md>), [fearless-concurrency-rust](<https://devfeed.tech/tags/fearless-concurrency-rust.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [lock-free-data-structures-rust](<https://devfeed.tech/tags/lock-free-data-structures-rust.md>), [managing-shared-resources-rust](<https://devfeed.tech/tags/managing-shared-resources-rust.md>), [mpsc-channels-rust](<https://devfeed.tech/tags/mpsc-channels-rust.md>), [one-shot-channels-rust](<https://devfeed.tech/tags/one-shot-channels-rust.md>), [optimizing-concurrency-in-rust](<https://devfeed.tech/tags/optimizing-concurrency-in-rust.md>), [performance](<https://devfeed.tech/tags/performance.md>), [robust-multithreaded-rust-apps](<https://devfeed.tech/tags/robust-multithreaded-rust-apps.md>), [rust](<https://devfeed.tech/tags/rust.md>), [rust-atomiccell](<https://devfeed.tech/tags/rust-atomiccell.md>), [rust-bounded-channels](<https://devfeed.tech/tags/rust-bounded-channels.md>), [rust-concurrency](<https://devfeed.tech/tags/rust-concurrency.md>), [rust-dashmap-dashset](<https://devfeed.tech/tags/rust-dashmap-dashset.md>), [rust-high-concurrency-techniques](<https://devfeed.tech/tags/rust-high-concurrency-techniques.md>), [rust-thread-multiplexing](<https://devfeed.tech/tags/rust-thread-multiplexing.md>), [rust-thread-safe-work-queues](<https://devfeed.tech/tags/rust-thread-safe-work-queues.md>), [rust-timeout-options](<https://devfeed.tech/tags/rust-timeout-options.md>), [scalable-rust-applications](<https://devfeed.tech/tags/scalable-rust-applications.md>), [thread](<https://devfeed.tech/tags/thread.md>), [thread-communication-rust](<https://devfeed.tech/tags/thread-communication-rust.md>)

### AI overview

The seventh and final episode of a Rust concurrency series covers lock-free data structures, channels for communication between threads, and techniques for managing shared resources. It discusses tools including DashMap, DashSet, Crossbeam, MPSC and one-shot channels, multiplexing, bounded channels, backpressure, memory usage, and timeouts.

### Source excerpt

Introduction: Welcome to Episode 7 of the Fearless Concurrency in Rust series! In this final episode, we explore advanced concurrency techniques that enable efficient, scalable, and robust multithreaded applications in Rust. The focus is on leveraging tools like lock-free data structures, channels for thread communication, and strategies for safely managing shared resources in complex systems. These approaches ensure developers can push the limits of Rust's concurrency model while maintaining safety and performance.

## Making unwinding through JIT-ed code scalable - Replacing the gcc hooks

DevFeed: [Making unwinding through JIT-ed code scalable - Replacing the gcc hooks](<https://devfeed.tech/articles/making-unwinding-through-jit-ed-code-scalable-replacing-the-gcc-hooks-25080.md>)

Original publisher: [Read original article](<https://databasearchitects.blogspot.com/2022/06/replacinggcchooks.html>)

Author: Thomas Neumann (noreply@blogger.com)

Published: 2022-06-26T08:48:00Z

Content type: article

Language: en

Sources: [Database Architects](<https://devfeed.tech/sources/database-architects.md>)

Topics: [gcc](<https://devfeed.tech/topics/gcc.md>), [patches](<https://devfeed.tech/topics/patches.md>), [JIT](<https://devfeed.tech/topics/jit.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [jit](<https://devfeed.tech/tags/jit.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [mutex](<https://devfeed.tech/tags/mutex.md>), [patches](<https://devfeed.tech/tags/patches.md>)

### AI overview

This article explains patches to GCC that replace a globally locked list of unwinding frames with a read-optimized B-tree. The change enables concurrent registration, deregistration, and lock-free lookups, while keeping frames immutable during unwinding on platforms that support atomics.

### Source excerpt

This article is part of the series about scalable unwinding that starts here. As discussed in the previous article, the gcc mechanism does not scale because it uses a global lock to protect its list of unwinding frames. To solve that problem, we replace that list with a read-optimized b-tree that allows for concurrent reads and writes. In this article we just discuss the patches to gcc necessary to enable that mechanism, the b-tree itself is discussed in subsequent articles. We start by replacing the old fast path mechanism with a b-tree root: index 8ee55be5675..d546b9e4c43 100644 --- a/libgcc/unwind-dw2-fde.c +++ b/libgcc/unwind-dw2-fde.c @@ -42,15 +42,34 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see #endif #endif +#ifdef ATOMIC_FDE_FAST_PATH +#include "unwind-dw2-btree.h" + +static struct btree registered_frames; + +static void +release_registered_frames (void) __attribute__ ((destructor (110))); +static void +release_registered_frames (void) +{ + /* Release the b-tree and all frames. Frame releases that happen later are + * silently ignored */ + btree_destroy (&registered_frames); +} + +static void +get_pc_range (const struct object *ob, uintptr_t *range); +static void +init_object (struct object *ob); + +#else + /* The unseen_objects list contains objects that have been registered but not yet categorized in any way. The seen_objects list has had its pc_begin and count fields initialized at minimum, and is sorted by decreasing value of pc_begin. */ static struct object *unseen_objects; static struct object *seen_objects; -#ifdef ATOMIC_FDE_FAST_PATH -static int any_objects_registered; -#endif #ifdef __GTHREAD_MUTEX_INIT static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; @@ -78,6 +97,7 @@ init_object_mutex_once (void) static __gthread_mutex_t object_mutex; #endif #endif +#endif When the platform supports atomics (ATOMIC_FDE_FAST_PATH), we replace the whole mechanism with one b-tree, whose root is registered_frames. Neither the

## Making unwinding through JIT-ed code scalable

DevFeed: [Making unwinding through JIT-ed code scalable](<https://devfeed.tech/articles/making-unwinding-through-jit-ed-code-scalable-25078.md>)

Original publisher: [Read original article](<https://databasearchitects.blogspot.com/2022/06/making-unwinding-through-jit-ed-code.html>)

Author: Thomas Neumann (noreply@blogger.com)

Published: 2022-06-26T08:46:00Z

Content type: tutorial

Language: en

Sources: [Database Architects](<https://devfeed.tech/sources/database-architects.md>)

Topics: [C++](<https://devfeed.tech/topics/c-plus-plus.md>), [Exception](<https://devfeed.tech/topics/exception.md>), [gcc](<https://devfeed.tech/topics/gcc.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Jule](<https://devfeed.tech/topics/jule.md>), [systems](<https://devfeed.tech/topics/systems.md>)

Tags: [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [exception](<https://devfeed.tech/tags/exception.md>), [gcc](<https://devfeed.tech/tags/gcc.md>), [hooks](<https://devfeed.tech/tags/hooks.md>), [jit](<https://devfeed.tech/tags/jit.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [mutex](<https://devfeed.tech/tags/mutex.md>), [series](<https://devfeed.tech/tags/series.md>)

### AI overview

This article explains why C++ exception unwinding remains effectively single-threaded when JIT-ed code is registered. It describes limitations in gcc and glibc mechanisms and introduces a gcc patch using a read-optimized lock-free b-tree to support parallel unwinding without atomic writes.

### Source excerpt

Exceptions are a very handy mechanism to propagate errors in C++ programs, but unfortunately they do not scale very well. In all common C++ implementations the unwinding mechanism takes global lock during unwinding, which has disastrous consequences when the number of threads is high. On a machine with 256 hardware context we see worse-than-single-threaded behavior even for relatively modest failure rates. Fortunately the Florian Weimer fixed one contention point in gcc 12 on systems with glibc 2.35 or newer, which gives us scalable exceptions as long as no JIT-ed code has been registered. Unfortunately our system does register JIT-ed code... Which means exception unwinding in our code base is still single-threaded in practice. But we can fix that by teaching gcc to store the unwinding information in a read-optimized b-tree, which allows for fully parallel unwinding without any atomic writes. There is a gcc patch that does just that, but unfortunately it is quite involved and difficult to review. This article series thus explains all parts of the patch and shows how a read-optimized b-tree can be implemented lock-free. In order to keep the article length somewhat reasonable, the discusses is broken into parts: The problem (this article) Replacing the gcc hooks Optimistic Lock Coupling The b-tree b-tree operations When unwinding exceptions, the compiler has to find the corresponding unwinding information for every call frame on the stack between the throw and the catch. gcc uses two different mechanisms for that: For ahead-of-time compiled code it asks glibc to find the unwinding information using either dl_iterate_phdr (on older systems) or _dl_find_object (on systems with glibc 2.35 or newer). Note that this mapping is not static, as shared libraries could be added or removed at any time, potentially during a concurrent unwind. For that reason dl_iterate_phdr was protected by a global mutex, which clearly does not scale. _dl_find_object avoids that mutex by using a

## Thread Local Randoms in Java

DevFeed: [Thread Local Randoms in Java](<https://devfeed.tech/articles/thread-local-randoms-in-java-24841.md>)

Original publisher: [Read original article](<https://alidg.me/blog/2020/4/24/thread-local-random>)

Author: Alimate

Published: 2020-04-24T00:00:00Z

Content type: tutorial

Language: en

Sources: [Ali Dehghan - Kemikit](<https://devfeed.tech/sources/ali-dehghan-kemikit.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Randomizer](<https://devfeed.tech/topics/randomizer.md>), [benchmarking](<https://devfeed.tech/topics/benchmarking.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Algorithm](<https://devfeed.tech/topics/algorithm.md>)

Tags: [algorithm](<https://devfeed.tech/tags/algorithm.md>), [atomics](<https://devfeed.tech/tags/atomics.md>), [benchmarking](<https://devfeed.tech/tags/benchmarking.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [java](<https://devfeed.tech/tags/java.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [performance](<https://devfeed.tech/tags/performance.md>), [state](<https://devfeed.tech/tags/state.md>)

### AI overview

This article examines thread-local random number generation in Java. It compares a shared generator, a simple thread-local implementation, and the built-in approach, explaining how contention, atomic operations, synchronization, and shared mutable state affect throughput.

### Source excerpt

Benchmarking regular randoms against thread-local ones!

## Can Reordering of Release/Acquire Operations Introduce Deadlock?

DevFeed: [Can Reordering of Release/Acquire Operations Introduce Deadlock?](<https://devfeed.tech/articles/can-reordering-of-release-acquire-operations-introduce-deadlock-21011.md>)

Original publisher: [Read original article](<https://preshing.com/20170612/can-reordering-of-release-acquire-operations-introduce-deadlock>)

Author: Jeff Preshing

Published: 2017-06-12T11:34:00Z

Content type: article

Language: en

Sources: [Jeff Preshing](<https://devfeed.tech/sources/jeff-preshing.md>)

Topics: [C++](<https://devfeed.tech/topics/c-plus-plus.md>), [Deadlock](<https://devfeed.tech/topics/deadlock.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [Programming](<https://devfeed.tech/topics/programming.md>), [cpu](<https://devfeed.tech/topics/cpu.md>), [x86](<https://devfeed.tech/topics/x86.md>)

Tags: [architectures](<https://devfeed.tech/tags/architectures.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [code](<https://devfeed.tech/tags/code.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [deadlock](<https://devfeed.tech/tags/deadlock.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [memory](<https://devfeed.tech/tags/memory.md>), [synchronization](<https://devfeed.tech/tags/synchronization.md>), [thread](<https://devfeed.tech/tags/thread.md>), [x86](<https://devfeed.tech/tags/x86.md>)

### AI overview

This article examines whether compiler or CPU reordering of C++ release and acquire operations can introduce deadlock when the operations implement spinlocks. It explains the interaction between memory-ordering rules, two threads acquiring locks in opposite orders, and a C++ standard rule concerning the visibility of values assigned by atomic or synchronization operations.

### Source excerpt

I wasn't planning to write about lock-free programming again, but a commenter named Mike recently asked an interesting question on my Acquire and Release Semantics post from 2012. It's a question I wondered about years ago, but could never really reconcile until (possibly) now. A quick recap: A read-acquire operation cannot be reordered, either by the compiler or the CPU, with any read or write operation that follows it in program order. A write-release operation cannot be reordered with any read or write operation that precedes it in program order. Those rules don't prevent the reordering of a write-release followed by a read-acquire. For example, in C++, if A and B are std::atomic<int>, and we write: A.store(1, std::memory_order_release); int b = B.load(std::memory_order_acquire); ...the compiler is free to reorder those statements, as if we had written: int b = B.load(std::memory_order_acquire); A.store(1, std::memory_order_release); And that's fair. Why the heck not? On many architectures, including x86, the CPU could perform this reordering anyway. Well, here's where Mike's question comes in. What if A and B are spinlocks? Let's say that the spinlock is initially 0. To lock it, we repeatedly attempt a compare-and-swap, with acquire semantics, until it changes from 0 to 1. To unlock it, we simply set it back to 0, with release semantics. Now, suppose Thread 1 does the following: // Lock A int expected = 0; while (!A.compare_exchange_weak(expected, 1, std::memory_order_acquire)) { expected = 0; } // Unlock A A.store(0, std::memory_order_release); // Lock B while (!B.compare_exchange_weak(expected, 1, std::memory_order_acquire)) { expected = 0; } // Unlock B B.store(0, std::memory_order_release); Meanwhile, Thread 2 does the following: // Lock B int expected = 0; while (!B.compare_exchange_weak(expected, 1, std::memory_order_acquire)) { expected = 0; } // Lock A while (!A.compare_exchange_weak(expected, 1, std::memory_order_acquire)) { expected = 0; } // Unlock A A.

## A Resizable Concurrent Map

DevFeed: [A Resizable Concurrent Map](<https://devfeed.tech/articles/a-resizable-concurrent-map-21005.md>)

Original publisher: [Read original article](<https://preshing.com/20160222/a-resizable-concurrent-map>)

Author: Jeff Preshing

Published: 2016-02-22T13:05:00Z

Content type: tutorial

Language: en

Sources: [Jeff Preshing](<https://devfeed.tech/sources/jeff-preshing.md>)

Topics: [C++](<https://devfeed.tech/topics/c-plus-plus.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Java](<https://devfeed.tech/topics/java.md>), [GitHub](<https://devfeed.tech/topics/github.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [data](<https://devfeed.tech/tags/data.md>), [github](<https://devfeed.tech/tags/github.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [map](<https://devfeed.tech/tags/map.md>), [memory](<https://devfeed.tech/tags/memory.md>), [migration](<https://devfeed.tech/tags/migration.md>), [root](<https://devfeed.tech/tags/root.md>), [structure](<https://devfeed.tech/tags/structure.md>), [thread](<https://devfeed.tech/tags/thread.md>)

### AI overview

This article explains Junction's Linear map, a C++ concurrent hash map that supports resizing and deletion. It contrasts the Linear map with the simpler Crude map and describes how table migration enables continued concurrent operations.

### Source excerpt

In an earlier post, I showed how to implement the "world's simplest lock-free hash table" in C++. It was so simple that you couldn't even delete entries or resize the table. Well, a few years have passed since then, and I've recently written some concurrent maps without those limitations. You'll find them in my Junction project on GitHub. Junction contains several concurrent maps - even the 'world's simplest' is there, under the name ConcurrentMap_Crude. For brevity, let's call that one the Crude map. In this post, I'll explain the difference between the Crude map and Junction's Linear map. Linear is the simplest Junction map that supports both resize and delete. You can review the original post for an explanation of how the Crude map works. To recap: It's based on open addressing and linear probing. That means it's basically a big array of keys and values using a linear search. When inserting or looking up a given key, you hash the key to determine where to begin the search. Concurrent inserts and lookups are permitted. Junction's Linear map is based on the same principle, except that when the array gets too full, its entire contents are migrated to a new, larger array. When the migration completes, the old table is replaced with the old one. So, how do we achieve that while still allowing concurrent operations? The Linear map's approach is based on Cliff Click's non-blocking hash map in Java, but has a few differences. The Data Structure First, we need to modify our data structure a little bit. The original Crude map had two data members: A pointer m_cells and an integer m_sizeMask. The Linear map instead has a single data member m_root, which points to a Table structure followed by the cells themselves in a single, contiguous memory block. In the Table structure, there's a new shared counter cellsRemaining, initially set to 75% of the table size. Whenever a thread tries to insert a new key, it decrements cellsRemaining first. If it decrements cellsRemaining below

## New Concurrent Hash Maps for C++

DevFeed: [New Concurrent Hash Maps for C++](<https://devfeed.tech/articles/new-concurrent-hash-maps-for-c-21004.md>)

Original publisher: [Read original article](<https://preshing.com/20160201/new-concurrent-hash-maps-for-cpp>)

Author: Jeff Preshing

Published: 2016-02-01T13:30:00Z

Content type: article

Language: en

Sources: [Jeff Preshing](<https://devfeed.tech/sources/jeff-preshing.md>)

Topics: [C++](<https://devfeed.tech/topics/c-plus-plus.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Library](<https://devfeed.tech/topics/library.md>), [Programming](<https://devfeed.tech/topics/programming.md>), [CMake](<https://devfeed.tech/topics/cmake.md>), [Ubuntu](<https://devfeed.tech/topics/ubuntu.md>), [Windows](<https://devfeed.tech/topics/windows.md>), [iOS](<https://devfeed.tech/topics/ios.md>), [Java](<https://devfeed.tech/topics/java.md>)

Tags: [c-plus-plus](<https://devfeed.tech/tags/c-plus-plus.md>), [cmake](<https://devfeed.tech/tags/cmake.md>), [code](<https://devfeed.tech/tags/code.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [data](<https://devfeed.tech/tags/data.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [efficiency](<https://devfeed.tech/tags/efficiency.md>), [ios](<https://devfeed.tech/tags/ios.md>), [java](<https://devfeed.tech/tags/java.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [lookup](<https://devfeed.tech/tags/lookup.md>), [map](<https://devfeed.tech/tags/map.md>), [os](<https://devfeed.tech/tags/os.md>), [platforms](<https://devfeed.tech/tags/platforms.md>), [programming](<https://devfeed.tech/tags/programming.md>), [structure](<https://devfeed.tech/tags/structure.md>), [thread](<https://devfeed.tech/tags/thread.md>), [ubuntu](<https://devfeed.tech/tags/ubuntu.md>), [windows](<https://devfeed.tech/tags/windows.md>)

### AI overview

The article introduces Junction, a BSD-licensed C++ library containing concurrent hash maps designed for lock-free, multi-threaded operations. It describes the Linear, Leapfrog, and Grampa map variants, their resizing and lookup strategies, platform support, and atomic operations.

### Source excerpt

A map is a data structure that maps a collection of keys to a collection of values. It's a common concept in computer programming. You typically manipulate maps using functions such as find, insert and erase. A concurrent map is one that lets you call some of those functions concurrently - even in combinations where the map is modified. If it lets you call insert from multiple threads, with no mutual exclusion, it's a concurrent map. If it lets you call insert while another thread is calling find, with no mutual exclusion, it's a concurrent map. Other combinations might be allowed, too. Traditional maps, such as std::map and std::unordered_map, don't allow that. Today I'm releasing Junction, a C++ library that contains several new concurrent maps. It's BSD-licensed, so you can use the source code freely in any project, for any purpose. On my Core i7-5930K, Junction's two fastest maps outperform all other concurrent maps. They come in three flavors: Junction's Linear map is similar to the simple lock-free hash table I published a while ago, except that it also supports resizing, deleting entries, and templated key/value types. It was inspired by Cliff Click's non-blocking hash map in Java, but has a few differences. Junction's Leapfrog map is similar to Linear, except that it uses a probing strategy loosely based on hopscotch hashing. This strategy improves lookup efficiency when the table is densely populated. Leapfrog scales better than Linear because it modifies shared state far less frequently. Junction's Grampa map is similar to Leapfrog, except that at high populations, the map gets split into a set of smaller, fixed-size Leapfrog tables. Whenever one of those tables overflows, it gets split into two new tables instead of resizing the entire map. Junction aims to support as many platforms as possible. So far, it's been tested on Windows, Ubuntu, OS X and iOS. Its main dependencies are CMake and a companion library called Turf. Turf is an abstraction layer over

## tCache - Scalable data-aware Java Caching

DevFeed: [tCache - Scalable data-aware Java Caching](<https://devfeed.tech/articles/tcache-scalable-data-aware-java-caching-27934.md>)

Original publisher: [Read original article](<https://tech.trivago.com/post/2015-10-15-tcache/>)

Author: Christian Esken

Published: 2015-10-15T00:00:00Z

Content type: article

Language: en

Sources: [Trivago](<https://devfeed.tech/sources/trivago.md>)

Topics: [Caching](<https://devfeed.tech/topics/caching.md>), [Java](<https://devfeed.tech/topics/java.md>), [data](<https://devfeed.tech/topics/data.md>), [Redis](<https://devfeed.tech/topics/redis.md>)

Tags: [backend](<https://devfeed.tech/tags/backend.md>), [caching](<https://devfeed.tech/tags/caching.md>), [consistency](<https://devfeed.tech/tags/consistency.md>), [data](<https://devfeed.tech/tags/data.md>), [java](<https://devfeed.tech/tags/java.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [locking](<https://devfeed.tech/tags/locking.md>), [memcached](<https://devfeed.tech/tags/memcached.md>), [network](<https://devfeed.tech/tags/network.md>), [open-source](<https://devfeed.tech/tags/open-source.md>), [performance](<https://devfeed.tech/tags/performance.md>), [redis](<https://devfeed.tech/tags/redis.md>)

### AI overview

This article presents tCache, a local in-process cache for the JVM that can complement shared caches such as Redis and Memcached. It describes data-aware and near-lock-free eviction, configurable expiration and invalidation, cache statistics, load spreading, and support for high-throughput operations.

### Source excerpt

Caching data is an essential part in many high-load scenarios. A local 1st-level cache can augment a shared 2nd-level cache like Redis and Memcached to further boost performance. An in-process cache involves no network overhead, so the cache speed is only limited by local resources like CPU, memory transfer speed and locking.

## You Can Do Any Kind of Atomic Read-Modify-Write Operation

DevFeed: [You Can Do Any Kind of Atomic Read-Modify-Write Operation](<https://devfeed.tech/articles/you-can-do-any-kind-of-atomic-read-modify-write-operation-21003.md>)

Original publisher: [Read original article](<https://preshing.com/20150402/you-can-do-any-kind-of-atomic-read-modify-write-operation>)

Author: Jeff Preshing

Published: 2015-04-02T11:20:00Z

Content type: tutorial

Language: en

Sources: [Jeff Preshing](<https://devfeed.tech/sources/jeff-preshing.md>)

Topics: [Code](<https://devfeed.tech/topics/code.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [cpu](<https://devfeed.tech/topics/cpu.md>)

Tags: [atomic](<https://devfeed.tech/tags/atomic.md>), [cas](<https://devfeed.tech/tags/cas.md>), [code](<https://devfeed.tech/tags/code.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [shift-left](<https://devfeed.tech/tags/shift-left.md>), [thread](<https://devfeed.tech/tags/thread.md>), [xor](<https://devfeed.tech/tags/xor.md>)

### AI overview

This article explains how to implement arbitrary atomic read-modify-write operations in C++11 using compare-and-swap loops. It covers lock-free behavior, the role of CPU instructions, and the challenges of concurrent modifications.

### Source excerpt

Atomic read-modify-write operations - or "RMWs" - are more sophisticated than atomic loads and stores. They let you read from a variable in shared memory and simultaneously write a different value in its place. In the C++11 atomic library, all of the following functions perform an RMW: std::atomic<>::fetch_add() std::atomic<>::fetch_sub() std::atomic<>::fetch_and() std::atomic<>::fetch_or() std::atomic<>::fetch_xor() std::atomic<>::exchange() std::atomic<>::compare_exchange_strong() std::atomic<>::compare_exchange_weak() fetch_add, for example, reads from a shared variable, adds another value to it, and writes the result back - all in one indivisible step. You can accomplish the same thing using a mutex, but a mutex-based version wouldn't be lock-free. RMW operations, on the other hand, are designed to be lock-free. They'll take advantage of lock-free CPU instructions whenever possible, such as ldrex/strex on ARMv7. A novice programmer might look at the above list of functions and ask, "Why does C++11 offer so few RMW operations? Why is there an atomic fetch_add, but no atomic fetch_multiply, no fetch_divide and no fetch_shift_left?" There are two reasons: Because there is very little need for those RMW operations in practice. Try not to get the wrong impression of how RMWs are used. You can't write safe multithreaded code by taking a single-threaded algorithm and turning each step into an RMW. Because if you do need those operations, you can easily implement them yourself. As the title says, you can do any kind of RMW operation! Compare-and-Swap: The Mother of All RMWs Out of all the available RMW operations in C++11, the only one that is absolutely essential is compare_exchange_weak. Every other RMW operation can be implemented using that one. It takes a minimum of two arguments: shared.compare_exchange_weak(T& expected, T desired, ...); This function attempts to store the desired value to shared, but only if the current value of shared matches expected. It return

## Lock-Based vs Lock-Free Concurrent Algorithms

DevFeed: [Lock-Based vs Lock-Free Concurrent Algorithms](<https://devfeed.tech/articles/lock-based-vs-lock-free-concurrent-algorithms-13634.md>)

Original publisher: [Read original article](<https://mechanical-sympathy.blogspot.com/2013/08/lock-based-vs-lock-free-concurrent.html>)

Author: Martin Thompson (noreply@blogger.com)

Published: 2013-08-26T10:48:00Z

Content type: opinion

Language: en

Sources: [Mechanical Sympathy](<https://devfeed.tech/sources/mechanical-sympathy.md>)

Topics: [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Java](<https://devfeed.tech/topics/java.md>), [Algorithm](<https://devfeed.tech/topics/algorithm.md>), [Code](<https://devfeed.tech/topics/code.md>)

Tags: [algorithms](<https://devfeed.tech/tags/algorithms.md>), [atomic](<https://devfeed.tech/tags/atomic.md>), [concurrency](<https://devfeed.tech/tags/concurrency.md>), [java](<https://devfeed.tech/tags/java.md>), [jdk](<https://devfeed.tech/tags/jdk.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [locks](<https://devfeed.tech/tags/locks.md>), [performance](<https://devfeed.tech/tags/performance.md>), [review](<https://devfeed.tech/tags/review.md>), [test](<https://devfeed.tech/tags/test.md>)

### AI overview

This article reviews Java lock implementations, focusing on StampedLock and its optimistic-read design for systems with concurrent readers accessing shared state. It compares lock-based and lock-free approaches using a garbage-free spaceship-position API and a test harness across different threading and contention scenarios. The author argues that lock-free algorithms can often be a better solution for multiple-reader cases, while noting that results may vary across CPUs and operating systems.

### Source excerpt

Last week I attended a review session of the new JSR166 StampedLock run by Heinz Kabutz at the excellent JCrete unconference. StampedLock is an attempt to address the contention issues that arise in a system when multiple readers concurrently access shared state. StampedLock is designed to perform better than ReentrantReadWriteLock by taking an optimistic read approach. While attending the session a couple of things occurred to me. Firstly, I thought it was about time I reviewed the current status of Java lock implementations. Secondly, that although StampedLock looks like a good addition to the JDK, it seems to miss the fact that lock-free algorithms are often a better solution to the multiple reader case. Test Case To compare implementations I needed an API test case that would not favour a particular approach. For example, the API should be garbage free and allow the methods to be atomic. A simple test case is to design a spaceship that can be moved around a 2-dimensional space with the coordinates of its position available to be read atomically. At least 2 fields need to be read, or written, per transaction to make the concurrency interesting. /** * Interface to a concurrent representation of a ship that can move around * a 2 dimensional space with updates and reads performed concurrently. */ public interface Spaceship { /** * Read the position of the spaceship into the array of coordinates provided. * * @param coordinates into which the x and y coordinates should be read. * @return the number of attempts made to read the current state. */ int readPosition(final int[] coordinates); /** * Move the position of the spaceship by a delta to the x and y coordinates. * * @param xDelta delta by which the spaceship should be moved in the x-axis. * @param yDelta delta by which the spaceship should be moved in the y-axis. * @return the number of attempts made to write the new coordinates. */ int move(final int xDelta, final int yDelta); } The above API would be cleaner by

## Concurrent queue in C

DevFeed: [Concurrent queue in C](<https://devfeed.tech/articles/concurrent-queue-in-c-38910.md>)

Original publisher: [Read original article](<https://idea.popcount.org/2012-09-11-concurrent-queue-in-c>)

Author: Marek

Published: 2012-09-10T22:00:00Z

Content type: tutorial

Language: en

Sources: [Marek Majkowski](<https://devfeed.tech/sources/marek-majkowski.md>)

Topics: [C](<https://devfeed.tech/topics/c.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Data structures](<https://devfeed.tech/topics/data-structures.md>), [Algorithms, Complexity](<https://devfeed.tech/topics/algorithms-complexity.md>)

Tags: [c](<https://devfeed.tech/tags/c.md>), [concurrent](<https://devfeed.tech/tags/concurrent.md>), [implementation](<https://devfeed.tech/tags/implementation.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [memory](<https://devfeed.tech/tags/memory.md>), [mutex](<https://devfeed.tech/tags/mutex.md>), [pointers](<https://devfeed.tech/tags/pointers.md>), [queue](<https://devfeed.tech/tags/queue.md>), [thread](<https://devfeed.tech/tags/thread.md>), [threads](<https://devfeed.tech/tags/threads.md>)

### AI overview

This article explains the design and implementation of a thread-safe concurrent queue in C. It compares a mutex-based approach with a lock-free design using CAS, discusses CPU memory ordering and pointer-related memory reclamation problems, and presents a blocking queue implementation using locks.

### Source excerpt

Concurrent queue in C I needed a queue implementation written in C for one of my ever-experimental projects. The complex part was to make it thread-safe - it was going to be used for exchanging data between threads. Usually, I'd just take the doubly linked list implementation from the linux kernel1, wrap it in a mutex and quickly move on to another challenge. This time though, I decided to make sure the queue is as efficient as possible.

## Java Lock Implementations

DevFeed: [Java Lock Implementations](<https://devfeed.tech/articles/java-lock-implementations-13620.md>)

Original publisher: [Read original article](<https://mechanical-sympathy.blogspot.com/2011/11/java-lock-implementations.html>)

Author: Martin Thompson (noreply@blogger.com)

Published: 2011-11-19T02:57:00Z

Content type: comparison

Language: en

Sources: [Mechanical Sympathy](<https://devfeed.tech/sources/mechanical-sympathy.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [Concurrent Programming](<https://devfeed.tech/topics/concurrent-programming.md>), [x86](<https://devfeed.tech/topics/x86.md>), [Linux](<https://devfeed.tech/topics/linux.md>)

Tags: [concurrent](<https://devfeed.tech/tags/concurrent.md>), [cpu](<https://devfeed.tech/tags/cpu.md>), [java](<https://devfeed.tech/tags/java.md>), [linux](<https://devfeed.tech/tags/linux.md>), [lock-free](<https://devfeed.tech/tags/lock-free.md>), [locking](<https://devfeed.tech/tags/locking.md>), [locks](<https://devfeed.tech/tags/locks.md>), [ordering](<https://devfeed.tech/tags/ordering.md>), [performance](<https://devfeed.tech/tags/performance.md>), [tests](<https://devfeed.tech/tags/tests.md>), [x86](<https://devfeed.tech/tags/x86.md>)

### AI overview

This article compares Java lock implementations, including atomic locking on language monitors, biased locking, and ReentrantLock. It describes a test measuring lock costs under increasing contention on Intel CPUs using Linux and Oracle JDK 1.6.0_29, and recommends measuring applications before choosing JVM lock settings.

### Source excerpt

We all use 3rd party libraries as a normal part of development. Generally, we have no control over their internals. The libraries provided with the JDK are a typical example. Many of these libraries employ locks to manage contention. JDK locks come with two implementations. One uses atomic CAS style instructions to manage the claim process. CAS instructions tend to be the most expensive type of CPU instructions and on x86 have memory ordering semantics. Often locks are un-contended which gives rise to a possible optimisation whereby a lock can be biased to the un-contended thread using techniques to avoid the use of atomic instructions. This biasing allows a lock in theory to be quickly reacquired by the same thread. If the lock turns out to be contended by multiple threads the algorithm with revert from being biased and fall back to the standard approach using atomic instructions. Biased locking became the default lock implementation with Java 6. When respecting the single writer principle, biased locking should be your friend. Lately, when using the sockets API, I decided to measure the lock costs and was surprised by the results. I found that my un-contended thread was incurring a bit more cost than I expected from the lock. I put together the following test to compare the cost of the current lock implementations available in Java 6. The Test For the test I shall increment a counter within a lock, and increase the number of contending threads on the lock. This test will be repeated for the 3 major lock implementations available to Java: Atomic locking on Java language monitors Biased locking on Java language monitors ReentrantLock introduced with the java.util.concurrent package in Java 5. I'll also run the tests on the 3 most recent generations of the Intel CPU. For each CPU I'll execute the tests up to the maximum number of concurrent threads the core count will support. The tests are carried out with 64-bit Linux (Fedora Core 15) and Oracle JDK 1.6.0_29. The C