Skip to content

New implementation of K/N multi-threaded dispatchers #3421

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

Merged
merged 9 commits into from
Oct 12, 2022

Conversation

qwwdfsad
Copy link
Member

No description provided.

@qwwdfsad qwwdfsad force-pushed the native-new-dispatchers branch from 39a63a2 to 049f0aa Compare August 23, 2022 14:27
@qwwdfsad qwwdfsad marked this pull request as ready for review August 30, 2022 14:52
@qwwdfsad qwwdfsad requested a review from dkhalanskyjb August 30, 2022 14:52
// TODO handle rejections
tasksQueue.trySend(block)
if (activeWorkers.value != workersCount) {
tryAddWorker()
Copy link
Member Author

Choose a reason for hiding this comment

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

I would really like to provide a proper keep-alive here, but it doesn't seem adequately possible: we must terminate workers and we must await termination in a blocking way, otherwise native resources leak.

The preliminary decision is to get rid of workers and design something better (i.e. Thread) in K/N

@qwwdfsad
Copy link
Member Author

qwwdfsad commented Aug 30, 2022

Long story short, I was trying to rewrite the dispatcher with proper locks (i.e. c414dce) in order to make it faster.

Apparently, zero-contention cases indeed become significantly faster, but any contention will kill all the dispatcher performance (I mean it, orders of magnitude). In order to avoid it, we need something that barely resembles a scalable lock (i.e. AbstractQueuedSynchronizer). The closest thing to it is, surprise, a channel :)

So we invested around ~10 human hours (I've also included K/N folk to help me and avoid some stupid gotcha) and result is to keep the code the way it is :)

I do have ideas on how to get rid of channel overhead for uncontended cases, but it doesn't seem to be worth it

@qwwdfsad
Copy link
Member Author

qwwdfsad commented Aug 30, 2022

On a side note, the documentation to the native declaration of newFixedThreadPoolContext will arrive later, first, we'll merge it, and I'll create Dispatchers.IO on top of that and only then KDoc will follow

@qwwdfsad qwwdfsad force-pushed the native-new-dispatchers branch from b91335b to 6ade8f1 Compare October 6, 2022 08:19
@qwwdfsad qwwdfsad requested a review from dkhalanskyjb October 10, 2022 09:14
@qwwdfsad qwwdfsad requested a review from dkhalanskyjb October 10, 2022 10:26
@qwwdfsad
Copy link
Member Author

The fix looks good to me

@dkhalanskyjb
Copy link
Collaborator

I am wary now that we found two races in the implementation, so I extracted the data structure and added a test for it. Sure, it's only used in one place, but the benefit of having that code tested (and also a bit more transparent, IMHO) outweighs this, I think.

@dkhalanskyjb dkhalanskyjb force-pushed the native-new-dispatchers branch from 9ab3fa7 to 1931831 Compare October 11, 2022 10:04
Copy link
Member Author

@qwwdfsad qwwdfsad left a comment

Choose a reason for hiding this comment

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

Otherwise good to go, cannot approve though due to GH limitations

* A thread-safe resource pool.
*
* [maxCapacity] is the maximum amount of elements.
* [create] is the function that creates a new element.
Copy link
Member Author

Choose a reason for hiding this comment

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

Suggested change
* [create] is the function that creates a new element.
* [create] is the function that creates a new element.
* It is part of 'common' source-set in order to be testable on JVM with Lincheck

Copy link
Member Author

Choose a reason for hiding this comment

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

Also, probably can be moved to 'concurrent'?

private val create: (Int) -> T
) {
/** Number of existing elements + isClosed flag in the highest bit.
* Once the flag is set, the value is guaranteed not to change anymore. */
Copy link
Member Author

Choose a reason for hiding this comment

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

I would stick with the default Java convention, that autoformats this comment into the following form:

/*
 * Comment
 */

I've stressed our (Kotlin) auto-formatter for a while, and it seems like it just doesn't work at all, I'll file all the bugs separately

@dkhalanskyjb dkhalanskyjb force-pushed the native-new-dispatchers branch from 1931831 to ac7bc3c Compare October 12, 2022 10:21
@qwwdfsad qwwdfsad merged commit 298eb11 into develop Oct 12, 2022
@qwwdfsad qwwdfsad deleted the native-new-dispatchers branch October 12, 2022 20:04
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