• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright (c) 2024 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 #include "libpandabase/os/mutex.h"
17 #include "plugins/ets/runtime/ets_coroutine.h"
18 #include "plugins/ets/runtime/types/ets_primitives.h"
19 #include "runtime/coroutines/coroutine_events.h"
20 #include "runtime/include/runtime.h"
21 
22 namespace ark::ets::intrinsics {
23 
24 /// @brief Mutex creation in internal space
InitializeMutex()25 extern "C" EtsLong InitializeMutex()
26 {
27     auto allocator = Runtime::GetCurrent()->GetInternalAllocator();
28     auto *mutex = allocator->New<os::memory::Mutex>();
29     return reinterpret_cast<EtsLong>(mutex);
30 }
31 
32 /// @brief Event creation in internal space
InitializeEvent()33 extern "C" EtsLong InitializeEvent()
34 {
35     EtsCoroutine *currentCoro = EtsCoroutine::GetCurrent();
36     auto allocator = Runtime::GetCurrent()->GetInternalAllocator();
37     auto *event = allocator->New<GenericEvent>(currentCoro->GetCoroutineManager());
38     return reinterpret_cast<EtsLong>(event);
39 }
40 
41 /// @brief Mutex deletion
DeleteMutex(EtsLong mutexPtr)42 extern "C" void DeleteMutex(EtsLong mutexPtr)
43 {
44     auto allocator = Runtime::GetCurrent()->GetInternalAllocator();
45     allocator->Delete(reinterpret_cast<os::memory::Mutex *>(mutexPtr));
46 }
47 
48 /// @brief Event deletion
DeleteEvent(EtsLong eventPtr)49 extern "C" void DeleteEvent(EtsLong eventPtr)
50 {
51     auto allocator = Runtime::GetCurrent()->GetInternalAllocator();
52     allocator->Delete(reinterpret_cast<GenericEvent *>(eventPtr));
53 }
54 
55 // Disable thread-safety-analysis because it creates warnings
56 // due to mutexes' manipulations at the end of functions
57 #if defined(__clang__)
58 #pragma clang diagnostic push
59 #pragma clang diagnostic ignored "-Wthread-safety-analysis"
60 #endif
61 
62 /**
63  * @brief Locking mutex
64  * Mutex may be unlocked with MutexUnlock or UnblockWaiters functions
65  */
MutexLock(EtsLong mutexPtr)66 extern "C" void MutexLock(EtsLong mutexPtr)
67 {
68     auto *mutex = reinterpret_cast<os::memory::Mutex *>(mutexPtr);
69     mutex->Lock();
70 }
71 
72 /// @brief Unlocking mutex that was locked with MutexLock function
MutexUnlock(EtsLong mutexPtr)73 extern "C" void MutexUnlock(EtsLong mutexPtr)
74 {
75     auto *mutex = reinterpret_cast<os::memory::Mutex *>(mutexPtr);
76     mutex->Unlock();
77 }
78 
79 /**
80  * @brief Setting event to be "not happened", unlocking mutex and
81  * awaiting for the event to happen. After "await" we try to lock
82  * the mutex again to continue working with the BlockingQueue
83  */
Await(EtsLong mutexPtr,EtsLong eventPtr)84 extern "C" void Await(EtsLong mutexPtr, EtsLong eventPtr)
85 {
86     EtsCoroutine *currentCoro = EtsCoroutine::GetCurrent();
87     auto *event = reinterpret_cast<GenericEvent *>(eventPtr);
88     auto *mutex = reinterpret_cast<os::memory::Mutex *>(mutexPtr);
89     event->SetNotHappened();
90     event->Lock();
91     mutex->Unlock();
92     currentCoro->GetCoroutineManager()->Await(event);
93     mutex->Lock();
94 }
95 
96 /**
97  * @brief Setting event to be "happened" and unlocking mutex.
98  * This function should be called after successful push() to the BlockingQueue
99  */
UnblockWaiters(EtsLong mutexPtr,EtsLong eventPtr)100 extern "C" void UnblockWaiters(EtsLong mutexPtr, EtsLong eventPtr)
101 {
102     auto *event = reinterpret_cast<GenericEvent *>(eventPtr);
103     auto *mutex = reinterpret_cast<os::memory::Mutex *>(mutexPtr);
104     event->Happen();
105     mutex->Unlock();
106 }
107 
108 #if defined(__clang__)
109 #pragma clang diagnostic pop
110 #endif
111 
112 }  // namespace ark::ets::intrinsics
113