summaryrefslogtreecommitdiff
path: root/monoio/src/scheduler.rs
blob: 594ec771b1a1a37483f1729781eeb02f8b98d5f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// 引入需要的库
use std::{cell::UnsafeCell, collections::VecDeque, marker::PhantomData};

use crate::task::{Schedule, Task};

// 本地调度器
pub(crate) struct LocalScheduler;

// 两种调度策略
impl Schedule for LocalScheduler {
    // 就绪队列
    fn schedule(&self, task: Task<Self>) {
        crate::runtime::CURRENT.with(|cx| cx.tasks.push(task));
    }
    // 就绪队列,立刻执行
    fn yield_now(&self, task: Task<Self>) {
        crate::runtime::CURRENT.with(|cx| cx.tasks.push_front(task));
    }
}

// 任务队列
pub(crate) struct TaskQueue {
    // Local queue. 就绪队列
    queue: UnsafeCell<VecDeque<Task<LocalScheduler>>>,
    // Make sure the type is `!Send` and `!Sync`.
    _marker: PhantomData<*const ()>, // 非跨线程
}

impl Default for TaskQueue {
    // 默认构造函数
    fn default() -> Self {
        Self::new()
    }
}

impl TaskQueue {
    // 创建就绪队列实例
    pub(crate) fn new() -> Self {
        const DEFAULT_TASK_QUEUE_SIZE: usize = 4096; // 默认4096
        Self::new_with_capacity(DEFAULT_TASK_QUEUE_SIZE)
    }
    // 创建指定容量的就绪队列实例
    pub(crate) fn new_with_capacity(capacity: usize) -> Self {
        Self {
            queue: UnsafeCell::new(VecDeque::with_capacity(capacity)), // 指定容量
            _marker: PhantomData, // 内存对齐?
        }
    }
    // 获取就绪队列长度
    pub(crate) fn len(&self) -> usize {
        unsafe { (*self.queue.get()).len() }
    }
    // 判断就绪队列是否为空
    pub(crate) fn is_empty(&self) -> bool {
        self.len() == 0
    }
    // 将任务加入就绪队列尾部
    pub(crate) fn push(&self, runnable: Task<LocalScheduler>) {
        unsafe {
            (*self.queue.get()).push_back(runnable);
        }
    }
    // 将任务加入就绪队列头部, 约等于立刻执行
    pub(crate) fn push_front(&self, runnable: Task<LocalScheduler>) {
        unsafe {
            (*self.queue.get()).push_front(runnable);
        }
    }
    // 从就绪队列头部弹出任务
    pub(crate) fn pop(&self) -> Option<Task<LocalScheduler>> {
        unsafe { (*self.queue.get()).pop_front() }
    }
}