Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[libc] implement pthread_mutex_trylock #93359

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

changkhothuychung
Copy link
Contributor

fix issue #85278

@llvmbot llvmbot added the libc label May 25, 2024
@llvmbot
Copy link

llvmbot commented May 25, 2024

@llvm/pr-subscribers-libc

Author: Nhat Nguyen (changkhothuychung)

Changes

fix issue #85278


Full diff: https://github.com/llvm/llvm-project/pull/93359.diff

1 Files Affected:

  • (modified) libc/src/__support/threads/linux/mutex.h (+21-1)
diff --git a/libc/src/__support/threads/linux/mutex.h b/libc/src/__support/threads/linux/mutex.h
index 6702de4651686..c7f9b4f320dc3 100644
--- a/libc/src/__support/threads/linux/mutex.h
+++ b/libc/src/__support/threads/linux/mutex.h
@@ -116,7 +116,27 @@ struct Mutex {
     }
   }
 
-  MutexError trylock();
+  MutexError trylock() {
+    FutexWordType mutex_status = FutexWordType(LockState::Free);
+    FutexWordType locked_status = FutexWordType(LockState::Locked);
+
+    if (futex_word.compare_exchange_strong(mutex_status,
+                                           FutexWordType(LockState::Locked))) {
+      return MutexError::NONE;
+    }
+
+    switch (LockState(mutex_status)) {
+    case LockState::Locked:
+      if (recursive && this == owner) {
+        lock_count++;
+        return MutexError::NONE;
+      }
+
+    case LockState::Free:
+      // If it was LockState::Free, we shouldn't be here at all.
+      return MutexError::BAD_LOCK_STATE;
+    }
+  }
 };
 
 } // namespace LIBC_NAMESPACE

@SchrodingerZhu
Copy link
Contributor

SchrodingerZhu commented May 25, 2024

I think this will conflict with the mutex rework. I will get that part fixed over the weekend. Sorry for that PR lasting longer than I have expected. My jet lag does not agree with me when coding at night 🤦.

@changkhothuychung
Copy link
Contributor Author

I think this will conflict with the mutex rework. I will get that part fixed over the weekend. Sorry for that PR lasting longer than I have expected. My jet lag does not agree with me when coding at night 🤦.

which PR are you referring to? can u send me the link here? Im not aware of that.

Copy link
Member

@nickdesaulniers nickdesaulniers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs unit tests. If you implement
C11 https://en.cppreference.com/w/c/thread/mtx_trylock in terms of this, then you can test it in test/integration/src/threads/mtx_test.cpp. I'd test an uncontended and a contended vanilla Mutex to start with.

Comment on lines +123 to +126
if (futex_word.compare_exchange_strong(mutex_status,
FutexWordType(LockState::Locked))) {
return MutexError::NONE;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (futex_word.compare_exchange_strong(mutex_status,
FutexWordType(LockState::Locked))) {
return MutexError::NONE;
}
if (futex_word.compare_exchange_strong(mutex_status,
FutexWordType(LockState::Locked)))
return MutexError::NONE;

https://llvm.org/docs/CodingStandards.html#don-t-use-braces-on-simple-single-statement-bodies-of-if-else-loop-statements

MutexError trylock();
MutexError trylock() {
FutexWordType mutex_status = FutexWordType(LockState::Free);
FutexWordType locked_status = FutexWordType(LockState::Locked);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This variable appears unused?

Comment on lines +130 to +132
if (recursive && this == owner) {
lock_count++;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (recursive && this == owner) {
lock_count++;
}
if (recursive && this == owner)
lock_count++;

Though I think we don't care what the resulting mutex_status value is if it's NOT Lock state::Locked, we should simply return MutexError::BUSY;.

@SchrodingerZhu
Copy link
Contributor

@nickdesaulniers I hope to put a pause to this PR since my mutex patch actually exposes try_lock api. (Sorry again for such conflicts.) It is okay to discuss suggested changes but please keep in mind that the implementation of try_lock using strong CAS may be already covered in another PR in flight.

It can be valuable if you can extend this PR to actually implement the POSIX API and provide test cases for that API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants