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

Introduce replacement for getting and setting thread name: #4312

Merged
merged 8 commits into from
Sep 7, 2023

Conversation

HowardHinnant
Copy link
Contributor

@HowardHinnant HowardHinnant commented Sep 22, 2022

High Level Overview of Change

  • In namespace ripple, introduces get_name function that takes a
    std::thread::native_handle_type and returns a std::string.
  • In namespace ripple, introduces get_name function that takes a
    std::thread or std::jthread and returns a std::string.
  • In namespace ripple::this_thread, introduces get_name function
    that takes no parameters and returns the name of the current
    thread as a std::string.
  • In namespace ripple::this_thread, introduces set_name function
    that takes a std::string_view and sets the name of the current
    thread.
  • Intended to replace the beast utilities setCurrentThreadName
    and getCurrentThreadName.

The new API for getting and setting the thread name:

namespace this_thread {
std::string
get_name();
void
set_name(std::string s);
} // namespace this_thread

Example:

auto name = ripple::this_thread::set_name("A");

The maximum length on the name is 15. There is an assert on that, and if asserts are turned off, the name is truncated to a max of 15.

Context of Change

Type of Change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Refactor (non-breaking change that only restructures code)
  • Tests (You added tests for code that already exists, or your new feature included in this PR)
  • Documentation Updates
  • Release

@greg7mdp
Copy link
Contributor

Also the linux and mac sections are almost identical. Maybe combine them?

@greg7mdp
Copy link
Contributor

Great, thanks for the updates @HowardHinnant! I learned some things as well :-).

@intelliot
Copy link
Collaborator

@HowardHinnant does this change still make sense to apply? If so, could you suggest 2 potential reviewers?

@HowardHinnant
Copy link
Contributor Author

Yes. I recommend @greg7mdp and @seelabs as reviewers.

/** Returns the name of the caller thread.
template <class Thread>
inline auto
get_name(Thread& t) -> decltype(t.native_handle(), t.join(), std::string{})
Copy link
Contributor

@greg7mdp greg7mdp Mar 23, 2023

Choose a reason for hiding this comment

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

That is so cool! Am I understanding correctly that the intent is to make the template substitution fail if Thread doesn't have native_handle() or join() members?
Reviewing your code is always fun as I learn modern best practices!

Copy link
Collaborator

@seelabs seelabs left a comment

Choose a reason for hiding this comment

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

There are two issues we'll need to resolve:

  1. On linux, threads do not start with an empty name (see: https://man7.org/linux/man-pages/man3/pthread_setname_np.3.html). This isn't a killer, but it makes a test fail.

  2. On linux (or at least my system) thread names are limited to 16 characters. We could just truncate the thread names, but it is unlikely anyone will notice their nice thread names were truncated until they look in a debugger - and fixing the thread names won't be a high priority if people are actively debugging other code.

I don't have a solution to offer. Thread names are usually known at compile time, so we could get "clever" and detect this at compile time, but honestly I'm not sure that kind of complexity is worth it for something like this.

At any rate, I'll let you think about solutions and I'll do so as well.

@intelliot intelliot added the Tech Debt Non-urgent improvements label Apr 27, 2023
@intelliot
Copy link
Collaborator

@HowardHinnant any thoughts on the issues mentioned above?

@HowardHinnant
Copy link
Contributor Author

Addressed reviewer comments and rebased to develop.

void
set_name(std::string s)
{
s.resize(15);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Instead of silently truncating, what do you think about asserting the size instead? If someone renames or add a thread with too long of a name, right now it won't be caught until someone looks at it in a debugger (which can be a LONG time). Instead we could assert and it would be caught the first time rippled was run in debug mode.

Incidentally, it also save a string copy because we could pass by const& again, but honestly I don't think we care; I'm much more worried about catching the long thread name.

* In namespace ripple, introduces get_name function that takes a
  std::thread::native_handle_type and returns a std::string.
* In namespace ripple, introduces get_name function that takes a
  std::thread or std::jthread and returns a std::string.
* In namespace ripple::this_thread, introduces get_name function
  that takes no parameters and returns the name of the current
  thread as a std::string.
* In namespace ripple::this_thread, introduces set_name function
  that takes a std::string_view and sets the name of the current
  thread.
* Intended to replace the beast utilities setCurrentThreadName
  and getCurrentThreadName.
1.  Remove test which assumes null default thread name
2.  Limit names to 15 characters
    (16  including trailing null)
@HowardHinnant
Copy link
Contributor Author

Addressed reviewer comments and rebased to develop.

Copy link
Collaborator

@seelabs seelabs left a comment

Choose a reason for hiding this comment

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

👍

@HowardHinnant HowardHinnant added the Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. label Aug 25, 2023
@intelliot intelliot added this to the 1.13 milestone Aug 27, 2023
@intelliot intelliot merged commit 36cb5f9 into XRPLF:develop Sep 7, 2023
15 checks passed
gregtatcam pushed a commit to gregtatcam/rippled that referenced this pull request Sep 8, 2023
* In namespace ripple, introduces get_name function that takes a
  std::thread::native_handle_type and returns a std::string.
* In namespace ripple, introduces get_name function that takes a
  std::thread or std::jthread and returns a std::string.
* In namespace ripple::this_thread, introduces get_name function
  that takes no parameters and returns the name of the current
  thread as a std::string.
* In namespace ripple::this_thread, introduces set_name function
  that takes a std::string_view and sets the name of the current
  thread.
* Intended to replace the beast utilities setCurrentThreadName
  and getCurrentThreadName.
@intelliot
Copy link
Collaborator

note: libxrpl should be considered part of the "API" since this change potentially breaks dependents such as Clio

@intelliot intelliot modified the milestones: 1.13 or 2.0, 1.12 Sep 11, 2023
@intelliot
Copy link
Collaborator

intelliot commented Sep 11, 2023

nb: this was merged after 1.12 and may be included in the next release (expected to be 1.13 or 2.0)

@intelliot
Copy link
Collaborator

intelliot commented Sep 11, 2023

From now on, we'll need to be more careful about making changes that break libxrpl users.

Test Plan

  • Can write C++ code to call libxrpl code. If those calls break, then libxrpl has been changed in an incompatible way. Such changes need to be documented and considered by Clio.
  • The code can run quickly since it just calls every interface in libxrpl.
  • An expansion to the test could verify that the return type from each call is the same.
  • A further improvement would be to consider the return values and fail the test on any changes.
  • @scottschurr and @HowardHinnant can assist with creating these tests.
  • Could be a lot of work without too much benefit. Ensure this work has a small scope (1-2 weeks of effort).
    • Just do it for 10-20 function calls, then see how many function calls the library has. Maybe it's a very large API surface area (10s of 1000s).
    • Many objects, and many of them have 10s of methods, all of which would need to be exercised to ensure no breaking changes.
    • Could be automatable. Again, that might be a lot of work without much benefit. Also wouldn't be complete since default arguments could change.

Notes

  • Changes can be identified in code reviews.
  • Relevant breaking changes will be quickly identified by Clio.
  • Making this an actual library that we support is a big deal.
  • It's unrealistic to commit to a stable API since we'll make changes as necessary to make rippled better.

HowardHinnant added a commit to HowardHinnant/rippled that referenced this pull request Sep 12, 2023
ximinez added a commit to ximinez/rippled that referenced this pull request Sep 13, 2023
ximinez added a commit to ximinez/rippled that referenced this pull request Sep 13, 2023
ximinez added a commit to ximinez/rippled that referenced this pull request Sep 14, 2023
intelliot pushed a commit that referenced this pull request Sep 14, 2023
* Revert "Remove CurrentThreadName.h from RippledCore.cmake (#4697)"

This reverts commit 3b5fcd5.

* Revert "Introduce replacement for getting and setting thread name: (#4312)"

This reverts commit 36cb5f9.
@intelliot intelliot mentioned this pull request Sep 14, 2023
1 task
@intelliot intelliot added Reverted Changes which should still be considered for re-merging. See "Closed" PRs with this label and removed API Change labels Sep 19, 2023
ckeshava pushed a commit to ckeshava/rippled that referenced this pull request Sep 22, 2023
* In namespace ripple, introduces get_name function that takes a
  std::thread::native_handle_type and returns a std::string.
* In namespace ripple, introduces get_name function that takes a
  std::thread or std::jthread and returns a std::string.
* In namespace ripple::this_thread, introduces get_name function
  that takes no parameters and returns the name of the current
  thread as a std::string.
* In namespace ripple::this_thread, introduces set_name function
  that takes a std::string_view and sets the name of the current
  thread.
* Intended to replace the beast utilities setCurrentThreadName
  and getCurrentThreadName.
ckeshava pushed a commit to ckeshava/rippled that referenced this pull request Sep 22, 2023
* Revert "Remove CurrentThreadName.h from RippledCore.cmake (XRPLF#4697)"

This reverts commit 3b5fcd5.

* Revert "Introduce replacement for getting and setting thread name: (XRPLF#4312)"

This reverts commit 36cb5f9.
ckeshava pushed a commit to ckeshava/rippled that referenced this pull request Sep 25, 2023
* In namespace ripple, introduces get_name function that takes a
  std::thread::native_handle_type and returns a std::string.
* In namespace ripple, introduces get_name function that takes a
  std::thread or std::jthread and returns a std::string.
* In namespace ripple::this_thread, introduces get_name function
  that takes no parameters and returns the name of the current
  thread as a std::string.
* In namespace ripple::this_thread, introduces set_name function
  that takes a std::string_view and sets the name of the current
  thread.
* Intended to replace the beast utilities setCurrentThreadName
  and getCurrentThreadName.
ckeshava pushed a commit to ckeshava/rippled that referenced this pull request Sep 25, 2023
* Revert "Remove CurrentThreadName.h from RippledCore.cmake (XRPLF#4697)"

This reverts commit 3b5fcd5.

* Revert "Introduce replacement for getting and setting thread name: (XRPLF#4312)"

This reverts commit 36cb5f9.
sophiax851 pushed a commit to sophiax851/rippled that referenced this pull request Jun 12, 2024
* In namespace ripple, introduces get_name function that takes a
  std::thread::native_handle_type and returns a std::string.
* In namespace ripple, introduces get_name function that takes a
  std::thread or std::jthread and returns a std::string.
* In namespace ripple::this_thread, introduces get_name function
  that takes no parameters and returns the name of the current
  thread as a std::string.
* In namespace ripple::this_thread, introduces set_name function
  that takes a std::string_view and sets the name of the current
  thread.
* Intended to replace the beast utilities setCurrentThreadName
  and getCurrentThreadName.
sophiax851 pushed a commit to sophiax851/rippled that referenced this pull request Jun 12, 2024
* Revert "Remove CurrentThreadName.h from RippledCore.cmake (XRPLF#4697)"

This reverts commit 3b5fcd5.

* Revert "Introduce replacement for getting and setting thread name: (XRPLF#4312)"

This reverts commit 36cb5f9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Passed Passed code review & PR owner thinks it's ready to merge. Perf sign-off may still be required. Reverted Changes which should still be considered for re-merging. See "Closed" PRs with this label Tech Debt Non-urgent improvements
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

4 participants