18 #include "tbb/compat/condition_variable" 30 using tbb::interface5::internal::condition_variable_using_event;
32 static atomic<do_once_state> condvar_api_state;
34 void WINAPI init_condvar_using_event( condition_variable_using_event* cv_event )
37 cv_event->event = CreateEventEx(NULL, NULL, 0x1 , EVENT_ALL_ACCESS );
38 InitializeCriticalSectionEx( &cv_event->mutex, 4000, 0 );
39 cv_event->n_waiters = 0;
40 cv_event->release_count = 0;
44 BOOL WINAPI sleep_condition_variable_cs_using_event( condition_variable_using_event* cv_event, LPCRITICAL_SECTION cs, DWORD dwMilliseconds )
46 EnterCriticalSection( &cv_event->mutex );
47 ++cv_event->n_waiters;
48 unsigned my_generation = cv_event->epoch;
49 LeaveCriticalSection( &cv_event->mutex );
50 LeaveCriticalSection( cs );
53 DWORD rc = WaitForSingleObjectEx( cv_event->event, dwMilliseconds, FALSE );
54 EnterCriticalSection( &cv_event->mutex );
55 if( rc!=WAIT_OBJECT_0 ) {
56 --cv_event->n_waiters;
57 LeaveCriticalSection( &cv_event->mutex );
58 if( rc==WAIT_TIMEOUT ) {
59 SetLastError( WAIT_TIMEOUT );
60 EnterCriticalSection( cs );
65 if( cv_event->release_count>0 && cv_event->epoch!=my_generation )
67 LeaveCriticalSection( &cv_event->mutex );
71 --cv_event->n_waiters;
72 int count = --cv_event->release_count;
73 LeaveCriticalSection( &cv_event->mutex );
76 __TBB_ASSERT( cv_event->event,
"Premature destruction of condition variable?" );
77 ResetEvent( cv_event->event );
79 EnterCriticalSection( cs );
83 void WINAPI wake_condition_variable_using_event( condition_variable_using_event* cv_event )
85 EnterCriticalSection( &cv_event->mutex );
86 if( cv_event->n_waiters>cv_event->release_count ) {
87 SetEvent( cv_event->event );
88 ++cv_event->release_count;
91 LeaveCriticalSection( &cv_event->mutex );
94 void WINAPI wake_all_condition_variable_using_event( condition_variable_using_event* cv_event )
96 EnterCriticalSection( &cv_event->mutex );
97 if( cv_event->n_waiters>0 ) {
98 SetEvent( cv_event->event );
99 cv_event->release_count = cv_event->n_waiters;
102 LeaveCriticalSection( &cv_event->mutex );
105 void WINAPI destroy_condvar_using_event( condition_variable_using_event* cv_event )
107 HANDLE my_event = cv_event->event;
108 EnterCriticalSection( &cv_event->mutex );
110 cv_event->event = NULL;
111 if( cv_event->n_waiters>0 ) {
112 LeaveCriticalSection( &cv_event->mutex );
115 EnterCriticalSection( &cv_event->mutex );
117 LeaveCriticalSection( &cv_event->mutex );
118 CloseHandle( my_event );
121 void WINAPI destroy_condvar_noop( CONDITION_VARIABLE* ) { }
123 static void (WINAPI *__TBB_init_condvar)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&init_condvar_using_event;
124 static BOOL (WINAPI *__TBB_condvar_wait)( PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD ) = (BOOL (WINAPI *)(PCONDITION_VARIABLE,LPCRITICAL_SECTION, DWORD))&sleep_condition_variable_cs_using_event;
125 static void (WINAPI *__TBB_condvar_notify_one)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&wake_condition_variable_using_event;
126 static void (WINAPI *__TBB_condvar_notify_all)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&wake_all_condition_variable_using_event;
127 static void (WINAPI *__TBB_destroy_condvar)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_using_event;
131 DLD(InitializeConditionVariable, __TBB_init_condvar),
132 DLD(SleepConditionVariableCS, __TBB_condvar_wait),
133 DLD(WakeConditionVariable, __TBB_condvar_notify_one),
134 DLD(WakeAllConditionVariable, __TBB_condvar_notify_all)
137 void init_condvar_module()
139 __TBB_ASSERT( (uintptr_t)__TBB_init_condvar==(uintptr_t)&init_condvar_using_event, NULL );
140 #if __TBB_WIN8UI_SUPPORT 143 __TBB_init_condvar = (
void (WINAPI *)(PCONDITION_VARIABLE))&InitializeConditionVariable;
144 __TBB_condvar_wait = (BOOL(WINAPI *)(PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD))&SleepConditionVariableCS;
145 __TBB_condvar_notify_one = (
void (WINAPI *)(PCONDITION_VARIABLE))&WakeConditionVariable;
146 __TBB_condvar_notify_all = (
void (WINAPI *)(PCONDITION_VARIABLE))&WakeAllConditionVariable;
147 __TBB_destroy_condvar = (
void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop;
150 __TBB_destroy_condvar = (
void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop;
159 namespace interface5 {
162 using tbb::internal::condvar_api_state;
163 using tbb::internal::__TBB_init_condvar;
164 using tbb::internal::__TBB_condvar_wait;
165 using tbb::internal::__TBB_condvar_notify_one;
166 using tbb::internal::__TBB_condvar_notify_all;
167 using tbb::internal::__TBB_destroy_condvar;
168 using tbb::internal::init_condvar_module;
170 void internal_initialize_condition_variable( condvar_impl_t& cv )
173 __TBB_init_condvar( &cv.cv_native );
176 void internal_destroy_condition_variable( condvar_impl_t& cv )
178 __TBB_destroy_condvar( &cv.cv_native );
181 void internal_condition_variable_notify_one( condvar_impl_t& cv )
183 __TBB_condvar_notify_one ( &cv.cv_native );
186 void internal_condition_variable_notify_all( condvar_impl_t& cv )
188 __TBB_condvar_notify_all( &cv.cv_native );
191 bool internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx,
const tick_count::interval_t* i )
193 DWORD duration = i ? DWORD((i->seconds()*1000)) : INFINITE;
194 mtx->set_state( mutex::INITIALIZED );
195 BOOL res = __TBB_condvar_wait( &cv.cv_native, mtx->native_handle(), duration );
196 mtx->set_state( mutex::HELD );
197 return res?
true:
false;
Association between a handler name and location of pointer to it.
void spin_wait_until_eq(const volatile T &location, const U value)
Spin UNTIL the value of the variable is equal to a given value.
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
OPEN_INTERNAL_NAMESPACE bool dynamic_link(const char *, const dynamic_link_descriptor *, size_t, dynamic_link_handle *handle, int)
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
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 count
#define DLD(s, h)
The helper to construct dynamic_link_descriptor structure.