tc08_hbl2.c revision 8777f7308785b4eb67898670e29ecdde42dec9df
1b411202f9ff33a587558e2e836626bc7eb9db183sewardj
2b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* FIXME: this is basically a bad test as it is scheduling-
3b411202f9ff33a587558e2e836626bc7eb9db183sewardj   sensitive.  Sometimes the output is:
4b411202f9ff33a587558e2e836626bc7eb9db183sewardj
5b411202f9ff33a587558e2e836626bc7eb9db183sewardj   child: new value 6
6b411202f9ff33a587558e2e836626bc7eb9db183sewardj   child: new value 10
7b411202f9ff33a587558e2e836626bc7eb9db183sewardj   done, x = 10
8b411202f9ff33a587558e2e836626bc7eb9db183sewardj
9b411202f9ff33a587558e2e836626bc7eb9db183sewardj   and sometimes
10b411202f9ff33a587558e2e836626bc7eb9db183sewardj
11b411202f9ff33a587558e2e836626bc7eb9db183sewardj   child: new value 10
12b411202f9ff33a587558e2e836626bc7eb9db183sewardj   done, x = 10
13b411202f9ff33a587558e2e836626bc7eb9db183sewardj*/
14b411202f9ff33a587558e2e836626bc7eb9db183sewardj
15b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <pthread.h>
16b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdio.h>
17b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <stdlib.h>
18b411202f9ff33a587558e2e836626bc7eb9db183sewardj#include <unistd.h>
19b411202f9ff33a587558e2e836626bc7eb9db183sewardj
20b411202f9ff33a587558e2e836626bc7eb9db183sewardj/* Simple test program, no race.  Parent writes atomically to a counter
21b411202f9ff33a587558e2e836626bc7eb9db183sewardj   whilst child reads it.  When counter reaches a prearranged value,
22b411202f9ff33a587558e2e836626bc7eb9db183sewardj   child joins back to parent.  Parent (writer) uses hardware bus lock;
23b411202f9ff33a587558e2e836626bc7eb9db183sewardj   child is only reading and so does not need to use a bus lock. */
24b411202f9ff33a587558e2e836626bc7eb9db183sewardj
258777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_ppc64_aix5
268777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_ppc32_aix5
278777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_x86_darwin
288777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_amd64_darwin
29b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_x86_linux
30b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_amd64_linux
31b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc32_linux
32b411202f9ff33a587558e2e836626bc7eb9db183sewardj#undef PLAT_ppc64_linux
338777f7308785b4eb67898670e29ecdde42dec9dfsewardj#undef PLAT_arm_linux
34b411202f9ff33a587558e2e836626bc7eb9db183sewardj
358777f7308785b4eb67898670e29ecdde42dec9dfsewardj#if defined(_AIX) && defined(__64BIT__)
368777f7308785b4eb67898670e29ecdde42dec9dfsewardj#  define PLAT_ppc64_aix5 1
378777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(_AIX) && !defined(__64BIT__)
388777f7308785b4eb67898670e29ecdde42dec9dfsewardj#  define PLAT_ppc32_aix5 1
398777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__APPLE__) && defined(__i386__)
408777f7308785b4eb67898670e29ecdde42dec9dfsewardj#  define PLAT_x86_darwin 1
418777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__APPLE__) && defined(__x86_64__)
428777f7308785b4eb67898670e29ecdde42dec9dfsewardj#  define PLAT_amd64_darwin 1
438777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__i386__)
44b411202f9ff33a587558e2e836626bc7eb9db183sewardj#  define PLAT_x86_linux 1
458777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__x86_64__)
46b411202f9ff33a587558e2e836626bc7eb9db183sewardj#  define PLAT_amd64_linux 1
478777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && !defined(__powerpc64__)
48b411202f9ff33a587558e2e836626bc7eb9db183sewardj#  define PLAT_ppc32_linux 1
498777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__powerpc__) && defined(__powerpc64__)
50b411202f9ff33a587558e2e836626bc7eb9db183sewardj#  define PLAT_ppc64_linux 1
518777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(__linux__) && defined(__arm__)
528777f7308785b4eb67898670e29ecdde42dec9dfsewardj#  define PLAT_arm_linux 1
53b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif
54b411202f9ff33a587558e2e836626bc7eb9db183sewardj
558777f7308785b4eb67898670e29ecdde42dec9dfsewardj
56b411202f9ff33a587558e2e836626bc7eb9db183sewardj#if defined(PLAT_amd64_linux) || defined(PLAT_x86_linux)
572ee33955b80812a8f31ec06a0430103b50aeca8csewardj#  define INC(_lval,_lqual)	     \
58b411202f9ff33a587558e2e836626bc7eb9db183sewardj      __asm__ __volatile__ ( \
59b411202f9ff33a587558e2e836626bc7eb9db183sewardj      "lock ; incl (%0)" : /*out*/ : /*in*/"r"(&(_lval)) : "memory", "cc" )
602ee33955b80812a8f31ec06a0430103b50aeca8csewardj#elif defined(PLAT_ppc32_linux) || defined(PLAT_ppc64_linux) \
612ee33955b80812a8f31ec06a0430103b50aeca8csewardj      || defined(PLAT_ppc32_aix5) || defined(PLAT_ppc64_aix5)
622ee33955b80812a8f31ec06a0430103b50aeca8csewardj#  define INC(_lval,_lqual)		  \
63b411202f9ff33a587558e2e836626bc7eb9db183sewardj   __asm__ __volatile__(                  \
642ee33955b80812a8f31ec06a0430103b50aeca8csewardj      "L1xyzzy1" _lqual ":\n"             \
65b411202f9ff33a587558e2e836626bc7eb9db183sewardj      "        lwarx 15,0,%0\n"           \
66b411202f9ff33a587558e2e836626bc7eb9db183sewardj      "        addi 15,15,1\n"            \
67b411202f9ff33a587558e2e836626bc7eb9db183sewardj      "        stwcx. 15,0,%0\n"          \
682ee33955b80812a8f31ec06a0430103b50aeca8csewardj      "        bne- L1xyzzy1" _lqual      \
69b411202f9ff33a587558e2e836626bc7eb9db183sewardj      : /*out*/ : /*in*/ "b"(&(_lval))    \
70b411202f9ff33a587558e2e836626bc7eb9db183sewardj      : /*trash*/ "r15", "cr0", "memory"  \
71b411202f9ff33a587558e2e836626bc7eb9db183sewardj   )
728777f7308785b4eb67898670e29ecdde42dec9dfsewardj#elif defined(PLAT_arm_linux)
738777f7308785b4eb67898670e29ecdde42dec9dfsewardj#  define INC(_lval,_lqual) \
748777f7308785b4eb67898670e29ecdde42dec9dfsewardj  __asm__ __volatile__( \
758777f7308785b4eb67898670e29ecdde42dec9dfsewardj      "L1xyzzy1" _lqual ":\n"                \
768777f7308785b4eb67898670e29ecdde42dec9dfsewardj      "        ldrex r8, [%0, #0]\n"         \
778777f7308785b4eb67898670e29ecdde42dec9dfsewardj      "        add   r8, r8, #1\n"           \
788777f7308785b4eb67898670e29ecdde42dec9dfsewardj      "        strex r9, r8, [%0, #0]\n"     \
798777f7308785b4eb67898670e29ecdde42dec9dfsewardj      "        cmp   r9, #0\n"               \
808777f7308785b4eb67898670e29ecdde42dec9dfsewardj      "        bne L1xyzzy1" _lqual          \
818777f7308785b4eb67898670e29ecdde42dec9dfsewardj      : /*out*/ : /*in*/ "r"(&(_lval))       \
828777f7308785b4eb67898670e29ecdde42dec9dfsewardj      : /*trash*/ "r8", "r9", "cc", "memory" \
838777f7308785b4eb67898670e29ecdde42dec9dfsewardj  );
84b411202f9ff33a587558e2e836626bc7eb9db183sewardj#else
85b411202f9ff33a587558e2e836626bc7eb9db183sewardj#  error "Fix Me for this platform"
86b411202f9ff33a587558e2e836626bc7eb9db183sewardj#endif
87b411202f9ff33a587558e2e836626bc7eb9db183sewardj
88b411202f9ff33a587558e2e836626bc7eb9db183sewardj
89b411202f9ff33a587558e2e836626bc7eb9db183sewardj
90b411202f9ff33a587558e2e836626bc7eb9db183sewardj#define LIMIT 10
91b411202f9ff33a587558e2e836626bc7eb9db183sewardj
92b411202f9ff33a587558e2e836626bc7eb9db183sewardjvolatile int x = 0;
93b411202f9ff33a587558e2e836626bc7eb9db183sewardj
94b411202f9ff33a587558e2e836626bc7eb9db183sewardjvoid* child_fn ( void* arg )
95b411202f9ff33a587558e2e836626bc7eb9db183sewardj{
96b411202f9ff33a587558e2e836626bc7eb9db183sewardj   int q = 0;
97b411202f9ff33a587558e2e836626bc7eb9db183sewardj   int oldx = 0;
98b411202f9ff33a587558e2e836626bc7eb9db183sewardj   int ctr = 0;
99b411202f9ff33a587558e2e836626bc7eb9db183sewardj   while (1) {
100b411202f9ff33a587558e2e836626bc7eb9db183sewardj      q = (x >= LIMIT);
101b411202f9ff33a587558e2e836626bc7eb9db183sewardj      if (x != oldx) {
102b411202f9ff33a587558e2e836626bc7eb9db183sewardj         oldx = x;
103b411202f9ff33a587558e2e836626bc7eb9db183sewardj         printf("child: new value %d\n", oldx);
104b411202f9ff33a587558e2e836626bc7eb9db183sewardj         fflush(stdout);
105b411202f9ff33a587558e2e836626bc7eb9db183sewardj      }
106b411202f9ff33a587558e2e836626bc7eb9db183sewardj      if (q) break;
107b411202f9ff33a587558e2e836626bc7eb9db183sewardj      /* Make sure the parent doesn't starve.  Seems to be a problem
108b411202f9ff33a587558e2e836626bc7eb9db183sewardj	 on very slow machines. */
109b411202f9ff33a587558e2e836626bc7eb9db183sewardj      ctr++;
110b411202f9ff33a587558e2e836626bc7eb9db183sewardj      if (ctr == 2000000) sleep(1);
111b411202f9ff33a587558e2e836626bc7eb9db183sewardj   }
112b411202f9ff33a587558e2e836626bc7eb9db183sewardj   return NULL;
113b411202f9ff33a587558e2e836626bc7eb9db183sewardj}
114b411202f9ff33a587558e2e836626bc7eb9db183sewardj
115b411202f9ff33a587558e2e836626bc7eb9db183sewardjint main ( void )
116b411202f9ff33a587558e2e836626bc7eb9db183sewardj{
117b411202f9ff33a587558e2e836626bc7eb9db183sewardj   pthread_t child;
118b411202f9ff33a587558e2e836626bc7eb9db183sewardj   int i;
119b411202f9ff33a587558e2e836626bc7eb9db183sewardj
120b411202f9ff33a587558e2e836626bc7eb9db183sewardj   if (pthread_create(&child, NULL, child_fn, NULL)) {
121b411202f9ff33a587558e2e836626bc7eb9db183sewardj      perror("pthread_create");
122b411202f9ff33a587558e2e836626bc7eb9db183sewardj      exit(1);
123b411202f9ff33a587558e2e836626bc7eb9db183sewardj   }
124b411202f9ff33a587558e2e836626bc7eb9db183sewardj
125b411202f9ff33a587558e2e836626bc7eb9db183sewardj   for (i = 0; i < LIMIT; i++) {
1262ee33955b80812a8f31ec06a0430103b50aeca8csewardj      INC(x, "main");
127b411202f9ff33a587558e2e836626bc7eb9db183sewardj      if (i == 5) sleep(1); /* make sure child doesn't starve */
128b411202f9ff33a587558e2e836626bc7eb9db183sewardj   }
129b411202f9ff33a587558e2e836626bc7eb9db183sewardj
130b411202f9ff33a587558e2e836626bc7eb9db183sewardj   if (pthread_join(child, NULL)) {
131b411202f9ff33a587558e2e836626bc7eb9db183sewardj      perror("pthread join");
132b411202f9ff33a587558e2e836626bc7eb9db183sewardj      exit(1);
133b411202f9ff33a587558e2e836626bc7eb9db183sewardj   }
134b411202f9ff33a587558e2e836626bc7eb9db183sewardj
135b411202f9ff33a587558e2e836626bc7eb9db183sewardj   printf("done, x = %d\n", x);
136b411202f9ff33a587558e2e836626bc7eb9db183sewardj
137b411202f9ff33a587558e2e836626bc7eb9db183sewardj   return 0;
138b411202f9ff33a587558e2e836626bc7eb9db183sewardj}
139