aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAldy Hernandez <aldyh@redhat.com>2011-10-10 18:32:07 +0000
committerAldy Hernandez <aldyh@gcc.gnu.org>2011-10-10 18:32:07 +0000
commit13d563f0742f043e94666965709462d1de456048 (patch)
treefa03215149018aa1220886091f1712884567ee0d
parentfa6963330dc6edccda21ca2af39bc40f9fda3094 (diff)
downloadgcc-13d563f0742f043e94666965709462d1de456048.zip
gcc-13d563f0742f043e94666965709462d1de456048.tar.gz
gcc-13d563f0742f043e94666965709462d1de456048.tar.bz2
simulate-thread.gdb: Call wrappers for *other_threads() and *final_verify().
* gcc.dg/simulate-thread/simulate-thread.gdb: Call wrappers for *other_threads() and *final_verify(). * gcc.dg/simulate-thread/simulate-thread.h (simulate_thread_wrapper_other_threads): New. (simulate_thread_wrapper_final_verify): New. Co-Authored-By: Andrew MacLeod <amacleod@redhat.com> From-SVN: r179768
-rw-r--r--gcc/testsuite/ChangeLog9
-rw-r--r--gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.gdb4
-rw-r--r--gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.h104
3 files changed, 115 insertions, 2 deletions
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 7d5a1f4..faa52ac 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,12 @@
+2011-10-10 Aldy Hernandez <aldyh@redhat.com>
+ Andrew Macleod <amacleod@redhat.com>
+
+ * gcc.dg/simulate-thread/simulate-thread.gdb: Call
+ wrappers for *other_threads() and *final_verify().
+ * gcc.dg/simulate-thread/simulate-thread.h
+ (simulate_thread_wrapper_other_threads): New.
+ (simulate_thread_wrapper_final_verify): New.
+
2011-10-10 Uros Bizjak <ubizjak@gmail.com>
* lib/gcc-gdb-test.exp (gdb-test): Delete $cmd_file before return.
diff --git a/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.gdb b/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.gdb
index 004909f..c7bac73 100644
--- a/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.gdb
+++ b/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.gdb
@@ -5,13 +5,13 @@ run
set $ret = 0
while (simulate_thread_fini != 1) && (! $ret)
- call simulate_thread_other_threads()
+ call simulate_thread_wrapper_other_threads()
stepi
set $ret |= simulate_thread_step_verify()
end
if (! $ret)
- set $ret |= simulate_thread_final_verify()
+ set $ret |= simulate_thread_wrapper_final_verify()
end
continue
quit $ret
diff --git a/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.h b/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.h
index 8dabfa2..9e2361f 100644
--- a/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.h
+++ b/gcc/testsuite/gcc.dg/simulate-thread/simulate-thread.h
@@ -5,3 +5,107 @@ simulate_thread_done ()
{
simulate_thread_fini = 1;
}
+
+/* A hostile thread is one which changes a memory location so quickly
+ that another thread may never see the same value again. This is
+ simulated when simulate_thread_other_thread() is defined to modify
+ a memory location every cycle.
+
+ A process implementing a dependency on this value can run into
+ difficulties with such a hostile thread. For instance,
+ implementing an add with a compare_and_swap loop goes something
+ like:
+
+ expected = *mem;
+ loop:
+ new = expected += value;
+ if (!succeed (expected = compare_and_swap (mem, expected, new)))
+ goto loop;
+
+ If the content of 'mem' are changed every cycle by
+ simulate_thread_other_thread () this will become an infinite loop
+ since the value *mem will never be 'expected' by the time the
+ compare_and_swap is executed.
+
+ HOSTILE_THREAD_THRESHOLD defines the number of intructions which a
+ program will execute before triggering the hostile thread
+ pause. The pause will last for HOSTILE_THREAD_PAUSE instructions,
+ and then the counter will reset and begin again. During the pause
+ period, simulate_thread_other_thread will not be called.
+
+ This provides a chance for forward progress to be made and the
+ infinite loop to be avoided.
+
+ If the testcase defines HOSTILE_PAUSE_ERROR, then it will be
+ considered an RUNTIME FAILURE if the hostile pause is triggered.
+ This will allow to test for guaranteed forward progress routines.
+
+ If the default values for HOSTILE_THREAD_THRESHOLD or
+ HOSTILE_THREAD_PAUSE are insufficient, then the testcase may
+ override these by defining the values before including this file.
+
+ Most testcase are intended to run for very short periods of time,
+ so these defaults are considered to be high enough to not trigger
+ on a typical case, but not drag the test time out too much if a
+ hostile condition is interferring. */
+
+
+/* Define the threshold to start pausing the hostile thread. */
+#if !defined (HOSTILE_THREAD_THRESHOLD)
+#define HOSTILE_THREAD_THRESHOLD 500
+#endif
+
+/* Define the length of pause in cycles for the hostile thread to pause to
+ allow forward progress to be made. */
+#if !defined (HOSTILE_THREAD_PAUSE)
+#define HOSTILE_THREAD_PAUSE 20
+#endif
+
+void simulate_thread_other_threads (void);
+int simulate_thread_final_verify (void);
+
+static int simulate_thread_hostile_pause = 0;
+
+/* This function wraps simulate_thread_other_threads an monitors for
+ an infinite loop. If the threshold value HOSTILE_THREAD_THRESHOLD
+ is reached, the other_thread process is paused for
+ HOSTILE_THREAD_PAUSE cycles before resuming, and the counters start
+ again. */
+void
+simulate_thread_wrapper_other_threads()
+{
+ static int count = 0;
+ static int pause = 0;
+
+ if (++count >= HOSTILE_THREAD_THRESHOLD)
+ {
+ if (!simulate_thread_hostile_pause)
+ simulate_thread_hostile_pause = 1;
+
+ /* Count cycles before calling the hostile thread again. */
+ if (pause++ < HOSTILE_THREAD_PAUSE)
+ return;
+
+ /* Reset the pause counter, as well as the thread counter. */
+ pause = 0;
+ count = 0;
+ }
+ simulate_thread_other_threads ();
+}
+
+
+/* If the test case defines HOSTILE_PAUSE_ERROR, then the test case
+ will fail execution if it had a hostile pause. */
+int
+simulate_thread_wrapper_final_verify ()
+{
+ int ret = simulate_thread_final_verify ();
+#if defined (HOSTILE_PAUSE_ERROR)
+ if (simulate_thread_hostile_pause)
+ {
+ printf ("FAIL: Forward progress made only by pausing hostile thread\n");
+ ret = ret | 1; /* 0 indicates proper comnpletion. */
+ }
+#endif
+ return ret;
+}