1 | /******************************************************************************* |
2 | * Copyright 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 | #ifdef _WIN32 |
18 | #include <windows.h> |
19 | #else |
20 | #include <pthread.h> |
21 | #endif |
22 | |
23 | #include "rw_mutex.hpp" |
24 | |
25 | using namespace dnnl; |
26 | using namespace dnnl::impl; |
27 | using namespace dnnl::impl::utils; |
28 | |
29 | struct rw_mutex_t::rw_mutex_impl_t { |
30 | #ifdef _WIN32 |
31 | using rwlock_t = SRWLOCK; |
32 | #else |
33 | using rwlock_t = pthread_rwlock_t; |
34 | #endif |
35 | rwlock_t &impl() { return impl_; } |
36 | |
37 | private: |
38 | rwlock_t impl_; |
39 | }; |
40 | |
41 | rw_mutex_t::rw_mutex_t() { |
42 | rw_mutex_impl_ = utils::make_unique<rw_mutex_impl_t>(); |
43 | auto &impl = rw_mutex_impl_->impl(); |
44 | #ifdef _WIN32 |
45 | InitializeSRWLock(&impl); |
46 | #else |
47 | pthread_rwlock_init(&impl, nullptr); |
48 | #endif |
49 | } |
50 | |
51 | void rw_mutex_t::lock_read() { |
52 | auto &impl = rw_mutex_impl_->impl(); |
53 | #ifdef _WIN32 |
54 | AcquireSRWLockShared(&impl); |
55 | #else |
56 | pthread_rwlock_rdlock(&impl); |
57 | #endif |
58 | } |
59 | |
60 | void rw_mutex_t::lock_write() { |
61 | auto &impl = rw_mutex_impl_->impl(); |
62 | #ifdef _WIN32 |
63 | AcquireSRWLockExclusive(&impl); |
64 | #else |
65 | pthread_rwlock_wrlock(&impl); |
66 | #endif |
67 | } |
68 | |
69 | void rw_mutex_t::unlock_read() { |
70 | auto &impl = rw_mutex_impl_->impl(); |
71 | #ifdef _WIN32 |
72 | ReleaseSRWLockShared(&impl); |
73 | #else |
74 | pthread_rwlock_unlock(&impl); |
75 | #endif |
76 | } |
77 | |
78 | void rw_mutex_t::unlock_write() { |
79 | auto &impl = rw_mutex_impl_->impl(); |
80 | #ifdef _WIN32 |
81 | ReleaseSRWLockExclusive(&impl); |
82 | #else |
83 | pthread_rwlock_unlock(&impl); |
84 | #endif |
85 | } |
86 | |
87 | rw_mutex_t::~rw_mutex_t() { |
88 | // SRW locks do not need to be explicitly destroyed |
89 | #ifndef _WIN32 |
90 | auto &impl = rw_mutex_impl_->impl(); |
91 | pthread_rwlock_destroy(&impl); |
92 | #endif |
93 | } |
94 | |
95 | lock_read_t::lock_read_t(rw_mutex_t &rw_mutex) : rw_mutex_(rw_mutex) { |
96 | rw_mutex_.lock_read(); |
97 | } |
98 | |
99 | lock_write_t::lock_write_t(rw_mutex_t &rw_mutex) : rw_mutex_(rw_mutex) { |
100 | rw_mutex_.lock_write(); |
101 | } |
102 | |
103 | lock_read_t::~lock_read_t() { |
104 | rw_mutex_.unlock_read(); |
105 | } |
106 | |
107 | lock_write_t::~lock_write_t() { |
108 | rw_mutex_.unlock_write(); |
109 | } |
110 | |