From a9e77155aee17d9e66603f970a964bee83f62248 Mon Sep 17 00:00:00 2001 From: bdemsky Date: Tue, 16 Jul 2019 17:03:54 -0700 Subject: [PATCH] Track whether a write was from an atomic --- datarace.cc | 27 ++++++++++++++------------- datarace.h | 8 ++++++-- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/datarace.cc b/datarace.cc index b3ce8abe..4a6b8d81 100644 --- a/datarace.cc +++ b/datarace.cc @@ -93,14 +93,15 @@ static void expandRecord(uint64_t *shadow) record->writeClock = writeClock; if (readClock != 0) { - record->capacity = INITCAPACITY; - record->thread = (thread_id_t *)snapshot_malloc(sizeof(thread_id_t) * record->capacity); - record->readClock = (modelclock_t *)snapshot_malloc(sizeof(modelclock_t) * record->capacity); + record->thread = (thread_id_t *)snapshot_malloc(sizeof(thread_id_t) * INITCAPACITY); + record->readClock = (modelclock_t *)snapshot_malloc(sizeof(modelclock_t) * INITCAPACITY); record->numReads = 1; ASSERT(readThread >= 0); record->thread[0] = readThread; record->readClock[0] = readClock; } + if (shadowval & ATOMICMASK) + record->isAtomic = 1; *shadow = (uint64_t) record; } @@ -201,6 +202,7 @@ struct DataRace * fullRaceCheckWrite(thread_id_t thread, void *location, uint64_ Exit: record->numReads = 0; record->writeThread = thread; + record->isAtomic = 0; modelclock_t ourClock = currClock->getClock(thread); record->writeClock = ourClock; return race; @@ -278,6 +280,7 @@ void fullRecordWrite(thread_id_t thread, void *location, uint64_t *shadow, Clock record->writeThread = thread; modelclock_t ourClock = currClock->getClock(thread); record->writeClock = ourClock; + record->isAtomic = 1; } /** This function just updates metadata on atomic write. */ @@ -301,7 +304,7 @@ void recordWrite(thread_id_t thread, void *location) { return; } - *shadow = ENCODEOP(0, 0, threadid, ourClock); + *shadow = ENCODEOP(0, 0, threadid, ourClock) | ATOMICMASK; } @@ -346,23 +349,21 @@ struct DataRace * fullRaceCheckRead(thread_id_t thread, const void *location, ui } } - if (copytoindex >= record->capacity) { - if (record->capacity == 0) { + if (__builtin_popcount(copytoindex) <= 1) { + if (copytoindex == 0) { int newCapacity = INITCAPACITY; record->thread = (thread_id_t *)snapshot_malloc(sizeof(thread_id_t) * newCapacity); record->readClock = (modelclock_t *)snapshot_malloc(sizeof(modelclock_t) * newCapacity); - record->capacity = newCapacity; - } else { - int newCapacity = record->capacity * 2; + } else if (copytoindex>=INITCAPACITY) { + int newCapacity = copytoindex * 2; thread_id_t *newthread = (thread_id_t *)snapshot_malloc(sizeof(thread_id_t) * newCapacity); modelclock_t *newreadClock = (modelclock_t *)snapshot_malloc(sizeof(modelclock_t) * newCapacity); - std::memcpy(newthread, record->thread, record->capacity * sizeof(thread_id_t)); - std::memcpy(newreadClock, record->readClock, record->capacity * sizeof(modelclock_t)); + std::memcpy(newthread, record->thread, copytoindex * sizeof(thread_id_t)); + std::memcpy(newreadClock, record->readClock, copytoindex * sizeof(modelclock_t)); snapshot_free(record->readClock); snapshot_free(record->thread); record->readClock = newreadClock; record->thread = newthread; - record->capacity = newCapacity; } } @@ -424,7 +425,7 @@ ShadowExit: } } - *shadow = ENCODEOP(threadid, ourClock, id_to_int(writeThread), writeClock); + *shadow = ENCODEOP(threadid, ourClock, id_to_int(writeThread), writeClock) | (shadowval & ATOMICMASK); } Exit: if (race) { diff --git a/datarace.h b/datarace.h index 7c841215..67d58e7c 100644 --- a/datarace.h +++ b/datarace.h @@ -55,8 +55,8 @@ void assert_race(struct DataRace *race); struct RaceRecord { modelclock_t *readClock; thread_id_t *thread; - int capacity; - int numReads; + int numReads : 31; + int isAtomic : 1; thread_id_t writeThread; modelclock_t writeClock; }; @@ -78,6 +78,9 @@ bool race_equals(struct DataRace *r1, struct DataRace *r2); #define WRITEMASK READMASK #define WRITEVECTOR(x) (((x)>>38)&WRITEMASK) +#define ATOMICMASK (0x1ULL << 63) +#define NONATOMICMASK ~(0x1ULL << 63) + /** * The basic encoding idea is that (void *) either: * -# points to a full record (RaceRecord) or @@ -88,6 +91,7 @@ bool race_equals(struct DataRace *r1, struct DataRace *r2); * - next 25 bits are read clock vector * - next 6 bits are write thread id * - next 25 bits are write clock vector + * - highest bit is 1 if the write is from an atomic */ #define ENCODEOP(rdthread, rdtime, wrthread, wrtime) (0x1ULL | ((rdthread)<<1) | ((rdtime) << 7) | (((uint64_t)wrthread)<<32) | (((uint64_t)wrtime)<<38)) -- 2.34.1