diff options
Diffstat (limited to 'tests/test-progs/mwait/mwait.c')
-rw-r--r-- | tests/test-progs/mwait/mwait.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/tests/test-progs/mwait/mwait.c b/tests/test-progs/mwait/mwait.c new file mode 100644 index 000000000..f5ce3c32b --- /dev/null +++ b/tests/test-progs/mwait/mwait.c @@ -0,0 +1,73 @@ +// author: Marc Orr + +#include <pthread.h> +#include <stdio.h> +#include <stdlib.h> + +#define NUM_TRIES 1000 + +// Make sure that flags and wait sit in different cache lines +volatile int flags[10]; +volatile int wait[10]; + +pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; + +void *DoWork1(void *threadid) +{ + flags[0] = flags[0] + 1; + wait[0] = 0; + pthread_exit(0); +} + +void *DoWork2(void *threadid) +{ + pthread_mutex_lock (&mutex); + flags[0] = flags[0] + 1; + pthread_mutex_unlock (&mutex); + pthread_exit(0); +} + +//////////////////////////////////////////////////////////////////////////////// +// Program main +//////////////////////////////////////////////////////////////////////////////// +int main( int argc, char** argv) +{ + // stuff for thread + pthread_t threads[1]; + + // initialize global variables + flags[0] = 0; + wait[0] = 1; + + // monitor (via gcc intrinsic) + __builtin_ia32_monitor ((void *)&flags, 0, 0); + + // invalidate flags in this cpu's cache + pthread_create(&threads[0], NULL, DoWork1, NULL); + while(wait[0]); + + // launch thread to invalidate address being monitored + pthread_create(&threads[0], NULL, DoWork2, NULL); + + // wait for other thread to modify flags + int mwait_cnt = 0; + do { + pthread_mutex_lock (&mutex); + if(flags[0] != 2) { + pthread_mutex_unlock (&mutex); + __builtin_ia32_mwait(0, 0); + } else { + pthread_mutex_unlock (&mutex); + } + mwait_cnt++; + } while(flags[0] != 2 && mwait_cnt < NUM_TRIES); + + // test may hang if mwait is not working + if(flags[0]==2) { + printf("mwait regression PASSED, flags[0] = %d\n", flags[0]); + } else { + printf("mwait regression FAILED, flags[0] = %d\n", flags[0]); + } + + return 0; +} |