forked from proxmox-mirrors/proxmox
shared-memory: formatting
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
This commit is contained in:
parent
1185458719
commit
fd39f876dc
@ -1,20 +1,20 @@
|
|||||||
use std::path::Path;
|
|
||||||
use std::os::unix::io::AsRawFd;
|
|
||||||
use std::mem::MaybeUninit;
|
|
||||||
use std::fs::File;
|
|
||||||
use std::os::unix::ffi::OsStrExt;
|
|
||||||
use std::os::unix::io::FromRawFd;
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
use std::fs::File;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
use std::os::unix::ffi::OsStrExt;
|
||||||
|
use std::os::unix::io::AsRawFd;
|
||||||
|
use std::os::unix::io::FromRawFd;
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
use anyhow::{bail, format_err, Error};
|
use anyhow::{bail, format_err, Error};
|
||||||
|
use nix::errno::Errno;
|
||||||
use nix::fcntl::OFlag;
|
use nix::fcntl::OFlag;
|
||||||
use nix::sys::mman::{MapFlags, ProtFlags};
|
use nix::sys::mman::{MapFlags, ProtFlags};
|
||||||
use nix::sys::stat::Mode;
|
use nix::sys::stat::Mode;
|
||||||
use nix::errno::Errno;
|
|
||||||
|
|
||||||
|
use proxmox_sys::error::SysError;
|
||||||
use proxmox_sys::fs::CreateOptions;
|
use proxmox_sys::fs::CreateOptions;
|
||||||
use proxmox_sys::mmap::Mmap;
|
use proxmox_sys::mmap::Mmap;
|
||||||
use proxmox_sys::error::SysError;
|
|
||||||
|
|
||||||
mod raw_shared_mutex;
|
mod raw_shared_mutex;
|
||||||
|
|
||||||
@ -31,7 +31,9 @@ pub trait Init: Sized {
|
|||||||
fn initialize(this: &mut MaybeUninit<Self>);
|
fn initialize(this: &mut MaybeUninit<Self>);
|
||||||
|
|
||||||
/// Check if the data has the correct format
|
/// Check if the data has the correct format
|
||||||
fn check_type_magic(_this: &MaybeUninit<Self>) -> Result<(), Error> { Ok(()) }
|
fn check_type_magic(_this: &MaybeUninit<Self>) -> Result<(), Error> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Memory mapped shared memory region
|
/// Memory mapped shared memory region
|
||||||
@ -45,7 +47,7 @@ pub struct SharedMemory<T> {
|
|||||||
mmap: Mmap<T>,
|
mmap: Mmap<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
const fn up_to_page_size(n: usize) -> usize {
|
const fn up_to_page_size(n: usize) -> usize {
|
||||||
// FIXME: use sysconf(_SC_PAGE_SIZE)
|
// FIXME: use sysconf(_SC_PAGE_SIZE)
|
||||||
(n + 4095) & !4095
|
(n + 4095) & !4095
|
||||||
}
|
}
|
||||||
@ -55,7 +57,8 @@ fn mmap_file<T: Init>(file: &mut File, initialize: bool) -> Result<Mmap<T>, Erro
|
|||||||
let mut mmap: Mmap<MaybeUninit<T>> = unsafe {
|
let mut mmap: Mmap<MaybeUninit<T>> = unsafe {
|
||||||
Mmap::map_fd(
|
Mmap::map_fd(
|
||||||
file.as_raw_fd(),
|
file.as_raw_fd(),
|
||||||
0, 1,
|
0,
|
||||||
|
1,
|
||||||
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
|
ProtFlags::PROT_READ | ProtFlags::PROT_WRITE,
|
||||||
MapFlags::MAP_SHARED | MapFlags::MAP_NORESERVE | MapFlags::MAP_POPULATE,
|
MapFlags::MAP_SHARED | MapFlags::MAP_NORESERVE | MapFlags::MAP_POPULATE,
|
||||||
)?
|
)?
|
||||||
@ -73,15 +76,17 @@ fn mmap_file<T: Init>(file: &mut File, initialize: bool) -> Result<Mmap<T>, Erro
|
|||||||
Ok(unsafe { std::mem::transmute(mmap) })
|
Ok(unsafe { std::mem::transmute(mmap) })
|
||||||
}
|
}
|
||||||
|
|
||||||
impl <T: Sized + Init> SharedMemory<T> {
|
impl<T: Sized + Init> SharedMemory<T> {
|
||||||
|
|
||||||
pub fn open(path: &Path, options: CreateOptions) -> Result<Self, Error> {
|
pub fn open(path: &Path, options: CreateOptions) -> Result<Self, Error> {
|
||||||
|
|
||||||
let size = std::mem::size_of::<T>();
|
let size = std::mem::size_of::<T>();
|
||||||
let up_size = up_to_page_size(size);
|
let up_size = up_to_page_size(size);
|
||||||
|
|
||||||
if size != up_size {
|
if size != up_size {
|
||||||
bail!("SharedMemory::open {:?} failed - data size {} is not a multiple of 4096", path, size);
|
bail!(
|
||||||
|
"SharedMemory::open {:?} failed - data size {} is not a multiple of 4096",
|
||||||
|
path,
|
||||||
|
size
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mmap = Self::open_shmem(path, options)?;
|
let mmap = Self::open_shmem(path, options)?;
|
||||||
@ -89,10 +94,7 @@ impl <T: Sized + Init> SharedMemory<T> {
|
|||||||
Ok(Self { mmap })
|
Ok(Self { mmap })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_shmem<P: AsRef<Path>>(
|
pub fn open_shmem<P: AsRef<Path>>(path: P, options: CreateOptions) -> Result<Mmap<T>, Error> {
|
||||||
path: P,
|
|
||||||
options: CreateOptions,
|
|
||||||
) -> Result<Mmap<T>, Error> {
|
|
||||||
let path = path.as_ref();
|
let path = path.as_ref();
|
||||||
|
|
||||||
let dir_name = path
|
let dir_name = path
|
||||||
@ -177,7 +179,7 @@ impl <T: Sized + Init> SharedMemory<T> {
|
|||||||
Err(err) => bail!("open {:?} failed - {}", path, err),
|
Err(err) => bail!("open {:?} failed - {}", path, err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => Err(err.into()),
|
Err(err) => Err(err.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -188,7 +190,6 @@ impl <T: Sized + Init> SharedMemory<T> {
|
|||||||
pub fn data_mut(&mut self) -> &mut T {
|
pub fn data_mut(&mut self) -> &mut T {
|
||||||
&mut self.mmap[0]
|
&mut self.mmap[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Helper to initialize nested data
|
/// Helper to initialize nested data
|
||||||
@ -217,10 +218,10 @@ mod test {
|
|||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use std::sync::Arc;
|
|
||||||
use std::sync::atomic::AtomicU64;
|
|
||||||
use std::thread::spawn;
|
|
||||||
use proxmox_sys::fs::create_path;
|
use proxmox_sys::fs::create_path;
|
||||||
|
use std::sync::atomic::AtomicU64;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread::spawn;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -231,7 +232,6 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Init for TestData {
|
impl Init for TestData {
|
||||||
|
|
||||||
fn initialize(this: &mut MaybeUninit<Self>) {
|
fn initialize(this: &mut MaybeUninit<Self>) {
|
||||||
this.write(Self {
|
this.write(Self {
|
||||||
count: 0,
|
count: 0,
|
||||||
@ -264,11 +264,12 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_shared_memory_mutex() -> Result<(), Error> {
|
fn test_shared_memory_mutex() -> Result<(), Error> {
|
||||||
|
|
||||||
create_path("../target/testdata/", None, None)?;
|
create_path("../target/testdata/", None, None)?;
|
||||||
|
|
||||||
let shared: SharedMemory<SingleMutexData> =
|
let shared: SharedMemory<SingleMutexData> = SharedMemory::open(
|
||||||
SharedMemory::open(Path::new("../target/testdata/test1.shm"), CreateOptions::new())?;
|
Path::new("../target/testdata/test1.shm"),
|
||||||
|
CreateOptions::new(),
|
||||||
|
)?;
|
||||||
|
|
||||||
let shared = Arc::new(shared);
|
let shared = Arc::new(shared);
|
||||||
|
|
||||||
@ -292,7 +293,7 @@ mod test {
|
|||||||
|
|
||||||
let end = shared.data().data.lock().count;
|
let end = shared.data().data.lock().count;
|
||||||
|
|
||||||
assert_eq!(end-start, 100);
|
assert_eq!(end - start, 100);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -327,13 +328,14 @@ mod test {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_shared_memory_multi_mutex() -> Result<(), Error> {
|
fn test_shared_memory_multi_mutex() -> Result<(), Error> {
|
||||||
|
|
||||||
create_path("../target/testdata/", None, None)?;
|
create_path("../target/testdata/", None, None)?;
|
||||||
|
|
||||||
let shared: SharedMemory<MultiMutexData> =
|
let shared: SharedMemory<MultiMutexData> = SharedMemory::open(
|
||||||
SharedMemory::open(Path::new("../target/testdata/test2.shm"), CreateOptions::new())?;
|
Path::new("../target/testdata/test2.shm"),
|
||||||
|
CreateOptions::new(),
|
||||||
|
)?;
|
||||||
|
|
||||||
let shared = Arc::new(shared);
|
let shared = Arc::new(shared);
|
||||||
|
|
||||||
let start1 = shared.data().block1.lock().count;
|
let start1 = shared.data().block1.lock().count;
|
||||||
let start2 = shared.data().block2.lock().count;
|
let start2 = shared.data().block2.lock().count;
|
||||||
@ -357,12 +359,11 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let end1 = shared.data().block1.lock().count;
|
let end1 = shared.data().block1.lock().count;
|
||||||
assert_eq!(end1-start1, 100);
|
assert_eq!(end1 - start1, 100);
|
||||||
|
|
||||||
let end2 = shared.data().block2.lock().count;
|
let end2 = shared.data().block2.lock().count;
|
||||||
assert_eq!(end2-start2, 200);
|
assert_eq!(end2 - start2, 200);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,32 @@ unsafe impl Send for RawSharedMutex {}
|
|||||||
unsafe impl Sync for RawSharedMutex {}
|
unsafe impl Sync for RawSharedMutex {}
|
||||||
|
|
||||||
impl RawSharedMutex {
|
impl RawSharedMutex {
|
||||||
|
|
||||||
pub const fn uninitialized() -> Self {
|
pub const fn uninitialized() -> Self {
|
||||||
Self { inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER) }
|
Self {
|
||||||
|
inner: UnsafeCell::new(libc::PTHREAD_MUTEX_INITIALIZER),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn init(&mut self) {
|
pub unsafe fn init(&mut self) {
|
||||||
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
let mut attr = MaybeUninit::<libc::pthread_mutexattr_t>::uninit();
|
||||||
cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap();
|
cvt_nz(libc::pthread_mutexattr_init(attr.as_mut_ptr())).unwrap();
|
||||||
let attr = PthreadMutexAttr(&mut attr);
|
let attr = PthreadMutexAttr(&mut attr);
|
||||||
cvt_nz(libc::pthread_mutexattr_settype(attr.0.as_mut_ptr(), libc::PTHREAD_MUTEX_NORMAL))
|
cvt_nz(libc::pthread_mutexattr_settype(
|
||||||
.unwrap();
|
attr.0.as_mut_ptr(),
|
||||||
cvt_nz(libc::pthread_mutexattr_setpshared(attr.0.as_mut_ptr(), libc::PTHREAD_PROCESS_SHARED))
|
libc::PTHREAD_MUTEX_NORMAL,
|
||||||
.unwrap();
|
))
|
||||||
cvt_nz(libc::pthread_mutexattr_setrobust(attr.0.as_mut_ptr(), libc::PTHREAD_MUTEX_ROBUST))
|
.unwrap();
|
||||||
.unwrap();
|
cvt_nz(libc::pthread_mutexattr_setpshared(
|
||||||
|
attr.0.as_mut_ptr(),
|
||||||
|
libc::PTHREAD_PROCESS_SHARED,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
|
cvt_nz(libc::pthread_mutexattr_setrobust(
|
||||||
|
attr.0.as_mut_ptr(),
|
||||||
|
libc::PTHREAD_MUTEX_ROBUST,
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
cvt_nz(libc::pthread_mutex_init(self.inner.get(), attr.0.as_ptr())).unwrap();
|
cvt_nz(libc::pthread_mutex_init(self.inner.get(), attr.0.as_ptr())).unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +45,7 @@ impl RawSharedMutex {
|
|||||||
if r == libc::EOWNERDEAD {
|
if r == libc::EOWNERDEAD {
|
||||||
r = libc::pthread_mutex_consistent(self.inner.get());
|
r = libc::pthread_mutex_consistent(self.inner.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
debug_assert_eq!(r, 0);
|
debug_assert_eq!(r, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,7 +66,6 @@ impl RawSharedMutex {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Note: copied from rust std::sys::unix::cvt_nz
|
// Note: copied from rust std::sys::unix::cvt_nz
|
||||||
fn cvt_nz(error: libc::c_int) -> std::io::Result<()> {
|
fn cvt_nz(error: libc::c_int) -> std::io::Result<()> {
|
||||||
if error == 0 {
|
if error == 0 {
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::mem::MaybeUninit;
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
use anyhow::{bail, Error};
|
use anyhow::{bail, Error};
|
||||||
|
|
||||||
use crate::Init;
|
|
||||||
use crate::raw_shared_mutex::RawSharedMutex;
|
use crate::raw_shared_mutex::RawSharedMutex;
|
||||||
|
use crate::Init;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -22,23 +22,23 @@ unsafe impl<T: ?Sized + Send> Sync for SharedMutex<T> {}
|
|||||||
// openssl::sha::sha256(b"Proxmox SharedMutex v1.0")[0..8];
|
// openssl::sha::sha256(b"Proxmox SharedMutex v1.0")[0..8];
|
||||||
pub const PROXMOX_SHARED_MUTEX_MAGIC_1_0: [u8; 8] = [124, 229, 154, 62, 248, 0, 154, 55];
|
pub const PROXMOX_SHARED_MUTEX_MAGIC_1_0: [u8; 8] = [124, 229, 154, 62, 248, 0, 154, 55];
|
||||||
|
|
||||||
impl <T: Init> Init for SharedMutex<T> {
|
impl<T: Init> Init for SharedMutex<T> {
|
||||||
|
|
||||||
fn initialize(this: &mut MaybeUninit<SharedMutex<T>>) {
|
fn initialize(this: &mut MaybeUninit<SharedMutex<T>>) {
|
||||||
|
|
||||||
let me = unsafe { &mut *this.as_mut_ptr() };
|
let me = unsafe { &mut *this.as_mut_ptr() };
|
||||||
|
|
||||||
me.magic = PROXMOX_SHARED_MUTEX_MAGIC_1_0;
|
me.magic = PROXMOX_SHARED_MUTEX_MAGIC_1_0;
|
||||||
|
|
||||||
me.inner = RawSharedMutex::uninitialized();
|
me.inner = RawSharedMutex::uninitialized();
|
||||||
unsafe { me.inner.init(); }
|
unsafe {
|
||||||
|
me.inner.init();
|
||||||
|
}
|
||||||
|
|
||||||
let u: &mut MaybeUninit<T> = unsafe { std::mem::transmute(me.data.get_mut()) };
|
let u: &mut MaybeUninit<T> = unsafe { std::mem::transmute(me.data.get_mut()) };
|
||||||
Init::initialize(u);
|
Init::initialize(u);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_type_magic(this: &MaybeUninit<Self>) -> Result<(), Error> {
|
fn check_type_magic(this: &MaybeUninit<Self>) -> Result<(), Error> {
|
||||||
let me = unsafe { & *this.as_ptr() };
|
let me = unsafe { &*this.as_ptr() };
|
||||||
if me.magic != PROXMOX_SHARED_MUTEX_MAGIC_1_0 {
|
if me.magic != PROXMOX_SHARED_MUTEX_MAGIC_1_0 {
|
||||||
bail!("SharedMutex: wrong magic number");
|
bail!("SharedMutex: wrong magic number");
|
||||||
}
|
}
|
||||||
@ -47,9 +47,7 @@ impl <T: Init> Init for SharedMutex<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> SharedMutex<T> {
|
impl<T> SharedMutex<T> {
|
||||||
|
|
||||||
pub fn lock(&self) -> SharedMutexGuard<'_, T> {
|
pub fn lock(&self) -> SharedMutexGuard<'_, T> {
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
self.inner.lock();
|
self.inner.lock();
|
||||||
SharedMutexGuard::new(self)
|
SharedMutexGuard::new(self)
|
||||||
@ -69,7 +67,6 @@ impl<T> SharedMutex<T> {
|
|||||||
pub fn unlock(guard: SharedMutexGuard<'_, T>) {
|
pub fn unlock(guard: SharedMutexGuard<'_, T>) {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SharedMutexGuard<'a, T: ?Sized + 'a> {
|
pub struct SharedMutexGuard<'a, T: ?Sized + 'a> {
|
||||||
|
Loading…
Reference in New Issue
Block a user