3aeb0708b97537dedf227ff118ceb1ee4916885e
[kazan.git] / vulkan-driver / src / shm.rs
1 // SPDX-License-Identifier: LGPL-2.1-or-later
2 // Copyright 2018 Jacob Lifshay
3 use errno;
4 use libc;
5 use std::marker::PhantomData;
6 use std::ops::Deref;
7 use std::ops::DerefMut;
8 use std::os::raw::c_int;
9 use std::ptr::null_mut;
10 use std::slice;
11
12 #[derive(Debug)]
13 pub struct SharedMemorySegment {
14 id: c_int,
15 size: usize,
16 _phantom_data: PhantomData<*mut u8>,
17 }
18
19 unsafe impl Send for SharedMemorySegment {}
20 unsafe impl Sync for SharedMemorySegment {}
21
22 impl SharedMemorySegment {
23 pub unsafe fn new(id: c_int, size: usize) -> Self {
24 assert_ne!(size, 0);
25 assert_ne!(id, -1);
26 SharedMemorySegment {
27 id,
28 size,
29 _phantom_data: PhantomData,
30 }
31 }
32 pub unsafe fn create_with_flags(size: usize, flags: c_int) -> Result<Self, errno::Errno> {
33 match libc::shmget(libc::IPC_PRIVATE, size, flags) {
34 -1 => Err(errno::errno()),
35 id => Ok(Self::new(id, size)),
36 }
37 }
38 pub fn create(size: usize) -> Result<Self, errno::Errno> {
39 unsafe { Self::create_with_flags(size, libc::IPC_CREAT | libc::IPC_EXCL | 0o666) }
40 }
41 pub fn map(&self) -> Result<MappedSharedMemorySegment, errno::Errno> {
42 unsafe {
43 let memory = libc::shmat(self.id, null_mut(), 0);
44 if memory == !0usize as *mut _ {
45 Err(errno::errno())
46 } else {
47 Ok(MappedSharedMemorySegment {
48 memory: memory as *mut u8,
49 size: self.size,
50 })
51 }
52 }
53 }
54 }
55
56 impl Drop for SharedMemorySegment {
57 fn drop(&mut self) {
58 unsafe {
59 libc::shmctl(self.id, libc::IPC_RMID, null_mut());
60 }
61 }
62 }
63
64 #[derive(Debug)]
65 pub struct MappedSharedMemorySegment {
66 memory: *mut u8,
67 size: usize,
68 }
69
70 impl MappedSharedMemorySegment {
71 unsafe fn get(&self) -> *mut [u8] {
72 slice::from_raw_parts_mut(self.memory, self.size)
73 }
74 }
75
76 unsafe impl Send for MappedSharedMemorySegment {}
77 unsafe impl Sync for MappedSharedMemorySegment {}
78
79 impl Deref for MappedSharedMemorySegment {
80 type Target = [u8];
81 fn deref(&self) -> &[u8] {
82 unsafe { &*self.get() }
83 }
84 }
85
86 impl DerefMut for MappedSharedMemorySegment {
87 fn deref_mut(&mut self) -> &mut [u8] {
88 unsafe { &mut *self.get() }
89 }
90 }
91
92 impl Drop for MappedSharedMemorySegment {
93 fn drop(&mut self) {
94 unsafe {
95 libc::shmdt(self.memory as *const _);
96 }
97 }
98 }