OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [gcc.dg/] [simulate-thread/] [README] - Blame information for rev 695

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 689 jeremybenn
OVERVIEW
2
--------
3
 
4
This is a harness to test the atomicity of certain operations, and to
5
make sure the compiler does not introduce data races in a
6
multi-threaded environment.
7
 
8
The basic premise is that we set up testcases such that the thing we
9
want test, say an atomic instruction which stores a double word is in
10
a function of its own.  We then run this testcase within GDB,
11
controlled by a gdb script (simulate-thread.gdb).  The gdb script will
12
break on the function to be tested, and then single step through every
13
machine instruction in the function.  We set this up so GDB can make a
14
couple of inferior function calls before and after each of these
15
single step instructions for a couple of purposes:
16
 
17
       1.  One of the calls simulates another thread running in the
18
           process which changes or access memory.
19
 
20
       2.  The other calls are used to verify that we always get the
21
           expected behavior.
22
 
23
For example, in the case of an atomic store, anyone looking at the
24
memory associated with an atomic variable should never see any in
25
between states. If you have an atomic long long int, and it starts
26
with the value 0, and you write the value MAX_LONG_LONG, any other
27
thread looking at that variable should never see anything other than 0
28
or MAX_LONG_LONG.  If you implement the atomic write as a sequence of
29
2 stores, it is possible for another thread to read the location after
30
the first store, but before the second one is complete. That thread
31
would then see an in-between state (one word would still be 0).
32
 
33
We simulate this in the testcase by having GDB step through the
34
program, instruction by instruction, and after each step, making an
35
inferior function call which looks at the value of the atomic variable
36
and verifies that it sees either 0 or MAX_LONG_LONG.  If it sees any
37
other value, it fails the testcase.
38
 
39
This way, we are *sure* there is no in between state because we
40
effectively acted like an OS and switched to another thread after
41
every single instruction of the routine is executed and looked at the
42
results each time.
43
 
44
We use the same idea to test for data races to see if an illegal load
45
has been hoisted, or that two parallel bitfield writes don't overlap
46
in a data race.
47
 
48
Below is a skeleton of how a test should look like.  For more details,
49
look at the tests themselves.
50
 
51
ANATOMY OF A TEST
52
-----------------
53
 
54
/* { dg-do link } */
55
/* { dg-options "-some-flags" } */
56
/* { dg-final { simulate-thread } } */
57
 
58
/* NOTE: Any failure must be indicated by displaying "FAIL:".  */
59
 
60
#include "simulate-thread.h"
61
 
62
/* Called before each instruction, simulating another thread executing.  */
63
void simulate_thread_other_threads()
64
{
65
}
66
 
67
/* Called after each instruction.  Returns 1 if any inconsistency is
68
   found, 0 otherwise.  */
69
int simulate_thread_step_verify()
70
{
71
  if (some_problem)
72
    {
73
      printf("FAIL: reason\n");
74
      return 1;
75
    }
76
  return 0;
77
}
78
 
79
/* Called at the end of the program (simulate_thread_fini == 1).  Verifies
80
   the state of the program and returns 1 if any inconsistency is
81
   found, 0 otherwise.  */
82
int simulate_thread_final_verify()
83
{
84
  if (some_problem)
85
    {
86
      printf("FAIL: reason\n");
87
      return 1;
88
    }
89
  return 0;
90
}
91
 
92
/* The gdb script will break on simulate_thread_main(), so make sure
93
   GCC does not inline it, thus making the break point fail.  */
94
__attribute__((noinline))
95
void simulate_thread_main()
96
{
97
  /* Do stuff.  */
98
}
99
 
100
int main()
101
{
102
 
103
  /* Perform any setup code that will run outside of the testing
104
     harness.  Put code here that you do NOT want to be interrupted on
105
     an instruction basis.  E.g., setup code, and system library
106
     calls.  */
107
 
108
     /* Do un-instrumented stuff. */
109
     /* ... */
110
 
111
  /* Start the instrumented show.  */
112
  simulate_thread_main();
113
 
114
  /* Must be called at the end of the test.  */
115
  simulate_thread_done();
116
 
117
  return 0;
118
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.