Add another mutex tester for Jeff's spinlock code w/ the refcount
authorMatthew Dillon <dillon@dragonflybsd.org>
Thu, 18 May 2006 02:22:46 +0000 (02:22 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Thu, 18 May 2006 02:22:46 +0000 (02:22 +0000)
optimization.

test/sysperf/Makefile
test/sysperf/mutex3.c [new file with mode: 0644]

index c5e78b1..10677e7 100644 (file)
@@ -1,11 +1,11 @@
 #
-# $DragonFly: src/test/sysperf/Makefile,v 1.14 2006/04/22 22:32:52 dillon Exp $
+# $DragonFly: src/test/sysperf/Makefile,v 1.15 2006/05/18 02:22:46 dillon Exp $
 #
 
 TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 \
        /tmp/loop1 /tmp/loop2 /tmp/loop3 \
        /tmp/call1 /tmp/call2 /tmp/call3 /tmp/cmp \
-       /tmp/mt2 \
+       /tmp/mt2 /tmp/mt3 \
        /tmp/fork1 /tmp/pipe1 /tmp/pipe2 \
        /tmp/sw1 /tmp/sw2 /tmp/sw3 \
        /tmp/mbw1 \
@@ -76,6 +76,9 @@ all:  $(TARGETS)
 /tmp/mt2: mutex2.c blib.c mtx.s
        $(CC) $(CFLAGS) mutex2.c blib.c mtx.s -o /tmp/mt2
 
+/tmp/mt3: mutex3.c blib.c mtx.s
+       $(CC) $(CFLAGS) mutex3.c blib.c mtx.s -o /tmp/mt3
+
 /tmp/sw1: quicksw1.c blib.c sw.S
        $(CC) $(CFLAGS) -DUSE_ALL quicksw1.c blib.c sw.S -o /tmp/sw1
 
diff --git a/test/sysperf/mutex3.c b/test/sysperf/mutex3.c
new file mode 100644 (file)
index 0000000..173ce4d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * mutex3.c
+ *
+ * $DragonFly: src/test/sysperf/mutex3.c,v 1.1 2006/05/18 02:22:46 dillon Exp $
+ */
+
+#include "blib.h"
+
+#include <sys/types.h>
+#include <machine/atomic.h>
+#include <machine/cpufunc.h>
+
+int *mtx;
+int refcnt;
+
+static void
+spin_lock_contested(void)
+{
+       int i;
+       int j;
+
+       j = 1;
+       while (atomic_swap_int(mtx, 1) != 0) {
+               for (i = 0; i < j; ++i)
+                       __asm __volatile("pause"::);
+               j <<= 1;
+       }
+}
+
+static __inline void
+spin_lock(void)
+{
+       if (refcnt == 1) {
+               if (*mtx == 0)
+                       *mtx = 1;
+               else
+                       spin_lock_contested();
+       } else if (atomic_swap_int(mtx, 1) != 0) {
+               spin_lock_contested();
+       }
+}
+
+static __inline void
+spin_unlock(void)
+{
+       cpu_sfence();
+       *mtx = 0;
+}
+
+int
+main(int ac, char **av)
+{
+    long long count = 0;
+    long long max;
+    int j;
+    int *counter;
+    pid_t pid;
+
+    printf("Test simple locked bus cycle mutex latency\n");
+    printf("auto-forks two processes for the test with shared memory\n");
+    printf("This test is only useful on a SMP box\n");
+
+    start_timing();
+    mtx = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANON, -1, 0);
+    counter = mtx + 64;
+    while (stop_timing(0, NULL) == 0) {
+       for (j = 0; j < 100; ++j) {
+           spin_lock();
+           spin_unlock();
+       }
+       count += 100;
+    }
+    max = count;
+    *mtx = 0;
+
+    refcnt = 1;
+    start_timing();
+    for (count = 0; count < max; count += 100) {
+       for (j = 0; j < 100; ++j) {
+           spin_lock();
+           spin_unlock();      /* release */
+           ++counter[64];
+       }
+    }
+    stop_timing(count, "complex_mtx(uncontested/1cpu)");
+    refcnt = 2;
+
+    if ((pid = fork()) == 0) {
+       for (;;) {
+           for (j = 0; j < 100; ++j) {
+               spin_lock();
+               spin_unlock();  /* release */
+               ++counter[128];
+           }
+       }
+    } else {
+       start_timing();
+       for (count = 0; count < max; count += 100) {
+           for (j = 0; j < 100; ++j) {
+               spin_lock();
+               spin_unlock();  /* release */
+               ++counter[64];
+           }
+       }
+       stop_timing(count, "complex_mtx");
+       printf("proc1=%d proc2=%d\n", counter[64], counter[128]);
+       kill(pid, 9);
+    }
+    return(0);
+}
+