[−]Struct std::os::fortanix_sgx::usercalls::raw::FifoDescriptor
A circular buffer used as a FIFO queue with atomic reads and writes.
The read offset is the element that was most recently read by the receiving end of the queue. The write offset is the element that was most recently written by the sending end. If the two offsets are equal, the queue is either empty or full.
The size of the buffer is such that not all the bits of the offset are necessary to encode the current offset. The next highest unused bit is used to keep track of the number of times the offset has wrapped around. If the offsets are the same and the bit is the same in the read and write offsets, the queue is empty. If the bit is different in the read and write offsets, the queue is full.
The following procedures will operate the queues in a multiple producer single consumer (MPSC) fashion.
Push operation
To push an element onto the queue:
- Load the current offsets.
- If the queue is full, wait, then go to step 1.
- Add 1 to the write offset and do an atomic compare-and-swap (CAS) with the current offsets. If the CAS was not succesful, go to step 1.
- Write the data, then the
id
. - If the queue was empty in step 1, signal the reader to wake up.
Pop operation
To pop an element off the queue:
- Load the current offsets.
- If the queue is empty, wait, then go to step 1.
- Add 1 to the read offset.
- Read the
id
at the new read offset. - If
id
is0
, go to step 4 (spin). Spinning is OK because data is expected to be written imminently. - Read the data, then store
0
in theid
. - Store the new read offset.
- If the queue was full in step 1, signal the writer to wake up.
Fields
data: *mut T
Pointer to the queue memory. Must have a size of
len * size_of::<T>()
bytes and have alignment align_of::<T>
.
len: usize
The number of elements pointed to by data
. Must be a power of two
less than or equal to 2³¹.
offsets: *const AtomicUsize
Actually a (u32, u32)
tuple, aligned to allow atomic operations
on both halves simultaneously. The first element (low dword) is
the read offset and the second element (high dword) is the write
offset.
Trait Implementations
impl<T> Clone for FifoDescriptor<T>
fn clone(&self) -> FifoDescriptor<T>
fn clone_from(&mut self, source: &Self)
1.0.0[src]
impl<T> Copy for FifoDescriptor<T>
impl<T> UserSafeSized for FifoDescriptor<T>
[src]
Auto Trait Implementations
impl<T> RefUnwindSafe for FifoDescriptor<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
impl<T> !Send for FifoDescriptor<T>
impl<T> !Sync for FifoDescriptor<T>
impl<T> Unpin for FifoDescriptor<T>
impl<T> UnwindSafe for FifoDescriptor<T> where
T: RefUnwindSafe,
T: RefUnwindSafe,
Blanket Implementations
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,
impl<T> Borrow<T> for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut<T> for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T> From<T> for T
[src]
impl<T, U> Into<U> for T where
U: From<T>,
[src]
U: From<T>,
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom<U> for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T, U> TryInto<U> for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,