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: add new optional Thread::Options argument to thread creation, which initially will allow specification of a name. #11440

Merged
merged 16 commits into from
Jun 8, 2020

Conversation

jmarantz
Copy link
Contributor

@jmarantz jmarantz commented Jun 4, 2020

Commit Message: Currently Envoy threads are unnamed. When tuning performance it might be useful to be able set names for threads based on what they are used for. Later it might be desirable to cpu affinity or other attributes when creating threads, but for now just adding name visibility seems useful.
Additional Description: Also moved a couple of platform-specific classes out of an impl.h and into the impl.cc as they weren't referenced anywhere else.
Risk Level: medium -- this does add an absl::Notification to thread creation to avoid a race when setting thread names, which affects prod. Also, this PR modifies Windows-specific code without manually testing it or even compiling it.
Testing: //test/...
Docs Changes: n/a
Release Notes: n/a
Fixes #11437

…nitially will allow specification of a name.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
…windows) and cover the case where the options are not provided.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
include/envoy/thread/thread.h Outdated Show resolved Hide resolved
source/server/worker_impl.cc Outdated Show resolved Hide resolved
source/common/common/posix/thread_impl.cc Outdated Show resolved Hide resolved
Signed-off-by: Joshua Marantz <jmarantz@google.com>
…to failing to set the thread name.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
@wrowe
Copy link
Contributor

wrowe commented Jun 4, 2020

This is what you'll observe compiling source/common/filesystem/win32/watcher_impl.cc

source/common/filesystem/win32/watcher_impl.cc(34): error C2065: 'dispatcher_': undeclared identifier
source/common/filesystem/win32/watcher_impl.cc(91): error C2039: 'ThreadImplWin32': is not a member of 'Envoy::Thread'
bazel-out/x64_windows-opt/bin/source/common/common/_virtual_includes/thread_impl_lib_win32\common/common/thread_impl.h(9): note: see declaration of 'Envoy::Thread'
source/common/filesystem/win32/watcher_impl.cc(91): error C2061: syntax error: identifier 'ThreadImplWin32'

The problem is that from the dispatcher, we need the HANDLE hThread (which is -not- the thread ID) which roughly corresponds to posix pthread_t of that implementation. The thread ID isn't helpful to the QueueUserAPC call which stacks the trigger onto the corresponding thread of that watcher.

watcher_impl used to consume the ThreadImplWin32 which provided transparent access to that thread handle, the new API will need to do the equivilant.

@wrowe
Copy link
Contributor

wrowe commented Jun 4, 2020

cc @sunjayBhatia

@jmarantz
Copy link
Contributor Author

jmarantz commented Jun 4, 2020

Due to the rather restrictive posix limit I wanted to test we were actually getting the 15 bytes, and if we wind up on a platform that is limited further we need to learn about it in tests because we'll need to re-think how we name the dispatcher threads to make them useful.

Note it's not enabled in prod, only for debug/fastbuild.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@eziskind
Copy link
Contributor

eziskind commented Jun 4, 2020

LGTM

@jmarantz
Copy link
Contributor Author

jmarantz commented Jun 5, 2020

Ah I managed to get windows CI passing :). Thanks @wrowe and @sunjayBhatia . Now for MacOS!

Of course MacOS fails for lots of people but this PR makes it fail worse, specifically because pthread_setname_np appears to not be available.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@jmarantz
Copy link
Contributor Author

jmarantz commented Jun 5, 2020

@envoyproxy/senior-maintainers I think this is ready for a look.

source/common/common/posix/thread_impl.cc Outdated Show resolved Hide resolved
source/common/common/posix/thread_impl.cc Outdated Show resolved Hide resolved
#ifndef NDEBUG
std::string check_name;
if (getNameFromOS(check_name)) {
ASSERT(check_name == name_,
Copy link
Contributor

Choose a reason for hiding this comment

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

The extra #if seems unneeded. Can you make getNameFromOS() return a std::string, and check for equality in the ASSERT so that no extra #if is needed here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it's a little tricky because it is valid for getNameFromOS to fail. That will happen if the thread exits after the call to pthread_setname_np and before the call to pthread_getname_np. This seemed like the easiest way to assert that, if we can get the name at all, it's what we expect.

If you have other ideas of how to structure this better I'm happy to try, but this seemed like the simplest approach so far.

Copy link
Contributor

@ggreenway ggreenway Jun 5, 2020

Choose a reason for hiding this comment

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

Regardless of the ifdef, I'd say make it return an optional<std::string>. And then I think you can change it to ASSERT(!getNameFromOS().valid() || getNameFromOS() == name_)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup that's better; actually i had done something similar to this but I'll switch to optional.

Copy link
Contributor Author

@jmarantz jmarantz Jun 5, 2020

Choose a reason for hiding this comment

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

actually I like what I have better at both call-sites. I don't like calling getNameFromOS() twice as it can fail due to subprocess exiting between the two calls.

source/common/grpc/google_async_client_impl.cc Outdated Show resolved Hide resolved
source/server/worker_impl.cc Show resolved Hide resolved
source/server/worker_impl.cc Outdated Show resolved Hide resolved
test/common/common/thread_test.cc Show resolved Hide resolved
test/common/common/thread_test.cc Show resolved Hide resolved
@ggreenway ggreenway self-assigned this Jun 5, 2020
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@jmarantz
Copy link
Contributor Author

jmarantz commented Jun 6, 2020

Any more comments on this? I'd love to get this in so it can start its way through the pipeline where we can use it to gain insight into how threading behaves on our traffic. Thanks!

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: Joshua Marantz <jmarantz@google.com>
@ggreenway ggreenway merged commit 97ecef8 into envoyproxy:master Jun 8, 2020
@jmarantz jmarantz deleted the thread-names branch June 8, 2020 15:40
songhu pushed a commit to songhu/envoy that referenced this pull request Jun 25, 2020
… which initially will allow specification of a name. (envoyproxy#11440)

Currently Envoy threads are unnamed. When tuning performance it might be useful to be able set names for threads based on what they are used for. Later it might be desirable to cpu affinity or other attributes when creating threads, but for now just adding name visibility seems useful.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
yashwant121 pushed a commit to yashwant121/envoy that referenced this pull request Jul 24, 2020
… which initially will allow specification of a name. (envoyproxy#11440)

Currently Envoy threads are unnamed. When tuning performance it might be useful to be able set names for threads based on what they are used for. Later it might be desirable to cpu affinity or other attributes when creating threads, but for now just adding name visibility seems useful.

Signed-off-by: Joshua Marantz <jmarantz@google.com>
Signed-off-by: yashwant121 <yadavyashwant36@gmail.com>
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.

thread: threads should be named to help performance analysis and tuning
4 participants