BDE 4.14.0 Production release
Loading...
Searching...
No Matches
bslmt_semaphoreimpl_counted.h
Go to the documentation of this file.
1/// @file bslmt_semaphoreimpl_counted.h
2///
3/// The content of this file has been pre-processed for Doxygen.
4///
5
6
7// bslmt_semaphoreimpl_counted.h -*-C++-*-
8#ifndef INCLUDED_BSLMT_SEMAPHOREIMPL_COUNTED
9#define INCLUDED_BSLMT_SEMAPHOREIMPL_COUNTED
10
11#include <bsls_ident.h>
12BSLS_IDENT("$Id: $")
13
14/// @defgroup bslmt_semaphoreimpl_counted bslmt_semaphoreimpl_counted
15/// @brief Provide an implementation of `bslmt::Semaphore` with count.
16/// @addtogroup bsl
17/// @{
18/// @addtogroup bslmt
19/// @{
20/// @addtogroup bslmt_semaphoreimpl_counted
21/// @{
22///
23/// <h1> Outline </h1>
24/// * <a href="#bslmt_semaphoreimpl_counted-purpose"> Purpose</a>
25/// * <a href="#bslmt_semaphoreimpl_counted-classes"> Classes </a>
26/// * <a href="#bslmt_semaphoreimpl_counted-description"> Description </a>
27/// * <a href="#bslmt_semaphoreimpl_counted-usage"> Usage </a>
28///
29/// # Purpose {#bslmt_semaphoreimpl_counted-purpose}
30/// Provide an implementation of `bslmt::Semaphore` with count.
31///
32/// # Classes {#bslmt_semaphoreimpl_counted-classes}
33///
34/// - bslmt::SemaphoreImpl<CountedSemaphore>: semaphore specialization with count
35///
36/// @see bslmt_semaphore
37///
38/// # Description {#bslmt_semaphoreimpl_counted-description}
39/// This component provides an implementation of
40/// `bslmt::Semaphore`, `bslmt::SemaphoreImpl<CountedSemaphore>`, via the
41/// template specialization:
42/// @code
43/// bslmt::SemaphoreImpl<Platform::CountedSemaphore>
44/// @endcode
45/// This template class should not be used (directly) by client code. Clients
46/// should instead use `bslmt::Semaphore`.
47///
48/// This implementation of `bslmt::Semaphore` is intended for platforms where a
49/// separate count must be maintained. `bslmt::Semaphore` supports large
50/// values, but the native semaphores provided on some platforms are restricted
51/// to a relatively small range of values (e.g., `[ 0 .. 32000 ]` on AIX) and on
52/// some other platforms do not provide a count at all (Darwin). To support
53/// uniform usage across platforms, this component maintains the count of the
54/// semaphore in a separate atomic integer. `post` is only invoked on the
55/// underlying semaphore when it is known there are threads blocked on it.
56///
57/// ## Usage {#bslmt_semaphoreimpl_counted-usage}
58///
59///
60/// This component is an implementation detail of `bslmt` and is *not* intended
61/// for direct client use. It is subject to change without notice. As such, a
62/// usage example is not provided.
63/// @}
64/** @} */
65/** @} */
66
67/** @addtogroup bsl
68 * @{
69 */
70/** @addtogroup bslmt
71 * @{
72 */
73/** @addtogroup bslmt_semaphoreimpl_counted
74 * @{
75 */
76
77#include <bslscm_version.h>
78
79#include <bslmt_platform.h>
80
81#ifdef BSLMT_PLATFORM_COUNTED_SEMAPHORE
82
83// Platform-specific implementation starts here.
84
85#include <bsls_atomic.h>
86
89
90
91namespace bslmt {
92
93template <class SEMAPHORE_POLICY>
94class SemaphoreImpl;
95
96 // ===============================================
97 // class SemaphoreImpl<Platform::CountedSemaphore>
98 // ===============================================
99
100/// This class provides a full specialization of `SemaphoreImpl` with a
101/// separate count variable. This implementation maintains the value of the
102/// semaphore in a separate atomic integer count, so as to allow for
103/// semaphore count on platforms where a semaphore implementation doesn't
104/// provide the count or the provided count has very limited range of
105/// values.
106template <>
107class SemaphoreImpl<Platform::CountedSemaphore> {
108
109 // DATA
110 bsls::AtomicInt d_resources; // if positive, number of available resources
111 // if negative: number of waiting threads
112
113 SemaphoreImpl<Platform::CountedSemaphoreImplPolicy>
114 d_sem; // platform semaphore implementation
115
116 // NOT IMPLEMENTED
117 SemaphoreImpl(const SemaphoreImpl&);
118 SemaphoreImpl& operator=(const SemaphoreImpl&);
119
120 public:
121 // CREATORS
122
123 /// Create a semaphore. This method does not return normally unless
124 /// there are sufficient system resources to construct the object.
125 SemaphoreImpl(int count);
126
127 /// Destroy a semaphore
128 ~SemaphoreImpl();
129
130 // MANIPULATORS
131
132 /// Atomically increment the count of this semaphore.
133 void post();
134
135 /// Atomically increment the count of this semaphore by the specified
136 /// `number`. The behavior is undefined unless `number > 0`.
137 void post(int number);
138
139 /// Decrement the count of this semaphore if it is positive and return
140 /// 0. Return a non-zero value otherwise.
141 int tryWait();
142
143 /// Block until the count of this semaphore is a positive value and
144 /// atomically decrement it.
145 void wait();
146
147 // ACCESSORS
148
149 /// Return the current value of this semaphore.
150 int getValue() const;
151};
152
153// ============================================================================
154// INLINE DEFINITIONS
155// ============================================================================
156
157 // -----------------------------------------------
158 // class SemaphoreImpl<Platform::CountedSemaphore>
159 // -----------------------------------------------
160
161// CREATORS
162inline
163SemaphoreImpl<bslmt::Platform::CountedSemaphore>::SemaphoreImpl(
164 int count)
165: d_resources(count)
166, d_sem(0)
167{
168}
169
170inline
171SemaphoreImpl<bslmt::Platform::CountedSemaphore>::~SemaphoreImpl()
172{
173}
174
175// MANIPULATORS
176inline
177void SemaphoreImpl<bslmt::Platform::CountedSemaphore>::post()
178{
179 if (++d_resources <= 0) {
180 d_sem.post();
181 }
182}
183
184inline
185void SemaphoreImpl<bslmt::Platform::CountedSemaphore>::post(int number)
186{
187 for (int i = 0; i < number; ++i) {
188 post();
189 }
190}
191
192inline
193int SemaphoreImpl<bslmt::Platform::CountedSemaphore>::tryWait()
194{
195 for (int i = d_resources; i > 0; i = d_resources) {
196 if (i == d_resources.testAndSwap(i, i - 1)) {
197 return 0;
198 }
199 }
200
201 return -1;
202}
203
204inline
205void SemaphoreImpl<bslmt::Platform::CountedSemaphore>::wait()
206{
207 if (--d_resources >= 0) {
208 return;
209 }
210
211 d_sem.wait();
212}
213
214// ACCESSORS
215inline
216int SemaphoreImpl<bslmt::Platform::CountedSemaphore>::getValue() const
217{
218 const int v = d_resources;
219 return v > 0 ? v : 0;
220}
221
222} // close package namespace
223
224
225#endif
226
227#endif
228
229// ----------------------------------------------------------------------------
230// Copyright 2015 Bloomberg Finance L.P.
231//
232// Licensed under the Apache License, Version 2.0 (the "License");
233// you may not use this file except in compliance with the License.
234// You may obtain a copy of the License at
235//
236// http://www.apache.org/licenses/LICENSE-2.0
237//
238// Unless required by applicable law or agreed to in writing, software
239// distributed under the License is distributed on an "AS IS" BASIS,
240// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
241// See the License for the specific language governing permissions and
242// limitations under the License.
243// ----------------------------- END-OF-FILE ----------------------------------
244
245/** @} */
246/** @} */
247/** @} */
Definition bsls_atomic.h:743
#define BSLS_IDENT(str)
Definition bsls_ident.h:195
Definition bslmt_barrier.h:344