xref: /aosp_15_r20/external/cronet/base/message_loop/work_id_provider.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2019 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "base/message_loop/work_id_provider.h"
6 
7 #include <memory>
8 
9 #include "base/memory/ptr_util.h"
10 #include "base/no_destructor.h"
11 #include "base/threading/thread_local.h"
12 
13 namespace base {
14 
15 // static
GetForCurrentThread()16 WorkIdProvider* WorkIdProvider::GetForCurrentThread() {
17   static NoDestructor<ThreadLocalOwnedPointer<WorkIdProvider>> instance;
18   if (!instance->Get())
19     instance->Set(WrapUnique(new WorkIdProvider));
20   return instance->Get();
21 }
22 
23 // This function must support being invoked while other threads are suspended so
24 // must not take any locks, including indirectly through use of heap allocation,
25 // LOG, CHECK, or DCHECK.
GetWorkId()26 unsigned int WorkIdProvider::GetWorkId() {
27   return work_id_.load(std::memory_order_acquire);
28 }
29 
30 WorkIdProvider::~WorkIdProvider() = default;
31 
SetCurrentWorkIdForTesting(unsigned int id)32 void WorkIdProvider::SetCurrentWorkIdForTesting(unsigned int id) {
33   work_id_.store(id, std::memory_order_relaxed);
34 }
35 
IncrementWorkIdForTesting()36 void WorkIdProvider::IncrementWorkIdForTesting() {
37   IncrementWorkId();
38 }
39 
WorkIdProvider()40 WorkIdProvider::WorkIdProvider() : work_id_(0) {}
41 
IncrementWorkId()42 void WorkIdProvider::IncrementWorkId() {
43   DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
44 
45   unsigned int next_id = work_id_.load(std::memory_order_relaxed) + 1;
46   // Reserve 0 to mean no work items have been executed.
47   if (next_id == 0)
48     ++next_id;
49   // Release order ensures this state is visible to other threads prior to the
50   // following task/event execution.
51   work_id_.store(next_id, std::memory_order_release);
52 }
53 
54 }  // namespace base
55