6 struct ShadowTable *root;
8 void initRaceDetector() {
9 root=(struct ShadowTable *) calloc(sizeof(struct ShadowTable),1);
12 static uint64_t * lookupAddressEntry(void * address) {
13 struct ShadowTable *currtable=root;
15 currtable=(struct ShadowTable *) currtable->array[(((uintptr_t)address)>>32)&0xffff];
16 if (currtable==NULL) {
17 currtable=(struct ShadowTable *) (root->array[(((uintptr_t)address)>>32)&MASK16BIT]=calloc(sizeof(struct ShadowTable),1));
21 struct ShadowBaseTable * basetable=(struct ShadowBaseTable *) currtable->array[(((uintptr_t)address)>>16)&MASK16BIT];
22 if (basetable==NULL) {
23 basetable=(struct ShadowBaseTable *) (currtable->array[(((uintptr_t)address)>>16)&MASK16BIT]=calloc(sizeof(struct ShadowBaseTable),1));
25 return &basetable->array[((uintptr_t)address)&MASK16BIT];
28 static void expandRecord(uint64_t * shadow) {
29 uint64_t shadowval=*shadow;
31 modelclock_t readClock = READVECTOR(shadowval);
32 thread_id_t readThread = int_to_id(RDTHREADID(shadowval));
33 modelclock_t writeClock = WRITEVECTOR(shadowval);
34 thread_id_t writeThread = int_to_id(WRTHREADID(shadowval));
36 struct RaceRecord * record=(struct RaceRecord *)calloc(1,sizeof(struct RaceRecord));
37 record->writeThread=writeThread;
38 record->writeClock=writeClock;
41 record->capacity=INITCAPACITY;
42 record->thread=(thread_id_t *) malloc(sizeof(thread_id_t)*record->capacity);
43 record->readClock=(modelclock_t *) malloc(sizeof(modelclock_t)*record->capacity);
45 record->thread[0]=readThread;
46 record->readClock[0]=readClock;
48 *shadow=(uint64_t) record;
51 static void reportDataRace() {
52 printf("The reportDataRace method should report useful things about this datarace!\n");
55 void fullRaceCheckWrite(thread_id_t thread, uint64_t * shadow, ClockVector *currClock) {
56 struct RaceRecord * record=(struct RaceRecord *) (*shadow);
58 /* Check for datarace against last read. */
60 for(int i=0;i<record->numReads;i++) {
61 modelclock_t readClock = record->readClock[i];
62 thread_id_t readThread = record->thread[i];
64 if (readThread != thread && readClock != 0 && currClock->getClock(readThread) <= readClock) {
65 /* We have a datarace */
70 /* Check for datarace against last write. */
72 modelclock_t writeClock = record->writeClock;
73 thread_id_t writeThread = record->writeThread;
75 if (writeThread != thread && writeClock != 0 && currClock->getClock(writeThread) <= writeClock) {
76 /* We have a datarace */
81 record->writeThread=thread;
82 modelclock_t ourClock = currClock->getClock(thread);
83 record->writeClock=ourClock;
86 void raceCheckWrite(thread_id_t thread, void *location, ClockVector *currClock) {
87 uint64_t * shadow=lookupAddressEntry(location);
88 uint64_t shadowval=*shadow;
91 if (shadowval!=0&&!ISSHORTRECORD(shadowval)) {
92 fullRaceCheckWrite(thread, shadow, currClock);
96 int threadid = id_to_int(thread);
97 modelclock_t ourClock = currClock->getClock(thread);
99 /* Thread ID is too large or clock is too large. */
100 if (threadid > MAXTHREADID || ourClock > MAXWRITEVECTOR) {
101 expandRecord(shadow);
102 fullRaceCheckWrite(thread, shadow, currClock);
106 /* Check for datarace against last read. */
108 modelclock_t readClock = READVECTOR(shadowval);
109 thread_id_t readThread = int_to_id(RDTHREADID(shadowval));
111 if (readThread != thread && readClock != 0 && currClock->getClock(readThread) <= readClock) {
112 /* We have a datarace */
116 /* Check for datarace against last write. */
118 modelclock_t writeClock = WRITEVECTOR(shadowval);
119 thread_id_t writeThread = int_to_id(WRTHREADID(shadowval));
121 if (writeThread != thread && writeClock != 0 && currClock->getClock(writeThread) <= writeClock) {
122 /* We have a datarace */
125 *shadow = ENCODEOP(0, 0, threadid, ourClock);
128 void fullRaceCheckRead(thread_id_t thread, uint64_t * shadow, ClockVector *currClock) {
129 struct RaceRecord * record=(struct RaceRecord *) (*shadow);
131 /* Check for datarace against last write. */
133 modelclock_t writeClock = record->writeClock;
134 thread_id_t writeThread = record->writeThread;
136 if (writeThread != thread && writeClock != 0 && currClock->getClock(writeThread) <= writeClock) {
137 /* We have a datarace */
141 /* Shorten vector when possible */
145 for(int i=0;i<record->numReads;i++) {
146 modelclock_t readClock = record->readClock[i];
147 thread_id_t readThread = record->thread[i];
149 if (readThread != thread && currClock->getClock(readThread) <= readClock) {
150 /* Still need this read in vector */
151 if (copytoindex!=i) {
152 record->readClock[copytoindex]=record->readClock[i];
153 record->thread[copytoindex]=record->thread[i];
159 if (copytoindex>=record->capacity) {
160 int newCapacity=record->capacity*2;
161 thread_id_t *newthread=(thread_id_t *) malloc(sizeof(thread_id_t)*newCapacity);
162 modelclock_t * newreadClock=(modelclock_t *) malloc(sizeof(modelclock_t)*newCapacity);
163 std::memcpy(newthread, record->thread, record->capacity*sizeof(thread_id_t));
164 std::memcpy(newreadClock, record->readClock, record->capacity*sizeof(modelclock_t));
165 free(record->readClock);
166 free(record->thread);
167 record->readClock=newreadClock;
168 record->thread=newthread;
169 record->capacity=newCapacity;
172 modelclock_t ourClock = currClock->getClock(thread);
174 record->thread[copytoindex]=thread;
175 record->readClock[copytoindex]=ourClock;
176 record->numReads=copytoindex+1;
179 void raceCheckRead(thread_id_t thread, void *location, ClockVector *currClock) {
180 uint64_t * shadow=lookupAddressEntry(location);
181 uint64_t shadowval=*shadow;
184 if (shadowval!=0&&!ISSHORTRECORD(shadowval)) {
185 fullRaceCheckRead(thread, shadow, currClock);
189 int threadid = id_to_int(thread);
190 modelclock_t ourClock = currClock->getClock(thread);
192 /* Thread ID is too large or clock is too large. */
193 if (threadid > MAXTHREADID || ourClock > MAXWRITEVECTOR) {
194 expandRecord(shadow);
195 fullRaceCheckRead(thread, shadow, currClock);
199 /* Check for datarace against last write. */
201 modelclock_t writeClock = WRITEVECTOR(shadowval);
202 thread_id_t writeThread = int_to_id(WRTHREADID(shadowval));
204 if (writeThread != thread && writeClock != 0 && currClock->getClock(writeThread) <= writeClock) {
205 /* We have a datarace */
209 modelclock_t readClock = READVECTOR(shadowval);
210 thread_id_t readThread = int_to_id(RDTHREADID(shadowval));
212 if (readThread != thread && readClock != 0 && currClock->getClock(readThread) <= readClock) {
213 /* We don't subsume this read... Have to expand record. */
214 expandRecord(shadow);
215 fullRaceCheckRead(thread, shadow, currClock);
219 *shadow = ENCODEOP(writeThread, writeClock, threadid, ourClock);