Skip to content

Unify lazy atomics in entropy backends#804

Open
tamird wants to merge 1 commit intorust-random:masterfrom
tamird:cleanup-atomics
Open

Unify lazy atomics in entropy backends#804
tamird wants to merge 1 commit intorust-random:masterfrom
tamird:cleanup-atomics

Conversation

@tamird
Copy link
Contributor

@tamird tamird commented Feb 3, 2026

Replace ad-hoc atomic lazy caches with shared lazy helpers in the Linux/Android fallback, NetBSD, RDRAND, and RNDR backends. Add LazyPtr alongside LazyUsize and LazyBool so pointer and boolean caches use the same initialization contract.

This reduces duplicated cache logic and keeps backend probing/fallback semantics aligned while preserving the existing retry-until-cached behavior.

Copy link
Member

@newpavlov newpavlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep the NonNull stuff.

Replace ad-hoc atomic lazy caches with shared lazy helpers in the
Linux/Android fallback, NetBSD, RDRAND, and RNDR backends. Add `LazyPtr`
alongside `LazyUsize` and `LazyBool` so pointer and boolean caches use
the same initialization contract.

This reduces duplicated cache logic and keeps backend probing/fallback
semantics aligned while preserving the existing retry-until-cached
behavior.
Copy link
Contributor Author

@tamird tamird left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer to keep the NonNull stuff.

Done.

Copy link
Member

@newpavlov newpavlov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's worth to split the lazy module to lazy_bool and lazy_ptr modules. It would allow us to remove the #![allow(dead_code)] part.

I also think it's fine to name LazyNonNull simply as LazyPtr and write proper docs for the structs since you no longer use macro to generate them.

const NOT_AVAILABLE: NonNull<c_void> = unsafe { NonNull::new_unchecked(usize::MAX as *mut c_void) };

static GETRANDOM_FN: AtomicPtr<c_void> = AtomicPtr::new(core::ptr::null_mut());
const NOT_AVAILABLE: NonNull<c_void> = NonNull::dangling();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is correct. Quoting the method docs:

Note that the address of the returned pointer may potentially be that of a valid pointer, which means this must not be used as a “not yet initialized” sentinel value.

Meanwhile with the usize::MAX variant we can argue that it fundamentally can not be a valid function pointer.

Some(fptr) => {
let getrandom_fn = unsafe { transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
let dangling_ptr = NonNull::dangling().as_ptr();
let getrandom_fn = unsafe { transmute::<*mut c_void, GetRandomFn>(fptr.as_ptr()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are you casting from NonNull<c_void> to *mut c_void?

} else {
// note: `transmute` is currently the only way to convert a pointer into a function reference
let getrandom_fn = unsafe { transmute::<NonNull<c_void>, GetRandomFn>(fptr) };
let getrandom_fn = unsafe { transmute::<*mut c_void, GetRandomFn>(fptr.as_ptr()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.

static GETRANDOM_FN: lazy::LazyNonNull<c_void> = lazy::LazyNonNull::new();

let fptr = GETRANDOM_FN.unsync_init(init);
let fptr = unsafe { mem::transmute::<*mut c_void, GetRandomFn>(fptr.as_ptr()) };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same.


// Identical to LazyUsize except with bool instead of usize.
pub(crate) struct LazyBool(LazyUsize);
pub(crate) struct LazyBool(AtomicUsize);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can use AtomicU8 here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants