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

Thread pool #62

Merged
merged 27 commits into from
Mar 1, 2024
Merged

Thread pool #62

merged 27 commits into from
Mar 1, 2024

Conversation

alt-graph
Copy link
Member

@alt-graph alt-graph commented Feb 1, 2024

This is an implementation of a ThreadPool class. We have some similar code in use in our HLC libs across multiple servers.

Some notes:

  • The pool always has a fixed number of threads (making that dynamic would complicate the design and I am not sure it would be worth the effort).
  • With 1 thread, this is a serial task queue.

Closes #28

@alt-graph alt-graph added the enhancement New feature or request label Feb 1, 2024
@alt-graph alt-graph self-assigned this Feb 1, 2024
@Finii

This comment was marked as resolved.

@alt-graph

This comment was marked as resolved.

@soerengrunewald

This comment was marked as resolved.

@soerengrunewald

This comment was marked as outdated.

@alt-graph

This comment was marked as outdated.

Copy link
Collaborator

@Finii Finii left a comment

Choose a reason for hiding this comment

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

Some thoughts on the first sequential code read ;-)

include/gul14/ThreadPool.h Outdated Show resolved Hide resolved
include/gul14/ThreadPool.h Show resolved Hide resolved
include/gul14/ThreadPool.h Outdated Show resolved Hide resolved
include/gul14/ThreadPool.h Outdated Show resolved Hide resolved
include/gul14/ThreadPool.h Outdated Show resolved Hide resolved
src/ThreadPool.cc Outdated Show resolved Hide resolved
src/ThreadPool.cc Show resolved Hide resolved
include/gul14/ThreadPool.h Outdated Show resolved Hide resolved
src/ThreadPool.cc Show resolved Hide resolved
src/ThreadPool.cc Outdated Show resolved Hide resolved
src/ThreadPool.cc Outdated Show resolved Hide resolved
include/gul14/ThreadPool.h Outdated Show resolved Hide resolved
@alt-graph alt-graph force-pushed the feature/ThreadPool branch 6 times, most recently from a2579db to 7b989c9 Compare February 2, 2024 14:16
@alt-graph alt-graph marked this pull request as ready for review February 9, 2024 15:52
@alt-graph alt-graph marked this pull request as draft February 9, 2024 18:19
@alt-graph alt-graph marked this pull request as ready for review February 9, 2024 20:56
@alt-graph
Copy link
Member Author

I believe this is ready for review now. The documentation looks OK, and the tests seem to pass.

@alt-graph
Copy link
Member Author

Hold on, I guess I'll move the std::invoke-related things into their own PR and squash some of the other commits. Otherwise this is just too much...

@alt-graph alt-graph marked this pull request as draft February 12, 2024 08:19
alt-graph and others added 21 commits February 28, 2024 15:58
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
We first erased a vector iterator, then used it to calculate its index.
Strictly speaking, the iterator was invalidated by the erase()
and may not be used afterwards. In debug mode, Microsoft's
STL asserts on that.
... and fix an unintentionally time-dependent test for
is_full().
Co-authored-by: Fini <ulf.fini.jastrow@desy.de>
[why]
The task ID is an implementation detail.

Proposed-by: Ulf Fini Jastrow <ulf.fini.jastrow@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
Missing "using namespace" directive to import chrono UDLs.

Reported-by: Ulf Fini Jastrow <ulf.fini.jastrow@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
[why]
Missing "using trim_sv" directive.

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
Having a ThreadPool class as a pure "facade" over a ThreadPoolEngine is
quite confusing.

[how]
Provide a factory function make_thread_pool() to create a ThreadPool
object in a shared_ptr, and make the ThreadPool constructor private.

Proposed-by: Ulf Fini Jastrow <ulf.fini.jastrow@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
This commit replaces the "one-trick pony" functions is_running() and
is_pending() by a quad-state get_state() function that returns an enum.

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
This solves several visibility problems and the order of classes in the
Doxygen documentation.

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
We used Doxygen's \addtogroup command to define entries for our header
files. In Doxygen 1.8.17 (Ubuntu 20), this category was selected for
display with the "modules" types. Doxygen 1.9.8 has learnt about C++20
modules and reserves the "modules" type for them, so we have to use the
new "topics" keyword.

[how]
Select both "modules" and "topics" for being displayed. Doxygen 1.8.x
ignores the "topics" and Doxygen 1.9.8 does not show anything additional
for "modules" because we do not have any C++ modules in GUL14.

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
For various reasons, the documentation did not render as expected.

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
[why]
The typedef is not useful outside of the ThreadPool class.

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
@alt-graph
Copy link
Member Author

What do you think about having a factory function instead?

It is now implemented like that. ThreadPoolEngine is gone, we need to call make_thread_pool() instead.

@alt-graph alt-graph requested a review from Finii February 28, 2024 15:20
[why]
The test only covered the possible outcomes "pending" and "running".

[how]
Add tests for "canceled" and "complete".

Signed-off-by: Lars Froehlich <lars.froehlich@desy.de>
Copy link
Collaborator

@Finii Finii left a comment

Choose a reason for hiding this comment

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

This looks good to merge!

What I do not understand is why we have

  • gul14::TaskState but
  • gul14::ThreadPool::TaskHandle

Maybe this is be accident - I think a unified solution would be easier for users to grasp.
What was the core guidline... if it does not need to access any members, keep it out of the class. But then...

I will have a look at the static/dynamic think later.

@alt-graph
Copy link
Member Author

Thanks for the review, @Finii! I think that both architecture and usability are much better than in the original version.

What I do not understand is why we have

* `gul14::TaskState` but

* `gul14::ThreadPool::TaskHandle`

The TaskHandle needs to access a private member of the ThreadPool, and keeping it separate leads to a mess of circular dependencies between the two classes. All of that can be solved, but is very messy. The nested class was by far the best solution I found.

TaskState could go anywhere, but since this is a scoped enum, people have to write the full type name a lot:

if (handle.get_state() == ThreadPool::TaskState::complete) ...;
if (handle.get_state() == TaskState::complete) ...;

I just prefer the second one.

@alt-graph alt-graph merged commit cb9c224 into main Mar 1, 2024
3 checks passed
@alt-graph alt-graph deleted the feature/ThreadPool branch March 1, 2024 11:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feature request: Thread pool
3 participants