]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/valgrind/src/valgrind-3.6.0-svn/none/tests/x86/yield.c
Some minor fixes.
[l4.git] / l4 / pkg / valgrind / src / valgrind-3.6.0-svn / none / tests / x86 / yield.c
1 /* 
2    Check that a thread which yields with pause (rep;nop) makes less
3    progress against a pure spinner.
4  */
5 #include <pthread.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <unistd.h>
9
10 static pthread_mutex_t m_go = PTHREAD_MUTEX_INITIALIZER;
11 static pthread_cond_t c_go = PTHREAD_COND_INITIALIZER;
12 static pthread_cond_t c_running = PTHREAD_COND_INITIALIZER;
13
14 static volatile int alive, running;
15
16 static int spin;
17 static int rep_nop;
18
19 static void *spinner(void *v)
20 {
21         pthread_mutex_lock(&m_go);
22         while(!alive)
23                 pthread_cond_wait(&c_go, &m_go);
24         running++;
25         pthread_cond_signal(&c_running);
26         pthread_mutex_unlock(&m_go);
27
28         while(alive)
29                 spin++;
30
31         return 0;
32 }
33
34 static void *rep_nopper(void *v)
35 {
36         pthread_mutex_lock(&m_go);
37         while(!alive)
38                 pthread_cond_wait(&c_go, &m_go);
39         running++;
40         pthread_cond_signal(&c_running);
41         pthread_mutex_unlock(&m_go);
42
43         while(alive) {
44                 rep_nop++;
45                 // This gives a hint to a P4, telling it to pause 
46                 // (ie. we're in a spin-wait loop)
47                 asm volatile ("rep; nop" : : : "memory");
48         }
49
50         return 0;
51 }
52
53 int main()
54 {
55         pthread_t a, b;
56
57         pthread_create(&a, NULL, spinner, NULL);
58         pthread_create(&b, NULL, rep_nopper, NULL);
59
60         /* make sure both threads start at the same time */
61         pthread_mutex_lock(&m_go);
62         alive = 1;
63         pthread_cond_broadcast(&c_go);
64
65         /* make sure they both get started */
66         while(running < 2)
67                 pthread_cond_wait(&c_running, &m_go);
68         pthread_mutex_unlock(&m_go);
69
70         sleep(2);
71
72         alive = 0;
73         pthread_join(a, NULL);
74         pthread_join(b, NULL);
75
76         if (0)
77                 printf("spin=%d rep_nop=%d rep_nop:spin ratio: %g\n", 
78                        spin, rep_nop, (float)rep_nop / spin);
79
80         if (spin > rep_nop)
81                 printf("PASS\n");
82         else
83                 printf("FAIL spin=%d rep_nop=%d rep_nop:spin ratio: %g\n", 
84                        spin, rep_nop, (float)rep_nop / spin);
85
86         return 0;
87 }