refactor: Make scheduler methods type safe #18289

pull MarcoFalke wants to merge 3 commits into bitcoin:master from MarcoFalke:2003-schedTypeChrono changing 8 files +43 −44
  1. MarcoFalke commented at 2:07 PM on March 7, 2020: member

    Main benefit is that stuff like 15 * 60 * 1000 is replaced by minutes{15}

  2. scheduler: Use C++11 member initialization, add shutdown assert
    "Initializing the members in the declaration makes it easy to spot
    uninitialized ones".
    https://github.com/bitcoin/bitcoin/blob/master/doc/developer-notes.md#c-data-structures
    fa70ccc6c4
  3. fanquake added the label Refactoring on Mar 7, 2020
  4. in src/scheduler.cpp:19 in fa70ccc6c4 outdated
      15 |  }
      16 |  
      17 |  CScheduler::~CScheduler()
      18 |  {
      19 |      assert(nThreadsServicingQueue == 0);
      20 | +    if (stopWhenEmpty) assert(taskQueue.empty());
    


    ajtowns commented at 2:13 PM on March 7, 2020:

    In that case, should stop() also assert(nThreadsServicingQueue > 0) at least when drain == true?


    vasild commented at 8:06 PM on March 7, 2020:

    I agree. Maybe relax the assert to assert(nThreadsServicingQueue > 0 || taskQueue.empty()) because otherwise CScheduler c; c.stop(); would assert.


    MarcoFalke commented at 1:36 PM on March 10, 2020:

    I don't think we can do that. The scheduler accepts events before any service thread has been started, also we can ask it to stop before any service threads have been started (they might be started later on).

    I will leave it as is for now.


    ajtowns commented at 8:32 AM on March 13, 2020:

    Makes sense

  5. MarcoFalke force-pushed on Mar 7, 2020
  6. ajtowns commented at 2:19 PM on March 7, 2020: member

    Concept ACK

  7. practicalswift commented at 4:31 PM on March 7, 2020: contributor

    Concept ACK

    Thanks for making the code easier to read. That is appreciated by future generations of Core developers :)

  8. in src/scheduler.cpp:117 in faa90a0f93 outdated
     113 | @@ -118,15 +114,15 @@ void CScheduler::MockForward(std::chrono::seconds delta_seconds)
     114 |      newTaskScheduled.notify_one();
     115 |  }
     116 |  
     117 | -static void Repeat(CScheduler* s, CScheduler::Function f, int64_t deltaMilliSeconds)
     118 | +static void Repeat(CScheduler& s, CScheduler::Function f, std::chrono::milliseconds delta)
    


    kallewoof commented at 5:16 AM on March 8, 2020:

    Nit: const std::chrono::milliseconds& to avoid copy (here and below).


    practicalswift commented at 9:19 AM on March 9, 2020:

    Nit on nit:

    I'm afraid that might be a pessimisation :)

    From a performance perspective the typical rule-of-thumb recommendation is to pass "in" parameters by value (instead of reference to const) if the parameter has a size up to 16 bytes ("cheaply-copied" types).

    Thus in this case the rule-of-thumb recommendation would be to pass by value instead of reference to const.

    (Disclaimer: As always with optimisations -- if it is worth trying to optimise then it is worth trying to quantify the impact of the optimisation by measuring! :))

    From the C++ Core Guidelines (Stroustrup & Sutter):

    F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to const

    Reason: Both let the caller know that a function will not modify the argument, and both allow initialization by rvalues.

    What is “cheap to copy” depends on the machine architecture, but two or three words (doubles, pointers, references) are usually best passed by value. When copying is cheap, nothing beats the simplicity and safety of copying, and for small objects (up to two or three words) it is also faster than passing by reference because it does not require an extra indirection to access from the function.

    Examples:

    void f1(const string& s);  // OK: pass by reference to const; always cheap
    
    void f2(string s);         // bad: potentially expensive
    
    void f3(int x);            // OK: Unbeatable
    
    void f4(const int& x);     // bad: overhead on access in f4()
    


    kallewoof commented at 9:22 AM on March 9, 2020:

    It feels unstable to me to depend on architecture and/or implementation rather than just go for const x& when you can, but it's a nit; I'll live. :)


    ajtowns commented at 4:40 AM on March 10, 2020:

    std::chrono::milliseconds is just a 64-bit int (well, 45-bit or greater int), so passing it as const & means you're passing a 64-bit pointer instead, and have to deref it later.


    MarcoFalke commented at 1:39 PM on March 10, 2020:

    Leaving as is for now, to not invalidate review


    MarcoFalke commented at 1:40 PM on March 10, 2020:

    The other feedback aside, I prefer the copy here over a reference because other arguments (like the function) must be copied anyway.


    kallewoof commented at 1:57 PM on March 10, 2020:

    Yep, copy seems sensible after all.

  9. kallewoof commented at 5:21 AM on March 8, 2020: member

    Concept ACK; light code review.

  10. in src/init.cpp:90 in faa90a0f93 outdated
      86 | @@ -87,7 +87,7 @@ static const bool DEFAULT_REST_ENABLE = false;
      87 |  static const bool DEFAULT_STOPAFTERBLOCKIMPORT = false;
      88 |  
      89 |  // Dump addresses to banlist.dat every 15 minutes (900s)
      90 | -static constexpr int DUMP_BANS_INTERVAL = 60 * 15;
      91 | +static constexpr std::chrono::minutes DUMP_BANS_INTERVAL{15};
    


    vasild commented at 6:50 PM on March 8, 2020:

    Nit: the comment warrants s/ (900s)//, or even reword to something like "How often to dump addresses to banlist.dat". Same below for DUMP_PEERS_INTERVAL.


    MarcoFalke commented at 1:58 PM on March 10, 2020:

    Thanks, done.

  11. vasild commented at 7:28 PM on March 8, 2020: member

    ACK faa90a0 (code review, not tested)

  12. in src/net.cpp:2346 in faa90a0f93 outdated
    2342 | @@ -2343,7 +2343,7 @@ bool CConnman::Start(CScheduler& scheduler, const Options& connOptions)
    2343 |      threadMessageHandler = std::thread(&TraceThread<std::function<void()> >, "msghand", std::function<void()>(std::bind(&CConnman::ThreadMessageHandler, this)));
    2344 |  
    2345 |      // Dump network addresses
    2346 | -    scheduler.scheduleEvery(std::bind(&CConnman::DumpAddresses, this), DUMP_PEERS_INTERVAL * 1000);
    2347 | +    scheduler.scheduleEvery([&] { this->DumpAddresses(); }, DUMP_PEERS_INTERVAL);
    


    promag commented at 9:51 PM on March 8, 2020:
        scheduler.scheduleEvery([this] { DumpAddresses(); }, DUMP_PEERS_INTERVAL);
    

    Same below.


    MarcoFalke commented at 1:58 PM on March 10, 2020:

    Same below.

    Where exactly?


    vasild commented at 2:10 PM on March 10, 2020:

    MarcoFalke commented at 2:24 PM on March 10, 2020:

    consensusParams needs to be passed in, not just this

  13. promag commented at 9:58 PM on March 8, 2020: member

    Code review ACK faa90a0f933f574aa3304df7616778fc01009f51.

  14. MarcoFalke force-pushed on Mar 10, 2020
  15. scheduler: Make schedule* methods type safe fadafb83cf
  16. MarcoFalke force-pushed on Mar 10, 2020
  17. refactor: move DUMP_BANS_INTERVAL to banman.h fa36f3a295
  18. MarcoFalke commented at 1:59 PM on March 10, 2020: member

    Addressed feedback by @vasild about the doxygen comment and feedback by @promag about the lambda stylistic syntax rewording. Also, added a commit to move the banman contstant to banman.

  19. vasild commented at 2:35 PM on March 10, 2020: member

    ACK fa36f3a (code review, not tested)

  20. DrahtBot commented at 11:31 PM on March 12, 2020: member

    <!--e57a25ab6845829454e8d69fc972939a-->

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

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #17383 (Refactor: Move consts to their correct translation units by jnewbery)

    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.

  21. ajtowns commented at 8:42 AM on March 13, 2020: member

    ACK fa36f3a29538012a6eb5c3402b3b3c18fd32b230

  22. in src/banman.h:19 in fa36f3a295
      17 | +#include <cstdint>
      18 | +#include <memory>
      19 | +
      20 |  // NOTE: When adjusting this, update rpcnet:setban's help ("24h")
      21 |  static constexpr unsigned int DEFAULT_MISBEHAVING_BANTIME = 60 * 60 * 24; // Default 24-hour ban
      22 | +// How often to dump addresses to banlist.dat
    


    jonatack commented at 6:06 PM on March 14, 2020:

    Would this be better as a Doxygen comment?


    MarcoFalke commented at 6:21 PM on March 16, 2020:

    Yes, but leaving as is for now

  23. in src/scheduler.h:60 in fa36f3a295
      63 | +    /**
      64 | +     * Repeat f until the scheduler is stopped. First run is after delta has passed once.
      65 | +     *
      66 | +     * The timing is not exact: Every time f is finished, it is rescheduled to run again after delta. If you need more
      67 | +     * accurate scheduling, don't use this method.
      68 | +     */
    


    jonatack commented at 6:15 PM on March 14, 2020:

    suggestion:

        /**
         * Repeat f indefinitely until the scheduler is stopped. The first run
         * occurs after delta time.
         *
         * The timing is not exact; every time f finishes, it is scheduled again
         * to run delta time later. If you need more accurate scheduling, don't
         * use this method.
         */
    

    MarcoFalke commented at 6:21 PM on March 16, 2020:

    might take, if I have to force push for other reasons

  24. jonatack commented at 6:17 PM on March 14, 2020: member

    ACK fa36f3a

    A couple of comments if you retouch.

  25. vasild approved
  26. MarcoFalke merged this on Mar 17, 2020
  27. MarcoFalke closed this on Mar 17, 2020

  28. MarcoFalke deleted the branch on Mar 17, 2020
  29. sidhujag referenced this in commit b6a01a68c8 on Mar 18, 2020
  30. in src/net_processing.cpp:1127 in fa36f3a295
    1123 | @@ -1124,7 +1124,7 @@ PeerLogicValidation::PeerLogicValidation(CConnman* connmanIn, BanMan* banman, CS
    1124 |      // combine them in one function and schedule at the quicker (peer-eviction)
    1125 |      // timer.
    1126 |      static_assert(EXTRA_PEER_CHECK_INTERVAL < STALE_CHECK_INTERVAL, "peer eviction timer should be less than stale tip check timer");
    1127 | -    scheduler.scheduleEvery(std::bind(&PeerLogicValidation::CheckForStaleTipAndEvictPeers, this, consensusParams), EXTRA_PEER_CHECK_INTERVAL * 1000);
    1128 | +    scheduler.scheduleEvery([&] { this->CheckForStaleTipAndEvictPeers(consensusParams); }, std::chrono::seconds{EXTRA_PEER_CHECK_INTERVAL});
    


    MarcoFalke commented at 1:37 PM on March 18, 2020:

    The referenced global consensusParams can change in tests, so it needs to be copied. Fixed in #18376

  31. deadalnix referenced this in commit ed2f9c673f on Jun 29, 2020
  32. sidhujag referenced this in commit 2ff10895d5 on Nov 10, 2020
  33. DrahtBot locked this on Feb 15, 2022

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-15 15:14 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me