#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,
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)
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)
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; \
})
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; } \
})
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)
{