1use std::sync::atomic::AtomicUsize;
2use std::sync::atomic::Ordering;
3
4#[allow(non_camel_case_types)]
5enum State {
6 WAITING,
7 RUNNING_NO_TASKS,
8 RUNNING_GOT_TASKS,
9}
10
11pub struct Tasks {
12 state: AtomicUsize
13}
14
15impl Tasks {
16 pub fn new() -> Tasks {
17 Tasks { state: AtomicUsize::new(State::WAITING as usize) }
18 }
19
20 pub fn fetch_task(&self) -> bool {
24 let old_state: usize = self.state.fetch_sub(1, Ordering::Relaxed);
25 if old_state == State::RUNNING_GOT_TASKS as usize {
26 return true;
27 } else if old_state == State::RUNNING_NO_TASKS as usize {
28 return false;
29 } else {
30 panic!(format!("unknown old state: {}", old_state));
31 }
32 }
33
34 pub fn add_task(&self) -> bool {
38 if self.state.load(Ordering::Relaxed) == State::RUNNING_GOT_TASKS as usize {
42 return false;
43 }
44
45 let old_state: usize = self.state.swap(State::RUNNING_GOT_TASKS as usize, Ordering::Relaxed);
46 return old_state == State::WAITING as usize;
47 }
48}