]> git.nega.tv - josh/narcissus/commitdiff
Use Rust's ThreadId instead of gettid
authorJoshua Simmons <josh@nega.tv>
Sat, 5 Nov 2022 12:53:12 +0000 (13:53 +0100)
committerJoshua Simmons <josh@nega.tv>
Sat, 5 Nov 2022 12:53:12 +0000 (13:53 +0100)
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.

narcissus-core/src/lib.rs
narcissus-core/src/libc.rs
narcissus-core/src/mutex.rs

index a15b10acb376b970a47e7161625970be16232097..6c2a35cf310921670d1b079903db0b86d0e2f337 100644 (file)
@@ -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<T>() -> Box<MaybeUninit<T>> {
     let layout = std::alloc::Layout::new::<MaybeUninit<T>>();
     unsafe {
index c933bb95ad917116ca7df6d463c5c5eb3ed861b0..1b40c1f7a125bfc259fa1f02700f75c742d88145 100644 (file)
@@ -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;
 }
index 23cb92e0982ca007a891285dcff04b78df2a479d..e5dd569bb99a1bd57d71001ab5f22471a1876474 100644 (file)
@@ -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<T: ?Sized> {
-    control: AtomicI32,
     #[cfg(debug_assertions)]
-    thread_id: AtomicI32,
+    thread_id: std::cell::Cell<Option<std::thread::ThreadId>>,
+    control: AtomicI32,
     data: UnsafeCell<T>,
 }
 
@@ -64,7 +67,7 @@ impl<T> Mutex<T> {
         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<T: ?Sized> Mutex<T> {
 
     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<T: ?Sized> Mutex<T> {
             ) {
                 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<T: ?Sized> Mutex<T> {
                 ) {
                     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<T: ?Sized> Mutex<T> {
 
     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<T: ?Sized> Mutex<T> {
                 .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<T: ?Sized> Mutex<T> {
 
     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);