123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- // Copyright 2017 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #ifndef BASE_THREADING_SCOPED_BLOCKING_CALL_H
- #define BASE_THREADING_SCOPED_BLOCKING_CALL_H
- #include "base/base_export.h"
- #include "base/callback_forward.h"
- #include "base/location.h"
- #include "base/strings/string_piece.h"
- #include "base/threading/scoped_blocking_call_internal.h"
- namespace base {
- // A "blocking call" refers to any call that causes the calling thread to wait
- // off-CPU. It includes but is not limited to calls that wait on synchronous
- // file I/O operations: read or write a file from disk, interact with a pipe or
- // a socket, rename or delete a file, enumerate files in a directory, etc.
- // Acquiring a low contention lock is not considered a blocking call.
- // BlockingType indicates the likelihood that a blocking call will actually
- // block.
- enum class BlockingType {
- // The call might block (e.g. file I/O that might hit in memory cache).
- MAY_BLOCK,
- // The call will definitely block (e.g. cache already checked and now pinging
- // server synchronously).
- WILL_BLOCK
- };
- // This class must be instantiated in every scope where a blocking call is made
- // and serves as a precise annotation of the scope that may/will block for the
- // scheduler. When a ScopedBlockingCall is instantiated, it asserts that
- // blocking calls are allowed in its scope with a call to
- // base::AssertBlockingAllowed(). CPU usage should be minimal within that scope.
- // //base APIs that block instantiate their own ScopedBlockingCall; it is not
- // necessary to instantiate another ScopedBlockingCall in the scope where these
- // APIs are used. Nested ScopedBlockingCalls are supported (mostly a no-op
- // except for WILL_BLOCK nested within MAY_BLOCK which will result in immediate
- // WILL_BLOCK semantics).
- //
- // Good:
- // Data data;
- // {
- // ScopedBlockingCall scoped_blocking_call(
- // FROM_HERE, BlockingType::WILL_BLOCK);
- // data = GetDataFromNetwork();
- // }
- // CPUIntensiveProcessing(data);
- //
- // Bad:
- // ScopedBlockingCall scoped_blocking_call(FROM_HERE,
- // BlockingType::WILL_BLOCK);
- // Data data = GetDataFromNetwork();
- // CPUIntensiveProcessing(data); // CPU usage within a ScopedBlockingCall.
- //
- // Good:
- // Data a;
- // Data b;
- // {
- // ScopedBlockingCall scoped_blocking_call(
- // FROM_HERE, BlockingType::MAY_BLOCK);
- // a = GetDataFromMemoryCacheOrNetwork();
- // b = GetDataFromMemoryCacheOrNetwork();
- // }
- // CPUIntensiveProcessing(a);
- // CPUIntensiveProcessing(b);
- //
- // Bad:
- // ScopedBlockingCall scoped_blocking_call(
- // FROM_HERE, BlockingType::MAY_BLOCK);
- // Data a = GetDataFromMemoryCacheOrNetwork();
- // Data b = GetDataFromMemoryCacheOrNetwork();
- // CPUIntensiveProcessing(a); // CPU usage within a ScopedBlockingCall.
- // CPUIntensiveProcessing(b); // CPU usage within a ScopedBlockingCall.
- //
- // Good:
- // base::WaitableEvent waitable_event(...);
- // waitable_event.Wait();
- //
- // Bad:
- // base::WaitableEvent waitable_event(...);
- // ScopedBlockingCall scoped_blocking_call(
- // FROM_HERE, BlockingType::WILL_BLOCK);
- // waitable_event.Wait(); // Wait() instantiates its own ScopedBlockingCall.
- //
- // When a ScopedBlockingCall is instantiated from a ThreadPool parallel or
- // sequenced task, the thread pool size is incremented to compensate for the
- // blocked thread (more or less aggressively depending on BlockingType).
- class BASE_EXPORT ScopedBlockingCall
- : public internal::UncheckedScopedBlockingCall {
- public:
- ScopedBlockingCall(const Location& from_here, BlockingType blocking_type);
- ~ScopedBlockingCall();
- };
- // Usage reserved for //base callers.
- namespace internal {
- // This class must be instantiated in every scope where a sync primitive is
- // used. When a ScopedBlockingCallWithBaseSyncPrimitives is instantiated, it
- // asserts that sync primitives are allowed in its scope with a call to
- // internal::AssertBaseSyncPrimitivesAllowed(). The same guidelines as for
- // ScopedBlockingCall should be followed.
- class BASE_EXPORT ScopedBlockingCallWithBaseSyncPrimitives
- : public UncheckedScopedBlockingCall {
- public:
- ScopedBlockingCallWithBaseSyncPrimitives(const Location& from_here,
- BlockingType blocking_type);
- ~ScopedBlockingCallWithBaseSyncPrimitives();
- };
- } // namespace internal
- using IOJankReportingCallback =
- RepeatingCallback<void(int janky_intervals_per_minute,
- int total_janks_per_minute)>;
- // Enables IO jank monitoring and reporting for this process. Should be called
- // at most once per process and only if
- // base::TimeTicks::IsConsistentAcrossProcesses() (the algorithm is unsafe
- // otherwise). |reporting_callback| will be invoked each time a monitoring
- // window completes, see internal::~IOJankMonitoringWindow() for details (must
- // be thread-safe).
- void BASE_EXPORT
- EnableIOJankMonitoringForProcess(IOJankReportingCallback reporting_callback);
- } // namespace base
- #endif // BASE_THREADING_SCOPED_BLOCKING_CALL_H
|