Optimizations and cleanups around sb_next_event().
This commit is contained in:
@ -19,7 +19,7 @@ ffi = require("ffi")
|
||||
ffi.cdef[[
|
||||
void sb_event_start(int thread_id);
|
||||
void sb_event_stop(int thread_id);
|
||||
bool sb_lua_more_events(int thread_id);
|
||||
bool sb_more_events(int thread_id);
|
||||
]]
|
||||
|
||||
-- ----------------------------------------------------------------------
|
||||
@ -28,7 +28,7 @@ bool sb_lua_more_events(int thread_id);
|
||||
function thread_run(thread_id)
|
||||
local success, ret
|
||||
|
||||
while ffi.C.sb_lua_more_events(thread_id) do
|
||||
while ffi.C.sb_more_events(thread_id) do
|
||||
ffi.C.sb_event_start(thread_id)
|
||||
|
||||
repeat
|
||||
|
||||
@ -97,9 +97,6 @@ bool sb_lua_more_events(int);
|
||||
|
||||
static lua_State **states CK_CC_CACHELINE;
|
||||
|
||||
/* Event counter */
|
||||
static unsigned int nevents CK_CC_CACHELINE;
|
||||
|
||||
static sb_test_t sbtest CK_CC_CACHELINE;
|
||||
|
||||
static const char *sb_lua_script_path CK_CC_CACHELINE;
|
||||
@ -124,7 +121,6 @@ static lua_State *gstate;
|
||||
|
||||
static int sb_lua_op_init(void);
|
||||
static int sb_lua_op_done(void);
|
||||
static sb_event_t sb_lua_next_event(int);
|
||||
static int sb_lua_op_thread_init(int);
|
||||
static int sb_lua_op_thread_run(int);
|
||||
static int sb_lua_op_thread_done(int);
|
||||
@ -132,7 +128,6 @@ static void sb_lua_op_print_stats(sb_stat_t type);
|
||||
|
||||
static sb_operations_t lua_ops = {
|
||||
.init = sb_lua_op_init,
|
||||
.next_event = &sb_lua_next_event,
|
||||
.done = sb_lua_op_done
|
||||
};
|
||||
|
||||
@ -264,24 +259,6 @@ int sb_lua_op_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
sb_event_t sb_lua_next_event(int thread_id)
|
||||
{
|
||||
sb_event_t req;
|
||||
|
||||
(void) thread_id; /* unused */
|
||||
|
||||
if (sb_globals.max_requests > 0 &&
|
||||
ck_pr_faa_uint(&nevents, 1) >= sb_globals.max_requests)
|
||||
{
|
||||
req.type = SB_REQ_TYPE_NULL;
|
||||
return req;
|
||||
}
|
||||
|
||||
req.type = SB_REQ_TYPE_SCRIPT;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
int sb_lua_op_thread_init(int thread_id)
|
||||
{
|
||||
lua_State * L;
|
||||
@ -1070,16 +1047,6 @@ unsigned int sb_lua_table_size(lua_State *L, int index)
|
||||
return i;
|
||||
}
|
||||
|
||||
/* Check if there are more events to execute */
|
||||
|
||||
bool sb_lua_more_events(int thread_id)
|
||||
{
|
||||
sb_event_t e;
|
||||
|
||||
e = sb_next_event(&sbtest, thread_id);
|
||||
return e.type == SB_REQ_TYPE_SCRIPT;
|
||||
}
|
||||
|
||||
/* Check if a specified hook exists */
|
||||
|
||||
bool sb_lua_hook_defined(lua_State *L, const char *name)
|
||||
|
||||
@ -152,9 +152,6 @@ static int report_thread_created;
|
||||
static int checkpoints_thread_created;
|
||||
static int eventgen_thread_created;
|
||||
|
||||
/* Time limit (--max-time) in nanoseconds */
|
||||
static uint64_t max_time_ns CK_CC_CACHELINE;
|
||||
|
||||
/* Global execution timer */
|
||||
sb_timer_t sb_exec_timer CK_CC_CACHELINE;
|
||||
|
||||
@ -412,7 +409,7 @@ void print_run_mode(sb_test_t *test)
|
||||
|
||||
if (sb_globals.force_shutdown)
|
||||
log_text(LOG_NOTICE, "Forcing shutdown in %u seconds",
|
||||
sb_globals.max_time + sb_globals.timeout);
|
||||
(unsigned) NS2SEC(sb_globals.max_time_ns) + sb_globals.timeout);
|
||||
|
||||
log_text(LOG_NOTICE, "");
|
||||
|
||||
@ -420,6 +417,29 @@ void print_run_mode(sb_test_t *test)
|
||||
test->ops.print_mode();
|
||||
}
|
||||
|
||||
bool sb_more_events(int thread_id)
|
||||
{
|
||||
(void) thread_id; /* unused */
|
||||
|
||||
if (sb_globals.error)
|
||||
return false;
|
||||
|
||||
/* Check if we have a time limit */
|
||||
if (sb_globals.max_time_ns > 0 &&
|
||||
sb_timer_value(&sb_exec_timer) >= sb_globals.max_time_ns)
|
||||
{
|
||||
log_text(LOG_INFO, "Time limit exceeded, exiting...");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if we have a limit on the number of events */
|
||||
if (sb_globals.max_requests > 0 &&
|
||||
ck_pr_faa_64(&sb_globals.nevents, 1) >= sb_globals.max_requests)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
Get the next event, or return an 'empty' event with type = SB_REQ_TYPE_NULL,
|
||||
if there are no more events to execute.
|
||||
@ -427,30 +447,20 @@ void print_run_mode(sb_test_t *test)
|
||||
|
||||
sb_event_t sb_next_event(sb_test_t *test, int thread_id)
|
||||
{
|
||||
sb_event_t event;
|
||||
sb_list_item_t *pos;
|
||||
event_queue_elem_t *elem;
|
||||
unsigned long long queue_start_time = 0;
|
||||
|
||||
event.type = SB_REQ_TYPE_NULL;
|
||||
|
||||
if (sb_globals.error)
|
||||
return event;
|
||||
|
||||
/* Check if we have a time limit */
|
||||
if (max_time_ns > 0 &&
|
||||
sb_timer_value(&sb_exec_timer) >= max_time_ns)
|
||||
{
|
||||
log_text(LOG_INFO, "Time limit exceeded, exiting...");
|
||||
return event;
|
||||
}
|
||||
|
||||
/* If we are in tx_rate mode, we take events from queue */
|
||||
if (sb_globals.tx_rate > 0)
|
||||
{
|
||||
if (queue_is_full)
|
||||
{
|
||||
log_text(LOG_FATAL, "Event queue is full.");
|
||||
|
||||
sb_event_t event;
|
||||
event.type = SB_REQ_TYPE_NULL;
|
||||
|
||||
return event;
|
||||
}
|
||||
pthread_mutex_lock(&event_queue_mutex);
|
||||
@ -476,9 +486,7 @@ sb_event_t sb_next_event(sb_test_t *test, int thread_id)
|
||||
|
||||
}
|
||||
|
||||
event = test->ops.next_event(thread_id);
|
||||
|
||||
return event;
|
||||
return test->ops.next_event(thread_id);
|
||||
}
|
||||
|
||||
|
||||
@ -524,9 +532,12 @@ static int thread_run(sb_test_t *test, int thread_id)
|
||||
sb_event_t event;
|
||||
int rc = 0;
|
||||
|
||||
while ((event = sb_next_event(test, thread_id)).type != SB_REQ_TYPE_NULL &&
|
||||
rc == 0)
|
||||
while (sb_more_events(thread_id) && rc == 0)
|
||||
{
|
||||
event = sb_next_event(test, thread_id);
|
||||
if (event.type == SB_REQ_TYPE_NULL)
|
||||
break;
|
||||
|
||||
sb_event_start(thread_id);
|
||||
|
||||
rc = test->ops.execute_event(&event, thread_id);
|
||||
@ -934,7 +945,7 @@ static int run_test(sb_test_t *test)
|
||||
/* Set the alarm to force shutdown */
|
||||
signal(SIGALRM, sigalrm_forced_shutdown_handler);
|
||||
|
||||
alarm(sb_globals.max_time + sb_globals.timeout);
|
||||
alarm(NS2SEC(sb_globals.max_time_ns) + sb_globals.timeout);
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -1044,30 +1055,29 @@ static int init(void)
|
||||
return 1;
|
||||
}
|
||||
sb_globals.max_requests = sb_get_value_int("max-requests");
|
||||
sb_globals.max_time = sb_get_value_int("max-time");
|
||||
max_time_ns = SEC2NS(sb_globals.max_time);
|
||||
sb_globals.max_time_ns = SEC2NS(sb_get_value_int("max-time"));
|
||||
|
||||
if (!sb_globals.max_requests && !sb_globals.max_time)
|
||||
if (!sb_globals.max_requests && !sb_globals.max_time_ns)
|
||||
log_text(LOG_WARNING, "WARNING: Both max-requests and max-time are 0, running endless test");
|
||||
|
||||
if (sb_globals.max_time > 0)
|
||||
if (sb_globals.max_time_ns > 0)
|
||||
{
|
||||
/* Parse the --forced-shutdown value */
|
||||
tmp = sb_get_value_string("forced-shutdown");
|
||||
if (tmp == NULL)
|
||||
{
|
||||
sb_globals.force_shutdown = 1;
|
||||
sb_globals.timeout = sb_globals.max_time / 20;
|
||||
sb_globals.timeout = NS2SEC(sb_globals.max_time_ns) / 20;
|
||||
}
|
||||
else if (strcasecmp(tmp, "off"))
|
||||
{
|
||||
char *endptr;
|
||||
|
||||
sb_globals.force_shutdown = 1;
|
||||
sb_globals.timeout = (unsigned int)strtol(tmp, &endptr, 10);
|
||||
sb_globals.timeout = (unsigned) strtol(tmp, &endptr, 10);
|
||||
if (*endptr == '%')
|
||||
sb_globals.timeout = (unsigned int)(sb_globals.timeout *
|
||||
(double)sb_globals.max_time / 100);
|
||||
sb_globals.timeout = (unsigned) (sb_globals.timeout *
|
||||
NS2SEC(sb_globals.max_time_ns) / 100);
|
||||
else if (*tmp == '\0' || *endptr != '\0')
|
||||
{
|
||||
log_text(LOG_FATAL, "Invalid value for --forced-shutdown: '%s'", tmp);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2004 MySQL AB
|
||||
Copyright (C) 2004-2016 Alexey Kopytov <akopytov@gmail.com>
|
||||
Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -180,10 +180,13 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int error CK_CC_CACHELINE; /* global error flag */
|
||||
unsigned int tx_rate; /* target transaction rate */
|
||||
unsigned int max_requests; /* maximum number of requests */
|
||||
unsigned int max_time_ns; /* total execution time limit */
|
||||
pthread_mutex_t exec_mutex CK_CC_CACHELINE; /* execution mutex */
|
||||
sb_cmd_t command; /* command passed from command line */
|
||||
int error; /* global error - everyone exit */
|
||||
pthread_mutex_t exec_mutex; /* execution mutex */
|
||||
unsigned int num_threads; /* number of threads to use */
|
||||
unsigned int num_threads CK_CC_CACHELINE; /* number of threads to use */
|
||||
unsigned int num_running; /* number of threads currently active */
|
||||
unsigned int report_interval; /* intermediate reports interval */
|
||||
unsigned int percentile; /* percentile rank for latency stats */
|
||||
@ -191,11 +194,7 @@ typedef struct
|
||||
/* array of report checkpoints */
|
||||
unsigned int checkpoints[MAX_CHECKPOINTS];
|
||||
unsigned int n_checkpoints; /* number of checkpoints */
|
||||
unsigned int tx_rate; /* target transaction rate */
|
||||
unsigned int max_requests; /* maximum number of requests */
|
||||
unsigned int max_time; /* total execution time limit */
|
||||
unsigned char debug; /* debug flag */
|
||||
int force_shutdown; /* whether we must force test shutdown */
|
||||
unsigned int timeout; /* forced shutdown timeout */
|
||||
unsigned char validate; /* validation flag */
|
||||
unsigned char verbosity; /* log verbosity */
|
||||
@ -204,11 +203,13 @@ typedef struct
|
||||
int concurrency; /* number of concurrent requests when tx-rate is
|
||||
used */
|
||||
/* 1 when forced shutdown is in progress, 0 otherwise */
|
||||
int force_shutdown; /* whether we must force test shutdown */
|
||||
int forced_shutdown_in_progress;
|
||||
uint64_t nevents CK_CC_CACHELINE; /* event counter */
|
||||
} sb_globals_t;
|
||||
|
||||
extern sb_globals_t sb_globals;
|
||||
extern pthread_mutex_t event_queue_mutex;
|
||||
extern sb_globals_t sb_globals CK_CC_CACHELINE;
|
||||
extern pthread_mutex_t event_queue_mutex CK_CC_CACHELINE;
|
||||
|
||||
/* Global execution timer */
|
||||
extern sb_timer_t sb_exec_timer CK_CC_CACHELINE;
|
||||
@ -220,6 +221,7 @@ extern sb_timer_t sb_checkpoint_timer2;
|
||||
|
||||
extern TLS int sb_tls_thread_id;
|
||||
|
||||
bool sb_more_events(int thread_id);
|
||||
sb_event_t sb_next_event(sb_test_t *test, int thread_id);
|
||||
void sb_event_start(int thread_id);
|
||||
void sb_event_stop(int thread_id);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2004 MySQL AB
|
||||
Copyright (C) 2004-2016 Alexey Kopytov <akopytov@gmail.com>
|
||||
Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -59,8 +59,6 @@ static sb_test_t cpu_test =
|
||||
|
||||
/* Upper limit for primes */
|
||||
static unsigned int max_prime;
|
||||
/* Request counter */
|
||||
static unsigned int req_performed;
|
||||
|
||||
int register_test_cpu(sb_list_t * tests)
|
||||
{
|
||||
@ -79,8 +77,6 @@ int cpu_init(void)
|
||||
}
|
||||
max_prime= (unsigned int)prime_option;
|
||||
|
||||
req_performed = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -91,19 +87,6 @@ sb_event_t cpu_next_event(int thread_id)
|
||||
|
||||
(void) thread_id; /* unused */
|
||||
|
||||
if (sb_globals.max_requests > 0)
|
||||
{
|
||||
SB_THREAD_MUTEX_LOCK();
|
||||
if (req_performed >= sb_globals.max_requests)
|
||||
{
|
||||
req.type = SB_REQ_TYPE_NULL;
|
||||
SB_THREAD_MUTEX_UNLOCK();
|
||||
return req;
|
||||
}
|
||||
req_performed++;
|
||||
SB_THREAD_MUTEX_UNLOCK();
|
||||
}
|
||||
|
||||
req.type = SB_REQ_TYPE_CPU;
|
||||
|
||||
return req;
|
||||
|
||||
@ -27,6 +27,7 @@
|
||||
#ifdef STDC_HEADERS
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
@ -199,6 +200,9 @@ static FILE_DESCRIPTOR *files;
|
||||
/* test mode type */
|
||||
static file_test_mode_t test_mode;
|
||||
|
||||
/* Limit on the number of events */
|
||||
static uint64_t max_events;
|
||||
|
||||
/* Previous request needed for validation */
|
||||
static sb_file_request_t prev_req;
|
||||
|
||||
@ -331,6 +335,10 @@ int file_init(void)
|
||||
init_vars();
|
||||
clear_stats();
|
||||
|
||||
/* Use our own limit on the number of events */
|
||||
max_events = sb_globals.max_requests;
|
||||
sb_globals.max_requests = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -433,7 +441,7 @@ sb_event_t file_get_seq_request(void)
|
||||
file_req->operation = FILE_OP_TYPE_READ;
|
||||
|
||||
/* Do final fsync on all files and quit if we are done */
|
||||
if (sb_globals.max_requests > 0 && req_performed >= sb_globals.max_requests)
|
||||
if (max_events > 0 && req_performed >= max_events)
|
||||
{
|
||||
/* no fsync for reads */
|
||||
if (file_fsync_end && file_req->operation == FILE_OP_TYPE_WRITE &&
|
||||
@ -548,7 +556,7 @@ sb_event_t file_get_rnd_request(int thread_id)
|
||||
}
|
||||
|
||||
/* fsync all files (if requested by user) as soon as we are done */
|
||||
if (sb_globals.max_requests > 0 && req_performed >= sb_globals.max_requests)
|
||||
if (max_events > 0 && req_performed >= max_events)
|
||||
{
|
||||
if (file_fsync_end != 0 &&
|
||||
(real_mode == MODE_RND_WRITE || real_mode == MODE_RND_RW ||
|
||||
@ -788,8 +796,8 @@ void file_print_mode(void)
|
||||
case MODE_RND_WRITE:
|
||||
case MODE_RND_READ:
|
||||
case MODE_RND_RW:
|
||||
log_text(LOG_NOTICE, "Number of IO requests: %d",
|
||||
sb_globals.max_requests);
|
||||
log_text(LOG_NOTICE, "Number of IO requests: %" PRIu64,
|
||||
max_events);
|
||||
log_text(LOG_NOTICE,
|
||||
"Read/Write ratio for combined random IO test: %2.2f",
|
||||
file_rw_ratio);
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2004 MySQL AB
|
||||
Copyright (C) 2004-2016 Alexey Kopytov <akopytov@gmail.com>
|
||||
Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -201,7 +201,10 @@ int memory_init(void)
|
||||
memset(buffers[i], 0, memory_block_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Use our own limit on the number of events */
|
||||
sb_globals.max_requests = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/* Copyright (C) 2004 MySQL AB
|
||||
Copyright (C) 2004-2016 Alexey Kopytov <akopytov@gmail.com>
|
||||
Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
@ -29,6 +29,7 @@
|
||||
#endif
|
||||
|
||||
#include "sysbench.h"
|
||||
#include "ck_pr.h"
|
||||
|
||||
/* How to test scheduler pthread_yield or sched_yield */
|
||||
#ifdef HAVE_PTHREAD_YIELD
|
||||
@ -92,7 +93,7 @@ int threads_init(void)
|
||||
thread_yields = sb_get_value_int("thread-yields");
|
||||
thread_locks = sb_get_value_int("thread-locks");
|
||||
req_performed = 0;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -135,18 +136,8 @@ sb_event_t threads_next_event(int thread_id)
|
||||
|
||||
(void) thread_id; /* unused */
|
||||
|
||||
SB_THREAD_MUTEX_LOCK();
|
||||
if (sb_globals.max_requests > 0 && req_performed >= sb_globals.max_requests)
|
||||
{
|
||||
sb_req.type = SB_REQ_TYPE_NULL;
|
||||
SB_THREAD_MUTEX_UNLOCK();
|
||||
return sb_req;
|
||||
}
|
||||
|
||||
sb_req.type = SB_REQ_TYPE_THREADS;
|
||||
threads_req->lock_num = req_performed % thread_locks;
|
||||
req_performed++;
|
||||
SB_THREAD_MUTEX_UNLOCK();
|
||||
threads_req->lock_num = ck_pr_faa_uint(&req_performed, 1) % thread_locks;
|
||||
|
||||
return sb_req;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user