diff options
author | Dmitry Vyukov <dvyukov@google.com> | 2012-12-18 12:20:55 +0000 |
---|---|---|
committer | Dmitry Vyukov <dvyukov@google.com> | 2012-12-18 12:20:55 +0000 |
commit | e3178e8fab67e77165978006928228f9be2ce30d (patch) | |
tree | f98c01295712a7ea1dd5371cc6e1545dedd22e2c /lib | |
parent | 0b1137574d93882f1e1ba4f463139345cec7afce (diff) |
tsan: add io_sync flag that controls amount of IO synchronization
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@170427 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/tsan/rtl/tsan_fd.cc | 13 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_flags.cc | 8 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_flags.h | 5 |
3 files changed, 24 insertions, 2 deletions
diff --git a/lib/tsan/rtl/tsan_fd.cc b/lib/tsan/rtl/tsan_fd.cc index 4431097e1..7428596b1 100644 --- a/lib/tsan/rtl/tsan_fd.cc +++ b/lib/tsan/rtl/tsan_fd.cc @@ -92,7 +92,15 @@ static void init(ThreadState *thr, uptr pc, int fd, FdSync *s) { // See e.g. libc __res_iclose(). if (d->sync) unref(thr, pc, d->sync); - d->sync = s; + if (flags()->io_sync == 0) { + unref(thr, pc, s); + d->sync = 0; + } else if (flags()->io_sync == 1) { + d->sync = s; + } else if (flags()->io_sync == 2) { + unref(thr, pc, s); + d->sync = &fdctx.globsync; + } d->creation_tid = thr->tid; d->creation_stack = CurrentStackId(thr, pc); // To catch races between fd usage and open. @@ -171,8 +179,9 @@ void FdDup(ThreadState *thr, uptr pc, int oldfd, int newfd) { void FdPipeCreate(ThreadState *thr, uptr pc, int rfd, int wfd) { DPrintf("#%d: FdCreatePipe(%d, %d)\n", thr->tid, rfd, wfd); FdSync *s = allocsync(); - init(thr, pc, rfd, s); + init(thr, pc, rfd, ref(s)); init(thr, pc, wfd, ref(s)); + unref(thr, pc, s); } void FdEventCreate(ThreadState *thr, uptr pc, int fd) { diff --git a/lib/tsan/rtl/tsan_flags.cc b/lib/tsan/rtl/tsan_flags.cc index 25c370f03..88c4bb6a2 100644 --- a/lib/tsan/rtl/tsan_flags.cc +++ b/lib/tsan/rtl/tsan_flags.cc @@ -58,6 +58,7 @@ void InitializeFlags(Flags *f, const char *env) { f->running_on_valgrind = false; f->external_symbolizer_path = ""; f->history_size = kGoMode ? 1 : 2; // There are a lot of goroutines in Go. + f->io_sync = 1; // Let a frontend override. OverrideFlags(f); @@ -83,6 +84,7 @@ void InitializeFlags(Flags *f, const char *env) { ParseFlag(env, &f->stop_on_start, "stop_on_start"); ParseFlag(env, &f->external_symbolizer_path, "external_symbolizer_path"); ParseFlag(env, &f->history_size, "history_size"); + ParseFlag(env, &f->io_sync, "io_sync"); if (!f->report_bugs) { f->report_thread_leaks = false; @@ -95,6 +97,12 @@ void InitializeFlags(Flags *f, const char *env) { " (must be [0..7])\n"); Die(); } + + if (f->io_sync < 0 || f->io_sync > 2) { + Printf("ThreadSanitizer: incorrect value for io_sync" + " (must be [0..2])\n"); + Die(); + } } } // namespace __tsan diff --git a/lib/tsan/rtl/tsan_flags.h b/lib/tsan/rtl/tsan_flags.h index 2fdcc2f1b..6547911ec 100644 --- a/lib/tsan/rtl/tsan_flags.h +++ b/lib/tsan/rtl/tsan_flags.h @@ -77,6 +77,11 @@ struct Flags { // the amount of memory accesses, up to history_size=7 that amounts to // 4M memory accesses. The default value is 2 (128K memory accesses). int history_size; + // Controls level of synchronization implied by IO operations. + // 0 - no synchronization + // 1 - reasonable level of synchronization (write->read) + // 2 - global synchronization of all IO operations + int io_sync; }; Flags *flags(); |