tasks_framework/
tasks.rs

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    /**
21     * recheck queue?
22     */
23    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    /**
35     * schedule task execution?
36     */
37    pub fn add_task(&self) -> bool {
38        // fast track for high-load applications
39        // atomic get is cheaper than atomic swap
40        // for both this thread and fetching thread
41        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}