use core::ptr;
use libc::*;
pub unsafe fn allocate_mirror(size: usize) -> Result<*mut u8, String> {
let name = format!(
"/picoring_{}_{}_{}",
getpid(),
ptr::null::<u8>() as usize,
size
);
let name_cstr = std::ffi::CString::new(name).map_err(|_| "invalid name")?;
let name_ptr = name_cstr.as_ptr();
let fd = shm_open(name_ptr, O_RDWR | O_CREAT | O_EXCL, 0600);
if fd < 0 {
return Err("shm_open failed".into());
}
shm_unlink(name_ptr);
if ftruncate(fd, size as off_t) != 0 {
close(fd);
return Err("ftruncate failed".into());
}
let target = mmap(
ptr::null_mut(),
2 * size,
PROT_NONE,
MAP_PRIVATE | MAP_ANON,
-1,
0,
);
if target == MAP_FAILED {
close(fd);
return Err("mmap reservation failed".into());
}
let m1 = mmap(
target,
size,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED,
fd,
0,
);
if m1 == MAP_FAILED {
munmap(target, 2 * size);
close(fd);
return Err("mirror mapping 1 failed".into());
}
let m2 = mmap(
(target as *mut u8).add(size) as *mut c_void,
size,
PROT_READ | PROT_WRITE,
MAP_FIXED | MAP_SHARED,
fd,
0,
);
if m2 == MAP_FAILED {
munmap(target, 2 * size);
close(fd);
return Err("mirror mapping 2 failed".into());
}
close(fd);
Ok(target as *mut u8)
}
pub unsafe fn deallocate_mirror(ptr: *mut u8, size: usize) {
if !ptr.is_null() {
munmap(ptr as *mut c_void, 2 * size);
}
}