Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
semaphore.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2018 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #ifndef __TBB_tbb_semaphore_H
22 #define __TBB_tbb_semaphore_H
23 
24 #include "tbb/tbb_stddef.h"
25 
26 #if _WIN32||_WIN64
28 
29 #elif __APPLE__
30 #include <mach/semaphore.h>
31 #include <mach/task.h>
32 #include <mach/mach_init.h>
33 #include <mach/error.h>
34 
35 #else
36 #include <semaphore.h>
37 #ifdef TBB_USE_DEBUG
38 #include <errno.h>
39 #endif
40 #endif /*_WIN32||_WIN64*/
41 
42 namespace tbb {
43 namespace internal {
44 
45 
46 #if _WIN32||_WIN64
47 typedef LONG sem_count_t;
49 class semaphore : no_copy {
50  static const int max_semaphore_cnt = MAXLONG;
51 public:
53  semaphore(size_t start_cnt_ = 0) {init_semaphore(start_cnt_);}
55  ~semaphore() {CloseHandle( sem );}
57  void P() {WaitForSingleObjectEx( sem, INFINITE, FALSE );}
59  void V() {ReleaseSemaphore( sem, 1, NULL );}
60 private:
61  HANDLE sem;
62  void init_semaphore(size_t start_cnt_) {
63  sem = CreateSemaphoreEx( NULL, LONG(start_cnt_), max_semaphore_cnt, NULL, 0, SEMAPHORE_ALL_ACCESS );
64  }
65 };
66 #elif __APPLE__
67 class semaphore : no_copy {
69 public:
71  semaphore(int start_cnt_ = 0) : sem(start_cnt_) { init_semaphore(start_cnt_); }
73  ~semaphore() {
74  kern_return_t ret = semaphore_destroy( mach_task_self(), sem );
75  __TBB_ASSERT_EX( ret==err_none, NULL );
76  }
78  void P() {
79  int ret;
80  do {
81  ret = semaphore_wait( sem );
82  } while( ret==KERN_ABORTED );
83  __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" );
84  }
86  void V() { semaphore_signal( sem ); }
87 private:
88  semaphore_t sem;
89  void init_semaphore(int start_cnt_) {
90  kern_return_t ret = semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, start_cnt_ );
91  __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" );
92  }
93 };
94 #else /* Linux/Unix */
95 typedef uint32_t sem_count_t;
97 class semaphore : no_copy {
98 public:
100  semaphore(int start_cnt_ = 0 ) { init_semaphore( start_cnt_ ); }
101 
104  int ret = sem_destroy( &sem );
105  __TBB_ASSERT_EX( !ret, NULL );
106  }
108  void P() {
109  while( sem_wait( &sem )!=0 )
110  __TBB_ASSERT( errno==EINTR, NULL );
111  }
113  void V() { sem_post( &sem ); }
114 private:
115  sem_t sem;
116  void init_semaphore(int start_cnt_) {
117  int ret = sem_init( &sem, /*shared among threads*/ 0, start_cnt_ );
118  __TBB_ASSERT_EX( !ret, NULL );
119  }
120 };
121 #endif /* _WIN32||_WIN64 */
122 
123 
125 #if _WIN32||_WIN64
126 #if !__TBB_USE_SRWLOCK
127 class binary_semaphore : no_copy {
129 public:
131  binary_semaphore() { my_sem = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS ); }
133  ~binary_semaphore() { CloseHandle( my_sem ); }
135  void P() { WaitForSingleObjectEx( my_sem, INFINITE, FALSE ); }
137  void V() { SetEvent( my_sem ); }
138 private:
139  HANDLE my_sem;
140 };
141 #else /* __TBB_USE_SRWLOCK */
142 
143 union srwl_or_handle {
144  SRWLOCK lock;
145  HANDLE h;
146 };
147 
149 class binary_semaphore : no_copy {
150 public:
156  void P();
158  void V();
159 private:
160  srwl_or_handle my_sem;
161 };
162 #endif /* !__TBB_USE_SRWLOCK */
163 #elif __APPLE__
164 class binary_semaphore : no_copy {
166 public:
168  binary_semaphore() : my_sem(0) {
169  kern_return_t ret = semaphore_create( mach_task_self(), &my_sem, SYNC_POLICY_FIFO, 0 );
170  __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" );
171  }
174  kern_return_t ret = semaphore_destroy( mach_task_self(), my_sem );
175  __TBB_ASSERT_EX( ret==err_none, NULL );
176  }
178  void P() {
179  int ret;
180  do {
181  ret = semaphore_wait( my_sem );
182  } while( ret==KERN_ABORTED );
183  __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" );
184  }
186  void V() { semaphore_signal( my_sem ); }
187 private:
188  semaphore_t my_sem;
189 };
190 #else /* Linux/Unix */
191 
192 #if __TBB_USE_FUTEX
193 class binary_semaphore : no_copy {
194 // The implementation is equivalent to the "Mutex, Take 3" one
195 // in the paper "Futexes Are Tricky" by Ulrich Drepper
196 public:
198  binary_semaphore() { my_sem = 1; }
200  ~binary_semaphore() {}
202  void P() {
203  int s;
204  if( (s = my_sem.compare_and_swap( 1, 0 ))!=0 ) {
205  if( s!=2 )
206  s = my_sem.fetch_and_store( 2 );
207  while( s!=0 ) { // This loop deals with spurious wakeup
208  futex_wait( &my_sem, 2 );
209  s = my_sem.fetch_and_store( 2 );
210  }
211  }
212  }
214  void V() {
215  __TBB_ASSERT( my_sem>=1, "multiple V()'s in a row?" );
216  if( my_sem.fetch_and_store( 0 )==2 )
217  futex_wakeup_one( &my_sem );
218  }
219 private:
220  atomic<int> my_sem; // 0 - open; 1 - closed, no waits; 2 - closed, possible waits
221 };
222 #else
223 typedef uint32_t sem_count_t;
226 public:
229  int ret = sem_init( &my_sem, /*shared among threads*/ 0, 0 );
230  __TBB_ASSERT_EX( !ret, NULL );
231  }
234  int ret = sem_destroy( &my_sem );
235  __TBB_ASSERT_EX( !ret, NULL );
236  }
238  void P() {
239  while( sem_wait( &my_sem )!=0 )
240  __TBB_ASSERT( errno==EINTR, NULL );
241  }
243  void V() { sem_post( &my_sem ); }
244 private:
245  sem_t my_sem;
246 };
247 #endif /* __TBB_USE_FUTEX */
248 #endif /* _WIN32||_WIN64 */
249 
250 } // namespace internal
251 } // namespace tbb
252 
253 #endif /* __TBB_tbb_semaphore_H */
void V()
post/release
Definition: semaphore.h:113
#define __TBB_ASSERT_EX(predicate, comment)
"Extended" version is useful to suppress warnings if a variable is only used with an assert
Definition: tbb_stddef.h:171
void const char const char int ITT_FORMAT __itt_group_sync s
uint32_t sem_count_t
for performance reasons, we want specialized binary_semaphore
Definition: semaphore.h:95
binary_semaphore for concurrent monitor
Definition: semaphore.h:225
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:335
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function h
Edsger Dijkstra's counting semaphore.
Definition: semaphore.h:97
void init_semaphore(int start_cnt_)
Definition: semaphore.h:116
The graph class.
void P()
wait/acquire
Definition: semaphore.h:108
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void * lock
semaphore(int start_cnt_=0)
ctor
Definition: semaphore.h:100

Copyright © 2005-2018 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.