e1b2035456a1b496d41b528ca7e7a0404db2d967
[gem5.git] / tests / test-progs / mwait / mwait.c
1 // author: Marc Orr
2
3 #include <pthread.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6
7 #define NUM_TRIES 1000
8
9 // Make sure that flags and wait sit in different cache lines
10 volatile int flags[10];
11 volatile int wait[10];
12
13 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
14
15 void *DoWork1(void *threadid)
16 {
17 flags[0] = flags[0] + 1;
18 wait[0] = 0;
19 pthread_exit(0);
20 }
21
22 void *DoWork2(void *threadid)
23 {
24 pthread_mutex_lock (&mutex);
25 flags[0] = flags[0] + 1;
26 pthread_mutex_unlock (&mutex);
27 pthread_exit(0);
28 }
29
30 ////////////////////////////////////////////////////////////////////////////////
31 // Program main
32 ////////////////////////////////////////////////////////////////////////////////
33 int main( int argc, char** argv)
34 {
35 // stuff for thread
36 pthread_t threads[1];
37
38 // initialize global variables
39 flags[0] = 0;
40 wait[0] = 1;
41
42 // monitor (via gcc intrinsic)
43 __builtin_ia32_monitor ((void *)&flags, 0, 0);
44
45 // invalidate flags in this cpu's cache
46 pthread_create(&threads[0], NULL, DoWork1, NULL);
47 while (wait[0]);
48
49 // launch thread to invalidate address being monitored
50 pthread_create(&threads[0], NULL, DoWork2, NULL);
51
52 // wait for other thread to modify flags
53 int mwait_cnt = 0;
54 do {
55 pthread_mutex_lock (&mutex);
56 if (flags[0] != 2) {
57 pthread_mutex_unlock (&mutex);
58 __builtin_ia32_mwait(0, 0);
59 } else {
60 pthread_mutex_unlock (&mutex);
61 }
62 mwait_cnt++;
63 } while (flags[0] != 2 && mwait_cnt < NUM_TRIES);
64
65 // test may hang if mwait is not working
66 if (flags[0]==2) {
67 printf("mwait regression PASSED, flags[0] = %d\n", flags[0]);
68 } else {
69 printf("mwait regression FAILED, flags[0] = %d\n", flags[0]);
70 }
71
72 return 0;
73 }