[libc-commits] [libc] [libc] implement recursive mutex and fix wrong initializer (PR #193992)
Schrodinger ZHU Yifan via libc-commits
libc-commits at lists.llvm.org
Mon Apr 27 13:53:39 PDT 2026
================
@@ -143,6 +156,79 @@ void trylock_test() {
LIBC_NAMESPACE::pthread_mutex_destroy(&trylock_mutex);
}
+void *trylock_other_thread(void *arg) {
+ auto *mutex = reinterpret_cast<pthread_mutex_t *>(arg);
+ int result = LIBC_NAMESPACE::pthread_mutex_trylock(mutex);
+ if (result == 0)
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_unlock(mutex), 0);
+ return reinterpret_cast<void *>(uintptr_t(result));
+}
+
+void recursive_mutex_test() {
+ pthread_mutexattr_t attr;
+ pthread_mutex_t recursive_mutex;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutexattr_init(&attr), 0);
+ ASSERT_EQ(
+ LIBC_NAMESPACE::pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE),
+ 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_init(&recursive_mutex, &attr), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutexattr_destroy(&attr), 0);
+
+ pthread_mutex_t snapshot = snapshot_mutex(&recursive_mutex);
+ ASSERT_TRUE(snapshot.__recursive);
+ ASSERT_EQ(snapshot.__owner, 0);
+ ASSERT_EQ(snapshot.__lock_count, size_t(0));
+
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_lock(&recursive_mutex), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_lock(&recursive_mutex), 0);
+
+ pthread_t thread;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_create(
+ &thread, nullptr, trylock_other_thread, &recursive_mutex),
+ 0);
+ void *retval = nullptr;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_join(thread, &retval), 0);
+ ASSERT_EQ(uintptr_t(retval), uintptr_t(EBUSY));
+
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_unlock(&recursive_mutex), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_unlock(&recursive_mutex), 0);
+ snapshot = snapshot_mutex(&recursive_mutex);
+ ASSERT_EQ(snapshot.__owner, 0);
+ ASSERT_EQ(snapshot.__lock_count, size_t(0));
+
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_trylock(&recursive_mutex), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_unlock(&recursive_mutex), 0);
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_destroy(&recursive_mutex), 0);
+}
+
+void initializer_acts_the_same_as_null_attr() {
+ pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_t mutex_from_init;
+ ASSERT_EQ(LIBC_NAMESPACE::pthread_mutex_init(&mutex_from_init, nullptr), 0);
+
+ pthread_mutex_t mutex_snapshot = snapshot_mutex(&mutex);
+ pthread_mutex_t mutex_from_init_snapshot = snapshot_mutex(&mutex_from_init);
+ ASSERT_EQ(mutex_snapshot.__ftxw.__word,
+ mutex_from_init_snapshot.__ftxw.__word);
+ ASSERT_EQ(mutex_snapshot.__priority_inherit,
+ mutex_from_init_snapshot.__priority_inherit);
+ ASSERT_EQ(mutex_snapshot.__recursive, mutex_from_init_snapshot.__recursive);
+ ASSERT_EQ(mutex_snapshot.__robust, mutex_from_init_snapshot.__robust);
+ ASSERT_EQ(mutex_snapshot.__pshared, mutex_from_init_snapshot.__pshared);
+ ASSERT_EQ(mutex_snapshot.__owner, mutex_from_init_snapshot.__owner);
+ ASSERT_EQ(mutex_snapshot.__lock_count, mutex_from_init_snapshot.__lock_count);
----------------
SchrodingerZhu wrote:
This is just test that INITIALIZER is the same as null attribute initialization, which is in the spec.
May be I should change this to bytewise memcmp.
https://github.com/llvm/llvm-project/pull/193992
More information about the libc-commits
mailing list