1 //===-- condition_variable_linux.cpp ----------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "platform.h" 10 11 #if SCUDO_LINUX 12 13 #include "condition_variable_linux.h" 14 15 #include "atomic_helpers.h" 16 17 #include <limits.h> 18 #include <linux/futex.h> 19 #include <sys/syscall.h> 20 #include <unistd.h> 21 22 namespace scudo { 23 24 void ConditionVariableLinux::notifyAllImpl(UNUSED HybridMutex &M) { 25 const u32 V = atomic_load_relaxed(&Counter); 26 atomic_store_relaxed(&Counter, V + 1); 27 28 // TODO(chiahungduan): Move the waiters from the futex waiting queue 29 // `Counter` to futex waiting queue `M` so that the awoken threads won't be 30 // blocked again due to locked `M` by current thread. 31 if (LastNotifyAll != V) { 32 syscall(SYS_futex, reinterpret_cast<uptr>(&Counter), FUTEX_WAKE_PRIVATE, 33 INT_MAX, nullptr, nullptr, 0); 34 } 35 36 LastNotifyAll = V + 1; 37 } 38 39 void ConditionVariableLinux::waitImpl(HybridMutex &M) { 40 const u32 V = atomic_load_relaxed(&Counter) + 1; 41 atomic_store_relaxed(&Counter, V); 42 43 // TODO: Use ScopedUnlock when it's supported. 44 M.unlock(); 45 syscall(SYS_futex, reinterpret_cast<uptr>(&Counter), FUTEX_WAIT_PRIVATE, V, 46 nullptr, nullptr, 0); 47 M.lock(); 48 } 49 50 } // namespace scudo 51 52 #endif // SCUDO_LINUX 53