Home | History | Annotate | Download | only in src
      1 //===---------------------- shared_mutex.cpp ------------------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is dual licensed under the MIT and the University of Illinois Open
      6 // Source Licenses. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #define _LIBCPP_BUILDING_SHARED_MUTEX
     11 #include "shared_mutex"
     12 
     13 #if !_LIBCPP_SINGLE_THREADED
     14 
     15 _LIBCPP_BEGIN_NAMESPACE_STD
     16 
     17 shared_timed_mutex::shared_timed_mutex()
     18     : __state_(0)
     19 {
     20 }
     21 
     22 // Exclusive ownership
     23 
     24 void
     25 shared_timed_mutex::lock()
     26 {
     27     unique_lock<mutex> lk(__mut_);
     28     while (__state_ & __write_entered_)
     29         __gate1_.wait(lk);
     30     __state_ |= __write_entered_;
     31     while (__state_ & __n_readers_)
     32         __gate2_.wait(lk);
     33 }
     34 
     35 bool
     36 shared_timed_mutex::try_lock()
     37 {
     38     unique_lock<mutex> lk(__mut_);
     39     if (__state_ == 0)
     40     {
     41         __state_ = __write_entered_;
     42         return true;
     43     }
     44     return false;
     45 }
     46 
     47 void
     48 shared_timed_mutex::unlock()
     49 {
     50     lock_guard<mutex> _(__mut_);
     51     __state_ = 0;
     52     __gate1_.notify_all();
     53 }
     54 
     55 // Shared ownership
     56 
     57 void
     58 shared_timed_mutex::lock_shared()
     59 {
     60     unique_lock<mutex> lk(__mut_);
     61     while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
     62         __gate1_.wait(lk);
     63     unsigned num_readers = (__state_ & __n_readers_) + 1;
     64     __state_ &= ~__n_readers_;
     65     __state_ |= num_readers;
     66 }
     67 
     68 bool
     69 shared_timed_mutex::try_lock_shared()
     70 {
     71     unique_lock<mutex> lk(__mut_);
     72     unsigned num_readers = __state_ & __n_readers_;
     73     if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
     74     {
     75         ++num_readers;
     76         __state_ &= ~__n_readers_;
     77         __state_ |= num_readers;
     78         return true;
     79     }
     80     return false;
     81 }
     82 
     83 void
     84 shared_timed_mutex::unlock_shared()
     85 {
     86     lock_guard<mutex> _(__mut_);
     87     unsigned num_readers = (__state_ & __n_readers_) - 1;
     88     __state_ &= ~__n_readers_;
     89     __state_ |= num_readers;
     90     if (__state_ & __write_entered_)
     91     {
     92         if (num_readers == 0)
     93             __gate2_.notify_one();
     94     }
     95     else
     96     {
     97         if (num_readers == __n_readers_ - 1)
     98             __gate1_.notify_one();
     99     }
    100 }
    101 
    102 
    103 _LIBCPP_END_NAMESPACE_STD
    104 
    105 #endif // !_LIBCPP_SINGLE_THREADED
    106 
    107 
    108