diff options
author | Marc Orr <morr@cs.wisc.edu> | 2014-11-06 05:42:21 -0600 |
---|---|---|
committer | Marc Orr <morr@cs.wisc.edu> | 2014-11-06 05:42:21 -0600 |
commit | 3947f88d0fa35d2134fa3e999e05bb184a01e396 (patch) | |
tree | 0eeff86094d8721cffb673cb39d9434d55a1ab88 /tests | |
parent | bd32d55a2c457e7e68c1462d05fa126aa131a21a (diff) | |
download | gem5-3947f88d0fa35d2134fa3e999e05bb184a01e396.tar.xz |
tests: A test program for the new mwait implementation.
This is a simple test program for the new mwait implemenation. It is uses
m5threads to create to threads of execution in syscall emulation mode that
interact using the mwait instruction.
Committed by: Nilay Vaish <nilay@cs.wisc.edu>
Diffstat (limited to 'tests')
-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; +} |