[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