• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef COMMON_COMPONENTS_PLATFORM_MUTEX_H
17 #define COMMON_COMPONENTS_PLATFORM_MUTEX_H
18 
19 #include "common_interfaces/base/common.h"
20 #include "thread/thread_state_transition.h"
21 
22 #ifdef DEBUG
23 #define FATAL_IF_ERROR(f, rc)                             \
24     do {                                                  \
25         if (rc != 0) {                                    \
26             LOG_COMMON(FATAL)<< f << " failed: " << rc;   \
27         }                                                 \
28     } while (false)
29 #else
30 #define FATAL_IF_ERROR(f, rc) static_cast<void>(0)
31 #endif
32 
33 namespace common {
34 class Mutex {
35 public:
36     explicit Mutex(bool isInit = true);
37 
38     ~Mutex();
39 
40     void Lock();
41 
42     bool TryLock();
43 
44     void Unlock();
45 
46 protected:
47     void Init(pthread_mutexattr_t *attrs);
48 
49 private:
50     pthread_mutex_t mutex_;
51     friend class ConditionVariable;
52 };
53 
Mutex(bool isInit)54 inline Mutex::Mutex(bool isInit) : mutex_()
55 {
56     if (isInit) {
57         Init(nullptr);
58     }
59 }
60 
~Mutex()61 inline Mutex::~Mutex()
62 {
63     [[maybe_unused]] int rc = pthread_mutex_destroy(&mutex_);
64     FATAL_IF_ERROR("pthread_mutex_destroy", rc);
65 }
66 
Init(pthread_mutexattr_t * attrs)67 inline void Mutex::Init(pthread_mutexattr_t *attrs)
68 {
69     [[maybe_unused]] int rc = pthread_mutex_init(&mutex_, attrs);
70     FATAL_IF_ERROR("pthread_mutex_init", rc);
71 }
72 
Lock()73 inline void Mutex::Lock()
74 {
75     [[maybe_unused]] int rc = pthread_mutex_lock(&mutex_);
76     FATAL_IF_ERROR("pthread_mutex_lock", rc);
77 }
78 
TryLock()79 inline bool Mutex::TryLock()
80 {
81     int rc = pthread_mutex_trylock(&mutex_);
82     if (rc == EBUSY) {
83         return false;
84     }
85 
86     FATAL_IF_ERROR("pthread_mutex_trylock", rc);
87 
88     return true;
89 }
90 
Unlock()91 inline void Mutex::Unlock()
92 {
93     [[maybe_unused]] int rc = pthread_mutex_unlock(&mutex_);
94     FATAL_IF_ERROR("pthread_mutex_unlock", rc);
95 }
96 
97 class LockHolder {
98 public:
LockHolder(Mutex & mtx)99     explicit LockHolder(Mutex &mtx) : lock_(mtx)
100     {
101         lock_.Lock();
102     }
103 
~LockHolder()104     ~LockHolder()
105     {
106         lock_.Unlock();
107     }
108 
109 private:
110     Mutex &lock_;
111 
112     NO_COPY_SEMANTIC_CC(LockHolder);
113     NO_MOVE_SEMANTIC_CC(LockHolder);
114 };
115 
116 class PUBLIC_API ConditionVariable {
117 public:
118     ConditionVariable();
119 
120     ~ConditionVariable();
121 
122     void Signal();
123 
124     void SignalAll();
125 
126     void Wait(Mutex *mutex);
127 
128     bool TimedWait(Mutex *mutex, uint64_t ms, uint64_t ns = 0, bool is_absolute = false);
129 
130 private:
131     pthread_cond_t cond_;
132 };
133 
ConditionVariable()134 inline ConditionVariable::ConditionVariable() : cond_()
135 {
136     [[maybe_unused]]int rc = pthread_cond_init(&cond_, nullptr);
137     FATAL_IF_ERROR("pthread_cond_init", rc);
138 }
139 
~ConditionVariable()140 inline ConditionVariable::~ConditionVariable()
141 {
142     [[maybe_unused]]int rc = pthread_cond_destroy(&cond_);
143     FATAL_IF_ERROR("pthread_cond_destroy", rc);
144 }
145 
Signal()146 inline void ConditionVariable::Signal()
147 {
148     [[maybe_unused]]int rc = pthread_cond_signal(&cond_);
149     FATAL_IF_ERROR("pthread_cond_signal", rc);
150 }
151 
SignalAll()152 inline void ConditionVariable::SignalAll()
153 {
154     [[maybe_unused]]int rc = pthread_cond_broadcast(&cond_);
155     FATAL_IF_ERROR("pthread_cond_broadcast", rc);
156 }
157 
Wait(Mutex * mutex)158 inline void ConditionVariable::Wait(Mutex *mutex)
159 {
160     [[maybe_unused]]int rc = pthread_cond_wait(&cond_, &mutex->mutex_);
161     FATAL_IF_ERROR("pthread_cond_wait", rc);
162 }
163 
164 }
165 #endif //COMMON_COMPONENTS_PLATFORM_MUTEX_H
166