1484543d1Sopenharmony_ci/* 2484543d1Sopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd. 3484543d1Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4484543d1Sopenharmony_ci * you may not use this file except in compliance with the License. 5484543d1Sopenharmony_ci * You may obtain a copy of the License at 6484543d1Sopenharmony_ci * 7484543d1Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8484543d1Sopenharmony_ci * 9484543d1Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10484543d1Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11484543d1Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12484543d1Sopenharmony_ci * See the License for the specific language governing permissions and 13484543d1Sopenharmony_ci * limitations under the License. 14484543d1Sopenharmony_ci */ 15484543d1Sopenharmony_ci 16484543d1Sopenharmony_ci#ifndef UTIL_SYNC_HPP 17484543d1Sopenharmony_ci#define UTIL_SYNC_HPP 18484543d1Sopenharmony_ci// Provide synchronization primitives 19484543d1Sopenharmony_ci 20484543d1Sopenharmony_ci#include <atomic> 21484543d1Sopenharmony_ci#include <thread> 22484543d1Sopenharmony_ci#include <mutex> 23484543d1Sopenharmony_ci#include <condition_variable> 24484543d1Sopenharmony_ci#include <unistd.h> 25484543d1Sopenharmony_ci#include <sys/syscall.h> 26484543d1Sopenharmony_ci#include <linux/futex.h> 27484543d1Sopenharmony_ci#include "sched/execute_ctx.h" 28484543d1Sopenharmony_ci 29484543d1Sopenharmony_cinamespace ffrt { 30484543d1Sopenharmony_cinamespace sync_detail { 31484543d1Sopenharmony_ciconst int UNLOCK = 0; 32484543d1Sopenharmony_ciconst int LOCK = 1; 33484543d1Sopenharmony_ciconst int WAIT = 2; 34484543d1Sopenharmony_ci} // namespace sync_detail 35484543d1Sopenharmony_ci 36484543d1Sopenharmony_ciclass spin_mutex { 37484543d1Sopenharmony_ci std::atomic<int> l; 38484543d1Sopenharmony_ci void lock_contended(); 39484543d1Sopenharmony_ci 40484543d1Sopenharmony_cipublic: 41484543d1Sopenharmony_ci spin_mutex() : l(sync_detail::UNLOCK) 42484543d1Sopenharmony_ci { 43484543d1Sopenharmony_ci } 44484543d1Sopenharmony_ci spin_mutex(spin_mutex const&) = delete; 45484543d1Sopenharmony_ci void operator=(spin_mutex const&) = delete; 46484543d1Sopenharmony_ci 47484543d1Sopenharmony_ci void lock() 48484543d1Sopenharmony_ci { 49484543d1Sopenharmony_ci if (l.exchange(sync_detail::LOCK, std::memory_order_acquire) == sync_detail::UNLOCK) { 50484543d1Sopenharmony_ci return; 51484543d1Sopenharmony_ci } 52484543d1Sopenharmony_ci lock_contended(); 53484543d1Sopenharmony_ci } 54484543d1Sopenharmony_ci 55484543d1Sopenharmony_ci void unlock() 56484543d1Sopenharmony_ci { 57484543d1Sopenharmony_ci l.store(sync_detail::UNLOCK, std::memory_order_release); 58484543d1Sopenharmony_ci } 59484543d1Sopenharmony_ci}; 60484543d1Sopenharmony_ci 61484543d1Sopenharmony_ciclass fast_mutex { 62484543d1Sopenharmony_ci int l; 63484543d1Sopenharmony_ci void lock_contended(); 64484543d1Sopenharmony_ci 65484543d1Sopenharmony_cipublic: 66484543d1Sopenharmony_ci fast_mutex() : l(sync_detail::UNLOCK) 67484543d1Sopenharmony_ci { 68484543d1Sopenharmony_ci } 69484543d1Sopenharmony_ci fast_mutex(fast_mutex const&) = delete; 70484543d1Sopenharmony_ci void operator=(fast_mutex const&) = delete; 71484543d1Sopenharmony_ci 72484543d1Sopenharmony_ci void lock() 73484543d1Sopenharmony_ci { 74484543d1Sopenharmony_ci int v = sync_detail::UNLOCK; 75484543d1Sopenharmony_ci if (__atomic_compare_exchange_n(&l, &v, sync_detail::LOCK, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED)) { 76484543d1Sopenharmony_ci return; 77484543d1Sopenharmony_ci } 78484543d1Sopenharmony_ci lock_contended(); 79484543d1Sopenharmony_ci } 80484543d1Sopenharmony_ci 81484543d1Sopenharmony_ci bool try_lock() 82484543d1Sopenharmony_ci { 83484543d1Sopenharmony_ci int v = sync_detail::UNLOCK; 84484543d1Sopenharmony_ci return __atomic_compare_exchange_n(&l, &v, sync_detail::LOCK, 0, __ATOMIC_ACQUIRE, __ATOMIC_RELAXED); 85484543d1Sopenharmony_ci } 86484543d1Sopenharmony_ci 87484543d1Sopenharmony_ci void unlock() 88484543d1Sopenharmony_ci { 89484543d1Sopenharmony_ci if (__atomic_exchange_n(&l, sync_detail::UNLOCK, __ATOMIC_RELEASE) == sync_detail::WAIT) { 90484543d1Sopenharmony_ci syscall(SYS_futex, &l, FUTEX_WAKE_PRIVATE, 1, nullptr, nullptr, 0); 91484543d1Sopenharmony_ci } 92484543d1Sopenharmony_ci } 93484543d1Sopenharmony_ci}; 94484543d1Sopenharmony_ci 95484543d1Sopenharmony_cibool DelayedWakeup(const TimePoint& to, WaitEntry* we, const std::function<void(WaitEntry*)>& wakeup); 96484543d1Sopenharmony_cibool DelayedRemove(const TimePoint& to, WaitEntry* we); 97484543d1Sopenharmony_ci} // namespace ffrt 98484543d1Sopenharmony_ci#endif 99