scoped_blocking_call.h 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_THREADING_SCOPED_BLOCKING_CALL_H
  5. #define BASE_THREADING_SCOPED_BLOCKING_CALL_H
  6. #include "base/base_export.h"
  7. #include "base/callback_forward.h"
  8. #include "base/location.h"
  9. #include "base/strings/string_piece.h"
  10. #include "base/threading/scoped_blocking_call_internal.h"
  11. namespace base {
  12. // A "blocking call" refers to any call that causes the calling thread to wait
  13. // off-CPU. It includes but is not limited to calls that wait on synchronous
  14. // file I/O operations: read or write a file from disk, interact with a pipe or
  15. // a socket, rename or delete a file, enumerate files in a directory, etc.
  16. // Acquiring a low contention lock is not considered a blocking call.
  17. // BlockingType indicates the likelihood that a blocking call will actually
  18. // block.
  19. enum class BlockingType {
  20. // The call might block (e.g. file I/O that might hit in memory cache).
  21. MAY_BLOCK,
  22. // The call will definitely block (e.g. cache already checked and now pinging
  23. // server synchronously).
  24. WILL_BLOCK
  25. };
  26. // This class must be instantiated in every scope where a blocking call is made
  27. // and serves as a precise annotation of the scope that may/will block for the
  28. // scheduler. When a ScopedBlockingCall is instantiated, it asserts that
  29. // blocking calls are allowed in its scope with a call to
  30. // base::AssertBlockingAllowed(). CPU usage should be minimal within that scope.
  31. // //base APIs that block instantiate their own ScopedBlockingCall; it is not
  32. // necessary to instantiate another ScopedBlockingCall in the scope where these
  33. // APIs are used. Nested ScopedBlockingCalls are supported (mostly a no-op
  34. // except for WILL_BLOCK nested within MAY_BLOCK which will result in immediate
  35. // WILL_BLOCK semantics).
  36. //
  37. // Good:
  38. // Data data;
  39. // {
  40. // ScopedBlockingCall scoped_blocking_call(
  41. // FROM_HERE, BlockingType::WILL_BLOCK);
  42. // data = GetDataFromNetwork();
  43. // }
  44. // CPUIntensiveProcessing(data);
  45. //
  46. // Bad:
  47. // ScopedBlockingCall scoped_blocking_call(FROM_HERE,
  48. // BlockingType::WILL_BLOCK);
  49. // Data data = GetDataFromNetwork();
  50. // CPUIntensiveProcessing(data); // CPU usage within a ScopedBlockingCall.
  51. //
  52. // Good:
  53. // Data a;
  54. // Data b;
  55. // {
  56. // ScopedBlockingCall scoped_blocking_call(
  57. // FROM_HERE, BlockingType::MAY_BLOCK);
  58. // a = GetDataFromMemoryCacheOrNetwork();
  59. // b = GetDataFromMemoryCacheOrNetwork();
  60. // }
  61. // CPUIntensiveProcessing(a);
  62. // CPUIntensiveProcessing(b);
  63. //
  64. // Bad:
  65. // ScopedBlockingCall scoped_blocking_call(
  66. // FROM_HERE, BlockingType::MAY_BLOCK);
  67. // Data a = GetDataFromMemoryCacheOrNetwork();
  68. // Data b = GetDataFromMemoryCacheOrNetwork();
  69. // CPUIntensiveProcessing(a); // CPU usage within a ScopedBlockingCall.
  70. // CPUIntensiveProcessing(b); // CPU usage within a ScopedBlockingCall.
  71. //
  72. // Good:
  73. // base::WaitableEvent waitable_event(...);
  74. // waitable_event.Wait();
  75. //
  76. // Bad:
  77. // base::WaitableEvent waitable_event(...);
  78. // ScopedBlockingCall scoped_blocking_call(
  79. // FROM_HERE, BlockingType::WILL_BLOCK);
  80. // waitable_event.Wait(); // Wait() instantiates its own ScopedBlockingCall.
  81. //
  82. // When a ScopedBlockingCall is instantiated from a ThreadPool parallel or
  83. // sequenced task, the thread pool size is incremented to compensate for the
  84. // blocked thread (more or less aggressively depending on BlockingType).
  85. class BASE_EXPORT ScopedBlockingCall
  86. : public internal::UncheckedScopedBlockingCall {
  87. public:
  88. ScopedBlockingCall(const Location& from_here, BlockingType blocking_type);
  89. ~ScopedBlockingCall();
  90. };
  91. // Usage reserved for //base callers.
  92. namespace internal {
  93. // This class must be instantiated in every scope where a sync primitive is
  94. // used. When a ScopedBlockingCallWithBaseSyncPrimitives is instantiated, it
  95. // asserts that sync primitives are allowed in its scope with a call to
  96. // internal::AssertBaseSyncPrimitivesAllowed(). The same guidelines as for
  97. // ScopedBlockingCall should be followed.
  98. class BASE_EXPORT ScopedBlockingCallWithBaseSyncPrimitives
  99. : public UncheckedScopedBlockingCall {
  100. public:
  101. ScopedBlockingCallWithBaseSyncPrimitives(const Location& from_here,
  102. BlockingType blocking_type);
  103. ~ScopedBlockingCallWithBaseSyncPrimitives();
  104. };
  105. } // namespace internal
  106. using IOJankReportingCallback =
  107. RepeatingCallback<void(int janky_intervals_per_minute,
  108. int total_janks_per_minute)>;
  109. // Enables IO jank monitoring and reporting for this process. Should be called
  110. // at most once per process and only if
  111. // base::TimeTicks::IsConsistentAcrossProcesses() (the algorithm is unsafe
  112. // otherwise). |reporting_callback| will be invoked each time a monitoring
  113. // window completes, see internal::~IOJankMonitoringWindow() for details (must
  114. // be thread-safe).
  115. void BASE_EXPORT
  116. EnableIOJankMonitoringForProcess(IOJankReportingCallback reporting_callback);
  117. } // namespace base
  118. #endif // BASE_THREADING_SCOPED_BLOCKING_CALL_H