aboutsummaryrefslogtreecommitdiffstats
path: root/executor
diff options
context:
space:
mode:
authorDmitry Vyukov <dvyukov@google.com>2017-12-22 18:52:10 +0100
committerDmitry Vyukov <dvyukov@google.com>2017-12-22 18:55:38 +0100
commit8e4090902540da8c6e8fa640a0fc325c29c3efcb (patch)
tree42af582b4a6b448bc34329346046c67f07f26984 /executor
parent26cd53f078db858a6ccca338e13e7f4d1d291c22 (diff)
pkg/csource: mimic the way syscalls are scheduled in executor
Currently csource uses completely different, simpler way of scheduling syscalls onto threads (thread per call with random sleeps). Mimic the way calls are scheduled in executor. Fixes #312
Diffstat (limited to 'executor')
-rw-r--r--executor/common_linux.h64
-rw-r--r--executor/executor_linux.cc1
2 files changed, 64 insertions, 1 deletions
diff --git a/executor/common_linux.h b/executor/common_linux.h
index fc60e3a70..421486ed5 100644
--- a/executor/common_linux.h
+++ b/executor/common_linux.h
@@ -11,6 +11,7 @@
#include <sys/syscall.h>
#include <unistd.h>
#if defined(SYZ_EXECUTOR) || defined(SYZ_THREADED) || defined(SYZ_COLLIDE)
+#include <linux/futex.h>
#include <pthread.h>
#include <stdlib.h>
#endif
@@ -1045,3 +1046,66 @@ void loop()
}
#endif
#endif
+
+#if defined(SYZ_THREADED)
+struct thread_t {
+ int created, running, call;
+ pthread_t th;
+};
+
+static struct thread_t threads[16];
+static void execute_call(int call);
+static int running;
+#if defined(SYZ_COLLIDE)
+static int collide;
+#endif
+
+static void* thr(void* arg)
+{
+ struct thread_t* th = (struct thread_t*)arg;
+ for (;;) {
+ while (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE))
+ syscall(SYS_futex, &th->running, FUTEX_WAIT, 0, 0);
+ execute_call(th->call);
+ __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
+ __atomic_store_n(&th->running, 0, __ATOMIC_RELEASE);
+ syscall(SYS_futex, &th->running, FUTEX_WAKE);
+ }
+ return 0;
+}
+
+static void execute(int num_calls)
+{
+ int call, thread;
+ running = 0;
+ for (call = 0; call < num_calls; call++) {
+ for (thread = 0; thread < sizeof(threads) / sizeof(threads[0]); thread++) {
+ struct thread_t* th = &threads[thread];
+ if (!th->created) {
+ th->created = 1;
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstacksize(&attr, 128 << 10);
+ pthread_create(&th->th, &attr, thr, th);
+ }
+ if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) {
+ th->call = call;
+ __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
+ __atomic_store_n(&th->running, 1, __ATOMIC_RELEASE);
+ syscall(SYS_futex, &th->running, FUTEX_WAKE);
+#if defined(SYZ_COLLIDE)
+ if (collide && call % 2)
+ break;
+#endif
+ struct timespec ts;
+ ts.tv_sec = 0;
+ ts.tv_nsec = 20 * 1000 * 1000;
+ syscall(SYS_futex, &th->running, FUTEX_WAIT, 1, &ts);
+ if (running)
+ usleep((call == num_calls - 1) ? 10000 : 1000);
+ break;
+ }
+ }
+ }
+}
+#endif
diff --git a/executor/executor_linux.cc b/executor/executor_linux.cc
index 8b38dbf21..38ecf42f5 100644
--- a/executor/executor_linux.cc
+++ b/executor/executor_linux.cc
@@ -5,7 +5,6 @@
#include <fcntl.h>
#include <limits.h>
-#include <linux/futex.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/prctl.h>