preemptive_threads/
platform_timer.rs1use core::sync::atomic::{AtomicBool, AtomicU64, Ordering};
4
5static PREEMPTION_PENDING: AtomicBool = AtomicBool::new(false);
6static PREEMPTION_COUNT: AtomicU64 = AtomicU64::new(0);
7
8#[cfg(target_os = "linux")]
14pub unsafe extern "C" fn signal_safe_handler(_sig: i32) {
15 PREEMPTION_PENDING.store(true, Ordering::Release);
17 PREEMPTION_COUNT.fetch_add(1, Ordering::Relaxed);
18}
19
20pub fn is_preemption_pending() -> bool {
22 PREEMPTION_PENDING.load(Ordering::Acquire)
23}
24
25pub fn clear_preemption_pending() {
27 PREEMPTION_PENDING.store(false, Ordering::Release);
28}
29
30pub fn get_preemption_count() -> u64 {
32 PREEMPTION_COUNT.load(Ordering::Relaxed)
33}
34
35#[cfg(target_os = "linux")]
37pub mod linux_timer {
38
39 pub fn init_preemption_timer(_interval_ms: u64) -> Result<(), &'static str> {
40 Err("Hardware timer preemption not implemented - use cooperative yield points")
48 }
49
50 pub fn stop_preemption_timer() {
51 }
53}
54
55#[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
57pub mod bsd_timer {
58
59 pub fn init_preemption_timer(_interval_ms: u64) -> Result<(), &'static str> {
60 Err("Hardware timer preemption not implemented for BSD - use cooperative yield points")
63 }
64
65 pub fn stop_preemption_timer() {
66 }
68}
69
70#[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
72pub mod generic_timer {
73
74 pub fn init_preemption_timer(_interval_ms: u64) -> Result<(), &'static str> {
75 Err("Hardware timer preemption not supported on this platform")
76 }
77
78 pub fn stop_preemption_timer() {
79 }
81}
82
83pub fn init_preemption_timer(interval_ms: u64) -> Result<(), &'static str> {
85 #[cfg(target_os = "linux")]
86 return linux_timer::init_preemption_timer(interval_ms);
87
88 #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
89 return bsd_timer::init_preemption_timer(interval_ms);
90
91 #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
92 return generic_timer::init_preemption_timer(interval_ms);
93}
94
95pub fn stop_preemption_timer() {
97 #[cfg(target_os = "linux")]
98 linux_timer::stop_preemption_timer();
99
100 #[cfg(any(target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd"))]
101 bsd_timer::stop_preemption_timer();
102
103 #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "freebsd", target_os = "netbsd", target_os = "openbsd")))]
104 generic_timer::stop_preemption_timer();
105}
106
107pub fn preemption_checkpoint() {
110 if is_preemption_pending() {
111 clear_preemption_pending();
112
113 crate::sync::yield_thread();
116 }
117}
118
119#[macro_export]
121macro_rules! preemption_point {
122 () => {
123 $crate::platform_timer::preemption_checkpoint();
124 };
125}