Skip to content

Commit 800a548

Browse files
committed
Small optimizations
1 parent 4725a41 commit 800a548

File tree

3 files changed

+42
-6
lines changed

3 files changed

+42
-6
lines changed

kernel/src/syscall/task.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{
22
time::{timer::Timer, units::Nanosecond, uptime_fast},
33
user::{
44
self,
5-
scheduler::{self, Scheduler, SCHEDULER},
5+
scheduler::{self, round_robin::CURRENT_TASK, Scheduler, SCHEDULER},
66
string::SyscallString,
77
task,
88
},
@@ -37,7 +37,7 @@ pub fn exit(code: usize) -> ! {
3737
/// never happen and is a bug).
3838
#[allow(clippy::cast_possible_truncation)]
3939
pub fn id() -> Result<usize, isize> {
40-
Ok(SCHEDULER.current_task().id().0 as usize)
40+
Ok(CURRENT_TASK.local().borrow().as_ref().unwrap().id().0 as usize)
4141
}
4242

4343
/// Put the current task to sleep for at least the given number of nanoseconds. The task

kernel/src/user/task/preempt.rs

+20-4
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,36 @@ pub fn disable() {
4242

4343
/// Disable preemption during the execution of the given closure. This function is useful to avoid
4444
/// race conditions when multiple threads are accessing the same data. This function is implemented
45-
/// by disabling interrupts and preemption before executing the closure, and then restoring the
46-
/// previous state after the closure has finished.
45+
/// preemption before executing the closure, and then restoring the previous state after the closure
46+
/// has finished.
4747
///
4848
/// # Important
4949
/// Even if preemption is disabled, interrupts are still enabled. This means that the closure can
5050
/// still be interrupted by an IRQ handler. If you want to disable interrupts too, then you should
51+
/// use the `atomic` function instead.
5152
pub fn without<F, R>(f: F) -> R
5253
where
5354
F: FnOnce() -> R,
5455
{
55-
x86_64::irq::without(|| {
56+
{
5657
disable();
5758
let ret = f();
5859
enable();
5960
ret
60-
})
61+
}
62+
}
63+
64+
/// Disable preemption and interrupts during the execution of the given closure. This function is
65+
/// useful
66+
///
67+
/// Important
68+
/// Since this function disable interrupts and preemption, it should be used with caution. If the
69+
/// closure takes too much time to execute, it could cause the system to miss interrupts and
70+
/// increase the latency of the system. This function should only be used with caution, and only
71+
/// when it is really needed for short periods of time.
72+
pub fn atomic<F, R>(f: F) -> R
73+
where
74+
F: FnOnce() -> R,
75+
{
76+
x86_64::irq::without(|| without(f))
6177
}

user/shell/src/main.rs

+20
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,24 @@ fn main() {
99
let size = syscall::vfs::get_cwd(&mut buffer).expect("get_cwd failed");
1010

1111
println!("cwd: {}", core::str::from_utf8(&buffer[..size]).unwrap());
12+
13+
// Benchmark the get_pid syscall using the rdtsc
14+
let mut start: u64;
15+
let mut end: u64;
16+
let mut total: u64 = 0;
17+
18+
for _ in 0..1_000_000 {
19+
start = unsafe { core::arch::x86_64::_rdtsc() };
20+
syscall::task::id();
21+
end = unsafe { core::arch::x86_64::_rdtsc() };
22+
total += end - start;
23+
}
24+
25+
println!("Average get_pid syscall time: {} cycles", total / 1_000_000);
26+
27+
/// Convert cycles to nanoseconds, assuming a 4.2 GHz CPU
28+
println!(
29+
"Average get_pid syscall time: {} ns",
30+
(total / 1_000_000) * 1000 / 4200
31+
);
1232
}

0 commit comments

Comments
 (0)