open_coroutine_core/common/
constants.rs

1use crate::impl_display_by_debug;
2use once_cell::sync::Lazy;
3use std::time::Duration;
4
5/// Recommended stack size for coroutines.
6pub const DEFAULT_STACK_SIZE: usize = 128 * 1024;
7
8/// A user data used to indicate the timeout of `io_uring_enter`.
9#[cfg(all(target_os = "linux", feature = "io_uring"))]
10pub const IO_URING_TIMEOUT_USERDATA: usize = usize::MAX - 1;
11
12/// Coroutine global queue bean name.
13pub const COROUTINE_GLOBAL_QUEUE_BEAN: &str = "coroutineGlobalQueueBean";
14
15/// Task global queue bean name.
16pub const TASK_GLOBAL_QUEUE_BEAN: &str = "taskGlobalQueueBean";
17
18/// Monitor bean name.
19pub const MONITOR_BEAN: &str = "monitorBean";
20
21/// Default time slice.
22pub const SLICE: Duration = Duration::from_millis(10);
23
24/// Get the cpu count
25#[must_use]
26pub fn cpu_count() -> usize {
27    static CPU_COUNT: Lazy<usize> = Lazy::new(num_cpus::get);
28    *CPU_COUNT
29}
30
31/// Enums used to describe pool state
32#[repr(C)]
33#[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
34pub enum PoolState {
35    /// The pool is running.
36    Running,
37    /// The pool is stopping.
38    Stopping,
39    /// The pool is stopped.
40    Stopped,
41}
42
43impl_display_by_debug!(PoolState);
44
45/// Enums used to describe syscall
46#[allow(non_camel_case_types, missing_docs)]
47#[repr(C)]
48#[derive(Debug, Copy, Clone, Eq, PartialEq)]
49pub enum SyscallName {
50    #[cfg(windows)]
51    Sleep,
52    sleep,
53    usleep,
54    nanosleep,
55    poll,
56    select,
57    #[cfg(target_os = "linux")]
58    accept4,
59    #[cfg(target_os = "linux")]
60    epoll_ctl,
61    #[cfg(target_os = "linux")]
62    epoll_wait,
63    #[cfg(target_os = "linux")]
64    io_uring_enter,
65    #[cfg(any(
66        target_os = "macos",
67        target_os = "ios",
68        target_os = "tvos",
69        target_os = "watchos",
70        target_os = "freebsd",
71        target_os = "dragonfly",
72        target_os = "openbsd",
73        target_os = "netbsd"
74    ))]
75    kevent,
76    #[cfg(windows)]
77    iocp,
78    setsockopt,
79    recv,
80    #[cfg(windows)]
81    WSARecv,
82    recvfrom,
83    read,
84    pread,
85    readv,
86    preadv,
87    recvmsg,
88    connect,
89    listen,
90    accept,
91    #[cfg(windows)]
92    WSAAccept,
93    shutdown,
94    close,
95    socket,
96    #[cfg(windows)]
97    WSASocketW,
98    #[cfg(windows)]
99    ioctlsocket,
100    send,
101    #[cfg(windows)]
102    WSASend,
103    sendto,
104    write,
105    pwrite,
106    writev,
107    pwritev,
108    sendmsg,
109    fsync,
110    renameat,
111    #[cfg(target_os = "linux")]
112    renameat2,
113    mkdir,
114    mkdirat,
115    rmdir,
116    lseek,
117    openat,
118    link,
119    unlink,
120    pthread_cond_timedwait,
121    pthread_mutex_trylock,
122    pthread_mutex_lock,
123    pthread_mutex_unlock,
124    #[cfg(windows)]
125    CreateFileW,
126    #[cfg(windows)]
127    SetFilePointerEx,
128    #[cfg(windows)]
129    WaitOnAddress,
130    #[cfg(windows)]
131    WSAPoll,
132    /// panic!
133    panicking,
134}
135
136impl SyscallName {
137    /// Get the `NIO` syscall.
138    #[must_use]
139    pub fn nio() -> Self {
140        cfg_if::cfg_if! {
141            if #[cfg(target_os = "linux")] {
142                Self::epoll_wait
143            } else if #[cfg(any(
144                target_os = "macos",
145                target_os = "ios",
146                target_os = "tvos",
147                target_os = "watchos",
148                target_os = "freebsd",
149                target_os = "dragonfly",
150                target_os = "openbsd",
151                target_os = "netbsd"
152            ))] {
153                Self::kevent
154            } else if #[cfg(windows)] {
155                Self::iocp
156            } else {
157                compile_error!("unsupported")
158            }
159        }
160    }
161}
162
163impl_display_by_debug!(SyscallName);
164
165impl From<SyscallName> for &str {
166    fn from(val: SyscallName) -> Self {
167        format!("{val}").leak()
168    }
169}
170
171/// Enums used to describe syscall state
172#[repr(C)]
173#[derive(Debug, Copy, Clone, Eq, PartialEq)]
174pub enum SyscallState {
175    ///执行中
176    Executing,
177    ///被挂起到指定时间后继续执行,参数为时间戳
178    Suspend(u64),
179    ///到指定时间戳后回来,期间系统调用可能没执行完毕
180    ///对于sleep系列,这个状态表示正常完成
181    Timeout,
182    ///系统调用回调成功
183    Callback,
184}
185
186impl_display_by_debug!(SyscallState);
187
188/// Enums used to describe coroutine state
189#[repr(C)]
190#[derive(Debug, Copy, Clone, Eq, PartialEq)]
191pub enum CoroutineState<Y, R> {
192    ///The coroutine is ready to run.
193    Ready,
194    ///The coroutine is running.
195    Running,
196    ///The coroutine resumes execution after the specified time has been suspended(with a given value).
197    Suspend(Y, u64),
198    ///The coroutine enters the syscall.
199    Syscall(Y, SyscallName, SyscallState),
200    /// The coroutine cancelled.
201    Cancelled,
202    /// The coroutine completed with a return value.
203    Complete(R),
204    /// The coroutine completed with an error message.
205    Error(&'static str),
206}
207
208impl_display_by_debug!(CoroutineState<Y, R>);