Home ⌂Doc Index ◂Up ▴
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-2020 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 #ifndef __TBB_tbb_semaphore_H
18 #define __TBB_tbb_semaphore_H
19 
20 #include <tbb/atomic.h>
21 #include "tbb/tbb_stddef.h"
22 
23 #if _WIN32||_WIN64
25 
26 #elif __APPLE__
27 #include <mach/semaphore.h>
28 #include <mach/task.h>
29 #include <mach/mach_init.h>
30 #include <mach/error.h>
31 
32 #else
33 #include <semaphore.h>
34 #ifdef TBB_USE_DEBUG
35 #include <errno.h>
36 #endif
37 #endif /*_WIN32||_WIN64*/
38 
39 namespace tbb {
40 namespace internal {
41 
42 
43 #if _WIN32||_WIN64
44 typedef LONG sem_count_t;
46 class semaphore : no_copy {
47  static const int max_semaphore_cnt = MAXLONG;
48 public:
50  semaphore(size_t start_cnt_ = 0) {init_semaphore(start_cnt_);}
52  ~semaphore() {CloseHandle( sem );}
54  void P() {WaitForSingleObjectEx( sem, INFINITE, FALSE );}
56  void V() {ReleaseSemaphore( sem, 1, NULL );}
57 private:
58  HANDLE sem;
59  void init_semaphore(size_t start_cnt_) {
60  sem = CreateSemaphoreEx( NULL, LONG(start_cnt_), max_semaphore_cnt, NULL, 0, SEMAPHORE_ALL_ACCESS );
61  }
62 };
63 #elif __APPLE__
64 class semaphore : no_copy {
66 public:
68  semaphore(int start_cnt_ = 0) : sem(start_cnt_) { init_semaphore(start_cnt_); }
70  ~semaphore() {
71  kern_return_t ret = semaphore_destroy( mach_task_self(), sem );
72  __TBB_ASSERT_EX( ret==err_none, NULL );
73  }
75  void P() {
76  int ret;
77  do {
78  ret = semaphore_wait( sem );
79  } while( ret==KERN_ABORTED );
80  __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" );
81  }
83  void V() { semaphore_signal( sem ); }
84 private:
85  semaphore_t sem;
86  void init_semaphore(int start_cnt_) {
87  kern_return_t ret = semaphore_create( mach_task_self(), &sem, SYNC_POLICY_FIFO, start_cnt_ );
88  __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" );
89  }
90 };
91 #else /* Linux/Unix */
92 typedef uint32_t sem_count_t;
94 class semaphore : no_copy {
95 public:
97  semaphore(int start_cnt_ = 0 ) { init_semaphore( start_cnt_ ); }
98 
101  int ret = sem_destroy( &sem );
102  __TBB_ASSERT_EX( !ret, NULL );
103  }
105  void P() {
106  while( sem_wait( &sem )!=0 )
107  __TBB_ASSERT( errno==EINTR, NULL );
108  }
110  void V() { sem_post( &sem ); }
111 private:
112  sem_t sem;
113  void init_semaphore(int start_cnt_) {
114  int ret = sem_init( &sem, /*shared among threads*/ 0, start_cnt_ );
115  __TBB_ASSERT_EX( !ret, NULL );
116  }
117 };
118 #endif /* _WIN32||_WIN64 */
119 
120 
122 #if _WIN32||_WIN64
123 #if !__TBB_USE_SRWLOCK
124 class binary_semaphore : no_copy {
126 public:
128  binary_semaphore() { my_sem = CreateEventEx( NULL, NULL, 0, EVENT_ALL_ACCESS ); }
130  ~binary_semaphore() { CloseHandle( my_sem ); }
132  void P() { WaitForSingleObjectEx( my_sem, INFINITE, FALSE ); }
134  void V() { SetEvent( my_sem ); }
135 private:
136  HANDLE my_sem;
137 };
138 #else /* __TBB_USE_SRWLOCK */
139 
140 union srwl_or_handle {
141  SRWLOCK lock;
142  HANDLE h;
143 };
144 
146 class binary_semaphore : no_copy {
147 public:
153  void P();
155  void V();
156 private:
157  srwl_or_handle my_sem;
158 };
159 #endif /* !__TBB_USE_SRWLOCK */
160 #elif __APPLE__
161 class binary_semaphore : no_copy {
163 public:
165  binary_semaphore() : my_sem(0) {
166  kern_return_t ret = semaphore_create( mach_task_self(), &my_sem, SYNC_POLICY_FIFO, 0 );
167  __TBB_ASSERT_EX( ret==err_none, "failed to create a semaphore" );
168  }
171  kern_return_t ret = semaphore_destroy( mach_task_self(), my_sem );
172  __TBB_ASSERT_EX( ret==err_none, NULL );
173  }
175  void P() {
176  int ret;
177  do {
178  ret = semaphore_wait( my_sem );
179  } while( ret==KERN_ABORTED );
180  __TBB_ASSERT( ret==KERN_SUCCESS, "semaphore_wait() failed" );
181  }
183  void V() { semaphore_signal( my_sem ); }
184 private:
185  semaphore_t my_sem;
186 };
187 #else /* Linux/Unix */
188 
189 #if __TBB_USE_FUTEX
190 class binary_semaphore : no_copy {
191 // The implementation is equivalent to the "Mutex, Take 3" one
192 // in the paper "Futexes Are Tricky" by Ulrich Drepper
193 public:
195  binary_semaphore() { my_sem = 1; }
197  ~binary_semaphore() {}
199  void P() {
200  int s;
201  if( (s = my_sem.compare_and_swap( 1, 0 ))!=0 ) {
202  if( s!=2 )
203  s = my_sem.fetch_and_store( 2 );
204  while( s!=0 ) { // This loop deals with spurious wakeup
205  futex_wait( &my_sem, 2 );
206  s = my_sem.fetch_and_store( 2 );
207  }
208  }
209  }
211  void V() {
212  __TBB_ASSERT( my_sem>=1, "multiple V()'s in a row?" );
213  if( my_sem.fetch_and_store( 0 )==2 )
214  futex_wakeup_one( &my_sem );
215  }
216 private:
217  atomic<int> my_sem; // 0 - open; 1 - closed, no waits; 2 - closed, possible waits
218 };
219 #else
220 typedef uint32_t sem_count_t;
223 public:
226  int ret = sem_init( &my_sem, /*shared among threads*/ 0, 0 );
227  __TBB_ASSERT_EX( !ret, NULL );
228  }
231  int ret = sem_destroy( &my_sem );
232  __TBB_ASSERT_EX( !ret, NULL );
233  }
235  void P() {
236  while( sem_wait( &my_sem )!=0 )
237  __TBB_ASSERT( errno==EINTR, NULL );
238  }
240  void V() { sem_post( &my_sem ); }
241 private:
242  sem_t my_sem;
243 };
244 #endif /* __TBB_USE_FUTEX */
245 #endif /* _WIN32||_WIN64 */
246 
247 } // namespace internal
248 } // namespace tbb
249 
250 #endif /* __TBB_tbb_semaphore_H */
void P()
wait/acquire
Definition: semaphore.h:105
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:94
semaphore(int start_cnt_=0)
ctor
Definition: semaphore.h:97
void V()
post/release
Definition: semaphore.h:110
void init_semaphore(int start_cnt_)
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:167
binary_semaphore for concurrent monitor
Definition: semaphore.h:222
Base class for types that should not be copied or assigned.
Definition: tbb_stddef.h:330
void const char const char int ITT_FORMAT __itt_group_sync s
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
uint32_t sem_count_t
for performance reasons, we want specialized binary_semaphore
Definition: semaphore.h:92
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
The graph class.

Copyright © 2005-2020 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.