nlib
SharedCriticalSection.h
Go to the documentation of this file.
1 
2 /*--------------------------------------------------------------------------------*
3  Project: CrossRoad
4  Copyright (C)Nintendo All rights reserved.
5 
6  These coded instructions, statements, and computer programs contain proprietary
7  information of Nintendo and/or its licensed developers and are protected by
8  national and international copyright laws. They may not be disclosed to third
9  parties or copied or duplicated in any form, in whole or in part, without the
10  prior written consent of Nintendo.
11 
12  The content herein is highly confidential and should be handled accordingly.
13  *--------------------------------------------------------------------------------*/
14 
15 #pragma once
16 #ifndef INCLUDE_NN_NLIB_THREADING_SHAREDCRITICALSECTION_H_
17 #define INCLUDE_NN_NLIB_THREADING_SHAREDCRITICALSECTION_H_
18 
19 #include "nn/nlib/Config.h"
20 #include "nn/nlib/DateTime.h"
21 
22 NLIB_NAMESPACE_BEGIN
23 namespace threading {
24 
25 class NLIB_CAPABILITY("mutex") SharedCriticalSection NLIB_FINAL {
26  public:
27 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
28  constexpr SharedCriticalSection() NLIB_NOEXCEPT = default;
29 #else
30  SharedCriticalSection() NLIB_NOEXCEPT {
31  errno_t e = nlib_rwlock_init(&rwock_);
32  NLIB_ASSERT_NOERR(e);
33  NLIB_UNUSED(e);
34  }
35 #endif
36  ~SharedCriticalSection() NLIB_NOEXCEPT {
37  errno_t e = nlib_rwlock_destroy(&rwock_);
38  NLIB_ASSERT_NOERR(e);
39  NLIB_UNUSED(e);
40  }
41 
42  void lock_shared() NLIB_NOEXCEPT NLIB_ACQUIRE_SHARED() {
43  errno_t e = nlib_rwlock_rdlock(&rwock_);
44  NLIB_UNUSED(e);
45  NLIB_ASSERT_NOERR(e);
46  }
47  NLIB_CHECK_RESULT bool try_lock_shared() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE_SHARED(true) {
48  errno_t e = nlib_rwlock_tryrdlock(&rwock_);
49  NLIB_ASSERT(e == 0 || e == EBUSY);
50  return e == 0;
51  }
52  NLIB_CHECK_RESULT bool try_lock_shared_for(const TimeSpan& timeout) NLIB_NOEXCEPT
53  NLIB_TRY_ACQUIRE_SHARED(true) {
54  errno_t e = nlib_rwlock_tryrdlock_for(&rwock_, timeout.ToTimeValue().tick);
55  NLIB_ASSERT(e == 0 || e == ETIMEDOUT);
56  return e == 0;
57  }
58  NLIB_CHECK_RESULT bool try_lock_shared_until(const DateTime& abstime) NLIB_NOEXCEPT
59  NLIB_TRY_ACQUIRE_SHARED(true) {
60  errno_t e = nlib_rwlock_tryrdlock_until(&rwock_, abstime.ToTimeValue().tick);
61  NLIB_ASSERT(e == 0 || e == ETIMEDOUT);
62  return e == 0;
63  }
64  void unlock_shared() NLIB_NOEXCEPT NLIB_RELEASE_SHARED() {
65  errno_t e = nlib_rwlock_rdunlock(&rwock_);
66  NLIB_UNUSED(e);
67  NLIB_ASSERT_NOERR(e);
68  }
69 
70  void lock() NLIB_NOEXCEPT NLIB_ACQUIRE() {
71  errno_t e = nlib_rwlock_wrlock(&rwock_);
72  NLIB_UNUSED(e);
73  NLIB_ASSERT_NOERR(e);
74  }
75  NLIB_CHECK_RESULT bool try_lock() NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
76  errno_t e = nlib_rwlock_trywrlock(&rwock_);
77  NLIB_ASSERT(e == 0 || e == EBUSY);
78  return e == 0;
79  }
81  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
82  errno_t e = nlib_rwlock_trywrlock_for(&rwock_, timeout.ToTimeValue().tick);
83  NLIB_ASSERT(e == 0 || e == ETIMEDOUT);
84  return e == 0;
85  }
87  NLIB_NOEXCEPT NLIB_TRY_ACQUIRE(true) {
88  errno_t e = nlib_rwlock_trywrlock_until(&rwock_, abstime.ToTimeValue().tick);
89  NLIB_ASSERT(e == 0 || e == ETIMEDOUT);
90  return e == 0;
91  }
92  void unlock() NLIB_NOEXCEPT NLIB_RELEASE() {
93  errno_t e = nlib_rwlock_wrunlock(&rwock_);
94  NLIB_UNUSED(e);
95  NLIB_ASSERT_NOERR(e);
96  }
97 
98  private:
99 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
101 #else
102  nlib_rwlock rwock_;
103 #endif
104  friend class CondVarForSharedCriticalSection;
105 };
106 
108  public:
109 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
110  constexpr CondVarForSharedCriticalSection() NLIB_NOEXCEPT = default;
111 #else
112  CondVarForSharedCriticalSection() NLIB_NOEXCEPT {
113  errno_t e = nlib_condrwlock_init(&condrwlock_);
114  NLIB_ASSERT_NOERR(e);
115  NLIB_UNUSED(e);
116  }
117 #endif
119  errno_t e = nlib_condrwlock_destroy(&condrwlock_);
120  NLIB_ASSERT_NOERR(e);
121  NLIB_UNUSED(e);
122  }
123  void Notify() NLIB_NOEXCEPT {
124  errno_t e = nlib_condrwlock_signal(&condrwlock_);
125  NLIB_UNUSED(e);
126  NLIB_ASSERT_NOERR(e);
127  }
128  void NotifyAll() NLIB_NOEXCEPT {
129  errno_t e = nlib_condrwlock_broadcast(&condrwlock_);
130  NLIB_UNUSED(e);
131  NLIB_ASSERT_NOERR(e);
132  }
133 
134  errno_t WaitReader(SharedCriticalSection& lock) NLIB_NOEXCEPT { // NOLINT
135  return nlib_condrwlock_wait(&condrwlock_, &lock.rwock_, 1);
136  }
137  errno_t WaitReader(nlib_rwlock& lock) NLIB_NOEXCEPT { // NOLINT
138  return nlib_condrwlock_wait(&condrwlock_, &lock, 1);
139  }
140  errno_t Wait(SharedCriticalSection& lock) NLIB_NOEXCEPT { // NOLINT
141  return nlib_condrwlock_wait(&condrwlock_, &lock.rwock_, 0);
142  }
143  errno_t Wait(nlib_rwlock& lock) NLIB_NOEXCEPT { // NOLINT
144  return nlib_condrwlock_wait(&condrwlock_, &lock, 0);
145  }
146 
148  const TimeSpan& timeout) NLIB_NOEXCEPT {
149  return nlib_condrwlock_wait_for(&condrwlock_, &lock.rwock_,
150  timeout.ToTimeValue().tick, 1);
151  }
153  const TimeSpan& timeout) NLIB_NOEXCEPT {
154  return nlib_condrwlock_wait_for(&condrwlock_, &lock,
155  timeout.ToTimeValue().tick, 1);
156  }
158  const TimeSpan& timeout) NLIB_NOEXCEPT {
159  return nlib_condrwlock_wait_for(&condrwlock_, &lock.rwock_,
160  timeout.ToTimeValue().tick, 0);
161  }
163  const TimeSpan& timeout) NLIB_NOEXCEPT {
164  return nlib_condrwlock_wait_for(&condrwlock_, &lock,
165  timeout.ToTimeValue().tick, 0);
166  }
167 
169  const DateTime& datetime) NLIB_NOEXCEPT {
170  return nlib_condrwlock_wait_until(&condrwlock_, &lock.rwock_,
171  datetime.ToTimeValue().tick, 1);
172  }
174  const DateTime& datetime) NLIB_NOEXCEPT {
175  return nlib_condrwlock_wait_until(&condrwlock_, &lock,
176  datetime.ToTimeValue().tick, 1);
177  }
179  const DateTime& datetime) NLIB_NOEXCEPT {
180  return nlib_condrwlock_wait_until(&condrwlock_, &lock.rwock_,
181  datetime.ToTimeValue().tick, 0);
182  }
184  const DateTime& datetime) NLIB_NOEXCEPT {
185  return nlib_condrwlock_wait_until(&condrwlock_, &lock,
186  datetime.ToTimeValue().tick, 0);
187  }
188 
189  private:
190 #if defined(NLIB_CXX11_CONSTEXPR) && defined(NLIB_CXX11_DEFAULTED_AND_DELETED_FUNCTIONS)
192 #else
193  nlib_condrwlock condrwlock_;
194 #endif
195 };
196 
197 
198 } // namespace threading
199 NLIB_NAMESPACE_END
200 
201 #endif // INCLUDE_NN_NLIB_THREADING_SHAREDCRITICALSECTION_H_
A conditional variable for SharedCriticalSection and nlib_rwlock. This variable can be used in the sa...
errno_t nlib_rwlock_rdunlock(nlib_rwlock *rwlock) NLIB_RELEASE_SHARED(*rwlock)
Releases the read lock.
NLIB_CHECK_RESULT errno_t WaitFor(nlib_rwlock &lock, const TimeSpan &timeout) noexcept
Unlocks a write lock and waits for a conditional variable signal for a specified period. Also see nlib_condrwlock_wait_for().
void lock_shared() noexcept NLIB_ACQUIRE_SHARED()
Gets the read lock, and enters the critical section. Blocks until it can get a lock.
errno_t nlib_condrwlock_wait(nlib_condrwlock *cond, nlib_rwlock *rwlock, int rdlock)
Unlocks rwlock and waits for a conditional variable. It then locks rwlock again after the execution r...
NLIB_CHECK_RESULT bool try_lock_shared() noexcept NLIB_TRY_ACQUIRE_SHARED(true)
Gets the read lock, and attempts to enter the critical section.
errno_t nlib_rwlock_tryrdlock(nlib_rwlock *rwlock) NLIB_TRY_ACQUIRE_SHARED(0
Gets the read lock, and attempts to enter the critical section.
errno_t nlib_condrwlock_wait_until(nlib_condrwlock *cond, nlib_rwlock *rwlock, nlib_time abstime, int rdlock)
Unlocks rwlock and waits for a conditional variable. It then locks rwlock again after the execution r...
struct nlib_rwlock_ nlib_rwlock
The type for a read-write lock object.
Definition: Platform.h:852
NLIB_CHECK_RESULT bool try_lock_until(const DateTime &abstime) noexcept NLIB_TRY_ACQUIRE(true)
Gets a write lock, and attempts to enter the critical section. Times out.
void Notify() noexcept
Signals to at least one waiting thread. Also see nlib_condrwlock_signal().
#define NLIB_CHECK_RESULT
Indicates that the caller of the function must check the returned value.
errno_t WaitReader(SharedCriticalSection &lock) noexcept
Unlocks the read lock and waits for a signal from the condition variable. Also see nlib_condrwlock_wa...
errno_t nlib_rwlock_wrlock(nlib_rwlock *rwlock) NLIB_ACQUIRE(*rwlock)
Gets a write lock, and enters the critical section. Blocks until it can get a lock.
NLIB_CHECK_RESULT errno_t WaitUntil(SharedCriticalSection &lock, const DateTime &datetime) noexcept
Unlocks a write lock and waits for a conditional variable signal until specified date and time...
errno_t nlib_rwlock_destroy(nlib_rwlock *rwlock) NLIB_EXCLUDES(*rwlock)
Destroys a read-write lock object.
errno_t nlib_condrwlock_wait_for(nlib_condrwlock *cond, nlib_rwlock *rwlock, nlib_duration duration, int rdlock)
Unlocks rwlock and waits for a conditional variable. It then locks rwlock again after the execution r...
errno_t nlib_condrwlock_signal(nlib_condrwlock *cond)
Resumes the execution of one thread that is waiting for the read-write lock conditional variable cond...
NLIB_CHECK_RESULT errno_t WaitReaderFor(nlib_rwlock &lock, const TimeSpan &timeout) noexcept
Unlocks a read lock and waits for a conditional variable signal for a specified period. Also see nlib_condrwlock_wait_for().
The class for representing the date and time.
Definition: DateTime.h:261
NLIB_CHECK_RESULT errno_t WaitReaderFor(SharedCriticalSection &lock, const TimeSpan &timeout) noexcept
Unlocks a read lock and waits for a conditional variable signal for a specified period. Also see nlib_condrwlock_wait_for().
Implements a read/write lock. Used when multiple threads simultaneously read data, and a single thread writes data.
errno_t nlib_condrwlock_init(nlib_condrwlock *cond)
Initializes a read-write lock conditional variable.
NLIB_CHECK_RESULT bool try_lock() noexcept NLIB_TRY_ACQUIRE(true)
Gets a write lock, and attempts to enter the critical section.
errno_t WaitReader(nlib_rwlock &lock) noexcept
Unlocks the read lock and waits for a signal from the condition variable. Also see nlib_condrwlock_wa...
struct nlib_condrwlock_ nlib_condrwlock
Type of the conditional variable for read-write locks.
errno_t Wait(SharedCriticalSection &lock) noexcept
Unlocks a write lock and waits for a conditional variable signal. Also see nlib_condrwlock_wait().
#define NLIB_CONDRWLOCK_INITIALIZER
Constant for statically initializing nlib_condrwlock.
Definition: Platform.h:1022
errno_t nlib_rwlock_rdlock(nlib_rwlock *rwlock) NLIB_ACQUIRE_SHARED(*rwlock)
Gets the read lock, and enters the critical section. Blocks until it can get a lock.
#define NLIB_RWLOCK_INITIALIZER
Constant for statically initializing nlib_rwlock.
Definition: Platform.h:854
errno_t nlib_rwlock_wrunlock(nlib_rwlock *rwlock) NLIB_RELEASE(*rwlock)
Releases a write lock.
NLIB_CHECK_RESULT errno_t WaitReaderUntil(nlib_rwlock &lock, const DateTime &datetime) noexcept
Unlocks a read lock and waits for a conditional variable signal until specified date and time...
Defines the class for handling times and durations.
errno_t Wait(nlib_rwlock &lock) noexcept
Unlocks a write lock and waits for a conditional variable signal. Also see nlib_condrwlock_wait().
#define NLIB_NOEXCEPT
Defines noexcept geared to the environment, or the equivalent.
Definition: Config.h:99
errno_t nlib_rwlock_tryrdlock_for(nlib_rwlock *rwlock, nlib_duration duration) NLIB_TRY_ACQUIRE_SHARED(0
Gets the read lock, and attempts to enter the critical section. Times out.
A file that contains the configuration information for each development environment.
errno_t nlib_condrwlock_destroy(nlib_condrwlock *cond)
Destroys a read-write lock conditional variable.
void unlock_shared() noexcept NLIB_RELEASE_SHARED()
Releases the read lock.
errno_t nlib_rwlock_trywrlock_for(nlib_rwlock *rwlock, nlib_duration duration) NLIB_TRY_ACQUIRE(0
Gets a write lock, and attempts to enter the critical section. Times out.
NLIB_CHECK_RESULT errno_t WaitUntil(nlib_rwlock &lock, const DateTime &datetime) noexcept
Unlocks a write lock and waits for a conditional variable signal until specified date and time...
void unlock() noexcept NLIB_RELEASE()
Releases a write lock.
errno_t nlib_rwlock_trywrlock(nlib_rwlock *rwlock) NLIB_TRY_ACQUIRE(0
Gets a write lock, and attempts to enter the critical section.
NLIB_CHECK_RESULT bool try_lock_shared_for(const TimeSpan &timeout) noexcept NLIB_TRY_ACQUIRE_SHARED(true)
Gets the read lock, and attempts to enter the critical section. Times out.
errno_t nlib_rwlock_tryrdlock_until(nlib_rwlock *rwlock, nlib_time abstime) NLIB_TRY_ACQUIRE_SHARED(0
Gets the read lock, and attempts to enter the critical section. Times out.
errno_t nlib_condrwlock_broadcast(nlib_condrwlock *cond)
Resumes the execution of all threads that are waiting for the read-write lock conditional variable co...
void lock() noexcept NLIB_ACQUIRE()
Gets a write lock, and enters the critical section. Blocks until it can get a lock.
NLIB_CHECK_RESULT bool try_lock_shared_until(const DateTime &abstime) noexcept NLIB_TRY_ACQUIRE_SHARED(true)
Gets the read lock, and attempts to enter the critical section. Times out.
errno_t nlib_rwlock_init(nlib_rwlock *rwlock) NLIB_EXCLUDES(*rwlock)
Initializes a read-write lock object.
#define NLIB_FINAL
Defines final if it is available for use. If not, holds an empty string.
Definition: Config.h:229
The class for representing the time.
Definition: DateTime.h:106
NLIB_CHECK_RESULT errno_t WaitFor(SharedCriticalSection &lock, const TimeSpan &timeout) noexcept
Unlocks a write lock and waits for a conditional variable signal for a specified period. Also see nlib_condrwlock_wait_for().
NLIB_CHECK_RESULT errno_t WaitReaderUntil(SharedCriticalSection &lock, const DateTime &datetime) noexcept
Unlocks a read lock and waits for a conditional variable signal until specified date and time...
NLIB_CHECK_RESULT bool try_lock_for(const TimeSpan &timeout) noexcept NLIB_TRY_ACQUIRE(true)
Gets a write lock, and attempts to enter the critical section. Times out.
void NotifyAll() noexcept
Signals all waiting threads. Also see nlib_condrwlock_broadcast().
errno_t nlib_rwlock_trywrlock_until(nlib_rwlock *rwlock, nlib_time abstime) NLIB_TRY_ACQUIRE(0
Gets a write lock, and attempts to enter the critical section. Times out.
int errno_t
Indicates with an int-type typedef that a POSIX error value is returned as the return value...
Definition: NMalloc.h:37