From: bdemsky Date: Tue, 16 Jul 2019 23:34:29 +0000 (-0700) Subject: Make atomics actually write to memory for compatibility with normal accesses X-Git-Url: http://plrg.eecs.uci.edu/git/?p=c11tester.git;a=commitdiff_plain;h=56fc136acfee3e083b77b8bc2bd1149bf4e26f2e Make atomics actually write to memory for compatibility with normal accesses --- diff --git a/cmodelint.cc b/cmodelint.cc index c052552e..5b37e867 100644 --- a/cmodelint.cc +++ b/cmodelint.cc @@ -8,6 +8,7 @@ #include "cmodelint.h" #include "snapshot-interface.h" #include "threads-model.h" +#include "datarace.h" memory_order orders[6] = { memory_order_relaxed, memory_order_consume, memory_order_acquire, @@ -98,6 +99,10 @@ void model_rmwc_action_helper(void *obj, int atomic_index, const char *position) ensureModel(); \ model->switch_to_master(new ModelAction(ATOMIC_INIT, position, memory_order_relaxed, obj, (uint64_t) val)); \ *((uint ## size ## _t *)obj) = val; \ + thread_id_t tid = thread_current()->get_id(); \ + for(int i=0;i < size / 8;i++) { \ + recordWrite(tid, (void *)(((char *)obj)+i)); \ + } \ } CDSATOMICINT(8) @@ -119,12 +124,15 @@ CDSATOMICLOAD(32) CDSATOMICLOAD(64) // cds atomic stores - #define CDSATOMICSTORE(size) \ void cds_atomic_store ## size(void * obj, uint ## size ## _t val, int atomic_index, const char * position) { \ ensureModel(); \ model->switch_to_master(new ModelAction(ATOMIC_WRITE, position, orders[atomic_index], obj, (uint64_t) val)); \ - *((uint ## size ## _t *)obj) = val; \ + *((uint ## size ## _t *)obj) = val; \ + thread_id_t tid = thread_current()->get_id(); \ + for(int i=0;i < size / 8;i++) { \ + recordWrite(tid, (void *)(((char *)obj)+i)); \ + } \ } CDSATOMICSTORE(8) @@ -140,6 +148,11 @@ CDSATOMICSTORE(64) uint ## size ## _t _val = val; \ _copy __op__ _val; \ model_rmw_action_helper(addr, (uint64_t) _copy, atomic_index, position); \ + *((uint ## size ## _t *)addr) = _copy; \ + thread_id_t tid = thread_current()->get_id(); \ + for(int i=0;i < size / 8;i++) { \ + recordWrite(tid, (void *)(((char *)addr)+i)); \ + } \ return _old; \ }) @@ -219,7 +232,13 @@ CDSATOMICXOR(64) uint ## size ## _t _expected = expected; \ uint ## size ## _t _old = model_rmwrcas_action_helper(addr, atomic_index, _expected, sizeof(_expected), position); \ if (_old == _expected) { \ - model_rmw_action_helper(addr, (uint64_t) _desired, atomic_index, position); return _expected; } \ + model_rmw_action_helper(addr, (uint64_t) _desired, atomic_index, position); \ + *((uint ## size ## _t *)addr) = desired; \ + thread_id_t tid = thread_current()->get_id(); \ + for(int i=0;i < size / 8;i++) { \ + recordWrite(tid, (void *)(((char *)addr)+i)); \ + } \ + return _expected; } \ else { \ model_rmwc_action_helper(addr, atomic_index, position); _expected = _old; return _old; } \ }) diff --git a/datarace.cc b/datarace.cc index d15ca50c..b3ce8abe 100644 --- a/datarace.cc +++ b/datarace.cc @@ -270,6 +270,42 @@ Exit: else model_free(race); } } + +/** This function does race detection for a write on an expanded record. */ +void fullRecordWrite(thread_id_t thread, void *location, uint64_t *shadow, ClockVector *currClock) { + struct RaceRecord *record = (struct RaceRecord *)(*shadow); + record->numReads = 0; + record->writeThread = thread; + modelclock_t ourClock = currClock->getClock(thread); + record->writeClock = ourClock; +} + +/** This function just updates metadata on atomic write. */ +void recordWrite(thread_id_t thread, void *location) { + uint64_t *shadow = lookupAddressEntry(location); + uint64_t shadowval = *shadow; + ClockVector *currClock = get_execution()->get_cv(thread); + /* Do full record */ + if (shadowval != 0 && !ISSHORTRECORD(shadowval)) { + fullRecordWrite(thread, location, shadow, currClock); + return; + } + + int threadid = id_to_int(thread); + modelclock_t ourClock = currClock->getClock(thread); + + /* Thread ID is too large or clock is too large. */ + if (threadid > MAXTHREADID || ourClock > MAXWRITEVECTOR) { + expandRecord(shadow); + fullRecordWrite(thread, location, shadow, currClock); + return; + } + + *shadow = ENCODEOP(0, 0, threadid, ourClock); +} + + + /** This function does race detection on a read for an expanded record. */ struct DataRace * fullRaceCheckRead(thread_id_t thread, const void *location, uint64_t *shadow, ClockVector *currClock) { diff --git a/datarace.h b/datarace.h index 7e4e68e2..7c841215 100644 --- a/datarace.h +++ b/datarace.h @@ -45,6 +45,7 @@ struct DataRace { void initRaceDetector(); void raceCheckWrite(thread_id_t thread, void *location); void raceCheckRead(thread_id_t thread, const void *location); +void recordWrite(thread_id_t thread, void *location); bool checkDataRaces(); void assert_race(struct DataRace *race);