mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
fix(node): Implement os.cpus() (#21697)
Fixes https://github.com/denoland/deno/issues/21666 Zero added dependency and tries to match the libuv implementation
This commit is contained in:
parent
48dae2441c
commit
c08319262a
6 changed files with 408 additions and 90 deletions
|
@ -241,13 +241,11 @@ Deno.test({
|
||||||
assertEquals(os.cpus().length, navigator.hardwareConcurrency);
|
assertEquals(os.cpus().length, navigator.hardwareConcurrency);
|
||||||
|
|
||||||
for (const cpu of os.cpus()) {
|
for (const cpu of os.cpus()) {
|
||||||
assertEquals(cpu.model, "");
|
assert(cpu.model.length > 0);
|
||||||
assertEquals(cpu.speed, 0);
|
assert(cpu.speed >= 0);
|
||||||
assertEquals(cpu.times.user, 0);
|
assert(cpu.times.user > 0);
|
||||||
assertEquals(cpu.times.nice, 0);
|
assert(cpu.times.sys > 0);
|
||||||
assertEquals(cpu.times.sys, 0);
|
assert(cpu.times.idle > 0);
|
||||||
assertEquals(cpu.times.idle, 0);
|
|
||||||
assertEquals(cpu.times.irq, 0);
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -281,6 +281,7 @@ deno_core::extension!(deno_node,
|
||||||
ops::os::op_node_os_set_priority<P>,
|
ops::os::op_node_os_set_priority<P>,
|
||||||
ops::os::op_node_os_username<P>,
|
ops::os::op_node_os_username<P>,
|
||||||
ops::os::op_geteuid<P>,
|
ops::os::op_geteuid<P>,
|
||||||
|
ops::os::op_cpus<P>,
|
||||||
op_node_build_os,
|
op_node_build_os,
|
||||||
op_node_is_promise_rejected,
|
op_node_is_promise_rejected,
|
||||||
op_npm_process_state,
|
op_npm_process_state,
|
||||||
|
|
306
ext/node/ops/os/cpus.rs
Normal file
306
ext/node/ops/os/cpus.rs
Normal file
|
@ -0,0 +1,306 @@
|
||||||
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use deno_core::serde::Serialize;
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Clone)]
|
||||||
|
pub struct CpuTimes {
|
||||||
|
pub user: u64,
|
||||||
|
pub nice: u64,
|
||||||
|
pub sys: u64,
|
||||||
|
pub idle: u64,
|
||||||
|
pub irq: u64,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Default, Serialize, Clone)]
|
||||||
|
pub struct CpuInfo {
|
||||||
|
pub model: String,
|
||||||
|
/* in MHz */
|
||||||
|
pub speed: u64,
|
||||||
|
pub times: CpuTimes,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl CpuInfo {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "macos")]
|
||||||
|
pub fn cpu_info() -> Option<Vec<CpuInfo>> {
|
||||||
|
let mut model: [u8; 512] = [0; 512];
|
||||||
|
let mut size = std::mem::size_of_val(&model);
|
||||||
|
|
||||||
|
// Safety: Assumes correct behavior of platform-specific syscalls and data structures.
|
||||||
|
// Relies on specific sysctl names and sysconf parameter existence.
|
||||||
|
unsafe {
|
||||||
|
let ticks = libc::sysconf(libc::_SC_CLK_TCK);
|
||||||
|
let multiplier = 1000u64 / ticks as u64;
|
||||||
|
if libc::sysctlbyname(
|
||||||
|
"machdep.cpu.brand_string\0".as_ptr() as *const libc::c_char,
|
||||||
|
model.as_mut_ptr() as _,
|
||||||
|
&mut size,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
0,
|
||||||
|
) != 0
|
||||||
|
&& libc::sysctlbyname(
|
||||||
|
"hw.model\0".as_ptr() as *const libc::c_char,
|
||||||
|
model.as_mut_ptr() as _,
|
||||||
|
&mut size,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
0,
|
||||||
|
) != 0
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cpu_speed: u64 = 0;
|
||||||
|
let mut cpu_speed_size = std::mem::size_of_val(&cpu_speed);
|
||||||
|
|
||||||
|
libc::sysctlbyname(
|
||||||
|
"hw.cpufrequency\0".as_ptr() as *const libc::c_char,
|
||||||
|
&mut cpu_speed as *mut _ as *mut libc::c_void,
|
||||||
|
&mut cpu_speed_size,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
|
||||||
|
if cpu_speed == 0 {
|
||||||
|
// https://github.com/libuv/libuv/pull/3679
|
||||||
|
//
|
||||||
|
// hw.cpufrequency sysctl seems to be missing on darwin/arm64
|
||||||
|
// so we instead hardcode a plausible value. This value matches
|
||||||
|
// what the mach kernel will report when running Rosetta apps.
|
||||||
|
cpu_speed = 2_400_000_000;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut num_cpus: libc::natural_t = 0;
|
||||||
|
let mut info: *mut libc::processor_cpu_load_info_data_t =
|
||||||
|
std::ptr::null_mut();
|
||||||
|
let mut msg_type: libc::mach_msg_type_number_t = 0;
|
||||||
|
if libc::host_processor_info(
|
||||||
|
libc::mach_host_self(),
|
||||||
|
libc::PROCESSOR_CPU_LOAD_INFO,
|
||||||
|
&mut num_cpus,
|
||||||
|
&mut info as *mut _ as *mut libc::processor_info_array_t,
|
||||||
|
&mut msg_type,
|
||||||
|
) != 0
|
||||||
|
{
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cpus = vec![CpuInfo::new(); num_cpus as usize];
|
||||||
|
|
||||||
|
let info = std::slice::from_raw_parts(info, num_cpus as usize);
|
||||||
|
let model = std::ffi::CStr::from_ptr(model.as_ptr() as _)
|
||||||
|
.to_string_lossy()
|
||||||
|
.into_owned();
|
||||||
|
for (i, cpu) in cpus.iter_mut().enumerate() {
|
||||||
|
cpu.times.user =
|
||||||
|
info[i].cpu_ticks[libc::CPU_STATE_USER as usize] as u64 * multiplier;
|
||||||
|
cpu.times.nice =
|
||||||
|
info[i].cpu_ticks[libc::CPU_STATE_NICE as usize] as u64 * multiplier;
|
||||||
|
cpu.times.sys =
|
||||||
|
info[i].cpu_ticks[libc::CPU_STATE_SYSTEM as usize] as u64 * multiplier;
|
||||||
|
cpu.times.idle =
|
||||||
|
info[i].cpu_ticks[libc::CPU_STATE_IDLE as usize] as u64 * multiplier;
|
||||||
|
|
||||||
|
cpu.times.irq = 0;
|
||||||
|
|
||||||
|
cpu.model = model.clone();
|
||||||
|
cpu.speed = cpu_speed / 1000000;
|
||||||
|
}
|
||||||
|
|
||||||
|
libc::vm_deallocate(
|
||||||
|
libc::mach_task_self(),
|
||||||
|
info.as_ptr() as libc::vm_address_t,
|
||||||
|
msg_type as _,
|
||||||
|
);
|
||||||
|
|
||||||
|
Some(cpus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
pub fn cpu_info() -> Option<Vec<CpuInfo>> {
|
||||||
|
use windows_sys::Win32::System::WindowsProgramming::NtQuerySystemInformation;
|
||||||
|
use windows_sys::Win32::System::WindowsProgramming::SystemProcessorPerformanceInformation;
|
||||||
|
use windows_sys::Win32::System::WindowsProgramming::SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;
|
||||||
|
|
||||||
|
use std::os::windows::ffi::OsStrExt;
|
||||||
|
use std::os::windows::ffi::OsStringExt;
|
||||||
|
|
||||||
|
fn encode_wide(s: &str) -> Vec<u16> {
|
||||||
|
std::ffi::OsString::from(s)
|
||||||
|
.encode_wide()
|
||||||
|
.chain(Some(0))
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safety: Assumes correct behavior of platform-specific syscalls and data structures.
|
||||||
|
unsafe {
|
||||||
|
let mut system_info: winapi::um::sysinfoapi::SYSTEM_INFO =
|
||||||
|
std::mem::zeroed();
|
||||||
|
winapi::um::sysinfoapi::GetSystemInfo(&mut system_info);
|
||||||
|
|
||||||
|
let cpu_count = system_info.dwNumberOfProcessors as usize;
|
||||||
|
|
||||||
|
let mut cpus = vec![CpuInfo::new(); cpu_count];
|
||||||
|
|
||||||
|
let mut sppi: Vec<SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION> =
|
||||||
|
vec![std::mem::zeroed(); cpu_count];
|
||||||
|
|
||||||
|
let sppi_size = std::mem::size_of_val(&sppi[0]) * cpu_count;
|
||||||
|
let mut result_size = 0;
|
||||||
|
|
||||||
|
let status = NtQuerySystemInformation(
|
||||||
|
SystemProcessorPerformanceInformation,
|
||||||
|
sppi.as_mut_ptr() as *mut _,
|
||||||
|
sppi_size as u32,
|
||||||
|
&mut result_size,
|
||||||
|
);
|
||||||
|
if status != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(result_size, sppi_size as u32);
|
||||||
|
|
||||||
|
for i in 0..cpu_count {
|
||||||
|
let key_name =
|
||||||
|
format!("HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\{}", i);
|
||||||
|
let key_name = encode_wide(&key_name);
|
||||||
|
|
||||||
|
let mut processor_key: windows_sys::Win32::System::Registry::HKEY =
|
||||||
|
std::mem::zeroed();
|
||||||
|
let err = windows_sys::Win32::System::Registry::RegOpenKeyExW(
|
||||||
|
windows_sys::Win32::System::Registry::HKEY_LOCAL_MACHINE,
|
||||||
|
key_name.as_ptr(),
|
||||||
|
0,
|
||||||
|
windows_sys::Win32::System::Registry::KEY_QUERY_VALUE,
|
||||||
|
&mut processor_key,
|
||||||
|
);
|
||||||
|
|
||||||
|
if err != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut cpu_speed = 0;
|
||||||
|
let mut cpu_speed_size = std::mem::size_of_val(&cpu_speed) as u32;
|
||||||
|
|
||||||
|
let err = windows_sys::Win32::System::Registry::RegQueryValueExW(
|
||||||
|
processor_key,
|
||||||
|
encode_wide("~MHz").as_ptr() as *mut _,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
&mut cpu_speed as *mut _ as *mut _,
|
||||||
|
&mut cpu_speed_size,
|
||||||
|
);
|
||||||
|
|
||||||
|
if err != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cpu_brand: [u16; 512] = [0; 512];
|
||||||
|
let mut cpu_brand_size = std::mem::size_of_val(&cpu_brand) as u32;
|
||||||
|
|
||||||
|
let err = windows_sys::Win32::System::Registry::RegQueryValueExW(
|
||||||
|
processor_key,
|
||||||
|
encode_wide("ProcessorNameString").as_ptr() as *mut _,
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
std::ptr::null_mut(),
|
||||||
|
cpu_brand.as_ptr() as *mut _,
|
||||||
|
&mut cpu_brand_size,
|
||||||
|
);
|
||||||
|
windows_sys::Win32::System::Registry::RegCloseKey(processor_key);
|
||||||
|
|
||||||
|
if err != 0 {
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let cpu_brand =
|
||||||
|
std::ffi::OsString::from_wide(&cpu_brand[..cpu_brand_size as usize])
|
||||||
|
.into_string()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
cpus[i].model = cpu_brand;
|
||||||
|
cpus[i].speed = cpu_speed as u64;
|
||||||
|
|
||||||
|
cpus[i].times.user = sppi[i].UserTime as u64 / 10000;
|
||||||
|
cpus[i].times.sys =
|
||||||
|
(sppi[i].KernelTime - sppi[i].IdleTime) as u64 / 10000;
|
||||||
|
cpus[i].times.idle = sppi[i].IdleTime as u64 / 10000;
|
||||||
|
/* InterruptTime is Reserved1[1] */
|
||||||
|
cpus[i].times.irq = sppi[i].Reserved1[1] as u64 / 10000;
|
||||||
|
cpus[i].times.nice = 0;
|
||||||
|
}
|
||||||
|
Some(cpus)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
|
pub fn cpu_info() -> Option<Vec<CpuInfo>> {
|
||||||
|
use std::io::BufRead;
|
||||||
|
|
||||||
|
let mut cpus = vec![CpuInfo::new(); 8192]; /* Kernel maxmimum */
|
||||||
|
|
||||||
|
let fp = std::fs::File::open("/proc/stat").ok()?;
|
||||||
|
let reader = std::io::BufReader::new(fp);
|
||||||
|
|
||||||
|
for (i, line) in reader.lines().enumerate() {
|
||||||
|
let line = line.ok()?;
|
||||||
|
if !line.starts_with("cpu") {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let mut fields = line.split_whitespace();
|
||||||
|
fields.next()?;
|
||||||
|
let user = fields.next()?.parse::<u64>().ok()?;
|
||||||
|
let nice = fields.next()?.parse::<u64>().ok()?;
|
||||||
|
let sys = fields.next()?.parse::<u64>().ok()?;
|
||||||
|
let idle = fields.next()?.parse::<u64>().ok()?;
|
||||||
|
let irq = fields.next()?.parse::<u64>().ok()?;
|
||||||
|
|
||||||
|
cpus[i].times.user = user;
|
||||||
|
cpus[i].times.nice = nice;
|
||||||
|
cpus[i].times.sys = sys;
|
||||||
|
cpus[i].times.idle = idle;
|
||||||
|
cpus[i].times.irq = irq;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fp = std::fs::File::open("/proc/cpuinfo").ok()?;
|
||||||
|
let reader = std::io::BufReader::new(fp);
|
||||||
|
|
||||||
|
let mut i = 0;
|
||||||
|
for line in reader.lines() {
|
||||||
|
let line = line.ok()?;
|
||||||
|
if !line.starts_with("model name") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let mut fields = line.splitn(2, ':');
|
||||||
|
fields.next()?;
|
||||||
|
let model = fields.next()?.trim();
|
||||||
|
|
||||||
|
cpus[i].model = model.to_string();
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpus.truncate(i);
|
||||||
|
Some(cpus)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_cpu_info() {
|
||||||
|
let info = cpu_info();
|
||||||
|
assert!(info.is_some());
|
||||||
|
let info = info.unwrap();
|
||||||
|
assert!(!info.is_empty());
|
||||||
|
for cpu in info {
|
||||||
|
assert!(!cpu.model.is_empty());
|
||||||
|
assert!(cpu.times.user > 0);
|
||||||
|
assert!(cpu.times.sys > 0);
|
||||||
|
assert!(cpu.times.idle > 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
90
ext/node/ops/os/mod.rs
Normal file
90
ext/node/ops/os/mod.rs
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
|
use crate::NodePermissions;
|
||||||
|
use deno_core::error::type_error;
|
||||||
|
use deno_core::error::AnyError;
|
||||||
|
use deno_core::op2;
|
||||||
|
use deno_core::OpState;
|
||||||
|
|
||||||
|
mod cpus;
|
||||||
|
mod priority;
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
pub fn op_node_os_get_priority<P>(
|
||||||
|
state: &mut OpState,
|
||||||
|
pid: u32,
|
||||||
|
) -> Result<i32, AnyError>
|
||||||
|
where
|
||||||
|
P: NodePermissions + 'static,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
let permissions = state.borrow_mut::<P>();
|
||||||
|
permissions.check_sys("getPriority", "node:os.getPriority()")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
priority::get_priority(pid)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
pub fn op_node_os_set_priority<P>(
|
||||||
|
state: &mut OpState,
|
||||||
|
pid: u32,
|
||||||
|
priority: i32,
|
||||||
|
) -> Result<(), AnyError>
|
||||||
|
where
|
||||||
|
P: NodePermissions + 'static,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
let permissions = state.borrow_mut::<P>();
|
||||||
|
permissions.check_sys("setPriority", "node:os.setPriority()")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
priority::set_priority(pid, priority)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2]
|
||||||
|
#[string]
|
||||||
|
pub fn op_node_os_username<P>(state: &mut OpState) -> Result<String, AnyError>
|
||||||
|
where
|
||||||
|
P: NodePermissions + 'static,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
let permissions = state.borrow_mut::<P>();
|
||||||
|
permissions.check_sys("userInfo", "node:os.userInfo()")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(deno_whoami::username())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2(fast)]
|
||||||
|
pub fn op_geteuid<P>(state: &mut OpState) -> Result<u32, AnyError>
|
||||||
|
where
|
||||||
|
P: NodePermissions + 'static,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
let permissions = state.borrow_mut::<P>();
|
||||||
|
permissions.check_sys("geteuid", "node:os.geteuid()")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(windows)]
|
||||||
|
let euid = 0;
|
||||||
|
#[cfg(unix)]
|
||||||
|
// SAFETY: Call to libc geteuid.
|
||||||
|
let euid = unsafe { libc::geteuid() };
|
||||||
|
|
||||||
|
Ok(euid)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[op2]
|
||||||
|
#[serde]
|
||||||
|
pub fn op_cpus<P>(state: &mut OpState) -> Result<Vec<cpus::CpuInfo>, AnyError>
|
||||||
|
where
|
||||||
|
P: NodePermissions + 'static,
|
||||||
|
{
|
||||||
|
{
|
||||||
|
let permissions = state.borrow_mut::<P>();
|
||||||
|
permissions.check_sys("cpus", "node:os.cpus()")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
cpus::cpu_info().ok_or_else(|| type_error("Failed to get cpu info"))
|
||||||
|
}
|
|
@ -1,78 +1,11 @@
|
||||||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||||
|
|
||||||
use crate::NodePermissions;
|
|
||||||
use deno_core::error::AnyError;
|
use deno_core::error::AnyError;
|
||||||
use deno_core::op2;
|
|
||||||
use deno_core::OpState;
|
|
||||||
|
|
||||||
#[op2(fast)]
|
pub use impl_::*;
|
||||||
pub fn op_node_os_get_priority<P>(
|
|
||||||
state: &mut OpState,
|
|
||||||
pid: u32,
|
|
||||||
) -> Result<i32, AnyError>
|
|
||||||
where
|
|
||||||
P: NodePermissions + 'static,
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let permissions = state.borrow_mut::<P>();
|
|
||||||
permissions.check_sys("getPriority", "node:os.getPriority()")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
priority::get_priority(pid)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2(fast)]
|
|
||||||
pub fn op_node_os_set_priority<P>(
|
|
||||||
state: &mut OpState,
|
|
||||||
pid: u32,
|
|
||||||
priority: i32,
|
|
||||||
) -> Result<(), AnyError>
|
|
||||||
where
|
|
||||||
P: NodePermissions + 'static,
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let permissions = state.borrow_mut::<P>();
|
|
||||||
permissions.check_sys("setPriority", "node:os.setPriority()")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
priority::set_priority(pid, priority)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2]
|
|
||||||
#[string]
|
|
||||||
pub fn op_node_os_username<P>(state: &mut OpState) -> Result<String, AnyError>
|
|
||||||
where
|
|
||||||
P: NodePermissions + 'static,
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let permissions = state.borrow_mut::<P>();
|
|
||||||
permissions.check_sys("userInfo", "node:os.userInfo()")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(deno_whoami::username())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op2(fast)]
|
|
||||||
pub fn op_geteuid<P>(state: &mut OpState) -> Result<u32, AnyError>
|
|
||||||
where
|
|
||||||
P: NodePermissions + 'static,
|
|
||||||
{
|
|
||||||
{
|
|
||||||
let permissions = state.borrow_mut::<P>();
|
|
||||||
permissions.check_sys("geteuid", "node:os.geteuid()")?;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(windows)]
|
|
||||||
let euid = 0;
|
|
||||||
#[cfg(unix)]
|
|
||||||
// SAFETY: Call to libc geteuid.
|
|
||||||
let euid = unsafe { libc::geteuid() };
|
|
||||||
|
|
||||||
Ok(euid)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
mod priority {
|
mod impl_ {
|
||||||
use super::*;
|
use super::*;
|
||||||
use errno::errno;
|
use errno::errno;
|
||||||
use errno::set_errno;
|
use errno::set_errno;
|
||||||
|
@ -106,7 +39,7 @@ mod priority {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod priority {
|
mod impl_ {
|
||||||
use super::*;
|
use super::*;
|
||||||
use deno_core::error::type_error;
|
use deno_core::error::type_error;
|
||||||
use winapi::shared::minwindef::DWORD;
|
use winapi::shared::minwindef::DWORD;
|
|
@ -32,6 +32,8 @@ import { os } from "ext:deno_node/internal_binding/constants.ts";
|
||||||
import { osUptime } from "ext:runtime/30_os.js";
|
import { osUptime } from "ext:runtime/30_os.js";
|
||||||
import { Buffer } from "ext:deno_node/internal/buffer.mjs";
|
import { Buffer } from "ext:deno_node/internal/buffer.mjs";
|
||||||
|
|
||||||
|
const ops = core.ops;
|
||||||
|
|
||||||
export const constants = os;
|
export const constants = os;
|
||||||
|
|
||||||
interface CPUTimes {
|
interface CPUTimes {
|
||||||
|
@ -129,19 +131,7 @@ export function arch(): string {
|
||||||
(uptime as any)[Symbol.toPrimitive] = (): number => uptime();
|
(uptime as any)[Symbol.toPrimitive] = (): number => uptime();
|
||||||
|
|
||||||
export function cpus(): CPUCoreInfo[] {
|
export function cpus(): CPUCoreInfo[] {
|
||||||
return Array.from(Array(navigator.hardwareConcurrency), () => {
|
return ops.op_cpus();
|
||||||
return {
|
|
||||||
model: "",
|
|
||||||
speed: 0,
|
|
||||||
times: {
|
|
||||||
user: 0,
|
|
||||||
nice: 0,
|
|
||||||
sys: 0,
|
|
||||||
idle: 0,
|
|
||||||
irq: 0,
|
|
||||||
},
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue