151c0b2f7Stbbdev /*
2*c21e688aSSergey Zheltov Copyright (c) 2005-2022 Intel Corporation
351c0b2f7Stbbdev
451c0b2f7Stbbdev Licensed under the Apache License, Version 2.0 (the "License");
551c0b2f7Stbbdev you may not use this file except in compliance with the License.
651c0b2f7Stbbdev You may obtain a copy of the License at
751c0b2f7Stbbdev
851c0b2f7Stbbdev http://www.apache.org/licenses/LICENSE-2.0
951c0b2f7Stbbdev
1051c0b2f7Stbbdev Unless required by applicable law or agreed to in writing, software
1151c0b2f7Stbbdev distributed under the License is distributed on an "AS IS" BASIS,
1251c0b2f7Stbbdev WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1351c0b2f7Stbbdev See the License for the specific language governing permissions and
1451c0b2f7Stbbdev limitations under the License.
1551c0b2f7Stbbdev */
1651c0b2f7Stbbdev
1751c0b2f7Stbbdev #include "semaphore.h"
1851c0b2f7Stbbdev #if __TBB_USE_SRWLOCK
1951c0b2f7Stbbdev #include "dynamic_link.h" // Refers to src/tbb, not include/tbb
2051c0b2f7Stbbdev #include "tbb_misc.h"
2151c0b2f7Stbbdev #endif
2251c0b2f7Stbbdev
2351c0b2f7Stbbdev namespace tbb {
2451c0b2f7Stbbdev namespace detail {
2551c0b2f7Stbbdev namespace r1 {
2651c0b2f7Stbbdev
2751c0b2f7Stbbdev // TODO: For new win UI port, we can use SRWLock API without dynamic_link etc.
2851c0b2f7Stbbdev #if __TBB_USE_SRWLOCK
2951c0b2f7Stbbdev
3051c0b2f7Stbbdev static std::atomic<do_once_state> concmon_module_inited;
3151c0b2f7Stbbdev
init_binsem_using_event(SRWLOCK * h_)3251c0b2f7Stbbdev void WINAPI init_binsem_using_event( SRWLOCK* h_ )
3351c0b2f7Stbbdev {
3451c0b2f7Stbbdev srwl_or_handle* shptr = (srwl_or_handle*) h_;
3557f524caSIlya Isaev shptr->h = CreateEventEx( nullptr, nullptr, 0, EVENT_ALL_ACCESS|SEMAPHORE_ALL_ACCESS );
3651c0b2f7Stbbdev }
3751c0b2f7Stbbdev
acquire_binsem_using_event(SRWLOCK * h_)3851c0b2f7Stbbdev void WINAPI acquire_binsem_using_event( SRWLOCK* h_ )
3951c0b2f7Stbbdev {
4051c0b2f7Stbbdev srwl_or_handle* shptr = (srwl_or_handle*) h_;
4151c0b2f7Stbbdev WaitForSingleObjectEx( shptr->h, INFINITE, FALSE );
4251c0b2f7Stbbdev }
4351c0b2f7Stbbdev
release_binsem_using_event(SRWLOCK * h_)4451c0b2f7Stbbdev void WINAPI release_binsem_using_event( SRWLOCK* h_ )
4551c0b2f7Stbbdev {
4651c0b2f7Stbbdev srwl_or_handle* shptr = (srwl_or_handle*) h_;
4751c0b2f7Stbbdev SetEvent( shptr->h );
4851c0b2f7Stbbdev }
4951c0b2f7Stbbdev
5051c0b2f7Stbbdev static void (WINAPI *__TBB_init_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&init_binsem_using_event;
5151c0b2f7Stbbdev static void (WINAPI *__TBB_acquire_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&acquire_binsem_using_event;
5251c0b2f7Stbbdev static void (WINAPI *__TBB_release_binsem)( SRWLOCK* ) = (void (WINAPI *)(SRWLOCK*))&release_binsem_using_event;
5351c0b2f7Stbbdev
5451c0b2f7Stbbdev //! Table describing the how to link the handlers.
5551c0b2f7Stbbdev static const dynamic_link_descriptor SRWLLinkTable[] = {
5651c0b2f7Stbbdev DLD(InitializeSRWLock, __TBB_init_binsem),
5751c0b2f7Stbbdev DLD(AcquireSRWLockExclusive, __TBB_acquire_binsem),
5851c0b2f7Stbbdev DLD(ReleaseSRWLockExclusive, __TBB_release_binsem)
5951c0b2f7Stbbdev };
6051c0b2f7Stbbdev
init_concmon_module()6151c0b2f7Stbbdev inline void init_concmon_module()
6251c0b2f7Stbbdev {
6357f524caSIlya Isaev __TBB_ASSERT( (uintptr_t)__TBB_init_binsem==(uintptr_t)&init_binsem_using_event, nullptr);
6451c0b2f7Stbbdev if( dynamic_link( "Kernel32.dll", SRWLLinkTable, sizeof(SRWLLinkTable)/sizeof(dynamic_link_descriptor) ) ) {
6557f524caSIlya Isaev __TBB_ASSERT( (uintptr_t)__TBB_init_binsem!=(uintptr_t)&init_binsem_using_event, nullptr);
6657f524caSIlya Isaev __TBB_ASSERT( (uintptr_t)__TBB_acquire_binsem!=(uintptr_t)&acquire_binsem_using_event, nullptr);
6757f524caSIlya Isaev __TBB_ASSERT( (uintptr_t)__TBB_release_binsem!=(uintptr_t)&release_binsem_using_event, nullptr);
6851c0b2f7Stbbdev }
6951c0b2f7Stbbdev }
7051c0b2f7Stbbdev
binary_semaphore()7151c0b2f7Stbbdev binary_semaphore::binary_semaphore() {
7251c0b2f7Stbbdev atomic_do_once( &init_concmon_module, concmon_module_inited );
7351c0b2f7Stbbdev
7451c0b2f7Stbbdev __TBB_init_binsem( &my_sem.lock );
7551c0b2f7Stbbdev if( (uintptr_t)__TBB_init_binsem!=(uintptr_t)&init_binsem_using_event )
7651c0b2f7Stbbdev P();
7751c0b2f7Stbbdev }
7851c0b2f7Stbbdev
~binary_semaphore()7951c0b2f7Stbbdev binary_semaphore::~binary_semaphore() {
8051c0b2f7Stbbdev if( (uintptr_t)__TBB_init_binsem==(uintptr_t)&init_binsem_using_event )
8151c0b2f7Stbbdev CloseHandle( my_sem.h );
8251c0b2f7Stbbdev }
8351c0b2f7Stbbdev
P()8451c0b2f7Stbbdev void binary_semaphore::P() { __TBB_acquire_binsem( &my_sem.lock ); }
8551c0b2f7Stbbdev
V()8651c0b2f7Stbbdev void binary_semaphore::V() { __TBB_release_binsem( &my_sem.lock ); }
8751c0b2f7Stbbdev
8851c0b2f7Stbbdev #endif /* __TBB_USE_SRWLOCK */
8951c0b2f7Stbbdev
9051c0b2f7Stbbdev } // namespace r1
9151c0b2f7Stbbdev } // namespace detail
9251c0b2f7Stbbdev } // namespace tbb
93