pub fn allocate_mirrored(size: usize) -> Result<*mut u8, AllocError> {
    unsafe {
        assert!(size != 0);
        let half_size = size / 2;
        assert!(half_size % allocation_granularity() == 0);

        // 1. Allocate interprocess shared memory
        let shm = SharedMemory::allocate(half_size)?;

        const MAX_NO_ITERS: i32 = 10;
        let mut counter = 0;
        let ptr = loop {
            counter += 1;
            if counter > MAX_NO_ITERS {
                return Err(AllocError::Other);
            }

            // 2. Reserve virtual memory:
            let ptr = mmap(
                0 as *mut c_void,
                size,
                PROT_NONE,
                MAP_ANONYMOUS | MAP_PRIVATE,
                -1,
                0,
            );
            if ptr == MAP_FAILED {
                print_error("mmap initial");
                return Err(AllocError::Oom);
            }

            let ptr2 =
                (ptr as *mut u8).offset(half_size as isize) as *mut c_void;

            unmap(ptr, size).expect("unmap initial failed");

            // 3. Attach shared memory to virtual memory:
            let map0 = shm.attach(ptr);
            if map0.is_err() {
                print_error("attach_shm first failed");
                continue;
            }
            let map1 = shm.attach(ptr2);
            if map1.is_err() {
                print_error("attach_shm second failed");
                continue;
            }
            // On success we leak the maps to keep them alive.
            // On drop we rebuild the maps from ptr and ptr + half_size
            // to deallocate them.
            mem::forget(map0);
            mem::forget(map1);
            break ptr;
        };

        Ok(ptr as *mut u8)
    }
}
/// Allocates `size` bytes of uninitialized memory, where the bytes in range
/// `[0, size / 2)` are mirrored into the bytes in range `[size / 2, size)`.
///
/// The algorithm using System V interprocess shared-memory is:
///
/// * 1. Allocate `size / 2` of interprocess shared memory.
/// * 2. Reserve `size` bytes of virtual memory using `mmap + munmap`.
/// * 3. Attach the shared memory to the first and second half.
///
/// There is a race between steps 2 and 3 because after unmapping the memory
/// and before attaching the shared memory to it another process might use that
/// memory.


The algorithm using System V interprocess shared-memory is.

1. Allocate `size / 2` of interprocess shared memory.
2. Reserve `size` bytes of virtual memory using `mmap + munmap`.
3. Attach the shared memory to the first and second half.

There is a race between steps 2 and 3 because after unmapping the memory
and before attaching the shared memory to it another process might use that
memory.
The algorithm using System V interprocess shared - memory is . 1 . Allocate ` size / 2 ` of interprocess shared memory . 2 . Reserve ` size ` bytes of virtual memory using ` mmap + munmap ` . 3 . Attach the shared memory to the first and second half . There is a race between steps 2 and 3 because after unmapping the memory and before attaching the shared memory to it another process might use that memory .
pub fn allocate_mirrored(size: usize) -> Result<*mut u8, AllocError> {
    unsafe {
        assert!(size != 0);
        let half_size = size / 2;
        assert!(half_size % allocation_granularity() == 0);
        // 1. Allocate interprocess shared memory
        let shm = SharedMemory::allocate(half_size)?;
        const MAX_NO_ITERS: i32 = 10;
        let mut counter = 0;
        let ptr = loop {
            counter += 1;
            if counter > MAX_NO_ITERS {
                return Err(AllocError::Other);
            }
            // 2. Reserve virtual memory:
            let ptr = mmap(
                0 as *mut c_void,
                size,
                PROT_NONE,
                MAP_ANONYMOUS | MAP_PRIVATE,
                -1,
                0,
            );
            if ptr == MAP_FAILED {
                print_error("mmap initial");
                return Err(AllocError::Oom);
            }
            let ptr2 =
                (ptr as *mut u8).offset(half_size as isize) as *mut c_void;
            unmap(ptr, size).expect("unmap initial failed");
            // 3. Attach shared memory to virtual memory:
            let map0 = shm.attach(ptr);
            if map0.is_err() {
                print_error("attach_shm first failed");
                continue;
            }
            let map1 = shm.attach(ptr2);
            if map1.is_err() {
                print_error("attach_shm second failed");
                continue;
            }
            // On success we leak the maps to keep them alive.
            // On drop we rebuild the maps from ptr and ptr + half_size
            // to deallocate them.
            mem::forget(map0);
            mem::forget(map1);
            break ptr;
        };
        Ok(ptr as *mut u8)
    }
}
pub fn allocate_mirrored ( size : usize ) -> Result < * mut u8 , AllocError > { unsafe { assert ! ( size 0 ) ; let half_size = size / 2 ; assert ! ( half_size allocation_granularity ( ) 0 ) ; // 1. Allocate interprocess shared memory let shm = SharedMemory :: allocate ( half_size ) ? ; const MAX_NO_ITERS : i32 = 10 ; let mut counter = 0 ; let ptr = loop { counter += 1 ; if counter > MAX_NO_ITERS { return Err ( AllocError :: Other ) ; } // 2. Reserve virtual memory: let ptr = mmap ( 0 as * mut c_void , size , PROT_NONE , MAP_ANONYMOUS | MAP_PRIVATE , - 1 , 0 , ) ; if ptr == MAP_FAILED { print_error ( " " ) ; return Err ( AllocError :: Oom ) ; } let ptr2 = ( ptr as * mut u8 ) . offset ( half_size as isize ) as * mut c_void ; unmap ( ptr , size ) . expect ( " " ) ; // 3. Attach shared memory to virtual memory: let map0 = shm . attach ( ptr ) ; if map0 . is_err ( ) { print_error ( " " ) ; continue ; } let map1 = shm . attach ( ptr2 ) ; if map1 . is_err ( ) { print_error ( " " ) ; continue ; } // On success we leak the maps to keep them alive. // On drop we rebuild the maps from ptr and ptr + half_size // to deallocate them. mem :: forget ( map0 ) ; mem :: forget ( map1 ) ; break ptr ; } ; Ok ( ptr as * mut u8 ) } }
Allocates `size` bytes of uninitialized memory, where the bytes in range
`[0, size / 2)` are mirrored into the bytes in range `[size / 2, size)`.
Allocates ` size ` bytes of uninitialized memory where the bytes in range ` [ 0 size / 2 ) ` are mirrored into the bytes in range ` [ size / 2 size ) ` .
size
usize
size
usize