1353944Sdim//===-- tsan_stat.cpp -----------------------------------------------------===//
2353944Sdim//
3353944Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353944Sdim// See https://llvm.org/LICENSE.txt for license information.
5353944Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353944Sdim//
7353944Sdim//===----------------------------------------------------------------------===//
8353944Sdim//
9353944Sdim// This file is a part of ThreadSanitizer (TSan), a race detector.
10353944Sdim//
11353944Sdim//===----------------------------------------------------------------------===//
12353944Sdim#include "tsan_stat.h"
13353944Sdim#include "tsan_rtl.h"
14353944Sdim
15353944Sdimnamespace __tsan {
16353944Sdim
17353944Sdim#if TSAN_COLLECT_STATS
18353944Sdim
19353944Sdimvoid StatAggregate(u64 *dst, u64 *src) {
20353944Sdim  for (int i = 0; i < StatCnt; i++)
21353944Sdim    dst[i] += src[i];
22353944Sdim}
23353944Sdim
24353944Sdimvoid StatOutput(u64 *stat) {
25353944Sdim  stat[StatShadowNonZero] = stat[StatShadowProcessed] - stat[StatShadowZero];
26353944Sdim
27353944Sdim  static const char *name[StatCnt] = {};
28353944Sdim  name[StatMop]                          = "Memory accesses                   ";
29353944Sdim  name[StatMopRead]                      = "  Including reads                 ";
30353944Sdim  name[StatMopWrite]                     = "            writes                ";
31353944Sdim  name[StatMop1]                         = "  Including size 1                ";
32353944Sdim  name[StatMop2]                         = "            size 2                ";
33353944Sdim  name[StatMop4]                         = "            size 4                ";
34353944Sdim  name[StatMop8]                         = "            size 8                ";
35353944Sdim  name[StatMopSame]                      = "  Including same                  ";
36353944Sdim  name[StatMopIgnored]                   = "  Including ignored               ";
37353944Sdim  name[StatMopRange]                     = "  Including range                 ";
38353944Sdim  name[StatMopRodata]                    = "  Including .rodata               ";
39353944Sdim  name[StatMopRangeRodata]               = "  Including .rodata range         ";
40353944Sdim  name[StatShadowProcessed]              = "Shadow processed                  ";
41353944Sdim  name[StatShadowZero]                   = "  Including empty                 ";
42353944Sdim  name[StatShadowNonZero]                = "  Including non empty             ";
43353944Sdim  name[StatShadowSameSize]               = "  Including same size             ";
44353944Sdim  name[StatShadowIntersect]              = "            intersect             ";
45353944Sdim  name[StatShadowNotIntersect]           = "            not intersect         ";
46353944Sdim  name[StatShadowSameThread]             = "  Including same thread           ";
47353944Sdim  name[StatShadowAnotherThread]          = "            another thread        ";
48353944Sdim  name[StatShadowReplace]                = "  Including evicted               ";
49353944Sdim
50353944Sdim  name[StatFuncEnter]                    = "Function entries                  ";
51353944Sdim  name[StatFuncExit]                     = "Function exits                    ";
52353944Sdim  name[StatEvents]                       = "Events collected                  ";
53353944Sdim
54353944Sdim  name[StatThreadCreate]                 = "Total threads created             ";
55353944Sdim  name[StatThreadFinish]                 = "  threads finished                ";
56353944Sdim  name[StatThreadReuse]                  = "  threads reused                  ";
57353944Sdim  name[StatThreadMaxTid]                 = "  max tid                         ";
58353944Sdim  name[StatThreadMaxAlive]               = "  max alive threads               ";
59353944Sdim
60353944Sdim  name[StatMutexCreate]                  = "Mutexes created                   ";
61353944Sdim  name[StatMutexDestroy]                 = "  destroyed                       ";
62353944Sdim  name[StatMutexLock]                    = "  lock                            ";
63353944Sdim  name[StatMutexUnlock]                  = "  unlock                          ";
64353944Sdim  name[StatMutexRecLock]                 = "  recursive lock                  ";
65353944Sdim  name[StatMutexRecUnlock]               = "  recursive unlock                ";
66353944Sdim  name[StatMutexReadLock]                = "  read lock                       ";
67353944Sdim  name[StatMutexReadUnlock]              = "  read unlock                     ";
68353944Sdim
69353944Sdim  name[StatSyncCreated]                  = "Sync objects created              ";
70353944Sdim  name[StatSyncDestroyed]                = "             destroyed            ";
71353944Sdim  name[StatSyncAcquire]                  = "             acquired             ";
72353944Sdim  name[StatSyncRelease]                  = "             released             ";
73353944Sdim
74353944Sdim  name[StatClockAcquire]                 = "Clock acquire                     ";
75353944Sdim  name[StatClockAcquireEmpty]            = "  empty clock                     ";
76353944Sdim  name[StatClockAcquireFastRelease]      = "  fast from release-store         ";
77353944Sdim  name[StatClockAcquireFull]             = "  full (slow)                     ";
78353944Sdim  name[StatClockAcquiredSomething]       = "  acquired something              ";
79353944Sdim  name[StatClockRelease]                 = "Clock release                     ";
80353944Sdim  name[StatClockReleaseResize]           = "  resize                          ";
81353944Sdim  name[StatClockReleaseFast]             = "  fast                            ";
82353944Sdim  name[StatClockReleaseSlow]             = "  dirty overflow (slow)           ";
83353944Sdim  name[StatClockReleaseFull]             = "  full (slow)                     ";
84353944Sdim  name[StatClockReleaseAcquired]         = "  was acquired                    ";
85353944Sdim  name[StatClockReleaseClearTail]        = "  clear tail                      ";
86353944Sdim  name[StatClockStore]                   = "Clock release store               ";
87353944Sdim  name[StatClockStoreResize]             = "  resize                          ";
88353944Sdim  name[StatClockStoreFast]               = "  fast                            ";
89353944Sdim  name[StatClockStoreFull]               = "  slow                            ";
90353944Sdim  name[StatClockStoreTail]               = "  clear tail                      ";
91353944Sdim  name[StatClockAcquireRelease]          = "Clock acquire-release             ";
92353944Sdim
93353944Sdim  name[StatAtomic]                       = "Atomic operations                 ";
94353944Sdim  name[StatAtomicLoad]                   = "  Including load                  ";
95353944Sdim  name[StatAtomicStore]                  = "            store                 ";
96353944Sdim  name[StatAtomicExchange]               = "            exchange              ";
97353944Sdim  name[StatAtomicFetchAdd]               = "            fetch_add             ";
98353944Sdim  name[StatAtomicFetchSub]               = "            fetch_sub             ";
99353944Sdim  name[StatAtomicFetchAnd]               = "            fetch_and             ";
100353944Sdim  name[StatAtomicFetchOr]                = "            fetch_or              ";
101353944Sdim  name[StatAtomicFetchXor]               = "            fetch_xor             ";
102353944Sdim  name[StatAtomicFetchNand]              = "            fetch_nand            ";
103353944Sdim  name[StatAtomicCAS]                    = "            compare_exchange      ";
104353944Sdim  name[StatAtomicFence]                  = "            fence                 ";
105353944Sdim  name[StatAtomicRelaxed]                = "  Including relaxed               ";
106353944Sdim  name[StatAtomicConsume]                = "            consume               ";
107353944Sdim  name[StatAtomicAcquire]                = "            acquire               ";
108353944Sdim  name[StatAtomicRelease]                = "            release               ";
109353944Sdim  name[StatAtomicAcq_Rel]                = "            acq_rel               ";
110353944Sdim  name[StatAtomicSeq_Cst]                = "            seq_cst               ";
111353944Sdim  name[StatAtomic1]                      = "  Including size 1                ";
112353944Sdim  name[StatAtomic2]                      = "            size 2                ";
113353944Sdim  name[StatAtomic4]                      = "            size 4                ";
114353944Sdim  name[StatAtomic8]                      = "            size 8                ";
115353944Sdim  name[StatAtomic16]                     = "            size 16               ";
116353944Sdim
117353944Sdim  name[StatAnnotation]                   = "Dynamic annotations               ";
118353944Sdim  name[StatAnnotateHappensBefore]        = "  HappensBefore                   ";
119353944Sdim  name[StatAnnotateHappensAfter]         = "  HappensAfter                    ";
120353944Sdim  name[StatAnnotateCondVarSignal]        = "  CondVarSignal                   ";
121353944Sdim  name[StatAnnotateCondVarSignalAll]     = "  CondVarSignalAll                ";
122353944Sdim  name[StatAnnotateMutexIsNotPHB]        = "  MutexIsNotPHB                   ";
123353944Sdim  name[StatAnnotateCondVarWait]          = "  CondVarWait                     ";
124353944Sdim  name[StatAnnotateRWLockCreate]         = "  RWLockCreate                    ";
125353944Sdim  name[StatAnnotateRWLockCreateStatic]   = "  StatAnnotateRWLockCreateStatic  ";
126353944Sdim  name[StatAnnotateRWLockDestroy]        = "  RWLockDestroy                   ";
127353944Sdim  name[StatAnnotateRWLockAcquired]       = "  RWLockAcquired                  ";
128353944Sdim  name[StatAnnotateRWLockReleased]       = "  RWLockReleased                  ";
129353944Sdim  name[StatAnnotateTraceMemory]          = "  TraceMemory                     ";
130353944Sdim  name[StatAnnotateFlushState]           = "  FlushState                      ";
131353944Sdim  name[StatAnnotateNewMemory]            = "  NewMemory                       ";
132353944Sdim  name[StatAnnotateNoOp]                 = "  NoOp                            ";
133353944Sdim  name[StatAnnotateFlushExpectedRaces]   = "  FlushExpectedRaces              ";
134353944Sdim  name[StatAnnotateEnableRaceDetection]  = "  EnableRaceDetection             ";
135353944Sdim  name[StatAnnotateMutexIsUsedAsCondVar] = "  MutexIsUsedAsCondVar            ";
136353944Sdim  name[StatAnnotatePCQGet]               = "  PCQGet                          ";
137353944Sdim  name[StatAnnotatePCQPut]               = "  PCQPut                          ";
138353944Sdim  name[StatAnnotatePCQDestroy]           = "  PCQDestroy                      ";
139353944Sdim  name[StatAnnotatePCQCreate]            = "  PCQCreate                       ";
140353944Sdim  name[StatAnnotateExpectRace]           = "  ExpectRace                      ";
141353944Sdim  name[StatAnnotateBenignRaceSized]      = "  BenignRaceSized                 ";
142353944Sdim  name[StatAnnotateBenignRace]           = "  BenignRace                      ";
143353944Sdim  name[StatAnnotateIgnoreReadsBegin]     = "  IgnoreReadsBegin                ";
144353944Sdim  name[StatAnnotateIgnoreReadsEnd]       = "  IgnoreReadsEnd                  ";
145353944Sdim  name[StatAnnotateIgnoreWritesBegin]    = "  IgnoreWritesBegin               ";
146353944Sdim  name[StatAnnotateIgnoreWritesEnd]      = "  IgnoreWritesEnd                 ";
147353944Sdim  name[StatAnnotateIgnoreSyncBegin]      = "  IgnoreSyncBegin                 ";
148353944Sdim  name[StatAnnotateIgnoreSyncEnd]        = "  IgnoreSyncEnd                   ";
149353944Sdim  name[StatAnnotatePublishMemoryRange]   = "  PublishMemoryRange              ";
150353944Sdim  name[StatAnnotateUnpublishMemoryRange] = "  UnpublishMemoryRange            ";
151353944Sdim  name[StatAnnotateThreadName]           = "  ThreadName                      ";
152353944Sdim  name[Stat__tsan_mutex_create]          = "  __tsan_mutex_create             ";
153353944Sdim  name[Stat__tsan_mutex_destroy]         = "  __tsan_mutex_destroy            ";
154353944Sdim  name[Stat__tsan_mutex_pre_lock]        = "  __tsan_mutex_pre_lock           ";
155353944Sdim  name[Stat__tsan_mutex_post_lock]       = "  __tsan_mutex_post_lock          ";
156353944Sdim  name[Stat__tsan_mutex_pre_unlock]      = "  __tsan_mutex_pre_unlock         ";
157353944Sdim  name[Stat__tsan_mutex_post_unlock]     = "  __tsan_mutex_post_unlock        ";
158353944Sdim  name[Stat__tsan_mutex_pre_signal]      = "  __tsan_mutex_pre_signal         ";
159353944Sdim  name[Stat__tsan_mutex_post_signal]     = "  __tsan_mutex_post_signal        ";
160353944Sdim  name[Stat__tsan_mutex_pre_divert]      = "  __tsan_mutex_pre_divert         ";
161353944Sdim  name[Stat__tsan_mutex_post_divert]     = "  __tsan_mutex_post_divert        ";
162353944Sdim
163353944Sdim  name[StatMtxTotal]                     = "Contentionz                       ";
164353944Sdim  name[StatMtxTrace]                     = "  Trace                           ";
165353944Sdim  name[StatMtxThreads]                   = "  Threads                         ";
166353944Sdim  name[StatMtxReport]                    = "  Report                          ";
167353944Sdim  name[StatMtxSyncVar]                   = "  SyncVar                         ";
168353944Sdim  name[StatMtxSyncTab]                   = "  SyncTab                         ";
169353944Sdim  name[StatMtxSlab]                      = "  Slab                            ";
170353944Sdim  name[StatMtxAtExit]                    = "  Atexit                          ";
171353944Sdim  name[StatMtxAnnotations]               = "  Annotations                     ";
172353944Sdim  name[StatMtxMBlock]                    = "  MBlock                          ";
173353944Sdim  name[StatMtxDeadlockDetector]          = "  DeadlockDetector                ";
174353944Sdim  name[StatMtxFired]                     = "  FiredSuppressions               ";
175353944Sdim  name[StatMtxRacy]                      = "  RacyStacks                      ";
176353944Sdim  name[StatMtxFD]                        = "  FD                              ";
177353944Sdim  name[StatMtxGlobalProc]                = "  GlobalProc                      ";
178353944Sdim
179353944Sdim  Printf("Statistics:\n");
180353944Sdim  for (int i = 0; i < StatCnt; i++)
181353944Sdim    Printf("%s: %16zu\n", name[i], (uptr)stat[i]);
182353944Sdim}
183353944Sdim
184353944Sdim#endif
185353944Sdim
186353944Sdim}  // namespace __tsan
187