Skip to content
Xila
Demonstration

Synchronization

The synchronization crate standardizes synchronization primitives used across Core.

Last updatedEdit page

The synchronization crate standardizes synchronization primitives used across Core.

  • Re-exports embassy_sync primitives through one crate-local entry point.
  • Provides portable Arc/Weak support, including a custom fallback for targets without atomic pointer support.
  • In scope: synchronization primitives and ownership wrappers.
  • Out of scope: scheduler/executor implementation and task lifecycle policy.
  • lib.rs: top-level re-exports.
  • arc/mod.rs: target-gated arc selection.
    • With target_has_atomic = "ptr": uses alloc::sync::Arc/Weak.
    • Without pointer atomics: uses arc/arc_lock.rs mutex-backed Arc implementation.
  • Modules and executables import mutex/rwlock/once/channel primitives from this crate.
  • Fallback Arc implementation uses CriticalSectionRawMutex + RefCell counters for no-atomic targets.
  • Primary dependency: embassy-sync (std feature enabled on host targets).
  • Broadly consumed by file-system backends, graphics, and other concurrent modules.
  • Most primitives are infallible at API level; contention manifests as wait/lock behavior.
  • Fallback Arc enforces overflow checks on reference counters and may panic on overflow.
  • Additional wrappers/adapters can be added to normalize synchronization semantics across targets.
  • Arc fallback can evolve independently while preserving exported Arc/Weak contract.
  • Contract: one consistent synchronization import surface across platforms.
  • Current implementation: direct embassy_sync re-export plus conditional Arc fallback implementation.
  • Behavior still inherits cooperative runtime assumptions from executor usage patterns.
  • Fallback Arc prioritizes portability over lock-free performance.

The crate is #![no_std], re-exports embassy_sync and provides synchronization::Arc/Weak. Choose primitives according to the execution context:

  • mutex::Mutex and rwlock::RwLock support async tasks sharing state; avoid holding a guard across lengthy operations that block protocol progress.
  • blocking_mutex and its CriticalSectionRawMutex are for short synchronous critical sections. A critical section does not automatically mean independent threads or interrupts may block arbitrarily.
  • signal, channels and once_lock provide task notification and one-time publication, used by Task, VFS and other services.
  • Arc/Weak manage heap-backed shared ownership, not scheduling or resource cleanup policy.

When target_has_atomic = "ptr", Arc and Weak come directly from alloc::sync. Otherwise Xila exports a custom arc_lock implementation using CriticalSectionRawMutex and interior-mutable reference counts. Both expose Arc::new, clone, downgrade, Weak::upgrade, strong_count, weak_count, get_mut and ptr_eq style APIs.

use synchronization::Arc;
let data = Arc::new(42);
let another = Arc::clone(&data);
assert!(Arc::ptr_eq(&data, &another));

The no-atomic fallback allocates an ArcInner<T> on the heap. Its reference counters are checked for overflow (which panics) and protected by critical-section locks, so cloning/dropping has a different performance cost from atomics. get_mut only returns mutable access when the allocation has a unique strong owner with no conflicting weak ownership.

Arc only provides shared ownership. Access to mutable T must still use synchronization appropriate for the target, and dropping the last reference is not a substitute for explicitly closing a VFS file, stopping a graphics animation, or tearing down a device context.