Sync sysperf with some random stuff, and add a cld instruction tester.
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 9 May 2008 15:49:42 +0000 (15:49 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 9 May 2008 15:49:42 +0000 (15:49 +0000)
test/sysperf/Makefile
test/sysperf/cld1.c [new file with mode: 0644]
test/sysperf/loop4.c [new file with mode: 0644]
test/sysperf/mutex4.c [new file with mode: 0644]

index 760f923..9a8df56 100644 (file)
@@ -1,5 +1,5 @@
 #
-# $DragonFly: src/test/sysperf/Makefile,v 1.16 2006/09/10 01:26:41 dillon Exp $
+# $DragonFly: src/test/sysperf/Makefile,v 1.17 2008/05/09 15:49:42 dillon Exp $
 #
 
 TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 \
@@ -11,7 +11,8 @@ TARGETS=/tmp/sc1 /tmp/sc2 /tmp/sc3 /tmp/sc4 /tmp/sc5 \
        /tmp/mbw1 \
        /tmp/upc1 \
        /tmp/exec1 /tmp/exec2 \
-       /tmp/mem1 /tmp/mem2
+       /tmp/mem1 /tmp/mem2 \
+       /tmp/cld1
 
 .if defined(NO_OPTIMIZE)
 COPTFLAGS= -O
@@ -22,6 +23,9 @@ CFLAGS= ${COPTFLAGS} -g -I/usr/src/sys
 
 all:   $(TARGETS)
 
+/tmp/cld1: cld1.c blib.c
+       $(CC) $(CFLAGS) cld1.c blib.c -o /tmp/cld1
+
 /tmp/sc1: syscall1.c blib.c
        $(CC) $(CFLAGS) syscall1.c blib.c -o /tmp/sc1
 
diff --git a/test/sysperf/cld1.c b/test/sysperf/cld1.c
new file mode 100644 (file)
index 0000000..7b3a751
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * cld1.c
+ *
+ * $DragonFly: src/test/sysperf/cld1.c,v 1.1 2008/05/09 15:49:42 dillon Exp $
+ */
+
+#include "blib.h"
+
+static __attribute__ ((noinline)) void dummy_with_cld(void);
+static __attribute__ ((noinline)) void dummy_without_cld(void);
+
+int
+main(int ac, char **av)
+{
+    long long count = 0;
+    long long max;
+    char c;
+    int j;
+
+    printf("timing the cld instruction\n");
+
+    start_timing();
+    while (stop_timing(0, NULL) == 0) {
+       for (j = 0; j < 100; ++j)
+           getuid();
+       count += 100;
+    }
+    max = count;
+    start_timing();
+    for (count = 0; count < max; count += 100) {
+       for (j = 0; j < 100; ++j)
+           dummy_without_cld();
+    }
+    stop_timing(count, "dummy() - without cld");
+
+    start_timing();
+    for (count = 0; count < max; count += 100) {
+       for (j = 0; j < 100; ++j)
+           dummy_with_cld();
+    }
+    stop_timing(count, "dummy() - with cld");
+    return(0);
+}
+
+static
+__attribute__ ((noinline))
+void
+dummy_with_cld(void)
+{
+       volatile int i, j, k;
+
+       i = 0;
+       j = 0;
+       k = 0;
+       __asm __volatile("cld"::);
+}
+
+static
+__attribute__ ((noinline))
+void
+dummy_without_cld(void)
+{
+       volatile int i, j, k;
+
+       i = 0;
+       j = 0;
+       k = 0;
+}
diff --git a/test/sysperf/loop4.c b/test/sysperf/loop4.c
new file mode 100644 (file)
index 0000000..4006721
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ * loop4.c
+ *
+ * Used to test syscall mpsafeness, with editing
+ *
+ * $DragonFly: src/test/sysperf/loop4.c,v 1.1 2008/05/09 15:49:42 dillon Exp $
+ */
+
+#include "blib.h"
+#include <fcntl.h>
+
+#define INNER 100
+
+void doloop(int count);
+void func_nop1(void);
+void func_nop2(void);
+
+int
+main(int ac, char **av)
+{
+    int i;
+    int fd;
+    int count;
+    int nfork;
+    pid_t pid;
+
+    if (ac > 1)
+       nfork = strtoul(av[1], NULL, 0);
+
+    printf("SMP contention, dup() + close(), Run just one\n");
+
+    start_timing();
+    count = 0;
+    while (stop_timing(0, NULL) == 0) {
+       doloop(1000);
+       count += 1000;
+    }
+    printf("loop %d times\n", count);
+
+    start_timing();
+    for (i = 1; i < nfork; ++i) {
+           if (fork() == 0) {
+               doloop(count);
+               _exit(1);
+           }
+    }
+    doloop(count);
+    while (wait(NULL) > 0)
+       ;
+    stop_timing(count * INNER, "loop2/2xfork");
+    return(0);
+}
+
+void
+doloop(int count)
+{
+    int i;
+    int j;
+    int fd = open("/usr/share/dict/words", O_RDONLY);
+    register void (*func)(void) = func_nop1;
+
+    if (fd < 0)
+       perror("open");
+    for (i = count; i > 0; --i) {
+       for (j = INNER; j > 0; --j) {
+               getuid();
+       }
+    }
+    close(fd);
+}
+
+void
+func_nop1(void)
+{
+}
+
+void
+func_nop2(void)
+{
+}
+
diff --git a/test/sysperf/mutex4.c b/test/sysperf/mutex4.c
new file mode 100644 (file)
index 0000000..ec3ea0d
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * mutex4.c
+ *
+ * $DragonFly: src/test/sysperf/mutex4.c,v 1.1 2008/05/09 15:49:42 dillon Exp $
+ */
+
+#include "blib.h"
+
+#include <sys/types.h>
+#include <machine/atomic.h>
+#include <machine/cpufunc.h>
+
+struct globaldata {
+       int gd_cpumask;
+       int gd_spinlocks;
+};
+
+int *mtx;
+struct globaldata gd;
+
+typedef struct globaldata *globaldata_t;
+
+void
+rd_lock_contested(void)
+{
+}
+
+static __inline void
+rd_lock(void)
+{
+       atomic_set_int(mtx, 1);
+       *mtx = 2;
+       *mtx = 3;
+}
+
+static __inline void
+rd_unlock(void)
+{
+}
+
+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;
+    gd.gd_cpumask = 0x00000001;
+    gd.gd_spinlocks = 0;
+    while (stop_timing(0, NULL) == 0) {
+       for (j = 0; j < 100; ++j) {
+           rd_lock();
+           rd_unlock();
+       }
+       count += 100;
+    }
+    max = count;
+    *mtx = 0;
+
+    start_timing();
+    for (count = 0; count < max; count += 100) {
+       for (j = 0; j < 100; ++j) {
+           rd_lock();
+           rd_unlock();        /* release */
+       }
+    }
+    stop_timing(count, "complex_mtx(uncontested/1cpu)");
+
+    if ((pid = fork()) == 0) {
+       for (;;) {
+           for (j = 0; j < 100; ++j) {
+               rd_lock();
+               rd_unlock();    /* release */
+               ++counter[128];
+           }
+       }
+    } else {
+       gd.gd_cpumask = 0x00000002;
+       gd.gd_spinlocks = 0;
+       start_timing();
+       for (count = 0; count < max; count += 100) {
+           for (j = 0; j < 100; ++j) {
+               rd_lock();
+               rd_unlock();    /* release */
+               ++counter[64];
+           }
+       }
+       stop_timing(count, "complex_mtx");
+       printf("proc1=%d proc2=%d\n", counter[64], counter[128]);
+       kill(pid, 9);
+    }
+    return(0);
+}
+