1use core::ffi::c_void;
22
23pub trait Scheduler: Send + Sync + 'static {
24    fn enable(&self);
26
27    fn disable(&self);
29
30    fn yield_task(&self);
32
33    fn current_task(&self) -> *mut c_void;
37
38    fn task_create(
41        &self,
42        task: extern "C" fn(*mut c_void),
43        param: *mut c_void,
44        task_stack_size: usize,
45    ) -> *mut c_void;
46
47    fn schedule_task_deletion(&self, task_handle: *mut c_void);
52
53    fn current_task_thread_semaphore(&self) -> *mut c_void;
57}
58
59extern "Rust" {
60    fn esp_wifi_preempt_enable();
61    fn esp_wifi_preempt_disable();
62    fn esp_wifi_preempt_yield_task();
63    fn esp_wifi_preempt_current_task() -> *mut c_void;
64    fn esp_wifi_preempt_task_create(
65        task: extern "C" fn(*mut c_void),
66        param: *mut c_void,
67        task_stack_size: usize,
68    ) -> *mut c_void;
69    fn esp_wifi_preempt_schedule_task_deletion(task_handle: *mut c_void);
70    fn esp_wifi_preempt_current_task_thread_semaphore() -> *mut c_void;
71}
72
73pub(crate) fn enable() {
74    unsafe { esp_wifi_preempt_enable() }
75}
76
77pub(crate) fn disable() {
78    unsafe { esp_wifi_preempt_disable() }
79}
80
81pub(crate) fn yield_task() {
82    unsafe { esp_wifi_preempt_yield_task() }
83}
84
85pub(crate) fn current_task() -> *mut c_void {
86    unsafe { esp_wifi_preempt_current_task() }
87}
88
89pub(crate) fn task_create(
90    task: extern "C" fn(*mut c_void),
91    param: *mut c_void,
92    task_stack_size: usize,
93) -> *mut c_void {
94    unsafe { esp_wifi_preempt_task_create(task, param, task_stack_size) }
95}
96
97pub(crate) fn schedule_task_deletion(task_handle: *mut c_void) {
98    unsafe { esp_wifi_preempt_schedule_task_deletion(task_handle) }
99}
100
101pub(crate) fn current_task_thread_semaphore() -> *mut c_void {
102    unsafe { esp_wifi_preempt_current_task_thread_semaphore() }
103}
104
105#[macro_export]
109macro_rules! scheduler_impl {
110    (static $name:ident: $t: ty = $val:expr) => {
111        static $name: $t = $val;
112
113        #[no_mangle]
114        fn esp_wifi_preempt_enable() {
115            <$t as $crate::preempt::Scheduler>::enable(&$name)
116        }
117        #[no_mangle]
118        fn esp_wifi_preempt_disable() {
119            <$t as $crate::preempt::Scheduler>::disable(&$name)
120        }
121        #[no_mangle]
122        fn esp_wifi_preempt_yield_task() {
123            <$t as $crate::preempt::Scheduler>::yield_task(&$name)
124        }
125        #[no_mangle]
126        fn esp_wifi_preempt_current_task() -> *mut c_void {
127            <$t as $crate::preempt::Scheduler>::current_task(&$name)
128        }
129        #[no_mangle]
130        fn esp_wifi_preempt_task_create(
131            task: extern "C" fn(*mut c_void),
132            param: *mut c_void,
133            task_stack_size: usize,
134        ) -> *mut c_void {
135            <$t as $crate::preempt::Scheduler>::task_create(&$name, task, param, task_stack_size)
136        }
137        #[no_mangle]
138        fn esp_wifi_preempt_schedule_task_deletion(task_handle: *mut c_void) {
139            <$t as $crate::preempt::Scheduler>::schedule_task_deletion(&$name, task_handle)
140        }
141        #[no_mangle]
142        fn esp_wifi_preempt_current_task_thread_semaphore() -> *mut c_void {
143            <$t as $crate::preempt::Scheduler>::current_task_thread_semaphore(&$name)
144        }
145    };
146}