stack_queue/
helpers.rs

1use crate::queue::INDEX_SHIFT;
2
3pub(crate) const REGION_MASK: usize = 0b11111111;
4
5#[cfg(target_pointer_width = "64")]
6pub(crate) const REGION_COUNT: usize = 8;
7
8#[cfg(target_pointer_width = "32")]
9pub(crate) const REGION_COUNT: usize = 4;
10
11/// 8 regions, 8 bits per region
12#[inline(always)]
13#[cfg(target_pointer_width = "64")]
14pub(crate) const fn region_size<const N: usize>() -> usize {
15  N >> 3
16}
17
18/// 4 regions, 8 bits per region
19#[inline(always)]
20#[cfg(target_pointer_width = "32")]
21pub(crate) const fn region_size<const N: usize>() -> usize {
22  N >> 2
23}
24
25/// Number of bits necessary to bitwise shift index into region
26#[inline(always)]
27#[cfg(target_pointer_width = "64")]
28pub(crate) const fn region_shift<const N: usize>() -> usize {
29  N.trailing_zeros() as usize - 3
30}
31
32/// Number of bits necessary to bitwise shift index into region
33#[inline(always)]
34#[cfg(target_pointer_width = "32")]
35pub(crate) const fn region_shift<const N: usize>() -> usize {
36  N.trailing_zeros() as usize - 2
37}
38
39/// Current occupancy region 0-7 or 0-3 depending on pointer width
40#[inline(always)]
41pub(crate) fn current_region<const N: usize>(index: usize) -> usize {
42  index >> region_shift::<N>()
43}
44
45/// The 8-bit mask of the current region, used for extracting regional occupancy
46#[inline(always)]
47pub(crate) fn region_mask<const N: usize>(index: usize) -> usize {
48  // Shift the region mask 8 bits per region
49  REGION_MASK << (current_region::<N>(index) << REGION_COUNT.trailing_zeros())
50}
51
52/// Convert slot into an index by bitwise shifting away flag bits
53#[inline(always)]
54pub(crate) fn slot_index<const N: usize>(slot: usize) -> usize {
55  // The bitwise right shift discards flags and gives us a counter that wraps around. The bitwise
56  // AND gives us the modulus; this works because N will always be a power of 2, and so N - 1 will
57  // always be a mask of N-bits set that can then extract N-bits, giving values 0..N in a loop
58  // across all values in the counter and with usize::MAX being divisible by all values N
59  slot >> INDEX_SHIFT & (N - 1)
60}
61
62/// One shifted relative to the current region
63#[inline(always)]
64pub(crate) fn one_shifted<const N: usize>(index: usize) -> usize {
65  1 << ((index >> region_shift::<N>()) << REGION_COUNT.trailing_zeros())
66}