summaryrefslogtreecommitdiff
path: root/tests/test-progs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test-progs')
-rw-r--r--tests/test-progs/mwait/Makefile20
-rw-r--r--tests/test-progs/mwait/mwait.c73
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;
+}