tests: A test program for the new mwait implementation.
authorMarc Orr <morr@cs.wisc.edu>
Thu, 6 Nov 2014 11:42:21 +0000 (05:42 -0600)
committerMarc Orr <morr@cs.wisc.edu>
Thu, 6 Nov 2014 11:42:21 +0000 (05:42 -0600)
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>

tests/test-progs/mwait/Makefile [new file with mode: 0644]
tests/test-progs/mwait/mwait.c [new file with mode: 0644]

diff --git a/tests/test-progs/mwait/Makefile b/tests/test-progs/mwait/Makefile
new file mode 100644 (file)
index 0000000..6b88811
--- /dev/null
@@ -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 (file)
index 0000000..f5ce3c3
--- /dev/null
@@ -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;
+}