Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/coldtrace/entries.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,12 @@ struct coldtrace_free_entry {
struct coldtrace_stack_diff stack;
};

struct coldtrace_atomic_access_entry {
struct coldtrace_entry_header _;
uint64_t size;
uint64_t atomic_index;
};

struct coldtrace_atomic_entry {
struct coldtrace_entry_header _;
uint64_t atomic_index;
Expand Down
8 changes: 6 additions & 2 deletions scripts/trace_dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ def get_multiple_file_log(s):
COLD_ALLOC_ENTRY_SZ = 5 * 8 # bytes; sizeof(L3_ENTRY)
COLD_FREE_ENTRY_SZ = 4 * 8 # bytes; sizeof(L3_ENTRY)
COLD_ATOMIC_ENTRY_SZ = 2 * 8 # bytes; sizeof(L3_ENTRY)
COLD_ATOMIC_ACCESS_ENTRY_SZ = 3 * 8 # bytes; sizeof(L3_ENTRY)
COLD_THREAD_ENTRY_SZ = 4 * 8 # bytes; sizeof(L3_ENTRY)

if len(sys.argv) != 2 and not (len(sys.argv) == 3 and sys.argv[2] == "-d"):
Expand Down Expand Up @@ -177,6 +178,9 @@ class EntryType(Enum):
print(stacks)
elif (entry_type.value == 9):
atomic_timestamp, thread_stack_ptr, thread_stack_size = struct.unpack('<QQQ', file.read(COLD_THREAD_ENTRY_SZ - COLD_BASE_ENTRY_SZ))
elif (entry_type.value == 4 or entry_type.value == 5): # ATOMIC_READ & ATOMIC_WRITE
raw_ext = file.read(COLD_ATOMIC_ACCESS_ENTRY_SZ - COLD_BASE_ENTRY_SZ)
size, atomic_timestamp = struct.unpack('<QQ', raw_ext)
else:
atomic_timestamp, = struct.unpack('<Q', file.read(COLD_ATOMIC_ENTRY_SZ - COLD_BASE_ENTRY_SZ))

Expand All @@ -193,9 +197,9 @@ class EntryType(Enum):
case EntryType.WRITE:
print(f"{nentries}) {tid}: write access {size}B @{ptr:x} {stack_depth + 1}: {caller_0:x}, {caller_1:x}, {caller_2:x}\n")
case EntryType.ATOMIC_READ:
print(f"{nentries}) {tid}: atomic read @{ptr:x} [{atomic_timestamp}]\n")
print(f"{nentries}) {tid}: atomic read {size}B @{ptr:x} [{atomic_timestamp}]\n")
case EntryType.ATOMIC_WRITE:
print(f"{nentries}) {tid}: atomic write @{ptr:x} [{atomic_timestamp}]\n")
print(f"{nentries}) {tid}: atomic write {size}B @{ptr:x} [{atomic_timestamp}]\n")
case EntryType.LOCK_ACQUIRE:
print(f"{nentries}) {tid}: acquire lock @{ptr:x} [{atomic_timestamp}]\n")
case EntryType.LOCK_RELEASE:
Expand Down
44 changes: 27 additions & 17 deletions src/entries.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ coldtrace_entry_parse_atomic_index(const void *buf)
if (type >= COLDTRACE_MMAP || type < COLDTRACE_ATOMIC_READ) {
return INVALID_ATOMIC_INDEX;
}

if (type == COLDTRACE_ATOMIC_READ || type == COLDTRACE_ATOMIC_WRITE) {
uint64_t atomic_index = ((uint64_t *)buf)[2];
return atomic_index;
}

uint64_t atomic_index = ((uint64_t *)buf)[1];
return atomic_index;
}
Expand All @@ -107,6 +113,7 @@ coldtrace_entry_parse_size(const void *buf)
int type = coldtrace_entry_parse_type(buf);
if (type == COLDTRACE_ALLOC || type == COLDTRACE_READ ||
type == COLDTRACE_WRITE || type == COLDTRACE_MMAP ||
type == COLDTRACE_ATOMIC_READ || type == COLDTRACE_ATOMIC_WRITE ||
type == COLDTRACE_MUNMAP) {
uint64_t size = ((uint64_t *)buf)[1];
return size;
Expand Down Expand Up @@ -146,6 +153,9 @@ coldtrace_entry_get_size(const void *buf)

case COLDTRACE_ATOMIC_READ:
case COLDTRACE_ATOMIC_WRITE:
next += sizeof(struct coldtrace_atomic_access_entry);
break;

case COLDTRACE_LOCK_ACQUIRE:
case COLDTRACE_LOCK_RELEASE:
case COLDTRACE_RW_LOCK_CREATE:
Expand Down Expand Up @@ -174,23 +184,23 @@ coldtrace_entry_get_size(const void *buf)


static const size_t space_map_[] = {
[COLDTRACE_FREE] = sizeof(struct coldtrace_free_entry),
[COLDTRACE_ALLOC] = sizeof(struct coldtrace_alloc_entry),
[COLDTRACE_MMAP] = sizeof(struct coldtrace_alloc_entry),
[COLDTRACE_MUNMAP] = sizeof(struct coldtrace_alloc_entry),
[COLDTRACE_READ] = sizeof(struct coldtrace_access_entry),
[COLDTRACE_WRITE] = sizeof(struct coldtrace_access_entry),
[COLDTRACE_ATOMIC_READ] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_ATOMIC_WRITE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_LOCK_ACQUIRE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_LOCK_RELEASE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_CREATE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_DESTROY] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_ACQ_SHR] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_ACQ_EXC] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_REL_SHR] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_REL_EXC] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_REL] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_FREE] = sizeof(struct coldtrace_free_entry),
[COLDTRACE_ALLOC] = sizeof(struct coldtrace_alloc_entry),
[COLDTRACE_MMAP] = sizeof(struct coldtrace_alloc_entry),
[COLDTRACE_MUNMAP] = sizeof(struct coldtrace_alloc_entry),
[COLDTRACE_READ] = sizeof(struct coldtrace_access_entry),
[COLDTRACE_WRITE] = sizeof(struct coldtrace_access_entry),
[COLDTRACE_ATOMIC_READ] = sizeof(struct coldtrace_atomic_access_entry),
[COLDTRACE_ATOMIC_WRITE] = sizeof(struct coldtrace_atomic_access_entry),
[COLDTRACE_LOCK_ACQUIRE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_LOCK_RELEASE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_CREATE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_DESTROY] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_ACQ_SHR] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_ACQ_EXC] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_REL_SHR] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_REL_EXC] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_RW_LOCK_REL] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_CXA_GUARD_ACQUIRE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_CXA_GUARD_RELEASE] = sizeof(struct coldtrace_atomic_entry),
[COLDTRACE_THREAD_JOIN] = sizeof(struct coldtrace_atomic_entry),
Expand Down
24 changes: 15 additions & 9 deletions src/subs_tsan.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,46 +65,52 @@ area_t areas_[AREAS];
caslock_acquire(&area->lock); \
area->idx_a = coldtrace_next_atomic_idx();

#define REL_LOG_R(addr, size) \
#define REL_LOG_R(addr, sz) \
area_t *area = get_area(addr); \
uint64_t idx_a = area->idx_a; \
caslock_release(&area->lock); \
struct coldtrace_atomic_entry *e; \
struct coldtrace_atomic_access_entry *e; \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_READ, addr); \
e->size = sz; \
e->atomic_index = idx_a;

#define REL_LOG_W(addr, size) \
#define REL_LOG_W(addr, sz) \
area_t *area = get_area(addr); \
uint64_t idx_a = area->idx_a; \
caslock_release(&area->lock); \
struct coldtrace_atomic_entry *e; \
struct coldtrace_atomic_access_entry *e; \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_WRITE, addr); \
e->size = sz; \
e->atomic_index = idx_a;

#define REL_LOG_RW(addr, size) \
#define REL_LOG_RW(addr, sz) \
area_t *area = get_area(addr); \
uint64_t idx_a = area->idx_a; \
uint64_t idx_b = coldtrace_next_atomic_idx(); \
caslock_release(&area->lock); \
struct coldtrace_atomic_entry *e; \
struct coldtrace_atomic_access_entry *e; \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_READ, addr); \
e->size = sz; \
e->atomic_index = idx_a; \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_WRITE, addr); \
e->size = sz; \
e->atomic_index = idx_b;

#define REL_LOG_RW_COND(addr, size, success) \
#define REL_LOG_RW_COND(addr, sz, success) \
uint64_t idx_b = 0; \
if (success) { \
idx_b = coldtrace_next_atomic_idx(); \
} \
area_t *area = get_area(addr); \
uint64_t idx_a = area->idx_a; \
caslock_release(&area->lock); \
struct coldtrace_atomic_entry *e; \
struct coldtrace_atomic_access_entry *e; \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_READ, addr); \
e->size = sz; \
e->atomic_index = idx_a; \
if (success) { \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_WRITE, addr); \
e = coldtrace_thread_append(md, COLDTRACE_ATOMIC_WRITE, addr); \
e->size = sz; \
e->atomic_index = idx_b; \
}

Expand Down
92 changes: 92 additions & 0 deletions test/trace_aread_awrite_size.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
#include <atomic>
#include <cstdio>
#include <cstdlib>
#include <trace_checker.h>

struct expected_entry expected_1[] = {

EXPECT_SUFFIX(COLDTRACE_FENCE),

EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 0, sizeof(uint8_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 0, sizeof(uint8_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 1, sizeof(uint16_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 1, sizeof(uint16_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 2, sizeof(uint32_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 2, sizeof(uint32_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 3, sizeof(uint64_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 3, sizeof(uint64_t)),

EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 5, sizeof(float)),
Comment thread
ggeier marked this conversation as resolved.
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 5, sizeof(float)),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_SOME(COLDTRACE_READ, 0, 1),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 6, sizeof(double)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 6, sizeof(double)),
EXPECT_SOME(COLDTRACE_WRITE, 0, 1),
EXPECT_SOME(COLDTRACE_READ, 0, 1),

EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 0, sizeof(uint8_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 0, sizeof(uint8_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 1, sizeof(uint16_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 1, sizeof(uint16_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 2, sizeof(uint32_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 2, sizeof(uint32_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_READ, 3, sizeof(uint64_t)),
EXPECT_VALUE_SIZE(COLDTRACE_ATOMIC_WRITE, 3, sizeof(uint64_t)),

EXPECT_SUFFIX(COLDTRACE_THREAD_EXIT),
EXPECT_END,
};

#define VALUE 10
#define FLOAT_VALUE 10.0
int
main(void)
{
register_expected_trace(1, expected_1);

std::atomic<uint8_t> at_8;
std::atomic<uint16_t> at_16;
std::atomic<uint32_t> at_32;
std::atomic<uint64_t> at_64;
std::atomic<float> at_float;
std::atomic<double> at_double;

std::atomic_thread_fence(std::memory_order_release); // fence

at_8.store(VALUE, std::memory_order_release); // write
uint8_t val_8 = at_8.load(std::memory_order_acquire); // read

at_16.store(VALUE * 2, std::memory_order_release); // write
uint16_t val_16 = at_16.load(std::memory_order_acquire); // read

at_32.store(VALUE * 3, std::memory_order_release); // write
uint32_t val_32 = at_32.load(std::memory_order_acquire); // read

at_64.store(VALUE * 4, std::memory_order_release); // write
uint64_t val_64 = at_64.load(std::memory_order_acquire); // read

at_float.store(FLOAT_VALUE, std::memory_order_release); // write
float val_float = at_float.load(std::memory_order_acquire); // read

at_double.store(FLOAT_VALUE * 2, std::memory_order_release); // write
double val_double = at_double.load(std::memory_order_acquire); // read

at_8.fetch_add(1, std::memory_order_release); // RMW
at_16.fetch_add(1, std::memory_order_release); // RMW
at_32.fetch_add(1, std::memory_order_release); // RMW
at_64.fetch_add(1, std::memory_order_release); // RMW

printf("Loaded 8-bit atomic: %u\n", val_8);
printf("Loaded 16-bit atomic: %u\n", val_16);
printf("Loaded 32-bit atomic: %u\n", val_32);
printf("Loaded 64-bit atomic: %lu\n", val_64);
printf("Loaded float atomic: %f\n", val_float);
printf("Loaded double atomic: %f\n", val_double);

return 0;
}
Loading