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 - [email protected]
+
+- 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 <[email protected]>
+
+   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 <[email protected]>
+
+   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 <pthread.h>
+#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);
 


Reply via email to