22 #include "tbb/compat/condition_variable" 34 using tbb::interface5::internal::condition_variable_using_event;
36 static atomic<do_once_state> condvar_api_state;
38 void WINAPI init_condvar_using_event( condition_variable_using_event* cv_event )
41 cv_event->event = CreateEventEx(NULL, NULL, 0x1 , EVENT_ALL_ACCESS );
42 InitializeCriticalSectionEx( &cv_event->mutex, 4000, 0 );
43 cv_event->n_waiters = 0;
44 cv_event->release_count = 0;
48 BOOL WINAPI sleep_condition_variable_cs_using_event( condition_variable_using_event* cv_event, LPCRITICAL_SECTION cs, DWORD dwMilliseconds )
50 EnterCriticalSection( &cv_event->mutex );
51 ++cv_event->n_waiters;
52 unsigned my_generation = cv_event->epoch;
53 LeaveCriticalSection( &cv_event->mutex );
54 LeaveCriticalSection( cs );
57 DWORD rc = WaitForSingleObjectEx( cv_event->event, dwMilliseconds, FALSE );
58 EnterCriticalSection( &cv_event->mutex );
59 if( rc!=WAIT_OBJECT_0 ) {
60 --cv_event->n_waiters;
61 LeaveCriticalSection( &cv_event->mutex );
62 if( rc==WAIT_TIMEOUT ) {
63 SetLastError( WAIT_TIMEOUT );
64 EnterCriticalSection( cs );
69 if( cv_event->release_count>0 && cv_event->epoch!=my_generation )
71 LeaveCriticalSection( &cv_event->mutex );
75 --cv_event->n_waiters;
76 int count = --cv_event->release_count;
77 LeaveCriticalSection( &cv_event->mutex );
80 __TBB_ASSERT( cv_event->event,
"Premature destruction of condition variable?" );
81 ResetEvent( cv_event->event );
83 EnterCriticalSection( cs );
87 void WINAPI wake_condition_variable_using_event( condition_variable_using_event* cv_event )
89 EnterCriticalSection( &cv_event->mutex );
90 if( cv_event->n_waiters>cv_event->release_count ) {
91 SetEvent( cv_event->event );
92 ++cv_event->release_count;
95 LeaveCriticalSection( &cv_event->mutex );
98 void WINAPI wake_all_condition_variable_using_event( condition_variable_using_event* cv_event )
100 EnterCriticalSection( &cv_event->mutex );
101 if( cv_event->n_waiters>0 ) {
102 SetEvent( cv_event->event );
103 cv_event->release_count = cv_event->n_waiters;
106 LeaveCriticalSection( &cv_event->mutex );
109 void WINAPI destroy_condvar_using_event( condition_variable_using_event* cv_event )
111 HANDLE my_event = cv_event->event;
112 EnterCriticalSection( &cv_event->mutex );
114 cv_event->event = NULL;
115 if( cv_event->n_waiters>0 ) {
116 LeaveCriticalSection( &cv_event->mutex );
119 EnterCriticalSection( &cv_event->mutex );
121 LeaveCriticalSection( &cv_event->mutex );
122 CloseHandle( my_event );
125 void WINAPI destroy_condvar_noop( CONDITION_VARIABLE* ) { }
127 static void (WINAPI *__TBB_init_condvar)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&init_condvar_using_event;
128 static BOOL (WINAPI *__TBB_condvar_wait)( PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD ) = (BOOL (WINAPI *)(PCONDITION_VARIABLE,LPCRITICAL_SECTION, DWORD))&sleep_condition_variable_cs_using_event;
129 static void (WINAPI *__TBB_condvar_notify_one)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&wake_condition_variable_using_event;
130 static void (WINAPI *__TBB_condvar_notify_all)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&wake_all_condition_variable_using_event;
131 static void (WINAPI *__TBB_destroy_condvar)( PCONDITION_VARIABLE ) = (
void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_using_event;
135 DLD(InitializeConditionVariable, __TBB_init_condvar),
136 DLD(SleepConditionVariableCS, __TBB_condvar_wait),
137 DLD(WakeConditionVariable, __TBB_condvar_notify_one),
138 DLD(WakeAllConditionVariable, __TBB_condvar_notify_all)
141 void init_condvar_module()
143 __TBB_ASSERT( (uintptr_t)__TBB_init_condvar==(uintptr_t)&init_condvar_using_event, NULL );
144 #if __TBB_WIN8UI_SUPPORT 147 __TBB_init_condvar = (
void (WINAPI *)(PCONDITION_VARIABLE))&InitializeConditionVariable;
148 __TBB_condvar_wait = (BOOL(WINAPI *)(PCONDITION_VARIABLE, LPCRITICAL_SECTION, DWORD))&SleepConditionVariableCS;
149 __TBB_condvar_notify_one = (
void (WINAPI *)(PCONDITION_VARIABLE))&WakeConditionVariable;
150 __TBB_condvar_notify_all = (
void (WINAPI *)(PCONDITION_VARIABLE))&WakeAllConditionVariable;
151 __TBB_destroy_condvar = (
void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop;
154 __TBB_destroy_condvar = (
void (WINAPI *)(PCONDITION_VARIABLE))&destroy_condvar_noop;
163 namespace interface5 {
166 using tbb::internal::condvar_api_state;
167 using tbb::internal::__TBB_init_condvar;
168 using tbb::internal::__TBB_condvar_wait;
169 using tbb::internal::__TBB_condvar_notify_one;
170 using tbb::internal::__TBB_condvar_notify_all;
171 using tbb::internal::__TBB_destroy_condvar;
172 using tbb::internal::init_condvar_module;
174 void internal_initialize_condition_variable( condvar_impl_t& cv )
177 __TBB_init_condvar( &cv.cv_native );
180 void internal_destroy_condition_variable( condvar_impl_t& cv )
182 __TBB_destroy_condvar( &cv.cv_native );
185 void internal_condition_variable_notify_one( condvar_impl_t& cv )
187 __TBB_condvar_notify_one ( &cv.cv_native );
190 void internal_condition_variable_notify_all( condvar_impl_t& cv )
192 __TBB_condvar_notify_all( &cv.cv_native );
195 bool internal_condition_variable_wait( condvar_impl_t& cv, mutex* mtx,
const tick_count::interval_t* i )
197 DWORD duration = i ? DWORD((i->seconds()*1000)) : INFINITE;
199 BOOL res = __TBB_condvar_wait( &cv.cv_native, mtx->native_handle(), duration );
201 return res?
true:
false;
#define DLD(s, h)
The helper to construct dynamic_link_descriptor structure.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Association between a handler name and location of pointer to it.
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
OPEN_INTERNAL_NAMESPACE bool dynamic_link(const char *, const dynamic_link_descriptor *, size_t, dynamic_link_handle *handle, int)
void atomic_do_once(const F &initializer, atomic< do_once_state > &state)
One-time initialization function.
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.