Skip to content

Mutex for Kotlin/Common #508

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

Open
wants to merge 20 commits into
base: develop
Choose a base branch
from
Open

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?

* 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!

@bbrockbernd bbrockbernd force-pushed the bbrockbernd/common-mutex branch from 71dfd4b to 28f0d71 Compare March 13, 2025 14:42
@bbrockbernd bbrockbernd force-pushed the bbrockbernd/common-mutex branch 2 times, most recently from bfa21fb to cdc1df9 Compare April 25, 2025 14:18
@bbrockbernd bbrockbernd force-pushed the native-thread-parking branch from 519e59d to 0d9ea07 Compare April 29, 2025 11:59
@bbrockbernd bbrockbernd force-pushed the bbrockbernd/common-mutex branch from cdc1df9 to f9c6167 Compare May 1, 2025 08:57
@bbrockbernd bbrockbernd force-pushed the bbrockbernd/common-mutex branch from f9c6167 to 7a35ef7 Compare June 3, 2025 13:21
@bbrockbernd bbrockbernd changed the base branch from native-thread-parking to develop June 4, 2025 12:44
@bbrockbernd bbrockbernd requested a review from dkhalanskyjb June 4, 2025 12:45

final fun lock() // kotlinx.atomicfu.locks/NativeMutexNode.lock|lock(){}[0]
final fun unlock() // kotlinx.atomicfu.locks/NativeMutexNode.unlock|unlock(){}[0]
}

Choose a reason for hiding this comment

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

I assume removing this implementation detail is safe, but cc @fzhinkin: he probably knows if this was already used by someone else.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, there's a lot of API entries that were unintentionally left public.
Last time I checked, nobody actually use them, but it might be worth explicitly announcing the removal prior the release.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

explicitly announcing the removal

@fzhinkin Do you mean deprecating these functions?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes. Or posting a message in kotlinlang slack, to bring some attention. Anyway, I'll handle it, don't worry about it.

@bbrockbernd bbrockbernd requested a review from dkhalanskyjb July 2, 2025 17:57
@dkhalanskyjb dkhalanskyjb requested a review from fzhinkin July 3, 2025 06:40
Copy link

@dkhalanskyjb dkhalanskyjb left a comment

Choose a reason for hiding this comment

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

Well done! All I have left are stylistic nitpicks.

@fzhinkin fzhinkin self-assigned this Jul 11, 2025
Copy link
Collaborator

@fzhinkin fzhinkin left a comment

Choose a reason for hiding this comment

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

Just in case: did you check the performance characteristics of the new lock with existing kotlinx-coroutines benchmarks?


final fun lock() // kotlinx.atomicfu.locks/NativeMutexNode.lock|lock(){}[0]
final fun unlock() // kotlinx.atomicfu.locks/NativeMutexNode.unlock|unlock(){}[0]
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Well, there's a lot of API entries that were unintentionally left public.
Last time I checked, nobody actually use them, but it might be worth explicitly announcing the removal prior the release.

@fzhinkin
Copy link
Collaborator

It seems like rebase is needed to make CI green.

@fzhinkin fzhinkin assigned bbrockbernd and unassigned fzhinkin Jul 23, 2025
@bbrockbernd bbrockbernd force-pushed the bbrockbernd/common-mutex branch from 5768a08 to dfb6ea0 Compare July 24, 2025 12:39
@bbrockbernd
Copy link
Collaborator Author

bbrockbernd commented Jul 24, 2025

Just in case: did you check the performance characteristics of the new lock with existing kotlinx-coroutines benchmarks?

@dkhalanskyjb tested coroutines performance with the new mutex a while back. It might be worth retesting this since there have been some implementation changes in the meantime.

@bbrockbernd bbrockbernd requested a review from fzhinkin July 25, 2025 14:06
@ndkoval ndkoval removed their request for review August 13, 2025 10:36
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.

3 participants