Skip to content

Commit 31b64bc

Browse files
committed
refactor(driver): make the flag more meaningful
1 parent 03c748f commit 31b64bc

5 files changed

Lines changed: 64 additions & 35 deletions

File tree

compio-driver/src/sys/driver/iocp/mod.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,16 @@ impl Driver {
186186
entry.notify();
187187
has_entry = true;
188188
}
189+
if self.notify.reset() {
190+
has_entry = true;
191+
}
189192

190193
if !has_entry {
191194
for e in self.notify.port.poll(timeout)? {
192-
self.notify.set_awake(true);
193195
if let Some(e) = Self::create_entry(notify, &mut self.waits, e) {
196+
self.notifier.set_awake();
194197
e.notify()
195198
}
196-
self.notify.set_awake(false);
197199
}
198200
}
199201

@@ -231,8 +233,12 @@ impl Notify {
231233
}
232234
}
233235

234-
fn set_awake(&self, awake: bool) {
235-
self.awake.set(awake);
236+
fn set_awake(&self) {
237+
self.awake.set();
238+
}
239+
240+
fn reset(&self) -> bool {
241+
self.awake.reset()
236242
}
237243
}
238244

compio-driver/src/sys/driver/iour/mod.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -149,12 +149,12 @@ impl Driver {
149149
}
150150

151151
// Auto means that it choose to wait or not automatically.
152-
fn submit_auto(&mut self, timeout: Option<Duration>) -> io::Result<()> {
152+
fn submit_auto(&mut self, timeout: Option<Duration>, need_wait: bool) -> io::Result<()> {
153153
instrument!(compio_log::Level::TRACE, "submit_auto", ?timeout);
154154

155155
// when taskrun is true, there are completed cqes wait to handle, no need to
156156
// block the submit
157-
let want_sqe = if self.inner.submission().taskrun() {
157+
let want_sqe = if !need_wait || self.inner.submission().taskrun() {
158158
0
159159
} else {
160160
1
@@ -196,14 +196,10 @@ impl Driver {
196196
has_entry
197197
}
198198

199-
fn poll_entries(&mut self, hot_path: bool) -> bool {
199+
fn poll_entries(&mut self) -> bool {
200200
let mut cqueue = self.inner.completion();
201201
cqueue.sync();
202202
let has_entry = !cqueue.is_empty();
203-
// TODO: likely hint
204-
if hot_path {
205-
self.notifier.set_awake(true);
206-
}
207203
for entry in cqueue {
208204
match entry.user_data() {
209205
Self::CANCEL => {}
@@ -235,9 +231,6 @@ impl Driver {
235231
}
236232
}
237233
}
238-
if hot_path {
239-
self.notifier.set_awake(false);
240-
}
241234
has_entry
242235
}
243236

@@ -289,7 +282,7 @@ impl Driver {
289282
}
290283
Err(_) => {
291284
drop(squeue);
292-
match self.submit_auto(Some(Duration::ZERO)) {
285+
match self.submit_auto(Some(Duration::ZERO), true) {
293286
Ok(()) => {}
294287
Err(e)
295288
if matches!(
@@ -303,7 +296,7 @@ impl Driver {
303296
// event indefinitely.
304297
//
305298
// Anyway it is not a hot path, so we can afford an extra `write` syscall here.
306-
self.poll_entries(false);
299+
self.poll_entries();
307300
}
308301
}
309302
}
@@ -372,6 +365,8 @@ impl Driver {
372365

373366
trace!("start polling");
374367

368+
let need_wait = !self.notifier.reset();
369+
375370
if self.need_push_notifier {
376371
#[allow(clippy::useless_conversion)]
377372
self.push_raw(
@@ -384,8 +379,10 @@ impl Driver {
384379
self.need_push_notifier = false;
385380
}
386381

387-
self.submit_auto(timeout)?;
388-
self.poll_entries(true);
382+
self.submit_auto(timeout, need_wait)?;
383+
384+
self.notifier.set_awake();
385+
self.poll_entries();
389386

390387
Ok(())
391388
}

compio-driver/src/sys/driver/iour/notify.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,12 @@ impl Notifier {
3030
Ok(())
3131
}
3232

33-
pub fn set_awake(&self, awake: bool) {
34-
self.notify.set_awake(awake);
33+
pub fn set_awake(&self) {
34+
self.notify.set_awake();
35+
}
36+
37+
pub fn reset(&self) -> bool {
38+
self.notify.reset()
3539
}
3640

3741
pub fn waker(&self) -> Waker {
@@ -66,8 +70,12 @@ impl Notify {
6670
}
6771
}
6872

69-
pub fn set_awake(&self, awake: bool) {
70-
self.awake.set(awake);
73+
pub fn set_awake(&self) {
74+
self.awake.set();
75+
}
76+
77+
pub fn reset(&self) -> bool {
78+
self.awake.reset()
7179
}
7280
}
7381

compio-driver/src/sys/driver/mod.rs

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::sync::atomic::{AtomicBool, Ordering};
1+
use std::sync::atomic::{AtomicU8, Ordering};
22

33
cfg_if::cfg_if! {
44
if #[cfg(windows)] {
@@ -24,19 +24,33 @@ cfg_if::cfg_if! {
2424
crate::assert_not_impl!(Driver, Send);
2525
crate::assert_not_impl!(Driver, Sync);
2626

27+
const IDLE: u8 = 0b00;
28+
const NOTIFIED: u8 = 0b01;
29+
const AWAKE: u8 = 0b10;
30+
2731
#[derive(Debug)]
28-
struct AwakeFlag(AtomicBool);
32+
struct AwakeFlag(AtomicU8);
2933

3034
impl AwakeFlag {
3135
pub fn new() -> Self {
32-
Self(AtomicBool::new(false))
36+
Self(AtomicU8::new(IDLE))
37+
}
38+
39+
/// Set the awake flag. It is true before the driver sleeps, and false after
40+
/// it wakes up.
41+
pub fn set(&self) {
42+
self.0.fetch_or(AWAKE, Ordering::SeqCst);
3343
}
3444

35-
pub fn set(&self, awake: bool) {
36-
self.0.store(awake, Ordering::SeqCst);
45+
/// Reset the flags. Returns true if it was notified.
46+
pub fn reset(&self) -> bool {
47+
(self.0.swap(IDLE, Ordering::SeqCst) & NOTIFIED) != 0
3748
}
3849

50+
/// Set the notified flag. Returns true if the awake flag is set or the
51+
/// notified flag is set. If the awake flag is not set, the driver needs
52+
/// to be notified through a syscall.
3953
pub fn wake(&self) -> bool {
40-
self.0.swap(true, Ordering::SeqCst)
54+
self.0.fetch_or(NOTIFIED, Ordering::SeqCst) != 0
4155
}
4256
}

compio-driver/src/sys/driver/poll/mod.rs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -172,10 +172,8 @@ impl Driver {
172172
F: FnOnce(&mut Self, &mut Events) -> R,
173173
{
174174
let mut events = std::mem::take(&mut self.events);
175-
self.notify.set_awake(true);
176175
let res = f(self, &mut events);
177176
self.events = events;
178-
self.notify.set_awake(false);
179177
res
180178
}
181179

@@ -440,20 +438,22 @@ impl Driver {
440438

441439
pub fn poll(&mut self, mut timeout: Option<Duration>) -> io::Result<()> {
442440
instrument!(compio_log::Level::TRACE, "poll", ?timeout);
441+
let timeout_is_some = timeout.is_some();
443442
let has_completed = !self.completed_rx.is_empty();
444-
if has_completed {
443+
let need_wait = !self.notify.reset();
444+
if !need_wait || has_completed {
445445
timeout = Some(Duration::ZERO);
446446
}
447447
// We need to poll the poller first to make sure it handles the internal notify
448448
// event (if any).
449449
self.events.clear();
450450
self.notify.poll.wait(&mut self.events, timeout)?;
451-
self.notify.set_awake(false);
451+
self.notify.set_awake();
452452
if self.events.is_empty() {
453453
if self.poll_completed() {
454454
return Ok(());
455455
}
456-
if timeout.is_some() {
456+
if timeout_is_some {
457457
return Err(io::Error::from_raw_os_error(libc::ETIMEDOUT));
458458
}
459459
} else if has_completed {
@@ -551,8 +551,12 @@ impl Notify {
551551
}
552552
}
553553

554-
fn set_awake(&self, awake: bool) {
555-
self.awake.set(awake);
554+
fn set_awake(&self) {
555+
self.awake.set();
556+
}
557+
558+
fn reset(&self) -> bool {
559+
self.awake.reset()
556560
}
557561
}
558562

0 commit comments

Comments
 (0)