110d565efSmrg //===-- tsan_trace.h --------------------------------------------*- C++ -*-===//
210d565efSmrg //
310d565efSmrg // This file is distributed under the University of Illinois Open Source
410d565efSmrg // License. See LICENSE.TXT for details.
510d565efSmrg //
610d565efSmrg //===----------------------------------------------------------------------===//
710d565efSmrg //
810d565efSmrg // This file is a part of ThreadSanitizer (TSan), a race detector.
910d565efSmrg //
1010d565efSmrg //===----------------------------------------------------------------------===//
1110d565efSmrg #ifndef TSAN_TRACE_H
1210d565efSmrg #define TSAN_TRACE_H
1310d565efSmrg 
1410d565efSmrg #include "tsan_defs.h"
1510d565efSmrg #include "tsan_mutex.h"
1610d565efSmrg #include "tsan_stack_trace.h"
1710d565efSmrg #include "tsan_mutexset.h"
1810d565efSmrg 
1910d565efSmrg namespace __tsan {
2010d565efSmrg 
2110d565efSmrg const int kTracePartSizeBits = 13;
2210d565efSmrg const int kTracePartSize = 1 << kTracePartSizeBits;
2310d565efSmrg const int kTraceParts = 2 * 1024 * 1024 / kTracePartSize;
2410d565efSmrg const int kTraceSize = kTracePartSize * kTraceParts;
2510d565efSmrg 
2610d565efSmrg // Must fit into 3 bits.
2710d565efSmrg enum EventType {
2810d565efSmrg   EventTypeMop,
2910d565efSmrg   EventTypeFuncEnter,
3010d565efSmrg   EventTypeFuncExit,
3110d565efSmrg   EventTypeLock,
3210d565efSmrg   EventTypeUnlock,
3310d565efSmrg   EventTypeRLock,
3410d565efSmrg   EventTypeRUnlock
3510d565efSmrg };
3610d565efSmrg 
3710d565efSmrg // Represents a thread event (from most significant bit):
3810d565efSmrg // u64 typ  : 3;   // EventType.
3910d565efSmrg // u64 addr : 61;  // Associated pc.
4010d565efSmrg typedef u64 Event;
4110d565efSmrg 
42*c7a68eb7Smrg const uptr kEventPCBits = 61;
43*c7a68eb7Smrg 
4410d565efSmrg struct TraceHeader {
4510d565efSmrg #if !SANITIZER_GO
4610d565efSmrg   BufferedStackTrace stack0;  // Start stack for the trace.
4710d565efSmrg #else
4810d565efSmrg   VarSizeStackTrace stack0;
4910d565efSmrg #endif
5010d565efSmrg   u64        epoch0;  // Start epoch for the trace.
5110d565efSmrg   MutexSet   mset0;
5210d565efSmrg 
TraceHeaderTraceHeader5310d565efSmrg   TraceHeader() : stack0(), epoch0() {}
5410d565efSmrg };
5510d565efSmrg 
5610d565efSmrg struct Trace {
5710d565efSmrg   Mutex mtx;
5810d565efSmrg #if !SANITIZER_GO
5910d565efSmrg   // Must be last to catch overflow as paging fault.
6010d565efSmrg   // Go shadow stack is dynamically allocated.
6110d565efSmrg   uptr shadow_stack[kShadowStackSize];
6210d565efSmrg #endif
6310d565efSmrg   // Must be the last field, because we unmap the unused part in
6410d565efSmrg   // CreateThreadContext.
6510d565efSmrg   TraceHeader headers[kTraceParts];
6610d565efSmrg 
TraceTrace6710d565efSmrg   Trace()
6810d565efSmrg     : mtx(MutexTypeTrace, StatMtxTrace) {
6910d565efSmrg   }
7010d565efSmrg };
7110d565efSmrg 
7210d565efSmrg }  // namespace __tsan
7310d565efSmrg 
7410d565efSmrg #endif  // TSAN_TRACE_H
75