Phase 2: Convert all 12 remaining modules to decision struct pattern#5
Merged
Phase 2: Convert all 12 remaining modules to decision struct pattern#5
Conversation
Rewrite k_mem_slab_alloc and k_mem_slab_free in the C shim to use the Extract/Decide/Apply pattern with Rust decision structs, matching the semaphore PoC. Rust now decides the action (ALLOC_OK/PEND/NOMEM and FREE_OK/WAKE_THREAD); C extracts kernel state, calls Rust, and applies. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace direct gale_stack_push_validate/pop_validate calls with the Extract→Decide→Apply pattern using GaleStackPushDecision and GaleStackPopDecision structs. Push: C peeks at wait queue head (no side effect), passes count/capacity/ has_waiter to Rust. Rust returns STORE_DATA, WAKE_WAITER, or FULL. C applies: unpend+wake, store+advance, or reject with -ENOMEM. Pop: C passes count and is_no_wait to Rust. Rust returns POP_OK (with ret=0 for data or ret=-EBUSY for empty+no_wait) or PEND_CURRENT. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add GaleFifoPutDecision, GaleFifoGetDecision, GaleLifoPutDecision, and GaleLifoGetDecision structs following the proven Extract-Decide-Apply pattern from semaphore. Rust decides whether to wake a waiter or insert data (put) and whether to dequeue, pend, or return empty (get). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace pointer-based gale_timer_expire/gale_timer_status_get with Extract-Decide-Apply decision structs (GaleTimerExpireDecision, GaleTimerStatusDecision). C extracts timer->status and timer->period, Rust returns a decision struct with the new status value, C applies it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite gale_event.c to use Extract-Decide-Apply with Rust decision structs. k_event_post_internal uses GaleEventPostDecision for masked bitmask computation, k_event_wait_internal and event_walk_op use GaleEventWaitDecision for ANY/ALL condition checks and pend/timeout decisions. Removes are_wait_conditions_met helper in favor of the unified decision struct. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite queue_insert and z_impl_k_queue_get in gale_queue.c to use the Extract→Decide→Apply pattern with Rust decision structs. C extracts kernel state (wait queue, list emptiness), Rust decides the action (WAKE vs INSERT, DEQUEUE vs RETURN_NULL vs PEND), C applies it. Data movement (linked list insertion, alloc nodes) stays in C. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite mbox_message_put and k_mbox_get in gale_mbox.c to use the Extract→Decide→Apply pattern with Rust decision structs. C extracts kernel state (rx/tx queue scan, message matching), Rust decides the post-scan action (MATCHED vs RETURN_ENOMSG vs PEND), C applies it. Data movement (message copy, async descriptors) stays in C. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace raw pointer output params in gale_timeout_add/abort/announce with decision structs (GaleTimeoutAddDecision, GaleTimeoutAbortDecision, GaleTimeoutAnnounceDecision) following the Extract->Decide->Apply pattern. Legacy pointer-based API retained as thin wrappers for backward compat. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrite z_impl_k_msgq_put and z_impl_k_msgq_get to use the Extract-Decide-Apply pattern: C extracts kernel state (spinlock, wait queue side effects), Rust decides the action via decision structs, C applies the result. - GaleMsgqPutDecision: PUT_OK / WAKE_READER / PEND_CURRENT / RETURN_FULL - GaleMsgqGetDecision: GET_OK / WAKE_WRITER / PEND_CURRENT / RETURN_EMPTY - put_front stays with Phase 1 API (always K_NO_WAIT, no decision needed) - Data copy (memcpy) remains in C; Rust decides index/count updates Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rust decides the lock/unlock action via GaleMutexLockDecision and GaleMutexUnlockDecision structs; C applies the decision including priority inheritance adjustments. Overflow protection preserved. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ar, futex, poll) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…pipe, queue, mbox, fifo, lifo) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…tructure modules Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ENOMSG, ETIMEDOUT, ECANCELED, EOVERFLOW, and EADDRINUSE used Linux values instead of Zephyr's. This caused msgq boundary tests to fail: Rust returned -42 (Linux ENOMSG) but Zephyr tests expect -35. Fixed all five mismatched constants in both src/error.rs and plain/src/error.rs to match zephyr/lib/libc/minimal/include/errno.h. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After a reader wakes from a direct copy by a writer, buf.used may already satisfy the request. The decision struct conversion moved the buf.used == len check inside the READ_OK/WAKE_WRITER branches, so when the loop re-entered and Rust returned READ_PEND (because the ring buffer was empty), the reader hung forever despite having all its data. Add buf.used >= len guard at the top of the for(;;) loop, matching the unconditional check in upstream Zephyr's k_pipe_read. This also fixes the semaphore test_sem_multi_take_timeout_diff_sem hang, which used a pipe for inter-thread result reporting. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gale_k_pipe_read_decide had a guard (size > 0) that prevented WAKE_WRITER from ever being returned for zero-size pipes. Upstream Zephyr wakes writers unconditionally when pipe_full() (space == 0), which is always true for zero-size pipes. Without this wake, the reader pends and no writer ever runs copy_to_pending_readers. Remove the size > 0 guard so the condition becomes used >= size, which for zero-size pipes is 0 >= 0 = true. This lets writers copy data directly to readers via the swap_data mechanism. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Converts all 12 remaining wired kernel modules from arithmetic-oracle to Extract→Decide→Apply decision struct pattern. Combined with Phase 1 (sem, PR #4), this completes all 13 wired modules.
Modules Converted
Test plan
cargo test— 66 test suites, 0 failurescargo build --manifest-path ffi/Cargo.toml— compiles🤖 Generated with Claude Code