diff options
-rw-r--r-- | tests/test-progs/mwait/Makefile | 20 | ||||
-rw-r--r-- | tests/test-progs/mwait/mwait.c | 73 |
2 files changed, 93 insertions, 0 deletions
diff --git a/tests/test-progs/mwait/Makefile b/tests/test-progs/mwait/Makefile new file mode 100644 index 000000000..6b888118d --- /dev/null +++ b/tests/test-progs/mwait/Makefile @@ -0,0 +1,20 @@ + +CPP := g++ + +TEST_OBJS := mwait.o +TEST_PROGS := $(TEST_OBJS:.o=) + +# ==== Rules ================================================================== + +.PHONY: default clean + +default: $(TEST_PROGS) + +clean: + $(RM) $(TEST_OBJS) $(TEST_PROGS) + +$(TEST_PROGS): $(TEST_OBJS) + $(CPP) -static -o $@ $@.o pthread.o + +%.o: %.c Makefile + $(CPP) -c -o $@ $*.c -msse3 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; +} |