Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /base /lazy_instance_helpers.cc
blob: 4d206dd091828849194ab18ac3e2140d52a2f061 [file] [log] [blame]
Avi Drissmane4622aa2022-09-08 20:36:06[diff] [blame]1// Copyright 2018 The Chromium Authors
deanm@google.com30039e62008-09-08 14:11:13[diff] [blame]2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Gabriel Charettef297f012018-01-17 20:59:07[diff] [blame]5#include"base/lazy_instance_helpers.h"
deanm@google.com30039e62008-09-08 14:11:13[diff] [blame]6
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]7#include<atomic>
8
deanm@google.com30039e62008-09-08 14:11:13[diff] [blame]9#include"base/at_exit.h"
brettw@chromium.orgce072a72010-12-31 20:02:16[diff] [blame]10#include"base/threading/platform_thread.h"
deanm@google.com30039e62008-09-08 14:11:13[diff] [blame]11
Peter Kasting811504a72025-01-09 03:18:50[diff] [blame]12namespace base::internal{
deanm@google.com30039e62008-09-08 14:11:13[diff] [blame]13
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]14boolNeedsLazyInstance(std::atomic<uintptr_t>& state){
joth@chromium.org6de0fd1d2011-11-15 13:31:49[diff] [blame]15// Try to create the instance, if we're the first, will go from 0 to
16// kLazyInstanceStateCreating, otherwise we've already been beaten here.
17// The memory access has no memory ordering as state 0 and
18// kLazyInstanceStateCreating have no associated data (memory barriers are
19// all about ordering of memory accesses to *associated* data).
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]20uintptr_t expected=0;
21if(state.compare_exchange_strong(expected, kLazyInstanceStateCreating,
22 std::memory_order_relaxed,
23 std::memory_order_relaxed)){
craig.schlenter@chromium.orgc1aeaac2010-03-12 15:28:48[diff] [blame]24// Caller must create instance
25returntrue;
Gabriel Charettef297f012018-01-17 20:59:07[diff] [blame]26}
dvyukov@google.com1b651d52011-05-16 15:01:54[diff] [blame]27
28// It's either in the process of being created, or already created. Spin.
29// The load has acquire memory ordering as a thread which sees
30// state_ == STATE_CREATED needs to acquire visibility over
31// the associated data (buf_). Pairing Release_Store is in
joth@chromium.org6de0fd1d2011-11-15 13:31:49[diff] [blame]32// CompleteLazyInstance().
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]33if(state.load(std::memory_order_acquire)== kLazyInstanceStateCreating){
Francois Doray94a0386f2018-01-23 14:18:46[diff] [blame]34const base::TimeTicks start= base::TimeTicks::Now();
Bruce Dawsoncdf5fae2018-01-05 22:12:49[diff] [blame]35do{
Francois Doray94a0386f2018-01-23 14:18:46[diff] [blame]36const base::TimeDelta elapsed= base::TimeTicks::Now()- start;
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]37// Spin with YieldCurrentThread for at most one ms - this ensures
38// maximum responsiveness. After that spin with Sleep(1ms) so that we
39// don't burn excessive CPU time - this also avoids infinite loops due
40// to priority inversions (https://crbug.com/797129).
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]41if(elapsed<Milliseconds(1)){
Bruce Dawsoncdf5fae2018-01-05 22:12:49[diff] [blame]42PlatformThread::YieldCurrentThread();
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]43}else{
Peter Kasting53fd6ee2021-10-05 20:40:48[diff] [blame]44PlatformThread::Sleep(Milliseconds(1));
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]45}
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]46}while(state.load(std::memory_order_acquire)==
47 kLazyInstanceStateCreating);
joth@chromium.org6de0fd1d2011-11-15 13:31:49[diff] [blame]48}
craig.schlenter@chromium.orgc1aeaac2010-03-12 15:28:48[diff] [blame]49// Someone else created the instance.
50returnfalse;
51}
52
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]53voidCompleteLazyInstance(std::atomic<uintptr_t>& state,
54uintptr_t new_instance,
Francois Doraya50035b2017-06-12 17:55:50[diff] [blame]55void(*destructor)(void*),
56void* destructor_arg){
Gabriel Charettef297f012018-01-17 20:59:07[diff] [blame]57// Instance is created, go from CREATING to CREATED (or reset it if
58// |new_instance| is null). Releases visibility over |private_buf_| to
59// readers. Pairing Acquire_Load is in NeedsLazyInstance().
Benoit Lizeb82171a62022-06-17 13:37:58[diff] [blame]60 state.store(new_instance, std::memory_order_release);
craig.schlenter@chromium.orgc1aeaac2010-03-12 15:28:48[diff] [blame]61
craig.schlenter@chromium.orgc1aeaac2010-03-12 15:28:48[diff] [blame]62// Make sure that the lazily instantiated object will get destroyed at exit.
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]63if(new_instance&& destructor){
Francois Doraya50035b2017-06-12 17:55:50[diff] [blame]64AtExitManager::RegisterCallback(destructor, destructor_arg);
Peter Kasting134ef9af2024-12-28 02:30:09[diff] [blame]65}
deanm@google.com30039e62008-09-08 14:11:13[diff] [blame]66}
67
Peter Kasting811504a72025-01-09 03:18:50[diff] [blame]68}// namespace base::internal

[8]ページ先頭

©2009-2025 Movatter.jp