N4508: A proposal to add shared_mutex (untimed)
(Revision 4)

Gor Nishanov (gorn@microsoft.com)

2015-5-5

Table of Contents

Background.. 1

Proposed Wording.. 1

Acknowledgements. 3

 

Background

At the Issaquah ISO C++ meeting of 2014 shared_mutex was renamed to shared_timed_mutex per proposal N3891 to follow the naming precedent set by timed_mutex and recursive_timed_mutex and to leave room for an untimed shared_mutex which can be more efficient on some platforms than shared_timed_mutex.

 

This paper introduces a shared_mutex type without timed locking requirement. This paper only includes the proposed wording. For background for shared locking please refer to N3568, N3659 and N3891.

 

This revision is a minor edit of an earlier paper N4241 that fixes the return type of unlock() to void as it should be, adds a comment //blocking to a lock function and clarifies that the wording is relative to N4431.

Proposed Wording

 

The proposed wording changes refer to N4431 (C++ Working Draft, 4/10/2015).

 

Modify shared_mutex synopsis of [thread.mutex] as follows:

Header <shared_mutex> synopsis

 

namespace std {

  class shared_mutex;

  class shared_timed_mutex;

  template <class Mutex> class shared_lock;

  template <class Mutex>

  void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;

}

 

Modify [thread.mutex.requirements.mutex] as follows:

 

Mutex types [thread.mutex.requirements.mutex]

1 The mutex types are the standard library types std::mutex, std::recursive_mutex, std::timed_mutex, std::recursive_timed_mutex, std::shared_mutex, and std::shared_timed_mutex. They shall meet the requirements set out in this section. In this description, m denotes an object of a mutex type.

                    6 The expression m.lock() shall be well-formed and have the following semantics:

7 Requires: If m is of type std::mutex, std::timed_mutex, std::shared_mutex, or std::shared_timed_mutex the calling thread does not own the mutex.

14 The expression m.try_lock() shall be well-formed and have the following semantics:

15 Requires: If m is of type std::mutex, std::timed_mutex, std::shared_mutex, or std::shared_timed_mutex, the calling thread does not own the mutex.

 

Insert a new section 30.4.1.4 [thread.sharedmutex.requirements]

30.4.1.4 Shared mutex types [thread.sharedmutex.requirements]

1 The standard library types std::shared_mutex and std::shared_timed_mutex are shared mutex types. Shared mutex types shall meet the requirements of mutex types (30.4.1.2), and additionally shall meet the requirements set out below. In this description, m denotes an object of a shared mutex type.

 

 Note to Editor: please move clauses 2-23 from [thread.sharedtimedmutex.requirements] to this point.

 

Excerpt from clauses 2 – 23 presented here for convenience of the reviewer.


2
In addition to the exclusive lock ownership mode specified in 30.4.1.2, shared mutex types provide a shared

lock ownership mode. Multiple execution agents can simultaneously hold a shared lock ownership of a shared

mutex type. But no execution agent shall hold a shared lock while another execution agent holds an exclusive lock on the same shared mutex type, and vice-versa. The maximum number of execution agents which can

share a shared lock on a single shared mutex type is unspecified, but shall be at least 10000. If more than

the maximum number of execution agents attempt to obtain a shared lock, the excess execution agents shall

block until the number of shared locks are reduced below the maximum amount by other execution agents

releasing their shared lock.

3 The expression m.lock_shared() shall be well-formed and have the following semantics:

11 The expression m.unlock_shared() shall be well-formed and have the following semantics:

17 The expression m.try_lock_shared() shall be well-formed and have the following semantics:

23 Throws: Nothing.

 

Insert a new section 30.4.1.4.1 [thread.sharedmutex.class]

 

30.4.1.4.1 Class shared_mutex [thread.sharedmutex.class]

namespace std {

    class shared_mutex {

    public:

         shared_mutex();

         ~shared_mutex();

 

         shared_mutex(const shared_mutex&) = delete;

         shared_mutex& operator=(const shared_mutex&) = delete;

 

          // Exclusive ownership

         void lock(); // blocking

         bool try_lock();

         void unlock();

 

                       // Shared ownership

                       void lock_shared(); // blocking

                       bool try_lock_shared();

                       void unlock_shared();

 

                       typedef implementation-defined native_handle_type; // See 30.2.3

                       native_handle_type native_handle(); // See 30.2.3

                  };

             }

             1 The class shared_mutex provides a non-recursive mutex with shared ownership semantics.

             2 The class shared_mutex shall satisfy all of the requirements for shared mutexes (30.4.1.4). It shall

            be a standard-layout class (Clause 9).

             3 The behavior of a program is undefined if:

            — it destroys a shared_mutex object owned by any thread,

            — a thread attempts to recursively gain any ownership of a shared_mutex.

            — a thread terminates while possessing any ownership of a shared_mutex.

         4 shared_mutex may be a synonym for shared_timed_mutex.

 

Modify section [thread.sharedtimedmutex.requirements] as follows

 

30.4.1.4.2 Shared timed mutex types [thread.sharedtimedmutex.requirements]

 

1 The standard library type std::shared_timed_mutex is a shared timed mutex type. Shared timed mutex

types shall meet the requirements of timed mutex types (30.4.1.3), shared mutex types (30.4.1.4), and additionally shall meet the requirements set out below. In this description, m denotes an object of a shared timed mutex type, rel_type denotes an object of an instantiation of duration (20.12.5), and abs_time denotes an object of an instantiation of time_point (20.12.6).

 

Note to Editor, Clauses 2-23 were moved to section [thread.sharedmutex.requirements] per earlier edits, clauses 24 – 37 remains here properly renumbered.

 

 

Excerpt from clauses 24 – 37 presented here for convenience of the reviewer.

 

24 The expression m.try_lock_shared_for(rel_time) shall be well-formed and have the following semantics:

30 Throws: Timeout-related exceptions (30.2.4).

 

31 The expression m.try_lock_shared_until(abs_time) shall be well-formed and have the following semantics:


37 Throws: Timeout-related exceptions (30.2.4).

 

Modify section 30.4.1.4.1 [thread.sharedtimedmutex.class] as follows:

 

30.4.1.4.13 Class shared_timed_mutex [thread.sharedtimedmutex.class]

 

 

2 The class shared_timed_mutex shall satisfy all of the SharedTimedMutex requirements (30.4.1.4).

   requirements for shared timed mutexes (30.4.1.4.2).  It shall be a standard-layout class (Clause 9).

Acknowledgements

Many thanks to Artur Laksberg, James McNellis and Stephan T. Lavavej for their feedback and review.