Skip to content

Commit 7709142

Browse files
committed
Remove support for macos
1 parent 90c3977 commit 7709142

File tree

6 files changed

+117
-28
lines changed

6 files changed

+117
-28
lines changed

src/shims/unix/linux/eventfd.rs

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,9 @@ impl FileDescription for Event {
4949
ecx: &mut MiriInterpCx<'tcx>,
5050
) -> InterpResult<'tcx, io::Result<usize>> {
5151
// Check the size of slice, and return error only if the size of the slice < 8.
52-
if bytes.first_chunk::<8>().is_none() {
52+
let Some(bytes) = bytes.first_chunk_mut::<8>() else {
5353
return Ok(Err(Error::from(ErrorKind::InvalidInput)));
54-
}
54+
};
5555
if self.counter == 0 {
5656
if self.is_nonblock {
5757
return Ok(Err(Error::from(ErrorKind::WouldBlock)));
@@ -63,12 +63,10 @@ impl FileDescription for Event {
6363
// Prevent false alarm in data race detection when doing synchronisation via eventfd.
6464
ecx.acquire_clock(&self.clock);
6565
// Return the counter in the host endianness using the buffer provided by caller.
66-
let counter_byte: [u8; 8] = match ecx.tcx.sess.target.endian {
66+
*bytes = match ecx.tcx.sess.target.endian {
6767
Endian::Little => self.counter.to_le_bytes(),
6868
Endian::Big => self.counter.to_be_bytes(),
6969
};
70-
// Use bytes[0..8] to prevent panic when size of bytes > 8.
71-
bytes[0..8].copy_from_slice(&counter_byte);
7270
self.counter = 0;
7371
return Ok(Ok(8));
7472
}
@@ -93,11 +91,8 @@ impl FileDescription for Event {
9391
ecx: &mut MiriInterpCx<'tcx>,
9492
) -> InterpResult<'tcx, io::Result<usize>> {
9593
// Check the size of slice, and return error only if the size of the slice < 8.
96-
let bytes = match bytes.first_chunk::<8>() {
97-
Some(bytes) => bytes,
98-
None => {
99-
return Ok(Err(Error::from(ErrorKind::InvalidInput)));
100-
}
94+
let Some(bytes) = bytes.first_chunk::<8>() else {
95+
return Ok(Err(Error::from(ErrorKind::InvalidInput)));
10196
};
10297
// Convert from target endianness to host endianness.
10398
let num = match ecx.tcx.sess.target.endian {
@@ -108,21 +103,21 @@ impl FileDescription for Event {
108103
if num == u64::MAX {
109104
return Ok(Err(Error::from(ErrorKind::InvalidInput)));
110105
}
111-
let max_addition = MAX_COUNTER.checked_sub(self.counter).unwrap();
112-
if num > max_addition {
113-
// If addition cause the counter value to exceed the maximum, block
114-
// or throw error based on the existence of non-blocking flag.
115-
if self.is_nonblock {
116-
return Ok(Err(Error::from(ErrorKind::WouldBlock)));
117-
} else {
118-
//FIXME: blocking is not supported
119-
throw_unsup_format!("eventfd: blocking is unsupported");
106+
match self.counter.checked_add(num) {
107+
Some(new_count @ 0..=MAX_COUNTER) => {
108+
// Prevent false alarm in data race detection when doing synchronisation via eventfd.
109+
self.clock.join(&ecx.release_clock().unwrap());
110+
self.counter = new_count;
120111
}
121-
} else {
122-
// Prevent false alarm in data race detection when doing synchronisation via eventfd.
123-
self.clock.join(&ecx.release_clock().unwrap());
124-
self.counter = self.counter.checked_add(num).unwrap();
125-
}
112+
None | Some(u64::MAX) => {
113+
if self.is_nonblock {
114+
return Ok(Err(Error::from(ErrorKind::WouldBlock)));
115+
} else {
116+
//FIXME: blocking is not supported
117+
throw_unsup_format!("eventfd: blocking is unsupported");
118+
}
119+
}
120+
};
126121
Ok(Ok(8))
127122
}
128123
}
@@ -148,6 +143,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
148143
fn eventfd(&mut self, val: &OpTy<'tcx>, flags: &OpTy<'tcx>) -> InterpResult<'tcx, Scalar> {
149144
let this = self.eval_context_mut();
150145

146+
// eventfd is Linux specific.
147+
this.assert_target_os("linux", "eventfd");
148+
151149
let val = this.read_scalar(val)?.to_u32()?;
152150
let mut flags = this.read_scalar(flags)?.to_i32()?;
153151

@@ -160,7 +158,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
160158
}
161159

162160
let mut is_nonblock = false;
163-
//Unload the flag that we support.
161+
// Unload the flag that we support.
164162
if flags & efd_cloexec == efd_cloexec {
165163
flags &= !efd_cloexec;
166164
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
//@ignore-target-windows: No eventfd on Windows
2+
//@ignore-target-apple: No eventfd in macos
3+
fn main() {
4+
// eventfd read will block when non-block flag is clear and counter = 0.
5+
// This will pass when blocking is implemented.
6+
let flags = libc::EFD_CLOEXEC;
7+
let fd = unsafe { libc::eventfd(0, flags) };
8+
let mut buf: [u8; 8] = [0; 8];
9+
let _res: i32 = unsafe {
10+
libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap() //~ERROR: blocking is unsupported
11+
};
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unsupported operation: eventfd: blocking is unsupported
2+
--> $DIR/libc_eventfd_read_block.rs:LL:CC
3+
|
4+
LL | libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap()
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ eventfd: blocking is unsupported
6+
|
7+
= help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
8+
= note: BACKTRACE:
9+
= note: inside `main` at $DIR/libc_eventfd_read_block.rs:LL:CC
10+
11+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
12+
13+
error: aborting due to 1 previous error
14+
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//@ignore-target-windows: No eventfd on Windows
2+
//@ignore-target-apple: No eventfd in macos
3+
fn main() {
4+
// eventfd write will block when we try to add until it exceed u64-1.
5+
// This will pass when blocking is implemented.
6+
let flags = libc::EFD_CLOEXEC;
7+
let fd = unsafe { libc::eventfd(0, flags) };
8+
let mut sized_8_data: [u8; 8];
9+
if cfg!(target_endian = "big") {
10+
// Adjust the data based on the endianness of host system.
11+
sized_8_data = [255, 255, 255, 255, 255, 255, 255, 254];
12+
} else {
13+
sized_8_data = [254, 255, 255, 255, 255, 255, 255, 255];
14+
}
15+
// Write u64 - 1.
16+
let _res: i64 = unsafe {
17+
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
18+
};
19+
// Write u64 - 1.
20+
let _res: i64 = unsafe {
21+
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap() //~ERROR: blocking is unsupported
22+
};
23+
if cfg!(target_endian = "big") {
24+
// Adjust the data based on the endianess of host system.
25+
sized_8_data = [0, 0, 0, 0, 0, 0, 0, 1];
26+
} else {
27+
sized_8_data = [1, 0, 0, 0, 0, 0, 0, 0];
28+
}
29+
// Write 1 to the counter.
30+
let _res: i64 = unsafe {
31+
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
32+
};
33+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
error: unsupported operation: eventfd: blocking is unsupported
2+
--> $DIR/libc_eventfd_write_block.rs:LL:CC
3+
|
4+
LL | libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ eventfd: blocking is unsupported
6+
|
7+
= help: this is likely not a bug in the program; it indicates that the program performed an operation that Miri does not support
8+
= note: BACKTRACE:
9+
= note: inside `main` at $DIR/libc_eventfd_write_block.rs:LL:CC
10+
11+
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
12+
13+
error: aborting due to 1 previous error
14+

tests/pass-dep/libc/libc-eventfd.rs

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
//@ignore-target-windows: No eventfd in windows
2+
//@ignore-target-apple: No eventfd in macos
3+
// test_race depends on a deterministic schedule.
4+
//@compile-flags: -Zmiri-preemption-rate=0
25

36
use std::thread;
47

@@ -24,7 +27,7 @@ fn test_read_write() {
2427
assert_eq!(res, 8);
2528

2629
// Read 1 from the counter.
27-
let mut buf: [u8; 8] = [1; 8];
30+
let mut buf: [u8; 8] = [0; 8];
2831
let res: i32 = unsafe {
2932
libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap()
3033
};
@@ -39,6 +42,14 @@ fn test_read_write() {
3942
}
4043
assert_eq!(counter, 1);
4144

45+
// Read when counter == 0 should fail.
46+
let mut buf: [u8; 8] = [0; 8];
47+
let res: i32 = unsafe {
48+
libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap()
49+
};
50+
// Read returns number of bytes has been read, which is always 8.
51+
assert_eq!(res, -1);
52+
4253
// Write with buffer size > 8 bytes.
4354
let res: i64 = unsafe {
4455
libc::write(fd, sized_8_data.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
@@ -77,6 +88,13 @@ fn test_read_write() {
7788
libc::read(fd, buf.as_mut_ptr().cast(), buf.len() as libc::size_t).try_into().unwrap()
7889
};
7990
assert_eq!(res, 8);
91+
92+
// Write u64::MAX should fail.
93+
let u64_max_bytes: [u8; 8] = [255; 8];
94+
let res: i64 = unsafe {
95+
libc::write(fd, u64_max_bytes.as_ptr() as *const libc::c_void, 8).try_into().unwrap()
96+
};
97+
assert_eq!(res, -1);
8098
}
8199

82100
fn test_race() {
@@ -92,7 +110,7 @@ fn test_race() {
92110
assert_eq!(res, 8);
93111
let counter: u64;
94112
if cfg!(target_endian = "big") {
95-
// Read will store the bytes based on the endianess of the host system.
113+
// Read will store the bytes based on the endianness of the host system.
96114
counter = u64::from_be_bytes(buf);
97115
} else {
98116
counter = u64::from_le_bytes(buf);
@@ -105,7 +123,7 @@ fn test_race() {
105123
unsafe { VAL = 1 };
106124
let data: [u8; 8];
107125
if cfg!(target_endian = "big") {
108-
// Adjust the data based on the endianess of host system.
126+
// Adjust the data based on the endianness of host system.
109127
data = [0, 0, 0, 0, 0, 0, 0, 1];
110128
} else {
111129
data = [1, 0, 0, 0, 0, 0, 0, 0];

0 commit comments

Comments
 (0)