• 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 UTIL_SYNC_HPP
17 #define UTIL_SYNC_HPP
18 // Provide synchronization primitives
19 
20 #include <atomic>
21 #include <thread>
22 #include <mutex>
23 #include <condition_variable>
24 #include "delayed_worker.h"
25 #ifndef _MSC_VER
26 #include <unistd.h>
27 #include <sys/syscall.h>
28 #include <linux/futex.h>
29 #endif
30 
31 namespace ffrt {
32 namespace sync_detail {
33 const int UNLOCK = 0;
34 const int LOCK = 1;
35 const int WAIT = 2;
36 } // namespace sync_detail
37 
38 class spin_mutex {
39     std::atomic<int> l;
40     void lock_contended();
41 
42 public:
spin_mutex()43     spin_mutex() : l(sync_detail::UNLOCK)
44     {
45     }
46     spin_mutex(spin_mutex const&) = delete;
47     void operator=(spin_mutex const&) = delete;
48 
lock()49     void lock()
50     {
51         if (l.exchange(sync_detail::LOCK, std::memory_order_acquire) == sync_detail::UNLOCK) {
52             return;
53         }
54         lock_contended();
55     }
56 
unlock()57     void unlock()
58     {
59         l.store(sync_detail::UNLOCK, std::memory_order_release);
60     }
61 };
62 
63 #ifdef _MSC_VER
64 using fast_mutex = spin_mutex;
65 #else
66 class fast_mutex {
67     int l;
68     void lock_contended();
69 
70 public:
fast_mutex()71     fast_mutex() : l(sync_detail::UNLOCK)
72     {
73     }
74     fast_mutex(fast_mutex const&) = delete;
75     void operator=(fast_mutex const&) = delete;
76 
lock()77     void lock()
78     {
79         int v = sync_detail::UNLOCK;
80         if (__atomic_compare_exchange_n(&l, &v, sync_detail::LOCK, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) {
81             return;
82         }
83         lock_contended();
84     }
85 
unlock()86     void unlock()
87     {
88         if (__atomic_exchange_n(&l, sync_detail::UNLOCK, __ATOMIC_RELEASE) == sync_detail::WAIT) {
89             syscall(SYS_futex, &l, FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0);
90         }
91     }
92 };
93 #endif
94 
95 bool DelayedWakeup(const time_point_t& to, WaitEntry* we, const std::function<void(WaitEntry*)>& wakeup);
96 } // namespace ffrt
97 #endif
98