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

Schrodinger ZHU Yifan via libc-commits libc-commits at lists.llvm.org
Fri May 24 15:42:09 PDT 2024


================
@@ -0,0 +1,78 @@
+//===-- Unittests for Linux's RawMutex ------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "include/llvm-libc-macros/linux/time-macros.h"
+#include "src/__support/CPP/atomic.h"
+#include "src/__support/OSUtil/syscall.h"
+#include "src/__support/threads/linux/raw_mutex.h"
+#include "src/__support/threads/sleep.h"
+#include "src/__support/time/linux/clock_gettime.h"
+#include "src/stdlib/exit.h"
+#include "src/sys/mman/mmap.h"
+#include "src/sys/mman/munmap.h"
+#include "test/UnitTest/Test.h"
+#include <sys/syscall.h>
+
+TEST(LlvmLibcSupportThreadsRawMutexTest, SmokeTest) {
+  LIBC_NAMESPACE::internal::RawMutex mutex;
+  ASSERT_TRUE(mutex.lock());
+  ASSERT_TRUE(mutex.unlock());
+  ASSERT_TRUE(mutex.try_lock());
+  ASSERT_FALSE(mutex.try_lock());
+  ASSERT_TRUE(mutex.unlock());
+  ASSERT_FALSE(mutex.unlock());
+}
+
+TEST(LlvmLibcSupportThreadsRawMutexTest, Timeout) {
+  LIBC_NAMESPACE::internal::RawMutex mutex;
+  ASSERT_TRUE(mutex.lock());
+  timespec ts;
+  LIBC_NAMESPACE::internal::clock_gettime(CLOCK_MONOTONIC, &ts);
+  ts.tv_sec += 1;
+  // Timeout will be respected when deadlock happens.
+  auto timeout = LIBC_NAMESPACE::internal::AbsTimeout::from_timespec(ts, false);
+  ASSERT_TRUE(timeout.has_value());
+  ASSERT_FALSE(mutex.lock(*timeout));
+  ASSERT_TRUE(mutex.unlock());
+  ASSERT_TRUE(mutex.lock(*timeout));
+  ASSERT_TRUE(mutex.unlock());
+  // If a lock can be acquired directly, expired timeout will not count.
+  ASSERT_TRUE(mutex.lock(*timeout));
+  ASSERT_TRUE(mutex.unlock());
----------------
SchrodingerZhu wrote:

Oops, one `timeout` ought to be removed.
```c++
  ASSERT_FALSE(mutex.lock(*timeout));    // this lock is a deadlock, but it is backed by a timeout
  ASSERT_TRUE(mutex.unlock());                 // this unlocks the previous locked mutex            
  ASSERT_TRUE(mutex.lock());                      // this line (with timeout removed),
  ASSERT_TRUE(mutex.unlock());                 // and this line checks that the mutex still works fine 
  // If a lock can be acquired directly, expired timeout will not count.
  ASSERT_TRUE(mutex.lock(*timeout));     // this is an expired lock, but it should succeed
  ASSERT_TRUE(mutex.unlock());
  ```

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


More information about the libc-commits mailing list