Optimizations and cleanups around sb_next_event().

This commit is contained in:
Alexey Kopytov
2017-01-22 10:45:08 +03:00
parent 21a28231ad
commit 45830f9cd0
8 changed files with 78 additions and 114 deletions

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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;
}