~bkerensa/ubuntu/raring/valgrind/merge-from-deb

« back to all changes in this revision

Viewing changes to helgrind/tests/tc08_hbl2.c

  • Committer: Bazaar Package Importer
  • Author(s): Andrés Roldán
  • Date: 2008-06-13 02:31:40 UTC
  • mto: (1.4.1 upstream) (2.2.1 squeeze)
  • mto: This revision was merged to the branch mainline in revision 24.
  • Revision ID: james.westby@ubuntu.com-20080613023140-iwk33rz9rhvfkr96
Import upstream version 3.3.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* FIXME: this is basically a bad test as it is scheduling-
 
3
   sensitive.  Sometimes the output is:
 
4
 
 
5
   child: new value 6
 
6
   child: new value 10
 
7
   done, x = 10
 
8
 
 
9
   and sometimes
 
10
 
 
11
   child: new value 10
 
12
   done, x = 10
 
13
*/
 
14
 
 
15
#include <pthread.h>
 
16
#include <stdio.h>
 
17
#include <stdlib.h>
 
18
#include <unistd.h>
 
19
 
 
20
/* Simple test program, no race.  Parent writes atomically to a counter
 
21
   whilst child reads it.  When counter reaches a prearranged value, 
 
22
   child joins back to parent.  Parent (writer) uses hardware bus lock;
 
23
   child is only reading and so does not need to use a bus lock. */
 
24
 
 
25
 
 
26
#undef PLAT_x86_linux
 
27
#undef PLAT_amd64_linux
 
28
#undef PLAT_ppc32_linux
 
29
#undef PLAT_ppc64_linux
 
30
#undef PLAT_ppc32_aix5
 
31
#undef PLAT_ppc64_aix5
 
32
 
 
33
#if !defined(_AIX) && defined(__i386__)
 
34
#  define PLAT_x86_linux 1
 
35
#elif !defined(_AIX) && defined(__x86_64__)
 
36
#  define PLAT_amd64_linux 1
 
37
#elif !defined(_AIX) && defined(__powerpc__) && !defined(__powerpc64__)
 
38
#  define PLAT_ppc32_linux 1
 
39
#elif !defined(_AIX) && defined(__powerpc__) && defined(__powerpc64__)
 
40
#  define PLAT_ppc64_linux 1
 
41
#elif defined(_AIX) && defined(__64BIT__)
 
42
#  define PLAT_ppc64_aix5 1
 
43
#elif defined(_AIX) && !defined(__64BIT__)
 
44
#  define PLAT_ppc32_aix5 1
 
45
#endif
 
46
 
 
47
#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux)
 
48
#  define INC(_lval,_lqual)          \
 
49
      __asm__ __volatile__ ( \
 
50
      "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" )
 
51
#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \
 
52
      || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5)
 
53
#  define INC(_lval,_lqual)               \
 
54
   __asm__ __volatile__(                  \
 
55
      "L1xyzzy1" _lqual ":\n"             \
 
56
      "        lwarx 15,0,%0\n"           \
 
57
      "        addi 15,15,1\n"            \
 
58
      "        stwcx. 15,0,%0\n"          \
 
59
      "        bne- L1xyzzy1" _lqual      \
 
60
      : /*out*/ : /*in*/ "b"(&(_lval))    \
 
61
      : /*trash*/ "r15", "cr0", "memory"  \
 
62
   )
 
63
#else
 
64
#  error "Fix Me for this platform"
 
65
#endif
 
66
 
 
67
 
 
68
 
 
69
#define LIMIT 10
 
70
 
 
71
volatile int x = 0;
 
72
 
 
73
void* child_fn ( void* arg )
 
74
{
 
75
   int q = 0;
 
76
   int oldx = 0;
 
77
   int ctr = 0;
 
78
   while (1) {
 
79
      q = (x >= LIMIT);
 
80
      if (x != oldx) {
 
81
         oldx = x;
 
82
         printf("child: new value %d\n", oldx);
 
83
         fflush(stdout);
 
84
      }
 
85
      if (q) break;
 
86
      /* Make sure the parent doesn't starve.  Seems to be a problem
 
87
         on very slow machines. */
 
88
      ctr++;
 
89
      if (ctr == 2000000) sleep(1);
 
90
   }
 
91
   return NULL;
 
92
}
 
93
 
 
94
int main ( void )
 
95
{
 
96
   pthread_t child;
 
97
   int i;
 
98
 
 
99
   if (pthread_create(&child, NULL, child_fn, NULL)) {
 
100
      perror("pthread_create");
 
101
      exit(1);
 
102
   }
 
103
 
 
104
   for (i = 0; i < LIMIT; i++) {
 
105
      INC(x, "main");
 
106
      if (i == 5) sleep(1); /* make sure child doesn't starve */
 
107
   }
 
108
 
 
109
   if (pthread_join(child, NULL)) {
 
110
      perror("pthread join");
 
111
      exit(1);
 
112
   }
 
113
 
 
114
   printf("done, x = %d\n", x);
 
115
 
 
116
   return 0;
 
117
}