Skip to content
Snippets Groups Projects
Commit e5d30740 authored by Michael Aaron Murphy's avatar Michael Aaron Murphy
Browse files

Use integer_atomics feature

Rather than using AtomicUsize and AtomicBool fields within
our ForegroundSignals structure, I'm switching this over
to using AtomicU32 and AtomicU8 values instead.
parent 5e2b08ab
No related branches found
No related tags found
No related merge requests found
#![allow(unknown_lints)] #![allow(unknown_lints)]
#![allow(while_let_on_iterator)] #![allow(while_let_on_iterator)]
#![feature(conservative_impl_trait)] #![feature(conservative_impl_trait)]
#![feature(integer_atomics)]
extern crate app_dirs; extern crate app_dirs;
#[macro_use] #[macro_use]
......
#![allow(unknown_lints)] #![allow(unknown_lints)]
#![allow(while_let_on_iterator)] #![allow(while_let_on_iterator)]
#![feature(conservative_impl_trait)] #![feature(conservative_impl_trait)]
#![feature(integer_atomics)]
// For a performance boost on Linux // For a performance boost on Linux
// #![feature(alloc_system)] // #![feature(alloc_system)]
......
//! Contains the logic for enabling foreground management. //! Contains the logic for enabling foreground management.
use std::sync::atomic::{AtomicU32, AtomicU8, Ordering};
use std::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
pub(crate) enum BackgroundResult { pub(crate) enum BackgroundResult {
Errored, Errored,
Status(u8), Status(u8),
} }
const REPLIED: u8 = 1;
const ERRORED: u8 = 2;
/// An atomic structure that can safely be shared across threads, which serves to provide /// An atomic structure that can safely be shared across threads, which serves to provide
/// communication between the shell and background threads. The `fg` command uses this /// communication between the shell and background threads. The `fg` command uses this
/// structure to notify a background thread that it needs to wait for and return /// structure to notify a background thread that it needs to wait for and return
/// the exit status back to the `fg` function. /// the exit status back to the `fg` function.
pub(crate) struct ForegroundSignals { pub(crate) struct ForegroundSignals {
grab: AtomicUsize, // TODO: Use AtomicU32 when stable grab: AtomicU32,
status: AtomicUsize, // TODO: Use AtomicU8 when stable status: AtomicU8,
reply: AtomicBool, reply: AtomicU8,
errored: AtomicBool, // TODO: Combine with reply when U8 is stable
} }
impl ForegroundSignals { impl ForegroundSignals {
pub(crate) fn new() -> ForegroundSignals { pub(crate) fn new() -> ForegroundSignals {
ForegroundSignals { ForegroundSignals {
grab: AtomicUsize::new(0), grab: AtomicU32::new(0),
status: AtomicUsize::new(0), status: AtomicU8::new(0),
reply: AtomicBool::new(false), reply: AtomicU8::new(0),
errored: AtomicBool::new(false),
} }
} }
pub(crate) fn signal_to_grab(&self, pid: u32) { pub(crate) fn signal_to_grab(&self, pid: u32) { self.grab.store(pid, Ordering::Relaxed); }
self.grab.store(pid as usize, Ordering::Relaxed);
}
pub(crate) fn reply_with(&self, status: i8) { pub(crate) fn reply_with(&self, status: i8) {
self.grab.store(0, Ordering::Relaxed); self.grab.store(0, Ordering::Relaxed);
self.status.store(status as usize, Ordering::Relaxed); self.status.store(status as u8, Ordering::Relaxed);
self.reply.store(true, Ordering::Relaxed); self.reply.store(REPLIED, Ordering::Relaxed);
} }
pub(crate) fn errored(&self) { pub(crate) fn errored(&self) {
self.grab.store(0, Ordering::Relaxed); self.grab.store(0, Ordering::Relaxed);
self.errored.store(true, Ordering::Relaxed); self.reply.store(ERRORED, Ordering::Relaxed);
self.reply.store(true, Ordering::Relaxed);
} }
pub(crate) fn was_processed(&self) -> Option<BackgroundResult> { pub(crate) fn was_processed(&self) -> Option<BackgroundResult> {
if self.reply.load(Ordering::Relaxed) { let reply = self.reply.load(Ordering::Relaxed);
self.reply.store(false, Ordering::Relaxed); self.reply.store(0, Ordering::Relaxed);
if self.errored.load(Ordering::Relaxed) { if reply & ERRORED != 0 {
self.errored.store(false, Ordering::Relaxed); Some(BackgroundResult::Errored)
Some(BackgroundResult::Errored) } else if reply & REPLIED != 0 {
} else { Some(BackgroundResult::Status(self.status.load(Ordering::Relaxed) as u8))
Some(BackgroundResult::Status(self.status.load(Ordering::Relaxed) as u8))
}
} else { } else {
None None
} }
} }
pub(crate) fn was_grabbed(&self, pid: u32) -> bool { pub(crate) fn was_grabbed(&self, pid: u32) -> bool { self.grab.load(Ordering::Relaxed) == pid }
self.grab.load(Ordering::Relaxed) == pid as usize
}
} }
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