David S from New Jersey Pattern

From: dseda1@xxxxxxx

Date: Thu Dec 11 2025 - 11:41:57 EST


Subject: [RFC] Lock-free atomic handler dispatch for runtime reconfiguration

To: linux-rt@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx

---

Hello,

I am writing to share a pattern I discovered while building single-producer/single-consumer (SPSC) ring buffers for low-latency systems. Over the past 18 months of learning C, I have developed a lock-free mechanism for hot-swapping function pointers at runtime using atomic operations with C11 acquire-release semantics.

**Backstory:** I have approximately 1.5 years of hands-on C experience and about 15,000 lines of production code. The first 10,000 lines focused heavily on understanding pointers. This atomic dispatch pattern emerged over 8 months of iterative development. I recognize the kernel community brings deep expertise, and I approach this with appropriate humility.

**Note on Presentation:** I am dyslexic and ambidextrous and I use Ai assistive tools for grammar and clarity, but all technical content and pattern discovery are entirely my own work.

---

## My Problem

In real-time systems with strict latency budgets, it is common to need runtime reconfiguration without stopping the world or coordinating threads. Examples include:

- Toggling audit/metrics export on and off
- Swapping diagnostic callbacks without restart
- Hot-swapping print functions for different output formats
- Changing processing strategies at runtime based on control-plane signals

Existing approaches have trade-offs:
- **Locks** introduce coordination overhead and potential contention
- **Callback tables** require index management and potentially CAS loops
- **Jump labels** provide compile-time flexibility only
- **Full restart** requires stopping the system

I needed a pattern that was lock-free, runtime-reconfigurable, and required zero coordination overhead.

---

## My Solution: Atomic Function Dispatch

The core idea is simple: store a function pointer in shared memory and update it atomically using C11 acquire-release semantics. The producer publishes a new handler; the consumer loads it with the guarantee that all prior writes are visible.

```c
/* Producer: hot-swap a new handler */
void Control_room_CheckOff_Switch(void (*fn)(const StringRegistry *)) {
    atomic_store_explicit(
        (_Atomic(void (**)(const StringRegistry *))) &CR.size,
        fn,
        memory_order_release
    );
}

/* Consumer: load and invoke safely */
void (*current_handler)(const StringRegistry *) = 
    atomic_load_explicit(
        (_Atomic(void (*)(const StringRegistry *))) &CR.size,
        memory_order_acquire
    );

if (current_handler) {
    current_handler(&registry);
}
```

The acquire-release pair ensures:
- Producer releases: "All prior writes are complete and visible."
- Consumer acquires: "I see all prior writes and the new handler safely."

---

## Performance Characteristics

| Attribute | Measurement |
|-----------|------------|
| **Latency** | ~8-12 CPU cycles (~15-20 ns on x86-64) |
| **Jitter** | Zero — fixed, deterministic latency |
| **Lock-Free** | Yes — single atomic store/load, no loops or coordination |
| **Coordination Overhead** | None — no locks, CAS loops, or kernel interaction |

This pattern occupies a middle ground:
- Near jump_label speed (3-5 cycles, but compile-time only)
- Full runtime flexibility (any function, any time)
- Zero stop-the-world pauses
- Predictable, bounded latency

---

## Real-World Usage

In production SPSC ring buffers, this enables control-plane hot-swaps:

```c
void ControlRoom_swap_audit(struct ControlRoom *cr, 
                            void (*new_fn)(const struct ControlRoom *)) {
    atomic_store_explicit(&cr->audit_fn, new_fn, memory_order_release);
}

void ControlRoom_swap_metrics(struct ControlRoom *cr, 
                              void (*new_fn)(const struct ControlRoom *)) {
    atomic_store_explicit(&cr->push_metrics_fn, new_fn, memory_order_release);
}
```

Each swap is instantaneous and visible to all consumers with no coordination. This is essential for real-time control in low-latency systems.

---

## Why Share This

I studied the Linux kernel extensively while learning systems programming. The kernel's latency discipline and careful use of memory ordering were my primary teachers. Similar structures exist in `kernel/jump_label.c` and `kernel/events/ring_buffer.c`, and I wanted to validate my approach against existing kernel patterns.

I do not claim this pattern is novel in the kernel context. But I discovered it independently through first-principles thinking about atomic operations, and it has proven invaluable in practice. I hope this submission demonstrates that careful study of kernel patterns, combined with first-principles reasoning about memory ordering, can lead to useful code even for newcomers to C.

---

## Limitations

1. **Specific to atomic function pointers** — not for larger structures
2. **Not a replacement for callback tables** — if I need index-based dispatch, a callback table may be more appropriate
3. **Still testing latency measurements** — I am validating the 8-12 cycle estimate with hardware performance counters

---

## Questions for the Community

I welcome feedback on:
- Memory ordering correctness across architectures
- Whether this pattern solves a problem the kernel cares about
- Suggestions for production-grade validation
- Any gotchas or limitations I may have missed

---

## Conclusion

The Atomic Function Dispatch pattern is a lock-free, zero-overhead mechanism for hot-swapping function pointers at runtime. I am grateful for the opportunity to share this work and welcome corrections or questions from the community.

Best regards,

David

---

**Appendix: RFC Document**

For detailed technical breakdown, wire diagrams, and integration examples, please refer to the attached RFC document.

David dseda1@xxxxxxx



### Appendix: Wire Diagram

```
┌──────────────────────────────────────────────────┐
│  CALLER                                          │
│  void new_handler(const StringRegistry *r) {...} │
│  Control_room_CheckOff_Switch(new_handler);      │
│                   │                              │
│                   ▼                              │
│            (*fn) = signal                        │
│                   │                              │
└───────────────────┼──────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────────┐
│  ATOMIC STORE (The Wire)                         │
│  atomic_store_explicit(                          │
│      &cr->handler_fn,                            │
│      fn,                                         │
│      memory_order_release)                       │
│                   │                              │
└───────────────────┼──────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────────┐
│  SHARED MEMORY (The Terminal)                    │
│  cr->handler_fn now points to: new_handler      │
│                                                  │
│  All prior writes are visible to consumers       │
│                   │                              │
└───────────────────┼──────────────────────────────┘
                    │
                    ▼
┌──────────────────────────────────────────────────┐
│  CONSUMER                                        │
│  void (*h)(...) = atomic_load_explicit(          │
│      &cr->handler_fn, memory_order_acquire)      │
│                                                  │
│  Safe to invoke; all prior writes visible        │
│  h(&registry);                                   │
└──────────────────────────────────────────────────┘
```

s


Subject: [RFC] Lock-free atomic handler dispatch for runtime reconfiguration

To: linux-rt@xxxxxxxxxxxxxxx
Cc: linux-kernel@xxxxxxxxxxxxxxx

---

Hello,

I am writing to share a pattern I discovered while building single-producer/single-consumer (SPSC) ring buffers for low-latency systems. Over the past 18 months of learning C, I have developed a lock-free mechanism for hot-swapping function pointers at runtime using atomic operations with C11 acquire-release semantics.

**Background:** I have approximately 1.5 years of hands-on C experience and about 15,000 lines of production code. The first 10,000 lines focused heavily on understanding pointers. This atomic dispatch pattern emerged over 8 months of iterative development. I recognize the kernel community brings deep expertise, and I approach this with appropriate humility.

**Note on presentation:** I am dyslexic and ambidextrous and I use Ai assistive tools for grammar and clarity, but all technical content and pattern discovery are entirely my own work.

---

## My Problem

In real-time systems with strict latency budgets, it is common to need runtime reconfiguration without stopping the world or coordinating threads. Examples include:

- Toggling audit/metrics export on and off
- Swapping diagnostic callbacks without restart
- Hot-swapping print functions for different output formats
- Changing processing strategies at runtime based on control-plane signals

Existing approaches have trade-offs:
- **Locks** introduce coordination overhead and potential contention
- **Callback tables** require index management and potentially CAS loops
- **Jump labels** provide compile-time flexibility only
- **Full restart** requires stopping the system

I needed a pattern that was lock-free, runtime-reconfigurable, and required zero coordination overhead.

---

## My Solution: Atomic Function Dispatch

The core idea is simple: store a function pointer in shared memory and update it atomically using C11 acquire-release semantics. The producer publishes a new handler; the consumer loads it with the guarantee that all prior writes are visible.

```c
/* Producer: hot-swap a new handler */
void Control_room_CheckOff_Switch(void (*fn)(const StringRegistry *)) {
atomic_store_explicit(
(_Atomic(void (**)(const StringRegistry *))) &CR.size,
fn,
memory_order_release
);
}

/* Consumer: load and invoke safely */
void (*current_handler)(const StringRegistry *) =
atomic_load_explicit(
(_Atomic(void (*)(const StringRegistry *))) &CR.size,
memory_order_acquire
);

if (current_handler) {
current_handler(&registry);
}
```

The acquire-release pair ensures:
- Producer releases: "All prior writes are complete and visible."
- Consumer acquires: "I see all prior writes and the new handler safely."

---

## Performance Characteristics

| Attribute | Measurement |
|-----------|------------|
| **Latency** | ~8-12 CPU cycles (~15-20 ns on x86-64) |
| **Jitter** | Zero â?? fixed, deterministic latency |
| **Lock-Free** | Yes â?? single atomic store/load, no loops or coordination |
| **Coordination Overhead** | None â?? no locks, CAS loops, or kernel interaction |

This pattern occupies a middle ground:
- Near jump_label speed (3-5 cycles, but compile-time only)
- Full runtime flexibility (any function, any time)
- Zero stop-the-world pauses
- Predictable, bounded latency

---

## Real-World Usage

In production SPSC ring buffers, this enables control-plane hot-swaps:

```c
void ControlRoom_swap_audit(struct ControlRoom *cr,
void (*new_fn)(const struct ControlRoom *)) {
atomic_store_explicit(&cr->audit_fn, new_fn, memory_order_release);
}

void ControlRoom_swap_metrics(struct ControlRoom *cr,
void (*new_fn)(const struct ControlRoom *)) {
atomic_store_explicit(&cr->push_metrics_fn, new_fn, memory_order_release);
}
```

Each swap is instantaneous and visible to all consumers with no coordination. This is essential for real-time control in low-latency systems.

---

## Why Share This

I studied the Linux kernel extensively while learning systems programming. The kernel's latency discipline and careful use of memory ordering were my primary teachers. Similar structures exist in `kernel/jump_label.c` and `kernel/events/ring_buffer.c`, and I wanted to validate my approach against existing kernel patterns.

I do not claim this pattern is novel in the kernel context. But I discovered it independently through first-principles thinking about atomic operations, and it has proven invaluable in practice. I hope this submission demonstrates that careful study of kernel patterns, combined with first-principles reasoning about memory ordering, can lead to useful code even for newcomers to C.

---

## Limitations

1. **Specific to atomic function pointers** â?? not for larger structures
2. **Not a replacement for callback tables** â?? if I need index-based dispatch, a callback table may be more appropriate
3. **Still testing latency measurements** â?? I am validating the 8-12 cycle estimate with hardware performance counters

---

## Questions for the Community

I welcome feedback on:
- Memory ordering correctness across architectures
- Whether this pattern solves a problem the kernel cares about
- Suggestions for production-grade validation
- Any gotchas or limitations I may have missed

---

## Conclusion

The Atomic Function Dispatch pattern is a lock-free, zero-overhead mechanism for hot-swapping function pointers at runtime. I am grateful for the opportunity to share this work and welcome corrections or questions from the community.

Best regards,

David

---

**Appendix: RFC Document**

For detailed technical breakdown, wire diagrams, and integration examples, please refer to the attached RFC document.

David dseda1@xxxxxxx



### Appendix: Wire Diagram

```
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â?? CALLER â??
â?? void new_handler(const StringRegistry *r) {...} â??
â?? Control_room_CheckOff_Switch(new_handler); â??
â?? â?? â??
â?? â?¼ â??
â?? (*fn) = signal â??
â?? â?? â??
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â?¼â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â??
â?¼
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â?? ATOMIC STORE (The Wire) â??
â?? atomic_store_explicit( â??
â?? &cr->handler_fn, â??
â?? fn, â??
â?? memory_order_release) â??
â?? â?? â??
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â?¼â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â??
â?¼
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â?? SHARED MEMORY (The Terminal) â??
â?? cr->handler_fn now points to: new_handler â??
â?? â??
â?? All prior writes are visible to consumers â??
â?? â?? â??
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â?¼â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â??
â?¼
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
â?? CONSUMER â??
â?? void (*h)(...) = atomic_load_explicit( â??
â?? &cr->handler_fn, memory_order_acquire) â??
â?? â??
â?? Safe to invoke; all prior writes visible â??
â?? h(&registry); â??
â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??â??
```