(index<- )        ./libstd/rt/bookkeeping.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Wed Apr  9 17:27:02 2014
  1  // Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
  2  // file at the top-level directory of this distribution and at
  3  // http://rust-lang.org/COPYRIGHT.
  4  //
  5  // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
  6  // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
  7  // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
  8  // option. This file may not be copied, modified, or distributed
  9  // except according to those terms.
 10  
 11  //! Task bookkeeping
 12  //!
 13  //! This module keeps track of the number of running tasks so that entry points
 14  //! with libnative know when it's possible to exit the program (once all tasks
 15  //! have exited).
 16  //!
 17  //! The green counterpart for this is bookkeeping on sched pools, and it's up to
 18  //! each respective runtime to make sure that they call increment() and
 19  //! decrement() manually.
 20  
 21  #![experimental] // this is a massive code smell
 22  #![doc(hidden)]
 23  
 24  use sync::atomics;
 25  use unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
 26  
 27  static mut TASK_COUNT: atomics::AtomicUint = atomics::INIT_ATOMIC_UINT;
 28  static mut TASK_LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
 29  
 30  pub fn increment() {
 31      let _ = unsafe { TASK_COUNT.fetch_add(1, atomics::SeqCst) };
 32  }
 33  
 34  pub fn decrement() {
 35      unsafe {
 36          if TASK_COUNT.fetch_sub(1, atomics::SeqCst) == 1 {
 37              let guard = TASK_LOCK.lock();
 38              guard.signal();
 39          }
 40      }
 41  }
 42  
 43  /// Waits for all other native tasks in the system to exit. This is only used by
 44  /// the entry points of native programs
 45  pub fn wait_for_other_tasks() {
 46      unsafe {
 47          let guard = TASK_LOCK.lock();
 48          while TASK_COUNT.load(atomics::SeqCst) > 0 {
 49              guard.wait();
 50          }
 51      }
 52  }