BDE 4.39.x 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 private:
117 // NOT IMPLEMENTED
118 SemaphoreImpl(const SemaphoreImpl&);
119 SemaphoreImpl& operator=(const SemaphoreImpl&);
120
121 public:
122 // CREATORS
123
124 /// Create a semaphore. This method does not return normally unless
125 /// there are sufficient system resources to construct the object.
126 SemaphoreImpl(int count);
127
128 /// Destroy a semaphore
129 ~SemaphoreImpl();
130
131 // MANIPULATORS
132
133 /// Atomically increment the count of this semaphore.
134 void post();
135
136 /// Atomically increment the count of this semaphore by the specified `number`.
137 ///
138 /// \pre The behavior is undefined unless `number > 0`.
139 void post(int number);
140
141 /// Decrement the count of this semaphore if it is positive and return
142 /// 0. Return a non-zero value otherwise.
143 int tryWait();
144
145 /// Block until the count of this semaphore is a positive value and
146 /// atomically decrement it.
147 void wait();
148
149 // ACCESSORS
150
151 /// Return the current value of this semaphore.
152 int getValue() const;
153};
154
155// ============================================================================
156// INLINE DEFINITIONS
157// ============================================================================
158
159 // -----------------------------------------------
160 // class SemaphoreImpl<Platform::CountedSemaphore>
161 // -----------------------------------------------
162
163// CREATORS
164inline
165SemaphoreImpl<bslmt::Platform::CountedSemaphore>::SemaphoreImpl(
166 int count)
167: d_resources(count)
168, d_sem(0)
169{
170}
171
172inline
173SemaphoreImpl<bslmt::Platform::CountedSemaphore>::~SemaphoreImpl()
174{
175}
176
177// MANIPULATORS
178inline
179void SemaphoreImpl<bslmt::Platform::CountedSemaphore>::post()
180{
181 if (++d_resources <= 0) {
182 d_sem.post();
183 }
184}
185
186inline
187void SemaphoreImpl<bslmt::Platform::CountedSemaphore>::post(int number)
188{
189 for (int i = 0; i < number; ++i) {
190 post();
191 }
192}
193
194inline
195int SemaphoreImpl<bslmt::Platform::CountedSemaphore>::tryWait()
196{
197 for (int i = d_resources; i > 0; i = d_resources) {
198 if (i == d_resources.testAndSwap(i, i - 1)) {
199 return 0;
200 }
201 }
202
203 return -1;
204}
205
206inline
207void SemaphoreImpl<bslmt::Platform::CountedSemaphore>::wait()
208{
209 if (--d_resources >= 0) {
210 return;
211 }
212
213 d_sem.wait();
214}
215
216// ACCESSORS
217inline
218int SemaphoreImpl<bslmt::Platform::CountedSemaphore>::getValue() const
219{
220 const int v = d_resources;
221 return v > 0 ? v : 0;
222}
223
224} // close package namespace
225
226
227#endif
228
229#endif
230
231// ----------------------------------------------------------------------------
232// Copyright 2015 Bloomberg Finance L.P.
233//
234// Licensed under the Apache License, Version 2.0 (the "License");
235// you may not use this file except in compliance with the License.
236// You may obtain a copy of the License at
237//
238// http://www.apache.org/licenses/LICENSE-2.0
239//
240// Unless required by applicable law or agreed to in writing, software
241// distributed under the License is distributed on an "AS IS" BASIS,
242// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
243// See the License for the specific language governing permissions and
244// limitations under the License.
245// ----------------------------- END-OF-FILE ----------------------------------
246
247/** @} */
248/** @} */
249/** @} */
Definition bsls_atomic.h:744
#define BSLS_IDENT(str)
BSLS_IDENT() - insert string into .comment binary segment (if supported)
Definition bsls_ident.h:238
Definition bslmt_barrier.h:344