use crate::types::int;
use std::sync::atomic::{AtomicUsize, Ordering};
pub const GOOS: &str = std::env::consts::OS;
pub const GOARCH: &str = std::env::consts::ARCH;
static GOMAXPROCS_SETTING: AtomicUsize = AtomicUsize::new(0);
pub(crate) static LIVE_GOROUTINES: AtomicUsize = AtomicUsize::new(1);
#[allow(non_snake_case)]
pub fn NumCPU() -> int {
std::thread::available_parallelism()
.map(|n| n.get() as int)
.unwrap_or(1)
}
#[allow(non_snake_case)]
pub fn GOMAXPROCS(n: int) -> int {
let prev = GOMAXPROCS_SETTING.load(Ordering::SeqCst);
let effective = if prev == 0 { NumCPU() as usize } else { prev };
if n > 0 {
GOMAXPROCS_SETTING.store(n as usize, Ordering::SeqCst);
}
effective as int
}
#[allow(non_snake_case)]
pub fn Gosched() {
std::thread::yield_now();
}
#[allow(non_snake_case)]
pub fn NumGoroutine() -> int {
LIVE_GOROUTINES.load(Ordering::SeqCst) as int
}
#[allow(non_snake_case)]
pub fn Version() -> &'static str {
concat!("goish-", env!("CARGO_PKG_VERSION"))
}
#[doc(hidden)]
#[derive(Debug)]
pub struct GoexitSentinel;
#[doc(hidden)]
pub fn is_goexit_panic(e: &Box<dyn std::any::Any + Send>) -> bool {
e.is::<GoexitSentinel>()
}
#[allow(non_snake_case)]
pub fn Goexit() -> ! {
std::panic::panic_any(GoexitSentinel);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn num_cpu_positive() {
assert!(NumCPU() >= 1);
}
#[test]
fn gomaxprocs_roundtrip() {
let prev = GOMAXPROCS(0);
assert!(prev >= 1);
let prev2 = GOMAXPROCS(4);
assert_eq!(prev2, prev);
assert_eq!(GOMAXPROCS(0), 4);
GOMAXPROCS(prev);
}
#[test]
fn gosched_runs() {
Gosched();
}
#[test]
fn os_and_arch_nonempty() {
assert!(!GOOS.is_empty());
assert!(!GOARCH.is_empty());
}
#[test]
fn version_format() {
assert!(Version().starts_with("goish-"));
}
}