From: Joshua Simmons Date: Sat, 5 Nov 2022 12:53:12 +0000 (+0100) Subject: Use Rust's ThreadId instead of gettid X-Git-Url: https://git.nega.tv//gitweb.cgi?a=commitdiff_plain;h=2fdf97a5eb1b1302c16813027d72f1f3ad885f1c;p=josh%2Fnarcissus Use Rust's ThreadId instead of gettid It's a little bit nasty due to needing to wrap it in Option, however it avoids making the gettid syscall every time we do a lock / unlock operation. Small performance improvement in debug mode. --- diff --git a/narcissus-core/src/lib.rs b/narcissus-core/src/lib.rs index a15b10a..6c2a35c 100644 --- a/narcissus-core/src/lib.rs +++ b/narcissus-core/src/lib.rs @@ -250,10 +250,6 @@ pub fn string_from_c_str(c_str: &[i8]) -> String { String::from_utf8_lossy(s).into_owned() } -pub fn get_thread_id() -> i32 { - unsafe { libc::gettid() } -} - pub fn uninit_box() -> Box> { let layout = std::alloc::Layout::new::>(); unsafe { diff --git a/narcissus-core/src/libc.rs b/narcissus-core/src/libc.rs index c933bb9..1b40c1f 100644 --- a/narcissus-core/src/libc.rs +++ b/narcissus-core/src/libc.rs @@ -428,7 +428,6 @@ pub const SYS_epoll_pwait2: c_long = 441; pub const SYS_mount_setattr: c_long = 442; extern "C" { - pub fn gettid() -> pid_t; pub fn syscall(num: c_long, ...) -> c_long; pub fn mmap( @@ -440,6 +439,5 @@ extern "C" { offset: off_t, ) -> *mut c_void; pub fn munmap(addr: *mut c_void, len: size_t) -> c_int; - pub fn mprotect(addr: *mut c_void, len: size_t, prot: c_int) -> c_int; } diff --git a/narcissus-core/src/mutex.rs b/narcissus-core/src/mutex.rs index 23cb92e..e5dd569 100644 --- a/narcissus-core/src/mutex.rs +++ b/narcissus-core/src/mutex.rs @@ -4,19 +4,22 @@ use std::{ sync::atomic::{AtomicI32, Ordering}, }; -#[cfg(debug_assertions)] -use crate::get_thread_id; - use crate::{waiter, PhantomUnsend}; +#[cfg(debug_assertions)] +#[inline(always)] +fn thread_id() -> std::thread::ThreadId { + std::thread::current().id() +} + const UNLOCKED: i32 = 0; const LOCKED: i32 = 1; const LOCKED_WAIT: i32 = 2; pub struct Mutex { - control: AtomicI32, #[cfg(debug_assertions)] - thread_id: AtomicI32, + thread_id: std::cell::Cell>, + control: AtomicI32, data: UnsafeCell, } @@ -64,7 +67,7 @@ impl Mutex { Self { control: AtomicI32::new(UNLOCKED), #[cfg(debug_assertions)] - thread_id: AtomicI32::new(0), + thread_id: std::cell::Cell::new(None), data: UnsafeCell::new(value), } } @@ -108,7 +111,7 @@ impl Mutex { unsafe fn raw_lock(&self) { #[cfg(debug_assertions)] - if self.thread_id.load(Ordering::Relaxed) == get_thread_id() { + if self.thread_id.get() == Some(std::thread::current().id()) { panic!("recursion not supported") } @@ -122,7 +125,7 @@ impl Mutex { ) { Ok(_) => { #[cfg(debug_assertions)] - self.thread_id.store(get_thread_id(), Ordering::Relaxed); + self.thread_id.set(Some(thread_id())); return; } Err(x) => c = x, @@ -156,7 +159,7 @@ impl Mutex { ) { Ok(_) => { #[cfg(debug_assertions)] - self.thread_id.store(get_thread_id(), Ordering::Relaxed); + self.thread_id.set(Some(thread_id())); return; } Err(x) => c = x, @@ -167,7 +170,7 @@ impl Mutex { unsafe fn raw_try_lock(&self) -> bool { #[cfg(debug_assertions)] - if self.thread_id.load(Ordering::Relaxed) == get_thread_id() { + if self.thread_id.get() == Some(thread_id()) { panic!("recursion not supported") } @@ -178,7 +181,7 @@ impl Mutex { .is_ok() { #[cfg(debug_assertions)] - self.thread_id.store(get_thread_id(), Ordering::Relaxed); + self.thread_id.set(Some(thread_id())); true } else { false @@ -187,7 +190,7 @@ impl Mutex { unsafe fn raw_unlock(&self) { #[cfg(debug_assertions)] - self.thread_id.store(0, Ordering::Relaxed); + self.thread_id.set(None); if self.control.fetch_sub(1, Ordering::Release) != LOCKED { self.control.store(UNLOCKED, Ordering::Release);