YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/gutil/once.cc
Line
Count
Source (jump to first uncovered line)
1
// Copyright 2008 Google Inc. All Rights Reserved.
2
//
3
// The following only applies to changes made to this file as part of YugaByte development.
4
//
5
// Portions Copyright (c) YugaByte, Inc.
6
//
7
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
8
// in compliance with the License.  You may obtain a copy of the License at
9
//
10
// http://www.apache.org/licenses/LICENSE-2.0
11
//
12
// Unless required by applicable law or agreed to in writing, software distributed under the License
13
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
14
// or implied.  See the License for the specific language governing permissions and limitations
15
// under the License.
16
//
17
18
#include <glog/logging.h>
19
#include "yb/gutil/logging-inl.h"
20
#include "yb/gutil/once.h"
21
#include "yb/gutil/dynamic_annotations.h"
22
#include "yb/gutil/spinlock_internal.h"
23
24
// All modifications to a GoogleOnceType occur inside GoogleOnceInternalInit.
25
// The fast path reads the variable with an acquire-load..
26
// This is safe provided we always perform a memory barrier
27
// immediately before setting the value to GOOGLE_ONCE_INTERNAL_DONE.
28
29
void GoogleOnceInternalInit(Atomic32 *control, void (*func)(),
30
206k
                            void (*func_with_arg)(void*), void* arg) {
31
206k
  if (DEBUG_MODE) {
32
206k
    int64 old_control = base::subtle::Acquire_Load(control);
33
206k
    if (old_control != GOOGLE_ONCE_INTERNAL_INIT &&
34
206k
        
old_control != GOOGLE_ONCE_INTERNAL_RUNNING1.94k
&&
35
206k
        
old_control != GOOGLE_ONCE_INTERNAL_WAITER820
&&
36
206k
        
old_control != GOOGLE_ONCE_INTERNAL_DONE65
) {
37
0
      LOG(FATAL) << "Either GoogleOnceType is used in non-static storage "
38
0
                    "(where GoogleOnceDynamic might be appropriate), "
39
0
                    "or there's a memory corruption.";
40
0
    }
41
206k
  }
42
206k
  static const yb::base::internal::SpinLockWaitTransition trans[] = {
43
206k
    { GOOGLE_ONCE_INTERNAL_INIT, GOOGLE_ONCE_INTERNAL_RUNNING, true },
44
206k
    { GOOGLE_ONCE_INTERNAL_RUNNING, GOOGLE_ONCE_INTERNAL_WAITER, false },
45
206k
    { GOOGLE_ONCE_INTERNAL_DONE, GOOGLE_ONCE_INTERNAL_DONE, true }
46
206k
  };
47
  // Short circuit the simplest case to avoid procedure call overhead.
48
206k
  if (::base::subtle::Acquire_CompareAndSwap(control, GOOGLE_ONCE_INTERNAL_INIT,
49
206k
          GOOGLE_ONCE_INTERNAL_RUNNING) == GOOGLE_ONCE_INTERNAL_INIT ||
50
206k
      
yb::base::internal::SpinLockWait(control, 4.62k
ARRAYSIZE4.62k
(trans), trans) ==
51
202k
      GOOGLE_ONCE_INTERNAL_INIT) {
52
202k
    if (func != nullptr) {
53
202k
      (*func)();
54
202k
    } else {
55
3
      (*func_with_arg)(arg);
56
3
    }
57
202k
    ANNOTATE_HAPPENS_BEFORE(control);
58
202k
    int64 old_control = base::subtle::NoBarrier_Load(control);
59
202k
    ::base::subtle::Release_Store(control, GOOGLE_ONCE_INTERNAL_DONE);
60
202k
    if (old_control == GOOGLE_ONCE_INTERNAL_WAITER) {
61
2.06k
      yb::base::internal::SpinLockWake(control, true);
62
2.06k
    }
63
202k
  } // else *control is already GOOGLE_ONCE_INTERNAL_DONE
64
206k
}