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

Mutex for Kotlin/Common #508

Open
wants to merge 4 commits into
base: native-thread-parking
Choose a base branch
from

Conversation

bbrockbernd
Copy link
Collaborator

@dkhalanskyjb
Copy link

It would be better to set native-thread-parking as the base branch of this PR. It's more difficult to review just the mutex when the changes related to parking are also included.

* Multiplatform mutex.
* On native based on pthread system calls.
* On JVM delegates to ReentrantLock.
*/

Choose a reason for hiding this comment

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

This is user-visible documentation, and so it must explain the contracts of the data structure. What is a mutex? What would an example of its usage look like? Is it reentrant? Is it fair? It should mention that it's unsuitable for async (suspend) code, blocks the thread, and is only suitable for low-level technical work.

The same goes for every function in the file: all API entries need to be documented. When does each function return? When can it throw an exception? What does it do?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have adjusted the docs, wdyt?

Choose a reason for hiding this comment

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

Great, thanks!

* On JVM delegates to ReentrantLock.
*/
expect class Mutex() {
fun isLocked(): Boolean

Choose a reason for hiding this comment

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

Even if it turns out someone does need this function, they can do fun Mutex.isLocked() = if (tryLock()) { unlock(); true } else false (right?), so including this function is purely a performance optimization for a performance problem that may not even exist. So, unless we know of some specific use cases for this function, let's not take on the extra commitment of including it.

Copy link
Collaborator Author

@bbrockbernd bbrockbernd Feb 10, 2025

Choose a reason for hiding this comment

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

That is correct. I have tried to keep the api similar to the coroutines mutex's api. But will remove it for now.

P.S. true and false should be swapped right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

On a second thought, this won't work if I am holding the lock myself since it is reentrant.

/**
* Multiplatform mutex.
* On native based on pthread system calls.
* On JVM delegates to ReentrantLock.

Choose a reason for hiding this comment

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

This doesn't seem accurate, though? ReentrantLock does get used in synchronized and kotlinx.atomicfu.ReentrantLock, but not in Mutex, right?

If so, there seems to be some inconsistency: on the one hand, atomicfu.ReentrantLock delegates to Java's ReentrantLock, on the other, atomicfu.Mutex doesn't, whereas on Native, atomicfu.ReentrantLock and atomcifu.Mutex are basically the same thing.
If we believe that our mutex is better, we should use it throughout; if we don't, we should use ReentrantLock throughout. Are there measurements showing which one performs better?

…o ReentrantLock on JVM, inline and private funs where possible. Additionally removed legacy NativeNode.
Comment on lines +140 to +141
public fun <init> (Ljava/util/concurrent/locks/ReentrantLock;)V
public final fun getReentrantLock ()Ljava/util/concurrent/locks/ReentrantLock;

Choose a reason for hiding this comment

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

Let's avoid exposing the ReentrantLock constructor and accessor for now. What if we do implement our own mutex down the line that performs better?

* Multiplatform mutex.
* On native based on pthread system calls.
* On JVM delegates to ReentrantLock.
*/

Choose a reason for hiding this comment

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

Great, thanks!

* Threads can acquire the lock by calling [lock] and release the lock by calling [unlock].
*
* When a thread calls [lock] while another thread is locked, it will suspend until the lock is released.
* When multiple threads are waiting for the lock, they will acquire it in a fair order (first in first out).

Choose a reason for hiding this comment

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

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

Successfully merging this pull request may close these issues.

2 participants