• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 ECMASCRIPT_PLATFORM_MUTEX_H
17 #define ECMASCRIPT_PLATFORM_MUTEX_H
18 
19 #include <pthread.h>
20 #include <atomic>
21 
22 #include "ecmascript/common.h"
23 #include "libpandabase/macros.h"
24 
25 #if defined(PANDA_USE_FUTEX)
26 #include "ecmascript/platform/unix/futex.h"
27 #endif
28 
29 #ifdef DEBUG
30 #define FATAL_IF_ERROR(f, rc)                           \
31     do {                                                \
32         if (rc != 0) {                                  \
33             LOG_ECMA(FATAL)<< f << " failed: " << rc;   \
34         }                                               \
35     } while (false)
36 #else
37 #define FATAL_IF_ERROR(f, rc) static_cast<void>(0)
38 #endif
39 namespace panda::ecmascript {
40 
41 class PUBLIC_API Mutex {
42 public:
43     explicit  Mutex(bool is_init = true);
44 
45     ~Mutex();
46 
47     void Lock();
48 
49     bool TryLock();
50 
51     void Unlock();
52 
53 protected:
54     void Init(pthread_mutexattr_t *attrs);
55 
56 private:
57     pthread_mutex_t mutex_;
58     friend class ConditionVariable;
59 };
60 
61 class RecursiveMutex : public Mutex {
62 public:
63     RecursiveMutex();
64 
65     ~RecursiveMutex() = default;
66 
67     NO_COPY_SEMANTIC(RecursiveMutex);
68     NO_MOVE_SEMANTIC(RecursiveMutex);
69 };
70 
71 class PUBLIC_API RWLock {
72 public:
73     RWLock();
74 
75     ~RWLock();
76 
77     void ReadLock();
78 
79     void WriteLock();
80 
81     bool TryReadLock();
82 
83     bool TryWriteLock();
84 
85     void Unlock();
86 
87 private:
88     pthread_rwlock_t rwlock_;
89 
90     NO_COPY_SEMANTIC(RWLock);
91     NO_MOVE_SEMANTIC(RWLock);
92 };
93 
94 class PUBLIC_API ConditionVariable {
95 public:
96     ConditionVariable();
97 
98     ~ConditionVariable();
99 
100     void Signal();
101 
102     void SignalAll();
103 
104     void Wait(Mutex *mutex);
105 
106     bool TimedWait(Mutex *mutex, uint64_t ms, uint64_t ns = 0, bool is_absolute = false);
107 
108 private:
109     pthread_cond_t cond_;
110 };
111 
112 class LockHolder {
113 public:
LockHolder(Mutex & mtx)114     explicit LockHolder(Mutex &mtx) : lock_(mtx)
115     {
116         lock_.Lock();
117     }
118 
~LockHolder()119     ~LockHolder()
120     {
121         lock_.Unlock();
122     }
123 
124 private:
125     Mutex &lock_;
126 
127     NO_COPY_SEMANTIC(LockHolder);
128     NO_MOVE_SEMANTIC(LockHolder);
129 };
130 
131 class ReadLockHolder {
132 public:
ReadLockHolder(RWLock & lock)133     explicit ReadLockHolder(RWLock &lock) : lock_(lock)
134     {
135         lock_.ReadLock();
136     }
137 
~ReadLockHolder()138     ~ReadLockHolder()
139     {
140         lock_.Unlock();
141     }
142 
143 private:
144     RWLock &lock_;
145 
146     NO_COPY_SEMANTIC(ReadLockHolder);
147     NO_MOVE_SEMANTIC(ReadLockHolder);
148 };
149 
150 class WriteLockHolder {
151 public:
WriteLockHolder(RWLock & lock)152     explicit WriteLockHolder(RWLock &lock) : lock_(lock)
153     {
154         lock_.WriteLock();
155     }
156 
~WriteLockHolder()157     ~WriteLockHolder()
158     {
159         lock_.Unlock();
160     }
161 
162 private:
163     RWLock &lock_;
164 
165     NO_COPY_SEMANTIC(WriteLockHolder);
166     NO_MOVE_SEMANTIC(WriteLockHolder);
167 };
168 }  // namespace panda::ecmascript
169 #endif  // ECMASCRIPT_PLATFORM_MUTEX_H
170