Coverage Report

Created: 2017-10-03 07:32

/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Support/ManagedStatic.cpp
Line
Count
Source
1
//===-- ManagedStatic.cpp - Static Global wrapper -------------------------===//
2
//
3
//                     The LLVM Compiler Infrastructure
4
//
5
// This file is distributed under the University of Illinois Open Source
6
// License. See LICENSE.TXT for details.
7
//
8
//===----------------------------------------------------------------------===//
9
//
10
// This file implements the ManagedStatic class and llvm_shutdown().
11
//
12
//===----------------------------------------------------------------------===//
13
14
#include "llvm/Support/ManagedStatic.h"
15
#include "llvm/Config/config.h"
16
#include "llvm/Support/Mutex.h"
17
#include "llvm/Support/MutexGuard.h"
18
#include "llvm/Support/Threading.h"
19
#include <cassert>
20
using namespace llvm;
21
22
static const ManagedStaticBase *StaticList = nullptr;
23
static sys::Mutex *ManagedStaticMutex = nullptr;
24
static llvm::once_flag mutex_init_flag;
25
26
110k
static void initializeMutex() {
27
110k
  ManagedStaticMutex = new sys::Mutex();
28
110k
}
29
30
1.26M
static sys::Mutex* getManagedStaticMutex() {
31
1.26M
  // We need to use a function local static here, since this can get called
32
1.26M
  // during a static constructor and we need to guarantee that it's initialized
33
1.26M
  // correctly.
34
1.26M
  llvm::call_once(mutex_init_flag, initializeMutex);
35
1.26M
  return ManagedStaticMutex;
36
1.26M
}
37
38
void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(),
39
1.16M
                                              void (*Deleter)(void*)) const {
40
1.16M
  assert(Creator);
41
1.16M
  if (
llvm_is_multithreaded()1.16M
) {
42
1.16M
    MutexGuard Lock(*getManagedStaticMutex());
43
1.16M
44
1.16M
    if (
!Ptr.load(std::memory_order_relaxed)1.16M
) {
45
1.16M
      void *Tmp = Creator();
46
1.16M
47
1.16M
      Ptr.store(Tmp, std::memory_order_release);
48
1.16M
      DeleterFn = Deleter;
49
1.16M
      
50
1.16M
      // Add to list of managed statics.
51
1.16M
      Next = StaticList;
52
1.16M
      StaticList = this;
53
1.16M
    }
54
1.16M
  } else {
55
18.4E
    assert(!Ptr && !DeleterFn && !Next &&
56
18.4E
           "Partially initialized ManagedStatic!?");
57
18.4E
    Ptr = Creator();
58
18.4E
    DeleterFn = Deleter;
59
18.4E
  
60
18.4E
    // Add to list of managed statics.
61
18.4E
    Next = StaticList;
62
18.4E
    StaticList = this;
63
18.4E
  }
64
1.16M
}
65
66
1.10M
void ManagedStaticBase::destroy() const {
67
1.10M
  assert(DeleterFn && "ManagedStatic not initialized correctly!");
68
1.10M
  assert(StaticList == this &&
69
1.10M
         "Not destroyed in reverse order of construction?");
70
1.10M
  // Unlink from list.
71
1.10M
  StaticList = Next;
72
1.10M
  Next = nullptr;
73
1.10M
74
1.10M
  // Destroy memory.
75
1.10M
  DeleterFn(Ptr);
76
1.10M
  
77
1.10M
  // Cleanup.
78
1.10M
  Ptr = nullptr;
79
1.10M
  DeleterFn = nullptr;
80
1.10M
}
81
82
/// llvm_shutdown - Deallocate and destroy all ManagedStatic variables.
83
101k
void llvm::llvm_shutdown() {
84
101k
  MutexGuard Lock(*getManagedStaticMutex());
85
101k
86
1.20M
  while (StaticList)
87
1.10M
    StaticList->destroy();
88
101k
}