Skip to content
Snippets Groups Projects
Verified Commit 4c8f51ac authored by jD91mZM2's avatar jD91mZM2
Browse files

Avoid allocations in redox epoll

parent 488981f9
No related branches found
No related tags found
No related merge requests found
...@@ -54,6 +54,7 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int { ...@@ -54,6 +54,7 @@ pub fn poll_epoll(fds: &mut [pollfd], timeout: c_int) -> c_int {
data: epoll_data { data: epoll_data {
u64: i as u64, u64: i as u64,
}, },
..Default::default()
}; };
for (p, ep) in event_map.iter() { for (p, ep) in event_map.iter() {
......
...@@ -28,12 +28,24 @@ pub union epoll_data { ...@@ -28,12 +28,24 @@ pub union epoll_data {
pub u32: u32, pub u32: u32,
pub u64: u64, pub u64: u64,
} }
impl Default for epoll_data {
fn default() -> Self {
Self { u64: 0 }
}
}
#[repr(C)] #[repr(C)]
#[derive(Clone, Copy)] #[derive(Clone, Copy, Default)]
// This will match in size with syscall::Event (24 bytes on 64-bit
// systems) on redox. The `Default` trait is here so we don't need to
// worry about the padding when using this type.
pub struct epoll_event { pub struct epoll_event {
pub events: u32, pub events: u32, // 4 bytes
pub data: epoll_data, // 4 automatic alignment bytes
pub data: epoll_data, // 8 bytes
#[cfg(target_os = "redox")]
pub _pad: u64, // 8 bytes
} }
#[no_mangle] #[no_mangle]
......
...@@ -80,6 +80,7 @@ pub fn select_epoll( ...@@ -80,6 +80,7 @@ pub fn select_epoll(
data: epoll_data { data: epoll_data {
fd: fd, fd: fd,
}, },
..Default::default()
}; };
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 { if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
return -1; return -1;
...@@ -93,6 +94,7 @@ pub fn select_epoll( ...@@ -93,6 +94,7 @@ pub fn select_epoll(
data: epoll_data { data: epoll_data {
fd: fd, fd: fd,
}, },
..Default::default()
}; };
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 { if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
return -1; return -1;
...@@ -106,6 +108,7 @@ pub fn select_epoll( ...@@ -106,6 +108,7 @@ pub fn select_epoll(
data: epoll_data { data: epoll_data {
fd: fd, fd: fd,
}, },
..Default::default()
}; };
if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 { if epoll_ctl(*ep, EPOLL_CTL_ADD, fd, &mut event) < 0 {
return -1; return -1;
......
...@@ -23,19 +23,19 @@ impl PalEpoll for Sys { ...@@ -23,19 +23,19 @@ impl PalEpoll for Sys {
} }
fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int { fn epoll_ctl(epfd: c_int, op: c_int, fd: c_int, event: *mut epoll_event) -> c_int {
let flags = unsafe { (*event).events };
Sys::write(epfd, &Event { Sys::write(epfd, &Event {
id: fd as usize, id: fd as usize,
flags: flags as usize, flags: unsafe { (*event).events as usize },
data: event as usize
// NOTE: Danger when using non 64-bit systems. If this is
// needed, use a box or something
data: unsafe { mem::transmute((*event).data) }
}) as c_int }) as c_int
} }
fn epoll_pwait(epfd: c_int, mut events: *mut epoll_event, maxevents: c_int, timeout: c_int, _sigset: *const sigset_t) -> c_int { fn epoll_pwait(epfd: c_int, mut events: *mut epoll_event, maxevents: c_int, timeout: c_int, _sigset: *const sigset_t) -> c_int {
// TODO: sigset // TODO: sigset
let mut redox_events = vec![Event::default(); maxevents as usize];
let _timer; let _timer;
if timeout != -1 { if timeout != -1 {
_timer = File::open(CStr::from_bytes_with_nul(b"time:\0").unwrap(), O_RDWR); _timer = File::open(CStr::from_bytes_with_nul(b"time:\0").unwrap(), O_RDWR);
...@@ -63,20 +63,25 @@ impl PalEpoll for Sys { ...@@ -63,20 +63,25 @@ impl PalEpoll for Sys {
} }
let bytes_read = Sys::read(epfd, unsafe { slice::from_raw_parts_mut( let bytes_read = Sys::read(epfd, unsafe { slice::from_raw_parts_mut(
redox_events.as_mut_ptr() as *mut u8, events as *mut u8,
redox_events.len() * mem::size_of::<Event>() maxevents as usize
) }); ) });
if bytes_read == -1 { if bytes_read == -1 {
return -1; return -1;
} }
let read = bytes_read as usize / mem::size_of::<Event>(); let read = bytes_read as usize / mem::size_of::<Event>();
for event in &redox_events { for i in 0..maxevents {
if event.data == 0 {
return EINTR;
}
unsafe { unsafe {
*events = *(event.data as *mut epoll_event); let event = *(events as *mut Event);
if event.data == 0 {
return EINTR;
}
*events = epoll_event {
events: event.flags as _,
data: mem::transmute(event.data),
..Default::default()
};
events = events.add(mem::size_of::<epoll_event>()); events = events.add(mem::size_of::<epoll_event>());
} }
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment