Added command-line option --first-race-only.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@9728 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/drd/drd_load_store.c b/drd/drd_load_store.c
index 6521073..8089a0d 100644
--- a/drd/drd_load_store.c
+++ b/drd/drd_load_store.c
@@ -53,20 +53,32 @@
 
 /* Local variables. */
 
-static Bool DRD_(s_check_stack_accesses) = False;
+static Bool s_check_stack_accesses = False;
+static Bool s_first_race_only      = False;
 
 
 /* Function definitions. */
 
 Bool DRD_(get_check_stack_accesses)()
 {
-   return DRD_(s_check_stack_accesses);
+   return s_check_stack_accesses;
 }
 
 void DRD_(set_check_stack_accesses)(const Bool c)
 {
    tl_assert(c == False || c == True);
-   DRD_(s_check_stack_accesses) = c;
+   s_check_stack_accesses = c;
+}
+
+Bool DRD_(get_first_race_only)()
+{
+   return s_first_race_only;
+}
+
+void DRD_(set_first_race_only)(const Bool fro)
+{
+   tl_assert(fro == False || fro == True);
+   s_first_race_only = fro;
 }
 
 void DRD_(trace_mem_access)(const Addr addr, const SizeT size,
@@ -124,6 +136,11 @@
                            VG_(get_IP)(VG_(get_running_tid)()),
                            "Conflicting accesses",
                            &drei);
+
+   if (s_first_race_only)
+   {
+      DRD_(start_suppression)(addr, addr + size, "first race only");
+   }
 }
 
 VG_REGPARM(2) void DRD_(trace_load)(Addr addr, SizeT size)
@@ -135,7 +152,7 @@
 #endif
 
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_load_triggers_conflict(addr, addr + size)
        && ! DRD_(is_suppressed)(addr, addr + size))
@@ -147,7 +164,7 @@
 static VG_REGPARM(1) void drd_trace_load_1(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_load_1_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 1))
@@ -159,7 +176,7 @@
 static VG_REGPARM(1) void drd_trace_load_2(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_load_2_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 2))
@@ -171,7 +188,7 @@
 static VG_REGPARM(1) void drd_trace_load_4(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_load_4_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 4))
@@ -183,7 +200,7 @@
 static VG_REGPARM(1) void drd_trace_load_8(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_load_8_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 8))
@@ -201,7 +218,7 @@
 #endif
 
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_store_triggers_conflict(addr, addr + size)
        && ! DRD_(is_suppressed)(addr, addr + size))
@@ -213,7 +230,7 @@
 static VG_REGPARM(1) void drd_trace_store_1(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_store_1_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 1))
@@ -225,7 +242,7 @@
 static VG_REGPARM(1) void drd_trace_store_2(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_store_2_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 2))
@@ -237,7 +254,7 @@
 static VG_REGPARM(1) void drd_trace_store_4(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_store_4_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 4))
@@ -249,7 +266,7 @@
 static VG_REGPARM(1) void drd_trace_store_8(Addr addr)
 {
    if (DRD_(running_thread_is_recording)()
-       && (DRD_(s_check_stack_accesses)
+       && (s_check_stack_accesses
            || ! DRD_(thread_address_on_stack)(addr))
        && bm_access_store_8_triggers_conflict(addr)
        && ! DRD_(is_suppressed)(addr, addr + 8))
@@ -310,7 +327,7 @@
                                             mkIRExpr_HWord(size)))));
    }
 
-   if (! DRD_(s_check_stack_accesses) && is_stack_access(bb, addr_expr))
+   if (! s_check_stack_accesses && is_stack_access(bb, addr_expr))
       return;
 
    switch (size)
@@ -375,7 +392,7 @@
                                                                  mkIRExpr_HWord(size)))));
    }
 
-   if (! DRD_(s_check_stack_accesses) && is_stack_access(bb, addr_expr))
+   if (! s_check_stack_accesses && is_stack_access(bb, addr_expr))
       return;
 
    switch (size)
diff --git a/drd/drd_load_store.h b/drd/drd_load_store.h
index fcd7cc8..974defc 100644
--- a/drd/drd_load_store.h
+++ b/drd/drd_load_store.h
@@ -38,6 +38,8 @@
 
 Bool DRD_(get_check_stack_accesses)(void);
 void DRD_(set_check_stack_accesses)(const Bool c);
+Bool DRD_(get_first_race_only)(void);
+void DRD_(set_first_race_only)(const Bool fro);
 IRSB* DRD_(instrument)(VgCallbackClosure* const closure,
                        IRSB* const bb_in,
                        VexGuestLayout* const layout,
diff --git a/drd/drd_main.c b/drd/drd_main.c
index 8d08678..0dfb00a 100644
--- a/drd/drd_main.c
+++ b/drd/drd_main.c
@@ -55,7 +55,6 @@
 
 /* Local variables. */
 
-static Bool DRD_(s_first_race_only)  = False;
 static Bool DRD_(s_print_stats)      = False;
 static Bool DRD_(s_var_info)         = False;
 static Bool DRD_(s_show_stack_usage) = False;
@@ -68,6 +67,7 @@
 {
    int check_stack_accesses   = -1;
    int exclusive_threshold_ms = -1;
+   int first_race_only        = -1;
    int report_signal_unlocked = -1;
    int segment_merging        = -1;
    int shared_threshold_ms    = -1;
@@ -87,7 +87,7 @@
 
    if      VG_BOOL_CLO(arg, "--check-stack-var",     check_stack_accesses) {}
    else if VG_BOOL_CLO(arg, "--drd-stats",           DRD_(s_print_stats)) {}
-   else if VG_BOOL_CLO(arg, "--first-race-only",     DRD_(s_first_race_only)) {}
+   else if VG_BOOL_CLO(arg, "--first-race-only",     first_race_only) {}
    else if VG_BOOL_CLO(arg,"--report-signal-unlocked",report_signal_unlocked) {}
    else if VG_BOOL_CLO(arg, "--segment-merging",     segment_merging) {}
    else if VG_BOOL_CLO(arg, "--show-confl-seg",      show_confl_seg) {}
@@ -118,6 +118,10 @@
       DRD_(mutex_set_lock_threshold)(exclusive_threshold_ms);
       DRD_(rwlock_set_exclusive_threshold)(exclusive_threshold_ms);
    }
+   if (first_race_only != -1)
+   {
+      DRD_(set_first_race_only)(first_race_only);
+   }
    if (report_signal_unlocked != -1)
    {
       DRD_(cond_set_report_signal_unlocked)(report_signal_unlocked);