Browse Source

Add a per-line lock

Log lines got mangled together previously, making the log unreadable. For multithreaded applications, this is rather annoying, for this reason we add a lock which is locked for every line ensuring atomicity.
ticki 8 years ago
parent
commit
1186e42714
5 changed files with 19 additions and 12 deletions
  1. 3 4
      src/allocator.rs
  2. 10 2
      src/log.rs
  3. 1 1
      src/prelude.rs
  4. 3 5
      src/sys.rs
  5. 2 0
      src/vec.rs

+ 3 - 4
src/allocator.rs

@@ -6,17 +6,16 @@ use prelude::*;
 
 use core::{mem, ops};
 
-use {brk, tls};
+use {brk, tls, sync};
 use bookkeeper::{self, Bookkeeper, Allocator};
-use sync::Mutex;
 
 /// Alias for the wrapper type of the thread-local variable holding the local allocator.
 type ThreadLocalAllocator = MoveCell<LazyInit<fn() -> LocalAllocator, LocalAllocator>>;
 
 /// The global default allocator.
 // TODO remove these filthy function pointers.
-static GLOBAL_ALLOCATOR: Mutex<LazyInit<fn() -> GlobalAllocator, GlobalAllocator>> =
-    Mutex::new(LazyInit::new(global_init));
+static GLOBAL_ALLOCATOR: sync::Mutex<LazyInit<fn() -> GlobalAllocator, GlobalAllocator>> =
+    sync::Mutex::new(LazyInit::new(global_init));
 tls! {
     /// The thread-local allocator.
     static THREAD_ALLOCATOR: ThreadLocalAllocator = MoveCell::new(LazyInit::new(local_init));

+ 10 - 2
src/log.rs

@@ -16,7 +16,7 @@ macro_rules! log {
     ($pool:expr, $( $arg:expr ),*) => {
         log!($pool;(), $( $arg ),*);
     };
-    ($bk:expr;$cur:expr, $( $arg:expr ),*) => {{
+    ($bk:expr;$cur:expr, $( $arg:expr ),*) => {
         #[cfg(feature = "log")]
         {
             use core::fmt::Write;
@@ -24,6 +24,9 @@ macro_rules! log {
             use {write, log};
             use log::internal::IntoCursor;
 
+            // To avoid cluttering the lines, we acquire a lock.
+            let _lock = log::internal::LINE_LOCK.lock();
+
             // Print the pool state.
             let mut stderr = write::Writer::stderr();
             let _ = write!(stderr, "({:2})   {:10?} : ", $bk.id, log::internal::BlockLogger {
@@ -35,7 +38,7 @@ macro_rules! log {
             let _ = write!(stderr, $( $arg ),*);
             let _ = writeln!(stderr, " (at {}:{})", file!(), line!());
         }
-    }};
+    };
 }
 
 /// Top secret place-holding module.
@@ -49,6 +52,11 @@ pub mod internal {
     use core::cell::Cell;
     use core::ops::Range;
 
+    /// The line lock.
+    ///
+    /// This lock is used to avoid bungling and intertwining lines.
+    pub static LINE_LOCK: Mutex<()> = Mutex::new(());
+
     /// A "cursor".
     ///
     /// Cursors represents a block or an interval in the log output. This trait is implemented for

+ 1 - 1
src/prelude.rs

@@ -5,6 +5,6 @@
 pub use block::Block;
 pub use cell::MoveCell;
 pub use lazy_init::LazyInit;
-pub use leak::Leak;
+pub use sync::Mutex;
 pub use ptr::Pointer;
 pub use vec::Vec;

+ 3 - 5
src/sys.rs

@@ -2,16 +2,14 @@
 
 extern crate ralloc_shim as shim;
 
-use core::mem;
+use prelude::*;
 
-#[cfg(not(feature = "unsafe_no_brk_lock"))]
-use sync;
+use core::mem;
 
 /// The BRK mutex.
 ///
 /// This is used for avoiding data races in multiple allocator.
-#[cfg(not(feature = "unsafe_no_brk_lock"))]
-static BRK_MUTEX: sync::Mutex<()> = sync::Mutex::new(());
+static BRK_MUTEX: Mutex<()> = Mutex::new(());
 
 /// Increment data segment of this process by some, _n_, return a pointer to the new data segment
 /// start.

+ 2 - 0
src/vec.rs

@@ -4,6 +4,8 @@ use prelude::*;
 
 use core::{slice, ops, mem, ptr};
 
+use leak::Leak;
+
 /// A low-level vector primitive.
 ///
 /// This does not perform allocation nor reallaction, thus these have to be done manually.