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 _LIBCPP_BEGIN_NAMESPACE_STD
     14 
     15 shared_timed_mutex::shared_timed_mutex()
     16     : __state_(0)
     17 {
     18 }
     19 
     20 // Exclusive ownership
     21 
     22 void
     23 shared_timed_mutex::lock()
     24 {
     25     unique_lock<mutex> lk(__mut_);
     26     while (__state_ & __write_entered_)
     27         __gate1_.wait(lk);
     28     __state_ |= __write_entered_;
     29     while (__state_ & __n_readers_)
     30         __gate2_.wait(lk);
     31 }
     32 
     33 bool
     34 shared_timed_mutex::try_lock()
     35 {
     36     unique_lock<mutex> lk(__mut_);
     37     if (__state_ == 0)
     38     {
     39         __state_ = __write_entered_;
     40         return true;
     41     }
     42     return false;
     43 }
     44 
     45 void
     46 shared_timed_mutex::unlock()
     47 {
     48     lock_guard<mutex> _(__mut_);
     49     __state_ = 0;
     50     __gate1_.notify_all();
     51 }
     52 
     53 // Shared ownership
     54 
     55 void
     56 shared_timed_mutex::lock_shared()
     57 {
     58     unique_lock<mutex> lk(__mut_);
     59     while ((__state_ & __write_entered_) || (__state_ & __n_readers_) == __n_readers_)
     60         __gate1_.wait(lk);
     61     unsigned num_readers = (__state_ & __n_readers_) + 1;
     62     __state_ &= ~__n_readers_;
     63     __state_ |= num_readers;
     64 }
     65 
     66 bool
     67 shared_timed_mutex::try_lock_shared()
     68 {
     69     unique_lock<mutex> lk(__mut_);
     70     unsigned num_readers = __state_ & __n_readers_;
     71     if (!(__state_ & __write_entered_) && num_readers != __n_readers_)
     72     {
     73         ++num_readers;
     74         __state_ &= ~__n_readers_;
     75         __state_ |= num_readers;
     76         return true;
     77     }
     78     return false;
     79 }
     80 
     81 void
     82 shared_timed_mutex::unlock_shared()
     83 {
     84     lock_guard<mutex> _(__mut_);
     85     unsigned num_readers = (__state_ & __n_readers_) - 1;
     86     __state_ &= ~__n_readers_;
     87     __state_ |= num_readers;
     88     if (__state_ & __write_entered_)
     89     {
     90         if (num_readers == 0)
     91             __gate2_.notify_one();
     92     }
     93     else
     94     {
     95         if (num_readers == __n_readers_ - 1)
     96             __gate1_.notify_one();
     97     }
     98 }
     99 
    100 
    101 _LIBCPP_END_NAMESPACE_STD
    102