1bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov/* Copyright (c) 2008-2010, Google Inc.
2bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * All rights reserved.
3bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *
4bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * Redistribution and use in source and binary forms, with or without
5bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * modification, are permitted provided that the following conditions are
6bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * met:
7bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *
8bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *     * Redistributions of source code must retain the above copyright
9bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * notice, this list of conditions and the following disclaimer.
10bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *     * Neither the name of Google Inc. nor the names of its
11bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * contributors may be used to endorse or promote products derived from
12bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * this software without specific prior written permission.
13bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov *
14bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
18bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
20bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov */
26bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
27bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// This file is part of ThreadSanitizer, a dynamic data race detector.
28bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Author: Konstantin Serebryany.
29bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Information about one TRACE (single-entry-multiple-exit region of code).
30bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#ifndef TS_TRACE_INFO_
31bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#define TS_TRACE_INFO_
32bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
33bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#include "ts_util.h"
34bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Information about one Memory Operation.
35bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov//
36bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// A memory access is represented by mop[idx] = {pc,size,is_write}
37bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// which is computed at instrumentation time and {actual_address} computed
38bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// at run-time. The instrumentation insn looks like
39bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov//  tleb[idx] = actual_address
40bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// The create_sblock field tells if we want to remember the stack trace
41bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// which corresponds to this Mop (i.e. create an SBLOCK).
42bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct MopInfo {
43bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov public:
44bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  MopInfo(uintptr_t pc, size_t size, bool is_write, bool create_sblock) {
45bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(sizeof(*this) == 8);
46bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    pc_ = pc;
47bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (size > 16) size = 16; // some instructions access more than 16 bytes.
48bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    size_minus1_ = size - 1;
49bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    is_write_ = is_write;
50bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    create_sblock_ = create_sblock;
51bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
52bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(size != 0);
53bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(this->size() == size);
54bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(this->is_write() == is_write);
55bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(this->create_sblock() == create_sblock);
56bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
57bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
58bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  MopInfo() {
59bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(sizeof(*this) == 8);
60bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    memset(this, 0, sizeof(*this));
61bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
62bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
63bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  uintptr_t pc()            { return pc_; };
64bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t    size()          { return size_minus1_ + 1; }
65bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  bool      is_write()      { return is_write_; }
66bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  bool      create_sblock() { return create_sblock_; }
67bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
68bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov private:
69db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  uint64_t  pc_           :58;  // 48 bits is enough for pc, even on x86-64.
70db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  uint64_t  create_sblock_ :1;
71db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  uint64_t  is_write_      :1;
72db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  uint64_t  size_minus1_   :4;  // 0..15
73bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov};
74bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
75bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// ---------------- Lite Race ------------------
76bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Experimental!
77bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov//
78bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// The idea was first introduced in LiteRace:
79bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// http://www.cs.ucla.edu/~dlmarino/pubs/pldi09.pdf
80bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Instead of analyzing all memory accesses, we do sampling.
81bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// For each trace (single-enry muliple-exit region) we maintain a counter of
82bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// executions. If a trace has been executed more than a certain threshold, we
83bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// start skipping this trace sometimes.
84bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// The LiteRace paper suggests several strategies for sampling, including
85bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// thread-local counters. Having thread local counters for all threads is too
86bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// expensive, so we have kLiteRaceNumTids arrays of counters and use
87bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// the array (tid % 8).
88bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov//
89bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// sampling_rate indicates the level of sampling.
90bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// 0 means no sampling.
91bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// 1 means handle *almost* all accesses.
92bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// ...
93bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// 31 means very aggressive sampling (skip a lot of accesses).
94bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
95bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov//
96bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// Note: ANNOTATE_PUBLISH_MEMORY() does not work with sampling... :(
97bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
98bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct LiteRaceCounters {
99bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  uint32_t counter;
100bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  int32_t num_to_skip;
101bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov};
102bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
103bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovstruct TraceInfoPOD {
104bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  enum { kLiteRaceNumTids = 8 };
105bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  enum { kLiteRaceStorageSize = 8 };
106db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  typedef LiteRaceCounters LiteRaceStorage[kLiteRaceNumTids][kLiteRaceStorageSize];
107db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov
108bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t n_mops_;
109bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t pc_;
110bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t counter_;
111bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  LiteRaceStorage *literace_storage;
112bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  int32_t storage_index;
113bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  MopInfo mops_[1];
114bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov};
115bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
116bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// An instance of this class is created for each TRACE (SEME region)
117bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// during instrumentation.
118bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanovclass TraceInfo : public TraceInfoPOD {
119bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov public:
120bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  static TraceInfo *NewTraceInfo(size_t n_mops, uintptr_t pc);
121bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  void DeleteTraceInfo(TraceInfo *trace_info) {
122bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    delete [] (uintptr_t*)trace_info;
123bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
124bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  MopInfo *GetMop(size_t i) {
125bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(i < n_mops_);
126bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return &mops_[i];
127bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
128bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
129bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t n_mops() const { return n_mops_; }
130bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t pc()     const { return pc_; }
131bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  size_t &counter()     { return counter_; }
132bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  MopInfo *mops()       { return mops_; }
133bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
134bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  static void PrintTraceProfile();
135bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
136bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  INLINE bool LiteRaceSkipTraceQuickCheck(uintptr_t tid_modulo_num) {
137bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(tid_modulo_num < kLiteRaceNumTids);
138db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov    // Check how may accesses are left to skip. Racey, but ok.
139db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov    LiteRaceCounters *counters =
140db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov        &((*literace_storage)[tid_modulo_num][storage_index]);
141db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov    int32_t num_to_skip = --counters->num_to_skip;
142bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (num_to_skip > 0) {
143bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov      return true;
144bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    }
145bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return false;
146bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
147bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
148bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  INLINE void LiteRaceUpdate(uintptr_t tid_modulo_num, uint32_t sampling_rate) {
149bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(sampling_rate < 32);
150bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    DCHECK(sampling_rate > 0);
151bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    LiteRaceCounters *counters =
152bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov        &((*literace_storage)[tid_modulo_num][storage_index]);
153bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    uint32_t cur_counter = counters->counter;
154bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    // The bigger the counter the bigger the number of skipped accesses.
155bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    int32_t next_num_to_skip = (cur_counter >> (32 - sampling_rate)) + 1;
156bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    counters->num_to_skip = next_num_to_skip;
157bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    counters->counter = cur_counter + next_num_to_skip;
158db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov
159db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  }
160db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov
161db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  // TODO(glider): get rid of this.
162db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov  INLINE void LLVMLiteRaceUpdate(uintptr_t tid_modulo_num,
163db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov                                 uint32_t sampling_rate) {
164db2b85ac6df2716e3ae85cccc29eefafa6b5d047Evgeniy Stepanov    LiteRaceUpdate(tid_modulo_num, sampling_rate);
165bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
166bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
167bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  // This is all racey, but ok.
168bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  INLINE bool LiteRaceSkipTrace(uint32_t tid_modulo_num,
169bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov                                uint32_t sampling_rate) {
170bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    if (LiteRaceSkipTraceQuickCheck(tid_modulo_num)) return true;
171bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    LiteRaceUpdate(tid_modulo_num, sampling_rate);
172bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return false;
173bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
174bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
175bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  INLINE bool LiteRaceSkipTraceRealTid(uint32_t tid, uint32_t sampling_rate) {
176bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov    return LiteRaceSkipTrace(tid % kLiteRaceNumTids, sampling_rate);
177bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  }
178bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
179bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov private:
180bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  static size_t id_counter_;
181bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  static vector<TraceInfo*> *g_all_traces;
182bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
183bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov  TraceInfo() : TraceInfoPOD() { }
184bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov};
185bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov
186bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// end. {{{1
187bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov#endif  // TS_TRACE_INFO_
188bec2f0e0495e343f55908a6f0cc4bd8dd27b27d1Evgeniy Stepanov// vim:shiftwidth=2:softtabstop=2:expandtab:tw=80
189