[libc-commits] [libc] [libc] rework mutex (PR #92168)

Michael Jones via libc-commits libc-commits at lists.llvm.org
Wed May 15 16:13:35 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();
----------------
michaelrj-google wrote:

This does look very similar to the rust implementation, I have two comments about that: First, make sure that you're not just blindly copying what they do, it might not match the use case or semantics of libc. Second, make sure that you're not copying the code because that could have license implications. It should be fine as long as you're primarily writing the code yourself (but also I am not a lawyer).

As for leaving the spinning in, that's fine with me now that I understand the purpose of it.

https://github.com/llvm/llvm-project/pull/92168


More information about the libc-commits mailing list