#include "common/strtol.h"
#include "common/Cond.h"
#include "common/Mutex.h"
+#include "global/signal_handler.h"
#include <iostream>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
using namespace std::chrono;
+static std::atomic<bool> terminating;
+static void handle_signal(int signum)
+{
+ ceph_assert(signum == SIGINT || signum == SIGTERM);
+ terminating = true;
+}
+
namespace rbd {
namespace action {
namespace bench {
write_bl.push_back(bp);
}
}
-
+
void start_io(int max, uint64_t off, uint64_t len, int op_flags, bool read_flag)
{
{
}
}
- void wait_for(int max) {
+ int wait_for(int max) {
Mutex::Locker l(lock);
- while (in_flight > max) {
+ while (in_flight > max && !terminating) {
utime_t dur;
dur.set_from_double(.2);
cond.WaitInterval(lock, dur);
}
+
+ return terminating ? -EINTR : 0;
}
};
for (off = 0; off < io_bytes; ) {
// Issue I/O
i = 0;
+ int r = 0;
while (i < io_threads && off < io_bytes) {
bool read_flag = should_read(read_proportion);
- b.wait_for(io_threads - 1);
+ r = b.wait_for(io_threads - 1);
+ if (r < 0) {
+ break;
+ }
b.start_io(io_threads, thread_offset[i], io_size, op_flags, read_flag);
++i;
write_ops++;
}
+ if (r < 0) {
+ break;
+ }
+
// Set the thread_offsets of next I/O
for (i = 0; i < io_threads; ++i) {
if (random) {
return r;
}
+ init_async_signal_handler();
+ register_async_signal_handler(SIGHUP, sighup_handler);
+ register_async_signal_handler_oneshot(SIGINT, handle_signal);
+ register_async_signal_handler_oneshot(SIGTERM, handle_signal);
+
r = do_bench(image, bench_io_type, bench_io_size, bench_io_threads,
bench_bytes, bench_random, bench_read_proportion);
+
+ unregister_async_signal_handler(SIGHUP, sighup_handler);
+ unregister_async_signal_handler(SIGINT, handle_signal);
+ unregister_async_signal_handler(SIGTERM, handle_signal);
+ shutdown_async_signal_handler();
+
if (r < 0) {
std::cerr << "bench failed: " << cpp_strerror(r) << std::endl;
return r;