Skip to content

Commit

Permalink
Merge pull request #11 from AuYang261/dev
Browse files Browse the repository at this point in the history
sysinfo
  • Loading branch information
coolyjg authored Sep 25, 2023
2 parents c18b02c + 898edd5 commit 3d4889e
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 25 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions api/arceos_posix_api/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ axnet = { path = "../../modules/axnet", optional = true }
# Other crates
axio = { path = "../../crates/axio" }
axerrno = { path = "../../crates/axerrno" }
memory_addr = { path = "../../crates/memory_addr" }
static_assertions = "1.1.0"
spin = { version = "0.9" }
lazy_static = { version = "1.4", features = ["spin_no_std"] }
Expand Down
1 change: 1 addition & 0 deletions api/arceos_posix_api/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ typedef struct {{
"clockid_t",
"rlimit",
"aibuf",
"sysinfo",
];
let allow_vars = [
"O_.*",
Expand Down
1 change: 1 addition & 0 deletions api/arceos_posix_api/ctypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/sysinfo.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/uio.h>
Expand Down
1 change: 1 addition & 0 deletions api/arceos_posix_api/src/imp/fd_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use spin::RwLock;
use super::stdio::{stdin, stdout};
use crate::ctypes;

/// Maximum number of files per process
pub const AX_FILE_LIMIT: usize = 1024;

pub trait FileLike: Send + Sync {
Expand Down
32 changes: 32 additions & 0 deletions api/arceos_posix_api/src/imp/resources.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,24 +18,56 @@ pub unsafe fn sys_getrlimit(resource: c_int, rlimits: *mut ctypes::rlimit) -> c_
debug!("sys_getrlimit <= {} {:#x}", resource, rlimits as usize);
syscall_body!(sys_getrlimit, {
match resource as u32 {
ctypes::RLIMIT_CPU => {}
ctypes::RLIMIT_FSIZE => {}
ctypes::RLIMIT_DATA => {}
ctypes::RLIMIT_STACK => {}
ctypes::RLIMIT_CORE => {}
ctypes::RLIMIT_RSS => {}
ctypes::RLIMIT_NPROC => {}
ctypes::RLIMIT_NOFILE => {}
ctypes::RLIMIT_MEMLOCK => {}
ctypes::RLIMIT_AS => {}
ctypes::RLIMIT_LOCKS => {}
ctypes::RLIMIT_SIGPENDING => {}
ctypes::RLIMIT_MSGQUEUE => {}
ctypes::RLIMIT_NICE => {}
ctypes::RLIMIT_RTPRIO => {}
ctypes::RLIMIT_RTTIME => {}
ctypes::RLIMIT_NLIMITS => {}
_ => return Err(LinuxError::EINVAL),
}
if rlimits.is_null() {
return Ok(0);
}
match resource as u32 {
ctypes::RLIMIT_CPU => {}
ctypes::RLIMIT_FSIZE => {}
ctypes::RLIMIT_DATA => {}
ctypes::RLIMIT_STACK => unsafe {
(*rlimits).rlim_cur = axconfig::TASK_STACK_SIZE as _;
(*rlimits).rlim_max = axconfig::TASK_STACK_SIZE as _;
},
ctypes::RLIMIT_CORE => {}
ctypes::RLIMIT_RSS => {}
ctypes::RLIMIT_NPROC => unsafe {
(*rlimits).rlim_cur = 1;
(*rlimits).rlim_max = 1;
},
#[cfg(feature = "fd")]
ctypes::RLIMIT_NOFILE => unsafe {
(*rlimits).rlim_cur = super::fd_ops::AX_FILE_LIMIT as _;
(*rlimits).rlim_max = super::fd_ops::AX_FILE_LIMIT as _;
},
ctypes::RLIMIT_MEMLOCK => {}
ctypes::RLIMIT_AS => {}
ctypes::RLIMIT_LOCKS => {}
ctypes::RLIMIT_SIGPENDING => {}
ctypes::RLIMIT_MSGQUEUE => {}
ctypes::RLIMIT_NICE => {}
ctypes::RLIMIT_RTPRIO => {}
ctypes::RLIMIT_RTTIME => {}
ctypes::RLIMIT_NLIMITS => {}
_ => {}
}
Ok(0)
Expand Down
66 changes: 44 additions & 22 deletions api/arceos_posix_api/src/imp/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,50 @@ use core::ffi::{c_int, c_long};

use crate::ctypes;

const PAGE_SIZE_4K: usize = 4096;

/// Return system configuration infomation
///
/// Notice: currently only support what unikraft covers
pub fn sys_sysconf(name: c_int) -> c_long {
debug!("sys_sysconf <= {}", name);
syscall_body!(sys_sysconf, {
match name as u32 {
// Page size
ctypes::_SC_PAGE_SIZE => Ok(PAGE_SIZE_4K),
// Total physical pages
ctypes::_SC_PHYS_PAGES => Ok(axconfig::PHYS_MEMORY_SIZE / PAGE_SIZE_4K),
// Number of processors in use
ctypes::_SC_NPROCESSORS_ONLN => Ok(axconfig::SMP),
// Avaliable physical pages
#[cfg(feature = "alloc")]
ctypes::_SC_AVPHYS_PAGES => Ok(axalloc::global_allocator().available_pages()),
// Maximum number of files per process
#[cfg(feature = "fd")]
ctypes::_SC_OPEN_MAX => Ok(super::fd_ops::AX_FILE_LIMIT),
_ => Ok(0),
/// Return sysinfo struct
#[no_mangle]
pub unsafe extern "C" fn sys_sysinfo(info: *mut ctypes::sysinfo) -> c_int {
debug!("sys_sysinfo");
syscall_body!(sys_sysinfo, {
let info_mut = info.as_mut().unwrap();

// If the kernel booted less than 1 second, it will be 0.
info_mut.uptime = axhal::time::current_time().as_secs() as c_long;

info_mut.loads = [0; 3];
#[cfg(feature = "axtask")]
{
axtask::get_avenrun(&mut info_mut.loads);
}

info_mut.sharedram = 0;
// TODO
info_mut.bufferram = 0;

info_mut.totalram = 0;
info_mut.freeram = 0;
#[cfg(feature = "alloc")]
{
use core::ffi::c_ulong;
let allocator = axalloc::global_allocator();
info_mut.freeram = (allocator.available_bytes()
+ allocator.available_pages() * memory_addr::PAGE_SIZE_4K)
as c_ulong;
info_mut.totalram = info_mut.freeram + allocator.used_bytes() as c_ulong;
}

// TODO
info_mut.totalswap = 0;
info_mut.freeswap = 0;

info_mut.procs = 1;

// unused in 64-bit
info_mut.totalhigh = 0;
info_mut.freehigh = 0;

info_mut.mem_unit = 1;

Ok(0)
})
}
3 changes: 2 additions & 1 deletion api/arceos_posix_api/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ mod imp;
/// Platform-specific constants and parameters.
pub mod config {
pub use axconfig::*;
pub use memory_addr::PAGE_SIZE_4K;
}

/// POSIX C types.
Expand All @@ -46,7 +47,7 @@ pub mod ctypes;

pub use imp::io::{sys_read, sys_write, sys_writev};
pub use imp::resources::{sys_getrlimit, sys_setrlimit};
pub use imp::sys::sys_sysconf;
pub use imp::sys::sys_sysinfo;
pub use imp::task::{sys_exit, sys_getpid, sys_sched_yield};
pub use imp::time::{sys_clock_gettime, sys_nanosleep};

Expand Down
16 changes: 16 additions & 0 deletions modules/axtask/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,22 @@ cfg_if::cfg_if! {
mod task;
mod api;
mod wait_queue;
#[cfg(feature = "irq")]
/// load average
pub mod loadavg;
/// TODO: if irq is disabled, what value should AVENRUN be?
/// average run load, same as in linux kernel
static mut AVENRUN: [u64; 3] = [0, 0, 0];

/// Get the load average
pub fn get_avenrun(loads: &mut [u64; 3]) {
for i in 0..3 {
unsafe {
// TODO: disable irq for safety
loads[i] = AVENRUN[i];
}
}
}

#[cfg(feature = "irq")]
mod timers;
Expand Down
78 changes: 78 additions & 0 deletions modules/axtask/src/loadavg.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Rukos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

use core::sync::atomic::{AtomicU64, Ordering};

use crate::AVENRUN;

/// bits to shift fixed point
const FSHIFT: u64 = 16;
/// fixed point
const FIXED_1: u64 = 1 << FSHIFT;
/// update AVENRUN per 5 seconds
const LOAD_FREQ: u64 = 5 * axhal::time::NANOS_PER_SEC + 1;

/* 1/exp(5sec/1min) as fixed-point */
/* 1/exp(5sec/5min) */
/* 1/exp(5sec/15min) */
const EXP: [u64; 3] = [1884, 2014, 2037];

/// count of idle ticks
static mut IDLE_CNT: AtomicU64 = AtomicU64::new(0);
/// count of all ticks
static mut ALL_CNT: AtomicU64 = AtomicU64::new(0);
/// last update time
static mut LAST_UPDATE: AtomicU64 = AtomicU64::new(0);

/*
* a1 = a0 * e + a * (1 - e)
*/
fn calc_load(load: u64, exp: u64, active: u64) -> u64 {
let mut newload: u64 = load * exp + active * (FIXED_1 - exp);
if active >= load {
newload += FIXED_1 - 1;
}
newload / FIXED_1
}

/*
* calc_load_tick - update the avenrun load
*
* Called from the scheduler_timer_tick.
*/
pub(crate) fn calc_load_tick(is_idle: bool) {
if is_idle {
unsafe {
IDLE_CNT.fetch_add(1, Ordering::Relaxed);
}
}
unsafe {
ALL_CNT.fetch_add(1, Ordering::Relaxed);
}

let curr = axhal::time::current_time_nanos();

if curr - unsafe { LAST_UPDATE.load(Ordering::Relaxed) } < LOAD_FREQ {
return;
}
let idle_cnt;
let all_cnt;
unsafe {
LAST_UPDATE.store(curr, Ordering::Relaxed);
idle_cnt = IDLE_CNT.load(Ordering::Relaxed);
IDLE_CNT.store(0, Ordering::Relaxed);
all_cnt = ALL_CNT.load(Ordering::Relaxed);
ALL_CNT.store(0, Ordering::Relaxed);
}
for i in 0..3 {
unsafe {
AVENRUN[i] = calc_load(AVENRUN[i], EXP[i], (all_cnt - idle_cnt) * FIXED_1 / all_cnt);
}
}
}
2 changes: 2 additions & 0 deletions modules/axtask/src/run_queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ impl AxRunQueue {

#[cfg(feature = "irq")]
pub fn scheduler_timer_tick(&mut self) {
use crate::loadavg;
let curr = crate::current();
loadavg::calc_load_tick(curr.is_idle());
if !curr.is_idle() && self.scheduler.task_tick(curr.as_task_ref()) {
#[cfg(feature = "preempt")]
curr.set_preempt_pending(true);
Expand Down
33 changes: 33 additions & 0 deletions ulib/axlibc/include/sys/sysinfo.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/* Copyright (c) [2023] [Syswonder Community]
* [Rukos] is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/

#ifndef __SYSINFO_H__
#define __SYSINFO_H__

#define SI_LOAD_SHIFT 16
struct sysinfo {
long uptime; /* Seconds since boot */
unsigned long loads[3]; /* 1, 5, and 15 minute load averages */
unsigned long totalram; /* Total usable main memory size */
unsigned long freeram; /* Available memory size */
unsigned long sharedram; /* Amount of shared memory */
unsigned long bufferram; /* Memory used by buffers */
unsigned long totalswap; /* Total swap space size */
unsigned long freeswap; /* swap space still available */
unsigned short procs; /* Number of current processes */
unsigned short pad; /* Explicit padding for m68k */
unsigned long totalhigh; /* Total high memory size */
unsigned long freehigh; /* Available high memory size */
unsigned int mem_unit; /* Memory unit size in bytes */
char _f[20 - 2 * sizeof(unsigned long) - sizeof(unsigned int)]; /* Padding: libc5 uses this.. */
};

int sys_sysinfo(struct sysinfo *);

#endif // __SYSINFO_H__
32 changes: 30 additions & 2 deletions ulib/axlibc/src/sys.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,41 @@
* See the Mulan PSL v2 for more details.
*/

use arceos_posix_api::sys_sysconf;
use crate::ctypes;
use arceos_posix_api::{config, sys_getrlimit};
use core::ffi::{c_int, c_long};

/// Return system configuration infomation
///
/// Notice: currently only support what unikraft covers
#[no_mangle]
pub unsafe extern "C" fn sysconf(name: c_int) -> c_long {
sys_sysconf(name)
match name as u32 {
// Maximum process number
ctypes::_SC_CHILD_MAX => {
let mut rl: ctypes::rlimit = core::mem::zeroed();
sys_getrlimit(ctypes::RLIMIT_NPROC.try_into().unwrap(), &mut rl);
rl.rlim_max as c_long
}
// Page size
ctypes::_SC_PAGE_SIZE => config::PAGE_SIZE_4K as c_long,
// Total physical pages
ctypes::_SC_PHYS_PAGES => (config::PHYS_MEMORY_SIZE / config::PAGE_SIZE_4K) as c_long,
// Number of processors in use
ctypes::_SC_NPROCESSORS_ONLN => config::SMP as c_long,
// Avaliable physical pages
ctypes::_SC_AVPHYS_PAGES => {
let mut info: ctypes::sysinfo = core::mem::zeroed();
arceos_posix_api::sys_sysinfo(&mut info);
(info.freeram / config::PAGE_SIZE_4K as u64) as c_long
}
// Maximum number of files per process
#[cfg(feature = "fd")]
ctypes::_SC_OPEN_MAX => {
let mut rl: ctypes::rlimit = core::mem::zeroed();
sys_getrlimit(ctypes::RLIMIT_NOFILE.try_into().unwrap(), &mut rl);
rl.rlim_max as c_long
}
_ => 0,
}
}

0 comments on commit 3d4889e

Please sign in to comment.