Skip to content

Conversation

@vchuravy
Copy link
Member

@vchuravy vchuravy commented Aug 10, 2023

Takes the changes from #49460 and separates out the pure sleep lock implementation.

Long-term we may want to adopt WTF ParkingLot, but this get's us going in the right direction.

- Rename jl_mutex_t -> jl_spin_mutex_t
- Rename jl_mutex_func->jl_spin_mutex_func
@brenhinkeller brenhinkeller added the multithreading Base.Threads and related functionality label Aug 10, 2023
if (safepoint)
gc_state = jl_gc_safe_enter(self->ptls);
uintptr_t hash = (uintptr_t)lock;
hash >>= SLEEP_IGNORED_BITS;
Copy link
Member

Choose a reason for hiding this comment

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

How safe is this? Do these hashes really not need to be unique?

Copy link
Member

Choose a reason for hiding this comment

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

collisions just wake up the collision

Copy link
Member

Choose a reason for hiding this comment

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

I would worry a bit about highly unpredictable performance phenomena due to this.

Copy link
Member

Choose a reason for hiding this comment

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

There is a predictable number of threads, so even one sleep_lock would be fine, but more just helps avoid some percentage of spurious wakeups

@JeffBezanson
Copy link
Member

What's the reason not to just use uv_mutex directly?

if ((waiters & 1) == 0) {
// nobody else holds the lock, we can take it
// this just subtracts 1 from the waiters count and sets the bottom bit to 1
jl_atomic_fetch_add(&lock->waiters, -1);
Copy link
Member

Choose a reason for hiding this comment

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

This appears to fail to atomically acquire the lock here (the comment is incorrect in the presence of threads)

Copy link
Member Author

Choose a reason for hiding this comment

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

We are currently holding the corresponding sleep_lock, so while other threads may have incremented the waiter counts,
they can't currently acquire the lock.

@vchuravy
Copy link
Member Author

What's the reason not to just use uv_mutex directly?

@pchintalapudi correct me if I am wrong.

The goal is to make it feasible to have cheaper locks, that are not spin-locks.
This amortized the cost of the uv_mutex in the style of https://webkit.org/blog/6161/locking-in-webkit/

Prem noticed in his work (see #49460) that the codegen lock was not ideal to be spin-lock since we can
hold it for long periods of time. Having cheaper locks that are not spin-lock would allow us to have locks per
objects, in particular for ir compress/uncompress.

One downside is that these locks are still not scheduler aware and we might eventually need/want that.
E.g. we are suspending the worker thread, instead of suspending the task.

In #50880 we are for now using uv_mutex, but wanted to explore if this lock would perform better.

@vchuravy vchuravy marked this pull request as draft February 10, 2024 23:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

multithreading Base.Threads and related functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants