[libc-commits] [libc] [libc] rework mutex (PR #92168)
via libc-commits
libc-commits at lists.llvm.org
Tue May 14 16:42:20 PDT 2024
================
@@ -0,0 +1,116 @@
+//===--- Implementation of a Linux RawMutex class ---------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RAW_MUTEX_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_LINUX_RAW_MUTEX_H
+
+#include "futex_word.h"
+#include "src/__support/CPP/optional.h"
+#include "src/__support/common.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/threads/linux/futex_utils.h"
+#include "src/__support/threads/sleep.h"
+#include "src/__support/time/linux/abs_timeout.h"
+#ifdef LIBC_COPT_TIMEOUT_ENSURE_MONOTONICITY
+#include "src/__support/time/linux/monotonicity.h"
+#endif
+
+#ifndef LIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT
+#define LIBC_COPT_RAW_MUTEX_DEFAULT_SPIN_COUNT 100
+#endif
+
+namespace LIBC_NAMESPACE {
+namespace internal {
+// Lock is a simple timable lock for internal usage.
+// This is separated from Mutex because this one does not need to consider
+// robustness and reentrancy. Also, this one has spin optimization for shorter
+// critical sections.
+class RawMutex {
+protected:
+ Futex futex;
+ LIBC_INLINE_VAR static constexpr FutexWordType UNLOCKED = 0b00;
+ LIBC_INLINE_VAR static constexpr FutexWordType LOCKED = 0b01;
+ LIBC_INLINE_VAR static constexpr FutexWordType CONTENTED = 0b10;
+
+ LIBC_INLINE FutexWordType spin(uint_fast32_t spin_count) {
+ FutexWordType result;
+ for (;;) {
+ result = futex.load(cpp::MemoryOrder::RELAXED);
+ // spin until one of the following conditions is met:
+ // - the mutex is unlocked
+ // - the mutex is contented
+ // - the spin count reaches 0
+ if (result != LOCKED || spin_count == 0)
+ return result;
+ // Pause the pipeline to avoid extraneous memory operations due to
+ // speculation.
+ sleep_briefly();
----------------
QuarticCat wrote:
I can only remember this [blog post](https://matklad.github.io/2020/01/04/mutexes-are-faster-than-spinlocks.html). But I do have seen this opinion in many places. Just think of many small critical regions contending for a single mutex. In this case, a few spins can avoid many syscalls.
https://github.com/llvm/llvm-project/pull/92168
More information about the libc-commits
mailing list