Hello community,
here is the log from the commit of package sysbench for openSUSE:Factory checked in at 2016-03-26 15:25:43
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/sysbench (Old)
and /work/SRC/openSUSE:Factory/.sysbench.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "sysbench"
Changes:
--------
--- /work/SRC/openSUSE:Factory/sysbench/sysbench.changes 2016-03-07 13:24:19.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.sysbench.new/sysbench.changes 2016-03-26 15:25:45.000000000 +0100
@@ -1,0 +2,23 @@
+Mon Mar 21 19:47:52 UTC 2016 - mpluskal@suse.com
+
+- Update to version 0.5.0~git.20160318:
+ + Some minor improvements to bulk_insert.lua
+ + Minor cleanups in bulk_insert.lua.
+ + Print the number of actually running threads instead of the
+ configured --num-threads value for intermediate reports. This
+ can make a big difference with network benchmarks to diagnose
+ TCP-related issues like SYN flood protection, throttling,
+ backlog issues, etc.
+ + Fix mutex_get_request() signature.
+ + Update GPLv2 text in COPYING with the current version from
+ https://gnu.org/licenses/gpl-2.0.txt.
+ + Update copyrights and FSF address.
+ + Fixes #17: Lua script without DB access crashes sysbench.
+ + Fixes #22: Timers and reporting thread should wait for worker
+ thread to be initialized
+ + Fix barrier error reporting.
+ + Fixes #25: Include database-related command line options in
+ help
+- Generate manpage
+
+-------------------------------------------------------------------
Old:
----
sysbench-0.5.0~git.20160223.tar.xz
New:
----
sysbench-0.5.0~git.20160318.tar.xz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ sysbench.spec ++++++
--- /var/tmp/diff_new_pack.7JOX7J/_old 2016-03-26 15:25:46.000000000 +0100
+++ /var/tmp/diff_new_pack.7JOX7J/_new 2016-03-26 15:25:46.000000000 +0100
@@ -16,8 +16,10 @@
#
+%define version_unconverted 0.5.0~git.20160318
+
Name: sysbench
-Version: 0.5.0~git.20160223
+Version: 0.5.0~git.20160318
Release: 0
Summary: A MySQL benchmarking tool
License: GPL-2.0
@@ -29,6 +31,7 @@
BuildRequires: automake
BuildRequires: docbook
BuildRequires: docbook-xsl-stylesheets
+BuildRequires: help2man
BuildRequires: libaio-devel
BuildRequires: libtool
BuildRequires: libxslt-tools
@@ -55,6 +58,8 @@
%install
%make_install
+help2man ./sysbench/sysbench > sysbench.1
+install -D -m 0644 sysbench.1 %{buildroot}%{_mandir}/man1/sysbench.1
install -D -m 0755 sysbench-example-tests/sysbench-example-test %{buildroot}%{_datadir}/sysbench/sysbench-example-test
install -D -m 0755 sysbench-example-tests/sysbench-example-all-tests %{buildroot}%{_datadir}/sysbench/sysbench-example-all-tests
rm -rf %{buildroot}%{_datadir}/doc/sysbench
@@ -63,6 +68,7 @@
%defattr(-,root,root)
%doc COPYING ChangeLog README.md doc/manual.html
%{_bindir}/sysbench
+%{_mandir}/man1/sysbench.1%{ext_man}
%{_datadir}/sysbench
%changelog
++++++ _service ++++++
--- /var/tmp/diff_new_pack.7JOX7J/_old 2016-03-26 15:25:46.000000000 +0100
+++ /var/tmp/diff_new_pack.7JOX7J/_new 2016-03-26 15:25:46.000000000 +0100
@@ -3,7 +3,8 @@
<param name="url">git://github.com/akopytov/sysbench</param>
<param name="scm">git</param>
<param name="filename">sysbench</param>
- <param name="revision">1c812ad6dd129f059691103c224bb0ea8006ff15</param>
+ <param name="changesgenerate">enable</param>
+ <param name="revision">57e62669b937b3c4ebaca237af65d69539bfb260</param>
<param name="versionformat">0.5.0~git.%cd</param>
</service>
<service mode="localonly" name="recompress">
++++++ sysbench-0.5.0~git.20160223.tar.xz -> sysbench-0.5.0~git.20160318.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/Makefile.am new/sysbench-0.5.0~git.20160318/sysbench/Makefile.am
--- old/sysbench-0.5.0~git.20160223/sysbench/Makefile.am 2016-03-01 16:00:45.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/Makefile.am 2016-03-21 20:47:52.000000000 +0100
@@ -49,7 +49,7 @@
sysbench_SOURCES = sysbench.c sysbench.h sb_timer.c sb_timer.h \
sb_options.c sb_options.h sb_logger.c sb_logger.h sb_list.h db_driver.h \
-db_driver.c sb_percentile.c sb_percentile.h
+db_driver.c sb_percentile.c sb_percentile.h sb_barrier.c sb_barrier.h
sysbench_LDADD = tests/fileio/libsbfileio.a tests/threads/libsbthreads.a \
tests/memory/libsbmemory.a tests/cpu/libsbcpu.a \
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/sb_barrier.c new/sysbench-0.5.0~git.20160318/sysbench/sb_barrier.c
--- old/sysbench-0.5.0~git.20160223/sysbench/sb_barrier.c 1970-01-01 01:00:00.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/sb_barrier.c 2016-03-21 20:47:52.000000000 +0100
@@ -0,0 +1,104 @@
+/*
+ Copyright (C) 2016 Alexey Kopytov
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/*
+ Thread barrier implementation. It differs from pthread_barrier_t in two ways:
+
+ - it's more portable (will also work on OS X and Windows with existing
+ pthread_* wrappers in sb_win.c).
+
+ - it allows defining a callback function which is called right before
+ signaling the participating threads to continue, i.e. as soon as the
+ required number of threads reach the barrier. The callback can also signal
+ an error to sb_barrier_wait() callers by returning a non-zero value. In
+ which case sb_barrier_wait() returns a negative value to all callers.
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "sb_barrier.h"
+
+int sb_barrier_init(sb_barrier_t *barrier, unsigned int count,
+ sb_barrier_cb_t callback, void *arg)
+{
+ if (count == 0)
+ return 1;
+
+ if (pthread_mutex_init(&barrier->mutex, NULL) ||
+ pthread_cond_init(&barrier->cond, NULL))
+ return 1;
+
+ barrier->init_count = count;
+ barrier->count = count;
+ barrier->callback = callback;
+ barrier->arg = arg;
+ barrier->serial = 0;
+ barrier->error = 0;
+
+ return 0;
+}
+
+
+int sb_barrier_wait(sb_barrier_t *barrier)
+{
+ int res;
+
+ pthread_mutex_lock(&barrier->mutex);
+
+ if (!--barrier->count)
+ {
+ barrier->serial++;
+ barrier->count = barrier->init_count;
+
+ res = SB_BARRIER_SERIAL_THREAD;
+
+ pthread_cond_broadcast(&barrier->cond);
+
+ if (barrier->callback != NULL && barrier->callback(barrier->arg) != 0)
+ {
+ barrier->error = 1;
+ res = -1;
+ }
+
+ pthread_mutex_unlock(&barrier->mutex);
+
+ }
+ else
+ {
+ unsigned int serial = barrier->serial;
+
+ do {
+ pthread_cond_wait(&barrier->cond, &barrier->mutex);
+ } while (serial == barrier->serial);
+
+ res = barrier->error ? -1 : 0;
+
+ pthread_mutex_unlock(&barrier->mutex);
+ }
+
+ return res;
+}
+
+
+void sb_barrier_destroy(sb_barrier_t *barrier)
+{
+ pthread_mutex_destroy(&barrier->mutex);
+ pthread_cond_destroy(&barrier->cond);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/sb_barrier.h new/sysbench-0.5.0~git.20160318/sysbench/sb_barrier.h
--- old/sysbench-0.5.0~git.20160223/sysbench/sb_barrier.h 1970-01-01 01:00:00.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/sb_barrier.h 2016-03-21 20:47:52.000000000 +0100
@@ -0,0 +1,58 @@
+/*
+ Copyright (C) 2016 Alexey Kopytov
+
+ 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
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+*/
+
+/* Thread barrier implementation. */
+
+#ifndef SB_BARRIER_H
+#define SB_BARRIER_H
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_PTHREAD_H
+# include
+#endif
+
+#ifdef _WIN32
+#include "sb_win.h"
+#endif
+
+#define SB_BARRIER_SERIAL_THREAD 1
+
+typedef int (*sb_barrier_cb_t)(void *);
+
+typedef struct {
+ unsigned int count;
+ unsigned int init_count;
+ unsigned int serial;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+ sb_barrier_cb_t callback;
+ void *arg;
+ int error;
+} sb_barrier_t;
+
+int sb_barrier_init(sb_barrier_t *barrier, unsigned int count,
+ sb_barrier_cb_t callback, void *arg);
+
+int sb_barrier_wait(sb_barrier_t *barrier);
+
+void sb_barrier_destroy(sb_barrier_t *barrier);
+
+#endif /* SB_BARRIER_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/sb_logger.c new/sysbench-0.5.0~git.20160318/sysbench/sb_logger.c
--- old/sysbench-0.5.0~git.20160223/sysbench/sb_logger.c 2016-03-01 16:00:45.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/sb_logger.c 2016-03-21 20:47:52.000000000 +0100
@@ -142,12 +142,14 @@
/* Display command line options for registered log handlers */
-void log_usage(void)
+void log_print_help(void)
{
unsigned int i;
sb_list_item_t *pos;
log_handler_t *handler;
+ printf("Log options:\n");
+
for (i = 0; i < LOG_MSG_TYPE_MAX; i++)
{
SB_LIST_FOR_EACH(pos, handlers + i)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/sb_logger.h new/sysbench-0.5.0~git.20160318/sysbench/sb_logger.h
--- old/sysbench-0.5.0~git.20160223/sysbench/sb_logger.h 2016-03-01 16:00:45.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/sb_logger.h 2016-03-21 20:47:52.000000000 +0100
@@ -128,7 +128,7 @@
/* Display command line options for all register log handlers */
-void log_usage(void);
+void log_print_help(void);
/* Initialize logger */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/scripting/script_lua.c new/sysbench-0.5.0~git.20160318/sysbench/scripting/script_lua.c
--- old/sysbench-0.5.0~git.20160223/sysbench/scripting/script_lua.c 2016-03-01 16:00:45.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/scripting/script_lua.c 2016-03-21 20:47:52.000000000 +0100
@@ -40,7 +40,7 @@
#define CALL_ERROR(L, name) \
do { \
const char *err = lua_tostring(L, -1); \
- log_text(LOG_DEBUG, "failed to execute function `%s': %s", \
+ log_text(LOG_FATAL, "failed to execute function `%s': %s", \
name, err ? err : "(null)"); \
} while (0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/sysbench-0.5.0~git.20160223/sysbench/sysbench.c new/sysbench-0.5.0~git.20160318/sysbench/sysbench.c
--- old/sysbench-0.5.0~git.20160223/sysbench/sysbench.c 2016-03-01 16:00:45.000000000 +0100
+++ new/sysbench-0.5.0~git.20160318/sysbench/sysbench.c 2016-03-21 20:47:52.000000000 +0100
@@ -68,6 +68,7 @@
#include "sb_options.h"
#include "scripting/sb_script.h"
#include "db_driver.h"
+#include "sb_barrier.h"
#define VERSION_STRING PACKAGE" "PACKAGE_VERSION
@@ -77,6 +78,9 @@
/* Maximum queue length for the tx-rate mode */
#define MAX_QUEUE_LEN 100000
+/* Wait at most this number of seconds for worker threads to initialize */
+#define THREAD_INIT_TIMEOUT 30
+
/* Random numbers distributions */
typedef enum
{
@@ -163,10 +167,11 @@
sb_globals_t sb_globals;
sb_test_t *current_test;
+/* Barrier to ensure we start the benchmark run when all workers are ready */
+static sb_barrier_t thread_start_barrier;
+
/* Mutexes */
-/* used to start test with all threads ready */
-static pthread_mutex_t thread_start_mutex;
static pthread_attr_t thread_attr;
/* structures to handle queue of events, needed for tx_rate mode */
@@ -178,30 +183,42 @@
static int queue_is_full;
static void print_header(void);
-static void print_usage(void);
+static void print_help(void);
static void print_run_mode(sb_test_t *);
#ifdef HAVE_ALARM
-static void sigalrm_handler(int sig)
+static void sigalrm_thread_init_timeout_handler(int sig)
{
- if (sig == SIGALRM)
- {
- sb_globals.forced_shutdown_in_progress = 1;
+ if (sig != SIGALRM)
+ return;
- sb_timer_stop(&sb_globals.exec_timer);
- sb_timer_stop(&sb_globals.cumulative_timer1);
- sb_timer_stop(&sb_globals.cumulative_timer2);
+ log_text(LOG_FATAL,
+ "Worker threads failed to initialize within %u seconds!",
+ THREAD_INIT_TIMEOUT);
+
+ exit(2);
+}
- log_text(LOG_FATAL,
- "The --max-time limit has expired, forcing shutdown...");
+static void sigalrm_forced_shutdown_handler(int sig)
+{
+ if (sig != SIGALRM)
+ return;
- if (current_test && current_test->ops.print_stats)
- current_test->ops.print_stats(SB_STAT_CUMULATIVE);
+ sb_globals.forced_shutdown_in_progress = 1;
- log_done();
+ sb_timer_stop(&sb_globals.exec_timer);
+ sb_timer_stop(&sb_globals.cumulative_timer1);
+ sb_timer_stop(&sb_globals.cumulative_timer2);
- exit(2);
- }
+ log_text(LOG_FATAL,
+ "The --max-time limit has expired, forcing shutdown...");
+
+ if (current_test && current_test->ops.print_stats)
+ current_test->ops.print_stats(SB_STAT_CUMULATIVE);
+
+ log_done();
+
+ exit(2);
}
#endif
@@ -272,19 +289,20 @@
/* Print program usage */
-void print_usage(void)
+void print_help(void)
{
sb_list_item_t *pos;
sb_test_t *test;
printf("Usage:\n");
- printf(" sysbench [general-options]... --test=<test-name> "
- "[test-options]... command\n\n");
+ printf(" sysbench --test=<test-name> [options]... <command>\n\n");
+ printf("Commands: prepare run cleanup help version\n\n");
printf("General options:\n");
sb_print_options(general_args);
- printf("Log options:\n");
- log_usage();
+ log_print_help();
+
+ db_print_help();
printf("Compiled-in tests:\n");
SB_LIST_FOR_EACH(pos, &tests)
@@ -293,7 +311,6 @@
printf(" %s - %s\n", test->sname, test->lname);
}
printf("\n");
- printf("Commands: prepare run cleanup help version\n\n");
printf("See 'sysbench --test=<name> help' for a list of options for each test.\n\n");
}
@@ -456,10 +473,10 @@
}
-/* Main runner test thread */
+/* Main worker test thread */
-static void *runner_thread(void *arg)
+static void *worker_thread(void *arg)
{
sb_request_t request;
sb_thread_ctxt_t *ctxt;
@@ -473,20 +490,20 @@
test = ctxt->test;
thread_id = ctxt->id;
- log_text(LOG_DEBUG, "Runner thread started (%d)!", thread_id);
if (test->ops.thread_init != NULL && test->ops.thread_init(thread_id) != 0)
{
+ log_text(LOG_DEBUG, "Worker thread (#%d) failed to initialize!", thread_id);
sb_globals.error = 1;
- return NULL; /* thread initialization failed */
+ /* Avoid blocking the main thread */
+ sb_barrier_wait(&thread_start_barrier);
+ return NULL;
}
- /*
- We do this to make sure all threads get to this barrier
- about the same time
- */
- pthread_mutex_lock(&thread_start_mutex);
- sb_globals.num_running++;
- pthread_mutex_unlock(&thread_start_mutex);
+ log_text(LOG_DEBUG, "Worker thread (#%d) started!", thread_id);
+
+ /* Wait for other threads to initialize */
+ if (sb_barrier_wait(&thread_start_barrier) < 0)
+ return NULL;
do
{
@@ -551,11 +568,7 @@
if (test->ops.thread_done != NULL)
test->ops.thread_done(thread_id);
- pthread_mutex_lock(&thread_start_mutex);
- sb_globals.num_running--;
- pthread_mutex_unlock(&thread_start_mutex);
-
- return NULL;
+ return NULL;
}
static void *eventgen_thread_proc(void *arg)
@@ -573,8 +586,9 @@
log_text(LOG_DEBUG, "Event generating thread started");
- pthread_mutex_lock(&thread_start_mutex);
- pthread_mutex_unlock(&thread_start_mutex);
+ /* Wait for other threads to initialize */
+ if (sb_barrier_wait(&thread_start_barrier) < 0)
+ return NULL;
curr_ns = sb_timer_value(&sb_globals.exec_timer);
/* emulate exponential distribution with Lambda = tx_rate */
@@ -637,6 +651,12 @@
(void)arg; /* unused */
+ log_text(LOG_DEBUG, "Reporting thread started");
+
+ /* Wait for other threads to initialize */
+ if (sb_barrier_wait(&thread_start_barrier) < 0)
+ return NULL;
+
if (current_test->ops.print_stats == NULL)
{
log_text(LOG_DEBUG, "Reporting not supported by the current test, ",
@@ -644,11 +664,6 @@
return NULL;
}
- log_text(LOG_DEBUG, "Reporting thread started");
-
- pthread_mutex_lock(&thread_start_mutex);
- pthread_mutex_unlock(&thread_start_mutex);
-
pause_ns = interval_ns;
prev_ns = sb_timer_value(&sb_globals.exec_timer) + interval_ns;
for (;;)
@@ -686,18 +701,19 @@
(void)arg; /* unused */
+ log_text(LOG_DEBUG, "Checkpoints report thread started");
+
+ /* Wait for other threads to initialize */
+ if (sb_barrier_wait(&thread_start_barrier) < 0)
+ return NULL;
+
if (current_test->ops.print_stats == NULL)
{
log_text(LOG_DEBUG, "Reporting not supported by the current test, ",
- "terminating the reporting thread");
+ "terminating the checkpoints thread");
return NULL;
}
- log_text(LOG_DEBUG, "Checkpoints report thread started");
-
- pthread_mutex_lock(&thread_start_mutex);
- pthread_mutex_unlock(&thread_start_mutex);
-
for (i = 0; i < sb_globals.n_checkpoints; i++)
{
next_ns = SEC2NS(sb_globals.checkpoints[i]);
@@ -723,11 +739,29 @@
return NULL;
}
-/*
- Main test function. Start threads.
- Wait for them to complete and measure time
-*/
+/* Callback to start timers when all threads are ready */
+static int threads_started_callback(void *arg)
+{
+ (void) arg; /* unused */
+
+ /* Report initialization errors to the main thread */
+ if (sb_globals.error)
+ return 1;
+
+ sb_globals.num_running = sb_globals.num_threads;
+
+ sb_timer_start(&sb_globals.exec_timer);
+ sb_timer_start(&sb_globals.cumulative_timer1);
+ sb_timer_start(&sb_globals.cumulative_timer2);
+
+ return 0;
+}
+
+/*
+ Main test function. Start threads.
+ Wait for them to complete and measure time
+*/
static int run_test(sb_test_t *test)
{
@@ -739,6 +773,7 @@
int report_thread_created = 0;
int checkpoints_thread_created = 0;
int eventgen_thread_created = 0;
+ unsigned int barrier_threads;
/* initialize test */
if (test->ops.init != NULL && test->ops.init() != 0)
@@ -769,9 +804,6 @@
sb_globals.event_queue_length = 0;
queue_is_full = 0;
- /* start mutex used for barrier */
- pthread_mutex_init(&thread_start_mutex,NULL);
- pthread_mutex_lock(&thread_start_mutex);
sb_globals.num_running = 0;
/* initialize attr */
@@ -791,6 +823,19 @@
pthread_mutex_init(&rnd_mutex, NULL);
pthread_mutex_init(&report_interval_mutex, NULL);
+ /* Calculate the required number of threads for the start barrier */
+ barrier_threads = 1 + sb_globals.num_threads +
+ (sb_globals.report_interval > 0) +
+ (sb_globals.tx_rate > 0) +
+ (sb_globals.n_checkpoints > 0);
+
+ /* Initialize the start barrier */
+ if (sb_barrier_init(&thread_start_barrier, barrier_threads,
+ threads_started_callback, NULL)) {
+ log_errno(LOG_FATAL, "sb_barrier_init() failed");
+ return 1;
+ }
+
if (sb_globals.report_interval > 0)
{
/* Create a thread for intermediate statistic reports */
@@ -827,36 +872,52 @@
checkpoints_thread_created = 1;
}
- /* Starting the test threads */
+ /* Starting the worker threads */
for(i = 0; i < sb_globals.num_threads; i++)
{
- if (sb_globals.error)
- return 1;
if ((err = pthread_create(&(threads[i].thread), &thread_attr,
- &runner_thread, (void*)(threads + i))) != 0)
+ &worker_thread, (void*)(threads + i))) != 0)
{
log_errno(LOG_FATAL, "pthread_create() for thread #%d failed.", i);
return 1;
}
}
- sb_timer_start(&sb_globals.exec_timer); /* Start benchmark timer */
- sb_timer_start(&sb_globals.cumulative_timer1);
- sb_timer_start(&sb_globals.cumulative_timer2);
+#ifdef HAVE_ALARM
+ /* Exit with an error if thread initialization timeout expires */
+ signal(SIGALRM, sigalrm_thread_init_timeout_handler);
+
+ alarm(THREAD_INIT_TIMEOUT);
+#endif
+
+ log_text(LOG_NOTICE, "Initializing worker threads...\n");
+
+ if (sb_barrier_wait(&thread_start_barrier) < 0)
+ {
+ log_text(LOG_FATAL, "Thread initialization failed!");
+ return 1;
+ }
#ifdef HAVE_ALARM
- /* Set the alarm to force shutdown */
+ alarm(0);
+
if (sb_globals.force_shutdown)
+ {
+ /* Set the alarm to force shutdown */
+ signal(SIGALRM, sigalrm_forced_shutdown_handler);
+
alarm(sb_globals.max_time + sb_globals.timeout);
+ }
#endif
-
- pthread_mutex_unlock(&thread_start_mutex);
-
- log_text(LOG_NOTICE, "Threads started!\n");
+
+ log_text(LOG_NOTICE, "Threads started!\n");
+
for(i = 0; i < sb_globals.num_threads; i++)
{
if((err = pthread_join(threads[i].thread, NULL)) != 0)
log_errno(LOG_FATAL, "pthread_join() for thread #%d failed.", i);
+
+ sb_globals.num_running--;
}
sb_timer_stop(&sb_globals.exec_timer);
@@ -886,8 +947,6 @@
pthread_mutex_destroy(&sb_globals.exec_mutex);
- pthread_mutex_destroy(&thread_start_mutex);
-
/* finalize test */
if (test->ops.done != NULL)
(*(test->ops.done))();
@@ -1118,7 +1177,7 @@
/* Parse command line arguments */
if (parse_arguments(argc,argv))
{
- print_usage();
+ print_help();
exit(1);
}
@@ -1131,7 +1190,7 @@
if (sb_globals.command == SB_COMMAND_NULL)
{
fprintf(stderr, "Missing required command argument.\n");
- print_usage();
+ print_help();
exit(1);
}
@@ -1155,7 +1214,7 @@
if (sb_globals.command == SB_COMMAND_HELP)
{
if (test == NULL)
- print_usage();
+ print_help();
else
{
if (test->args != NULL)
@@ -1175,7 +1234,7 @@
if (testname == NULL)
{
fprintf(stderr, "Missing required argument: --test.\n");
- print_usage();
+ print_help();
exit(1);
}
@@ -1213,9 +1272,6 @@
/* 'run' command */
current_test = test;
-#ifdef HAVE_ALARM
- signal(SIGALRM, sigalrm_handler);
-#endif
if (run_test(test))
exit(1);