tsan: fix a bug in MetaMap::ResetRange

The bug was uncovered by NegativeTests.MmapTest from
data-race-test suite, so port it as well.

llvm-svn: 232032
This commit is contained in:
Dmitry Vyukov 2015-03-12 12:48:19 +00:00
parent 8d6c3571b4
commit b75212878f
2 changed files with 51 additions and 2 deletions

View File

@ -162,8 +162,10 @@ void MetaMap::ResetRange(ThreadState *thr, uptr pc, uptr p, uptr sz) {
// freed). Note: we can't simply madvise, because we need to leave a zeroed // freed). Note: we can't simply madvise, because we need to leave a zeroed
// range (otherwise __tsan_java_move can crash if it encounters a left-over // range (otherwise __tsan_java_move can crash if it encounters a left-over
// meta objects in java heap). // meta objects in java heap).
UnmapOrDie((void*)p0, sz0); uptr metap = (uptr)MemToMeta(p0);
MmapFixedNoReserve(p0, sz0); uptr metasz = sz0 / kMetaRatio;
UnmapOrDie((void*)metap, metasz);
MmapFixedNoReserve(metap, metasz);
} }
MBlock* MetaMap::GetBlock(uptr p) { MBlock* MetaMap::GetBlock(uptr p) {

View File

@ -0,0 +1,47 @@
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include "test.h"
#include <errno.h>
#include <sys/mman.h>
void *SubWorker(void *arg) {
(void)arg;
const int kMmapSize = 65536;
for (int i = 0; i < 500; i++) {
int *ptr = (int*)mmap(0, kMmapSize, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
*ptr = 42;
munmap(ptr, kMmapSize);
}
return 0;
}
void *Worker1(void *arg) {
(void)arg;
pthread_t th[4];
for (int i = 0; i < 4; i++)
pthread_create(&th[i], 0, SubWorker, 0);
for (int i = 0; i < 4; i++)
pthread_join(th[i], 0);
return 0;
}
void *Worker(void *arg) {
(void)arg;
pthread_t th[4];
for (int i = 0; i < 4; i++)
pthread_create(&th[i], 0, Worker1, 0);
for (int i = 0; i < 4; i++)
pthread_join(th[i], 0);
return 0;
}
int main() {
pthread_t th[4];
for (int i = 0; i < 4; i++)
pthread_create(&th[i], 0, Worker, 0);
for (int i = 0; i < 4; i++)
pthread_join(th[i], 0);
fprintf(stderr, "DONE\n");
}
// CHECK: DONE