Skip to content

Conversation

jamesob
Copy link
Contributor

@jamesob jamesob commented Apr 18, 2019

I'm resurrecting this one (from #13168) because I need it to make progress on #15735.

It's now off by default and can be turned on with -logthreadnames=1.

Ran some benchmarks (IBD from local peer from 500_000 -> 504_000) and it's within spitting distance either on or off:

threadnames off (default)

2018-05-threadnames.3 vs. master (absolute)

name iterations 2018-05-threadnames.3 master
ibd.local.500000.504000.dbcache=2048 3 376.1584 (± 9.2944) 392.3414 (± 13.4238)
ibd.local.500000.504000.dbcache=2048.mem-usage 3 2236117.3333 (± 1845.9623) 2238690.6667 (± 2669.3487)

2018-05-threadnames.3 vs. master (relative)

name iterations 2018-05-threadnames.3 master
ibd.local.500000.504000.dbcache=2048 3 1 1.043
ibd.local.500000.504000.dbcache=2048.mem-usage 3 1 1.001

threadnames on

2018-05-threadnames-take-2 vs. master (absolute)

name iterations 2018-05-threadnames-take-2 master
ibd.local.500000.504000.dbcache=2048 3 367.6861 (± 0.3941) 364.1667 (± 0.9776)
ibd.local.500000.504000.dbcache=2048.mem-usage 3 2238461.3333 (± 3697.8730) 2237014.6667 (± 3307.6966)

2018-05-threadnames-take-2 vs. master (relative)

name iterations 2018-05-threadnames-take-2 master
ibd.local.500000.504000.dbcache=2048 3 1.010 1.00
ibd.local.500000.504000.dbcache=2048.mem-usage 3 1.001 1.00

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from 16f551c to a0ca62b Compare April 18, 2019 21:22
@DrahtBot
Copy link
Contributor

DrahtBot commented Apr 18, 2019

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #15606 ([experimental] UTXO snapshots by jamesob)
  • #15493 (rfc: Add -printconfig arg to bitcoind by promag)
  • #15382 ([util] add runCommandParseJSON by Sjors)
  • #13751 (Utils and libraries: Drops the boost/algorithm/string/split.hpp dependency by 251Labs)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@practicalswift
Copy link
Contributor

Concept ACK

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from a0ca62b to 503c1ff Compare April 26, 2019 13:56
Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 503c1ff. Looks like some windows tests are failing, but nothing to do with this PR. I left a few suggestions for changes, but please ignore any that do not sound like super great and wonderful ideas.

//! internal name.
static void SetThreadName(const char* name)
{
#if defined(PR_SET_NAME)
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "threads: introduce threadutil, refactor thread naming" (91cc480)

Note: Maybe obvious, but just in case it helps other reviewers, this code is unchanged (easy to verify with git log -p -n1 --color-moved=dimmed_zebra)

src/logging.cpp Outdated
@@ -5,6 +5,9 @@

#include <logging.h>
#include <util/time.h>
#include <threadutil.h>
Copy link
Contributor

Choose a reason for hiding this comment

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

In commit "threads: prefix log messages with thread names" (4fba3ea)

Could sort alphabetically (thread before util)

Note that this doesn't affect anything unless
DEBUG_LOCKCONTENTION is defined.

See discussions here:

- bitcoin#11722 (review)
- bitcoin#13168 (comment)
@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from 503c1ff to 28198a7 Compare April 26, 2019 19:04
@jamesob
Copy link
Contributor Author

jamesob commented Apr 26, 2019

@ryanofsky thanks very much for the review. Per usual, your suggested changes are indelibly righteous. I've made all of them save for the last I commented on.

@jamesob
Copy link
Contributor Author

jamesob commented Apr 26, 2019

Reran benchmarking; no performance difference.

absolute

name iterations master threadnames2.18
build.make.23.clang 1 135.8741 (± 0.0000) 133.9639 (± 0.0000)
build.make.23.clang.mem-usage 1 648692.0000 (± 0.0000) 646632.0000 (± 0.0000)
ibd.local.500000.504000.dbcache=2048 3 357.4552 (± 1.2016) 357.3936 (± 1.1932)
ibd.local.500000.504000.dbcache=2048.mem-usage 3 2240597.3333 (± 3291.6968) 2237538.6667 (± 4462.0143)

relative

name iterations master threadnames2.18
build.make.23.clang 1 1.014 1
build.make.23.clang.mem-usage 1 1.003 1
ibd.local.500000.504000.dbcache=2048 3 1.000 1
ibd.local.500000.504000.dbcache=2048.mem-usage 3 1.001 1

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from 28198a7 to 2e53d90 Compare April 26, 2019 20:03
Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 2e53d90. Just various suggested changes since last review.

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from 2e53d90 to eed4a5c Compare April 26, 2019 20:26
@jamesob
Copy link
Contributor Author

jamesob commented Apr 26, 2019

@ryanofsky Oops! Thanks, pushed.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK eed4a5c. Reference to temporary bug's fixed now. There is still the lint problem causing travis to fail, though (https://travis-ci.org/bitcoin/bitcoin/jobs/525122780#L356).

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from eed4a5c to 043a387 Compare April 26, 2019 21:16
Copy link
Member

@maflcko maflcko left a comment

Choose a reason for hiding this comment

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

utACK 043a387

Just some style comments that should probably be ignored

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from 043a387 to 0cfcb8d Compare April 26, 2019 22:47
@jamesob
Copy link
Contributor Author

jamesob commented Apr 27, 2019

Latest benchmark; 0.7% difference seems attributable to noise.

ibd local 500000 504000 dbcache=2048

@Empact
Copy link
Contributor

Empact commented Apr 27, 2019

utACK 0cfcb8d

nit: if I'm not mistaken you can use rvalues and move to avoid copies of the name throughout (channeling @sipa) #13168 (comment)

diff --git a/src/util/threadnames.cpp b/src/util/threadnames.cpp
index 3217855f7..2ca91613c 100644
--- a/src/util/threadnames.cpp
+++ b/src/util/threadnames.cpp
@@ -40,18 +40,18 @@ static thread_local std::string g_thread_name;
 const std::string& util::ThreadGetInternalName() { return g_thread_name; }
 //! Set the in-memory internal name for this thread. Does not affect the process
 //! name.
-static void SetInternalName(const std::string& name) { g_thread_name = name; }
+static void SetInternalName(std::string&& name) { g_thread_name = name; }
 
 // Without thread_local available, don't handle internal name at all.
 #else
 
 static const std::string empty_string;
 const std::string& util::ThreadGetInternalName() { return empty_string; }
-static void SetInternalName(const std::string& name) { }
+static void SetInternalName(std::string&& name) { }
 #endif
 
-void util::ThreadRename(const std::string& name)
+void util::ThreadRename(std::string&& name)
 {
     SetThreadName(("bitcoin-" + name).c_str());
-    SetInternalName(name);
+    SetInternalName(std::move(name));
 }
diff --git a/src/util/threadnames.h b/src/util/threadnames.h
index ecf6c50cc..aaf07b9bf 100644
--- a/src/util/threadnames.h
+++ b/src/util/threadnames.h
@@ -10,7 +10,7 @@
 namespace util {
 //! Rename a thread both in terms of an internal (in-memory) name as well
 //! as its system thread name.
-void ThreadRename(const std::string&);
+void ThreadRename(std::string&&);
 
 //! Get the thread's internal (in-memory) name; used e.g. for identification in
 //! logging.

@jamesob jamesob force-pushed the 2018-05-threadnames-take-2 branch from 0cfcb8d to 4b4bc00 Compare April 27, 2019 12:24
@jamesob
Copy link
Contributor Author

jamesob commented Apr 27, 2019

@Empact thanks, pushed.

@practicalswift
Copy link
Contributor

practicalswift commented Apr 27, 2019

I'm not sure the change from const std::string& to std::string&& is an improvement TBH.

It brings no performance benefit in this case AFAICT and const std::string& is what we're using in the rest of the code base.

$ git grep -E 'const std::string( |)&' | wc -l
851
$ git grep -E 'std::string( |)&&' | wc -l
0

@Empact
Copy link
Contributor

Empact commented Apr 27, 2019

@practicalswift Rvalues make sense in cases where you have setters or constructors which can consume / incorporate the object passed in. We're not using it with string but you can see other uses here:

$ git grep -E '[a-z]&&' | wc -l
44

If you're not seeing a performance benefit, it could be because my patch is apparently missing one move, as per: https://www.chromium.org/rvalue-references#TOC-9.-Move-constructors-should-be-accompanied-by-move-assignment-operators.

-static void SetInternalName(std::string&& name) { g_thread_name = name; }
+static void SetInternalName(std::string&& name) { g_thread_name = std::move(name); }

I don't think this is critical, but it seems semantically appropriate.

Copy link
Contributor

@ryanofsky ryanofsky left a comment

Choose a reason for hiding this comment

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

utACK 4b4bc00. Only changes since last review are disabling by default and adding const and &&.


re: #15849 (comment)

I'm not sure the change from const std::string& to std::string&& is an improvement TBH.

I also wouldn't consider this an improvement because now you can't call SetInternalName with an lvalue (plain variable or reference). This is now an error:

std::string name = "something";
SetInternalName(name);

People get really confused about this stuff, but if the goal is to just move-enable SetInternalName, it should take plain std::string not const std::string&, and not std::string&&.

  • If a function just needs to read an argument (and not manipulate it before throwing it away or move it into a data structure) it should take const T&.

  • If a function wants to give callers the option of moving from an argument but still allow copies, it should take plain T.

  • If a function wants to force callers to move it should take T &&.

@jnewbery
Copy link
Contributor

This is great. Very nicely structured PR and excellent commit messages 🙌

utACK 8722e54

The functional tests should be updated to have this enabled by default:

@maflcko
Copy link
Member

maflcko commented Apr 30, 2019

re-utACK 8722e54 (Only change since my previous review is DEFAULT_LOGTHREADNAMES=false and stylistic updates

Show signature and timestamp

Signature:

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA512

re-utACK 8722e54e56fd959fd4ff2321b36a7640dee440c5 (Only change since my previous review is DEFAULT_LOGTHREADNAMES=false and stylistic updates
-----BEGIN PGP SIGNATURE-----

iQGzBAEBCgAdFiEE+rVPoUahrI9sLGYTzit1aX5ppUgFAlwqrYAACgkQzit1aX5p
pUgtewv9FxicQmO1+eKzOzgPMHm+KzOsWSRPTJVEtCtLgpSOpE2p8YAYCtxnQQEi
XI+7EzSSyEE9IL66WPwXiDVxG3RkZcCpgKcf/oIb5CaVxRN9Ob03uYNup9qCOAey
YZgg9GMkhbAxfOh5ZO3LbembFqMYBv1KqHnSuGSil2VAnaJdTFY6IMhhwR5SWvZs
1Peh510KITCYCg1doua9FcPUBB67yG3zqF36PlHUGivA5C+Zr9kLMNSdNbBzSXf5
xlsqimIGSRjuk9qQx5P31XLx+yPEn3Si1ruTiN85CYMiPdRgIzg9lOmGHSBh1g38
gV19YXiUjikxSWBndXKht9ensL6SPnxseD5Zsca1qAaKbcG+V6rkgE8sLEZro4Qn
QShClrPnlwXvVmdJ8Ly5bnkyYWtC4jhlHu0bdtiyl/NOOWr29x6hGDsWw5l8tGfX
anwN/XWxYIn4pC5La3LP/biD4Jd/vrp0kL1ENp3723OxvP/iiHh+6E/6EcD4stBE
vv147CdK
=4CZG
-----END PGP SIGNATURE-----

Timestamp of file with hash 191793320e418666d66ac3696420980055c8e7f889470d345e05c3e4669b7398 -

pull bot pushed a commit to jaschadub/bitcoin that referenced this pull request Apr 30, 2019
8722e54 threads: add thread names to deadlock debugging message (James O'Beirne)
383b186 threads: prefix log messages with thread names (James O'Beirne)
ddd95cc tests: add threadutil tests (James O'Beirne)
ae5f2b6 threads: introduce util/threadnames, refactor thread naming (James O'Beirne)
188ca75 disable HAVE_THREAD_LOCAL on unreliable platforms (James O'Beirne)

Pull request description:

  I'm resurrecting this one (from bitcoin#13168) because I need it to make progress on bitcoin#15735.

  It's now off by default and can be turned on with `-logthreadnames=1`.

  Ran some benchmarks (IBD from local peer from 500_000 -> 504_000) and it's within spitting distance either on or off:

  ### threadnames off (default)

  #### 2018-05-threadnames.3 vs. master (absolute)
  |                      name                      | iterations |   2018-05-threadnames.3    |           master           |
  |------------------------------------------------|-----------:|----------------------------|----------------------------|
  | ibd.local.500000.504000.dbcache=2048           |          3 | 376.1584 (± 9.2944)        | 392.3414 (± 13.4238)       |
  | ibd.local.500000.504000.dbcache=2048.mem-usage |          3 | 2236117.3333 (± 1845.9623) | 2238690.6667 (± 2669.3487) |

  #### 2018-05-threadnames.3 vs. master (relative)
  |                      name                      | iterations | 2018-05-threadnames.3 | master |
  |------------------------------------------------|-----------:|----------------------:|-------:|
  | ibd.local.500000.504000.dbcache=2048           |          3 |                     1 |  1.043 |
  | ibd.local.500000.504000.dbcache=2048.mem-usage |          3 |                     1 |  1.001 |

  ### threadnames on

  #### 2018-05-threadnames-take-2 vs. master (absolute)
  |                      name                      | iterations | 2018-05-threadnames-take-2 |           master           |
  |------------------------------------------------|-----------:|----------------------------|----------------------------|
  | ibd.local.500000.504000.dbcache=2048           |          3 | 367.6861 (± 0.3941)        | 364.1667 (± 0.9776)        |
  | ibd.local.500000.504000.dbcache=2048.mem-usage |          3 | 2238461.3333 (± 3697.8730) | 2237014.6667 (± 3307.6966) |

  #### 2018-05-threadnames-take-2 vs. master (relative)
  |                      name                      | iterations | 2018-05-threadnames-take-2 | master |
  |------------------------------------------------|-----------:|---------------------------:|-------:|
  | ibd.local.500000.504000.dbcache=2048           |          3 |                      1.010 |   1.00 |
  | ibd.local.500000.504000.dbcache=2048.mem-usage |          3 |                      1.001 |   1.00 |
  ```

ACKs for commit 8722e5:
  Empact:
    utACK bitcoin@8722e54
  jnewbery:
    utACK 8722e54
  MarcoFalke:
    re-utACK 8722e54 (Only change since my previous review is DEFAULT_LOGTHREADNAMES=false and stylistic updates

Tree-SHA512: 50af992708295b8d680cf10025262dd964e599a356bdfc1dfc84fb18c00afabcb34d3d12d551b0677ff81f8fccad0e17c1d5b24dfecb953a913bc77fdd1a4577
@maflcko maflcko merged commit 8722e54 into bitcoin:master Apr 30, 2019
*darwin*)
# TODO enable thread_local on later versions of Darwin where it is
# supported (per https://stackoverflow.com/a/29929949)
AC_MSG_RESULT(no)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why can't we check with something like:

AC_MSG_CHECKING([for thread_local support])
AC_LINK_IFELSE([AC_LANG_SOURCE([
  #include <thread>
  static thread_local int foo = 0;
  static void run_thread() { foo++;}
  int main(){
  for(int i = 0; i < 10; i++) { std::thread(run_thread).detach();}
  return foo;
  }
  ])],
  [
    AC_DEFINE(HAVE_THREAD_LOCAL,1,[Define if thread_local is supported.])
    AC_MSG_RESULT(yes)
  ],
  [
    AC_MSG_RESULT(no)
  ]
)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because bad thread_local behavior sometimes doesn't fail explicitly on certain platforms (e.g. mingw32) until execution, and only under certain circumstances.

Copy link
Contributor

Choose a reason for hiding this comment

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

Can you elaborate a little bit what "bad behavior" exactly mean?
I assume the AC_LINK_IFELSE test would work on OSX,.. right? Or would it be a problem for our depends OSX build where we build with SDK 10.11 but allow min os version of 10.10?

Maybe I just open a PR and test it a bit.

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I couldn't add thread_local to the tests because of issues with macos: #14985

Might be solved by your AC_LINK check, but disabling it seems safer than running into issues later on.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jonasschnelli see the gist I link to in the code comment above (https://gist.github.com/jamesob/fe9a872051a88b2025b1aa37bfa98605). This example compiles but stackoverflows when run, and I had to specially construct that example IIRC because trivial usages worked okay.

deadalnix pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Mar 24, 2020
Summary:
Backport of core [[bitcoin/bitcoin#15849 | PR15849]].

The first commit disables `thread_local` on some platforms and is not ported:
 - The Darwin exclusion is no longer needed since D5514.
 - The MinGw exclusion does not seem necessary, at least with our version. The tests run fine on Windows, both 32 and 64 bits.
Also see D2219 which removes the `thread_local` check.

This introduces a number of bugs:
 - This is breaking the build for some *BSD.
 - This makes some Unix tools inefficient, like `ps` or `killall`.
 - Some thread names are truncated and cannot be differentiated.
The fixes will be ported in their own diff for readability.

Test Plan:
  ninja check
  make check

Run the Gitian builds.

Run test_bitcoin.exe on Windows (32 bits) for sanity.
Builld and run the tests on OSX.

Start `bitcoind` with `-logthreadnames=1` and check the debug log
contains the
thread names.

Reviewers: #bitcoin_abc, jasonbcox

Reviewed By: #bitcoin_abc, jasonbcox

Subscribers: jasonbcox

Differential Revision: https://reviews.bitcoinabc.org/D5540
jasonbcox pushed a commit to Bitcoin-ABC/bitcoin-abc that referenced this pull request Mar 27, 2020
Summary:
This is a follow-up for D5540. Despite the tests passing, the diff is
causing bitcoin-qt to fail quickly. Disabling thread_local for this
compiler fixes the issue.

The code is extracted from [[bitcoin/bitcoin#15849 | PR15849]], but the tests for thread_local is a
simplified version.

Test Plan:
Build for win32 with autotools and cmake. Run bitcoin-qt and check it
doesn't crash.

As a sanity check, build for win64 and any linux and check
`thread_local` is enabled.

Reviewers: #bitcoin_abc, jasonbcox

Reviewed By: #bitcoin_abc, jasonbcox

Subscribers: jasonbcox

Differential Revision: https://reviews.bitcoinabc.org/D5587
ftrader added a commit to bitcoin-cash-node/bitcoin-cash-node that referenced this pull request Dec 1, 2020
Thread names in logs and deadlock debug tools

See merge request bitcoin-cash-node/bitcoin-cash-node!834

This is a backport of [PR15849](bitcoin/bitcoin#15849) (Thread names in logs and deadlock debug tools).

See original PR for benchmarks.

Also includes some smaller follow-up PR's:
* [PR15968](bitcoin/bitcoin#15968) - Fix portability issue with pthreads
* [PR16984](bitcoin/bitcoin#16984) - util: Make thread names shorter
* [PR17038](bitcoin/bitcoin#17038) - Don't rename main thread at process level

## Test plan

New tests: `ninja check`

Run with `-logthreadnames`, observe lines are prefixed with thread

```
2020-10-28T11:39:16Z [init] init message: Done loading
2020-10-28T11:39:16Z [opencon] opencon thread start
2020-10-28T11:39:16Z [dnsseed] 0 addresses found from DNS seeds
2020-10-28T11:39:16Z [msghand] msghand thread start
2020-10-28T11:39:16Z [dnsseed] dnsseed thread exit
```

Compile with lockorder debugging enabled: `cmake -GNinja -DCMAKE_BUILD_TYPE=Debug ..`
kwvg added a commit to kwvg/dash that referenced this pull request Jun 5, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 6, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 6, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 7, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 8, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 8, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 9, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 10, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 11, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 16, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 16, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 24, 2021
kwvg added a commit to kwvg/dash that referenced this pull request Jun 25, 2021
Co-authored-by: UdjinM6 <UdjinM6@users.noreply.github.com>
UdjinM6 added a commit to dashpay/dash that referenced this pull request Jun 26, 2021
@bitcoin bitcoin locked as resolved and limited conversation to collaborators Dec 16, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants