From fbeeeb53fdbcb6b59e35c910e732173c6ead5e79 Mon Sep 17 00:00:00 2001 From: weiyu Date: Mon, 20 Apr 2020 15:58:30 -0700 Subject: [PATCH] Optimize RaceCheckRead --- datarace.cc | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++ datarace.h | 2 ++ librace.cc | 18 +++++++++++--- 3 files changed, 89 insertions(+), 3 deletions(-) diff --git a/datarace.cc b/datarace.cc index 4558e2ba..8af2b1e6 100644 --- a/datarace.cc +++ b/datarace.cc @@ -703,3 +703,75 @@ Exit: else model_free(race); } } + +void raceCheckReadOpt(thread_id_t thread, const void * addr, int bytes) +{ + const ModelExecution * execution = get_execution(); + ClockVector *currClock = execution->get_cv(thread); + if (currClock == NULL) + return; + + int threadid = id_to_int(thread); + modelclock_t ourClock = currClock->getClock(thread); + bool should_expand = threadid > MAXTHREADID || ourClock > MAXWRITEVECTOR; + + bool hasRace = false; + + for (int i = 0; i < bytes; i++) { + const void * location = (void *)(((uintptr_t)addr) + i); + uint64_t *shadow = lookupAddressEntry(location); + uint64_t shadowval = *shadow; + + struct DataRace * race = NULL; + + /* Do full record */ + if (shadowval != 0 && !ISSHORTRECORD(shadowval)) { + race = fullRaceCheckRead(thread, location, shadow, currClock); + goto Exit; + } + + { + /* Thread ID is too large or clock is too large. */ + if (should_expand) { + expandRecord(shadow); + race = fullRaceCheckRead(thread, location, shadow, currClock); + goto Exit; + } + + /* Check for datarace against last write. */ + + modelclock_t writeClock = WRITEVECTOR(shadowval); + thread_id_t writeThread = int_to_id(WRTHREADID(shadowval)); + + // If there is already has a race, skip check + if (!hasRace && clock_may_race(currClock, thread, writeClock, writeThread)) { + /* We have a datarace */ + race = reportDataRace(writeThread, writeClock, true, execution->get_parent_action(thread), false, location); + } + + modelclock_t readClock = READVECTOR(shadowval); + thread_id_t readThread = int_to_id(RDTHREADID(shadowval)); + + if (clock_may_race(currClock, thread, readClock, readThread)) { + /* We don't subsume this read... Have to expand record. */ + expandRecord(shadow); + struct RaceRecord *record = (struct RaceRecord *) (*shadow); + record->thread[1] = thread; + record->readClock[1] = ourClock; + record->numReads++; + + goto Exit; + } + + *shadow = ENCODEOP(threadid, ourClock, id_to_int(writeThread), writeClock) | (shadowval & ATOMICMASK); + } +Exit: + if (race) { + hasRace = true; + race->numframes=backtrace(race->backtrace, sizeof(race->backtrace)/sizeof(void*)); + if (raceset->add(race)) + assert_race(race); + else model_free(race); + } + } +} diff --git a/datarace.h b/datarace.h index f026556a..60392029 100644 --- a/datarace.h +++ b/datarace.h @@ -46,6 +46,8 @@ void initRaceDetector(); void raceCheckWrite(thread_id_t thread, void *location); void atomraceCheckWrite(thread_id_t thread, void *location); void raceCheckRead(thread_id_t thread, const void *location); +void raceCheckReadOpt(thread_id_t thread, const void *location, int bytes); + void atomraceCheckRead(thread_id_t thread, const void *location); void recordWrite(thread_id_t thread, void *location); void recordCalloc(void *location, size_t size); diff --git a/librace.cc b/librace.cc index faa98cdb..15ee94eb 100644 --- a/librace.cc +++ b/librace.cc @@ -152,31 +152,42 @@ void cds_load8(const void *addr) { if (!model) return; thread_id_t tid = thread_current()->get_id(); - raceCheckRead(tid, addr); + + raceCheckReadOpt(tid, addr, 1); +// raceCheckRead(tid, addr); } void cds_load16(const void *addr) { if (!model) return; thread_id_t tid = thread_current()->get_id(); - raceCheckRead(tid, addr); - raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 1)); + + raceCheckReadOpt(tid, addr, 2); +// raceCheckRead(tid, addr); +// raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 1)); } void cds_load32(const void *addr) { if (!model) return; thread_id_t tid = thread_current()->get_id(); + + raceCheckReadOpt(tid, addr, 4); +/* raceCheckRead(tid, addr); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 1)); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 2)); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 3)); +*/ } void cds_load64(const void *addr) { if (!model) return; thread_id_t tid = thread_current()->get_id(); + + raceCheckReadOpt(tid, addr, 8); +/* raceCheckRead(tid, addr); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 1)); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 2)); @@ -185,4 +196,5 @@ void cds_load64(const void *addr) { raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 5)); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 6)); raceCheckRead(tid, (const void *)(((uintptr_t)addr) + 7)); +*/ } -- 2.34.1