summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@kernel.org>2015-10-02 18:26:12 -0700
committerAndy Lutomirski <luto@kernel.org>2015-10-02 18:26:12 -0700
commit8418d642b72de80f8c0d1fa1bcb1576892d81b3e (patch)
tree75d5951c0fee0ffc0866df984fa3e2589d893912
parent4bfa4d8349a9e6a3747812ea9af49f211a621237 (diff)
parentb447269061ccc313e5f0cae623eca3786ba40219 (diff)
downloadmisc-tests-8418d642b72de80f8c0d1fa1bcb1576892d81b3e.tar.gz
Merge branch 'master' of ssh://ra.kernel.org/pub/scm/linux/kernel/git/luto/misc-tests
-rw-r--r--timing_test.cc52
1 files changed, 52 insertions, 0 deletions
diff --git a/timing_test.cc b/timing_test.cc
index a6b38ce..852a27c 100644
--- a/timing_test.cc
+++ b/timing_test.cc
@@ -10,8 +10,11 @@
#include <string.h>
#include <inttypes.h>
#include <atomic>
+#include <signal.h>
+#include <err.h>
typedef int (*vgettime_t)(clockid_t, timespec *);
+typedef long (*vgetcpu_t)(unsigned *cpu, unsigned *node, void *unused);
void describe_clock(const char *name, int id)
{
@@ -27,6 +30,22 @@ void describe_clock(const char *name, int id)
}
}
+static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
+ int flags)
+{
+ struct sigaction sa;
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_sigaction = handler;
+ sa.sa_flags = SA_SIGINFO | flags;
+ sigemptyset(&sa.sa_mask);
+ if (sigaction(sig, &sa, 0))
+ err(1, "sigaction");
+}
+
+static void sigusr1(int sig, siginfo_t *info, void *ctx_void)
+{
+}
+
int main(int argc, char **argv)
{
if (argc < 3) {
@@ -49,10 +68,16 @@ int main(int argc, char **argv)
if (!vgettime)
printf("dlsym failed: %s", dlerror());
+ vgetcpu_t vgetcpu = (vgetcpu_t)dlsym(vdso, "__vdso_getcpu");
+ if (!vgetcpu)
+ printf("dlsym failed: %s", dlerror());
+
size_t loops = (size_t)atol(argv[1]) * 1000000;
clockid_t c = argc > 3 ? atoi(argv[3]) : 0;
const char *mode = argv[2];
+ sethandler(SIGUSR1, sigusr1, 0);
+
timespec start;
clock_gettime(CLOCK_MONOTONIC, &start);
@@ -95,6 +120,26 @@ int main(int argc, char **argv)
std::atomic<unsigned int> x;
for (size_t i = 0; i < loops; ++i)
x += 2;
+ } else if (!strcmp(mode, "lock_xchg")) {
+ std::atomic<unsigned int> x;
+ for (size_t i = 0; i < loops; ++i)
+ x.exchange(2);
+ } else if (!strcmp(mode, "cmpxchg_mismatch")) {
+ std::atomic<unsigned long> x;
+ for (size_t i = 0; i < loops; ++i)
+ asm volatile ("cmpxchg %[newval], %[mem]"
+ : [mem] "+m" (x)
+ : "a" (1), [newval] "r" (2) : "flags");
+ } else if (!strcmp(mode, "cmpxchg_match")) {
+ std::atomic<unsigned long> x;
+ for (size_t i = 0; i < loops/2; ++i) {
+ asm volatile ("cmpxchg %[newval], %[mem]"
+ : [mem] "+m" (x)
+ : "a" (0), [newval] "r" (2) : "flags");
+ asm volatile ("cmpxchg %[newval], %[mem]"
+ : [mem] "+m" (x)
+ : "a" (2), [newval] "r" (0) : "flags");
+ }
} else if (!strcmp(mode, "rdtscp")) {
for (size_t i = 0; i < loops; ++i) {
unsigned int a, c, d;
@@ -134,6 +179,10 @@ int main(int argc, char **argv)
} else if (!strcmp(mode, "vclock_gettime")) {
for (size_t i = 0; i < loops; ++i)
vgettime(c, &t);
+ } else if (!strcmp(mode, "vgetcpu")) {
+ unsigned cpu;
+ for (size_t i = 0; i < loops; ++i)
+ vgetcpu(&cpu, NULL, NULL);
} else if (!strcmp(mode, "getpid")) {
for (size_t i = 0; i < loops; ++i)
syscall(SYS_getpid);
@@ -158,6 +207,9 @@ int main(int argc, char **argv)
for (size_t i = 0; i < loops; ++i)
vsyscall_time(nullptr);
#endif
+ } else if (!strcmp(mode, "raise")) {
+ for (size_t i = 0; i < loops; ++i)
+ raise(SIGUSR1);
} else {
printf("Unknown mode %s\n", mode);
return 1;