xref: /oneTBB/src/tbb/semaphore.cpp (revision c21e688a)
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