Преглед изворни кода

sys_yield for mutex locking

ticki пре 9 година
родитељ
комит
15b186fad9
2 измењених фајлова са 18 додато и 5 уклоњено
  1. 5 3
      src/allocator.rs
  2. 13 2
      src/sys.rs

+ 5 - 3
src/allocator.rs

@@ -7,8 +7,9 @@ use core::intrinsics;
 use core::ptr::Unique;
 use core::sync::atomic;
 
-use bookkeeper::Bookkeeper;
 use block::Block;
+use bookkeeper::Bookkeeper;
+use sys;
 
 /// The bookkeeper lock.
 ///
@@ -35,8 +36,9 @@ unsafe fn unlock_bookkeeper() {
 fn get_bookkeeper() -> &'static mut Bookkeeper {
     unsafe {
         // Lock the mutex.
-        while BOOKKEEPER_LOCK.load(atomic::Ordering::SeqCst) {}
-        BOOKKEEPER_LOCK.store(true, atomic::Ordering::SeqCst);
+        while BOOKKEEPER_LOCK.compare_and_swap(false, true, atomic::Ordering::SeqCst) {
+            sys::yield_now();
+        }
 
         if let Some(ref mut x) = BOOKKEEPER {
             x

+ 13 - 2
src/sys.rs

@@ -38,6 +38,17 @@ impl Error {
     }
 }
 
+/// Cooperatively gives up a timeslice to the OS scheduler.
+pub fn yield_now() {
+    unsafe {
+        #[cfg(unix)]
+        syscall!(SCHED_YIELD);
+
+        #[cfg(redox)]
+        ::system::syscall::unix::sys_yield();
+    }
+}
+
 /// Retrieve the end of the current data segment.
 ///
 /// This will not change the state of the process in any way, and is thus safe.
@@ -47,8 +58,8 @@ pub fn segment_end() -> Result<*mut u8, Error> {
     }.map(|x| x as *mut _)
 }
 
-/// Increment data segment of this process by some (signed) _n_, return a pointer to the new data
-/// segment start.
+/// Increment data segment of this process by some, _n_, return a pointer to the new data segment
+/// start.
 ///
 /// This uses the system call BRK as backend.
 pub fn inc_brk(n: usize) -> Result<Unique<u8>, Error> {