summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/Makefile.am1
-rw-r--r--client/client_priv.h1
-rw-r--r--client/mysqlslap.c131
3 files changed, 91 insertions, 42 deletions
diff --git a/client/Makefile.am b/client/Makefile.am
index 8b6da68a659..1c2ca0670c7 100644
--- a/client/Makefile.am
+++ b/client/Makefile.am
@@ -48,6 +48,7 @@ mysqlbinlog_SOURCES = mysqlbinlog.cc $(top_srcdir)/mysys/mf_tempdir.c \
$(top_srcdir)/mysys/my_vle.c \
$(top_srcdir)/mysys/base64.c
mysqlbinlog_LDADD = $(LDADD) $(CXXLDFLAGS)
+mysqlslap_LDADD = $(LDADD) $(CXXLDFLAGS) -lpthread
mysqltestmanager_pwgen_SOURCES = mysqlmanager-pwgen.c
mysqltestmanagerc_SOURCES= mysqlmanagerc.c $(yassl_dummy_link_fix)
mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix)
diff --git a/client/client_priv.h b/client/client_priv.h
index fb5c7d157f3..44f3ce227af 100644
--- a/client/client_priv.h
+++ b/client/client_priv.h
@@ -53,6 +53,7 @@ enum options_client
OPT_MYSQL_ONLY_PRINT,
OPT_MYSQL_LOCK_DIRECTORY,
OPT_MYSQL_SLAP_SLAVE,
+ OPT_USE_THREADS,
OPT_MYSQL_NUMBER_OF_QUERY,
OPT_MYSQL_PRESERVE_SCHEMA,
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
diff --git a/client/mysqlslap.c b/client/mysqlslap.c
index d371387de10..5fd4fad23a5 100644
--- a/client/mysqlslap.c
+++ b/client/mysqlslap.c
@@ -87,6 +87,7 @@ TODO:
#include <sys/types.h>
#include <sys/wait.h>
#include <ctype.h>
+#include <my_pthread.h>
#define MYSLAPLOCK "/myslaplock.lck"
#define MYSLAPLOCK_DIR "/tmp"
@@ -132,6 +133,7 @@ static uint opt_protocol= 0;
static int get_options(int *argc,char ***argv);
static uint opt_mysql_port= 0;
+static uint opt_use_threads;
static const char *load_default_groups[]= { "mysqlslap","client",0 };
@@ -151,6 +153,13 @@ struct stats {
unsigned long long rows;
};
+typedef struct thread_context thread_context;
+
+struct thread_context {
+ statement *stmt;
+ ulonglong limit;
+};
+
typedef struct conclusions conclusions;
struct conclusions {
@@ -184,7 +193,7 @@ static int create_schema(MYSQL *mysql, const char *db, statement *stmt,
statement *engine_stmt);
static int run_scheduler(stats *sptr, statement *stmts, uint concur,
ulonglong limit);
-int run_task(statement *stmt, ulonglong limit);
+int run_task(thread_context *con);
void statement_cleanup(statement *stmt);
static const char ALPHANUMERICS[]=
@@ -440,6 +449,10 @@ static struct my_option my_long_options[] =
{"socket", 'S', "Socket file to use for connection.",
(gptr*) &opt_mysql_unix_port, (gptr*) &opt_mysql_unix_port, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"use-threads", OPT_USE_THREADS,
+ "Use pthread calls instead of fork() calls (default on Windows)",
+ (gptr*) &opt_use_threads, (gptr*) &opt_use_threads, 0,
+ GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0},
#include <sslopt-longopts.h>
#ifndef DONT_ALLOW_USER_CHANGE
{"user", 'u', "User for login if not current user.", (gptr*) &user,
@@ -930,8 +943,11 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
uint x;
File lock_file;
struct timeval start_time, end_time;
+ thread_context con;
DBUG_ENTER("run_scheduler");
+ con.stmt= stmts;
+ con.limit= limit;
lock_file= my_open(lock_file_str, O_CREAT|O_WRONLY|O_TRUNC, MYF(0));
@@ -943,42 +959,67 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
exit(0);
}
- for (x= 0; x < concur; x++)
+ if (opt_use_threads)
{
- int pid;
- DBUG_PRINT("info", ("x %d concurrency %d", x, concurrency));
- pid= fork();
- switch(pid)
+ pthread_t mainthread; /* Thread descriptor */
+ pthread_attr_t attr; /* Thread attributes */
+
+ for (x= 0; x < concur; x++)
{
- case 0:
- /* child */
- DBUG_PRINT("info", ("fork returned 0, calling task(\"%s\"), pid %d gid %d",
- stmts->string, pid, getgid()));
- if (verbose >= 2)
+ pthread_attr_init(&attr);
+ pthread_attr_setdetachstate(&attr,
+ PTHREAD_CREATE_DETACHED);
+
+ /* now create the thread */
+ if (pthread_create(&mainthread, &attr, (void *)run_task,
+ (void *)&con) != 0)
+ {
+ fprintf(stderr,"%s: Could not create thread\n",
+ my_progname);
+ exit(0);
+ }
+ }
+ }
+ else
+ {
+ for (x= 0; x < concur; x++)
+ {
+ int pid;
+ DBUG_PRINT("info", ("x %d concurrency %d", x, concurrency));
+ pid= fork();
+ switch(pid)
+ {
+ case 0:
+ /* child */
+ DBUG_PRINT("info", ("fork returned 0, calling task(\"%s\"), pid %d gid %d",
+ stmts->string, pid, getgid()));
+ if (verbose >= 2)
+ fprintf(stderr,
+ "%s: fork returned 0, calling task pid %d gid %d\n",
+ my_progname, pid, getgid());
+ run_task(&con);
+ exit(0);
+ break;
+ case -1:
+ /* error */
+ DBUG_PRINT("info",
+ ("fork returned -1, failing pid %d gid %d", pid, getgid()));
fprintf(stderr,
- "%s: fork returned 0, calling task pid %d gid %d\n",
- my_progname, pid, getgid());
- run_task(stmts, limit);
- exit(0);
- break;
- case -1:
- /* error */
- DBUG_PRINT("info",
- ("fork returned -1, failing pid %d gid %d", pid, getgid()));
- fprintf(stderr,
- "%s: Failed on fork: -1, max procs per parent exceeded.\n",
- my_progname);
- /*exit(1);*/
- goto WAIT;
- default:
- /* parent, forked */
- DBUG_PRINT("info", ("default, break: pid %d gid %d", pid, getgid()));
- if (verbose >= 2)
- fprintf(stderr,"%s: fork returned %d, gid %d\n",
- my_progname, pid, getgid());
- break;
+ "%s: Failed on fork: -1, max procs per parent exceeded.\n",
+ my_progname);
+ /*exit(1);*/
+ goto WAIT;
+ default:
+ /* parent, forked */
+ DBUG_PRINT("info", ("default, break: pid %d gid %d", pid, getgid()));
+ if (verbose >= 2)
+ fprintf(stderr,"%s: fork returned %d, gid %d\n",
+ my_progname, pid, getgid());
+ break;
+ }
}
}
+
/* Lets release use some clients! */
if (!opt_slave)
my_lock(lock_file, F_UNLCK, 0, F_TO_EOF, MYF(0));
@@ -987,12 +1028,18 @@ run_scheduler(stats *sptr, statement *stmts, uint concur, ulonglong limit)
my_close(lock_file, MYF(0));
-WAIT:
- while (x--)
+ if (opt_use_threads)
+ {
+ }
+ else
{
- int status, pid;
- pid= wait(&status);
- DBUG_PRINT("info", ("Parent: child %d status %d", pid, status));
+WAIT:
+ while (x--)
+ {
+ int status, pid;
+ pid= wait(&status);
+ DBUG_PRINT("info", ("Parent: child %d status %d", pid, status));
+ }
}
gettimeofday(&end_time, NULL);
@@ -1004,7 +1051,7 @@ WAIT:
}
int
-run_task(statement *qstmt, ulonglong limit)
+run_task(thread_context *con)
{
ulonglong counter= 0, queries;
File lock_file;
@@ -1014,7 +1061,7 @@ run_task(statement *qstmt, ulonglong limit)
statement *ptr;
DBUG_ENTER("run_task");
- DBUG_PRINT("info", ("task script \"%s\"", qstmt->string));
+ DBUG_PRINT("info", ("task script \"%s\"", con->stmt->string));
mysql_init(&mysql);
@@ -1036,7 +1083,7 @@ run_task(statement *qstmt, ulonglong limit)
queries= 0;
limit_not_met:
- for (ptr= qstmt; ptr && ptr->length; ptr= ptr->next)
+ for (ptr= con->stmt; ptr && ptr->length; ptr= ptr->next)
{
if (opt_only_print)
{
@@ -1060,11 +1107,11 @@ limit_not_met:
}
queries++;
- if (limit && queries == limit)
+ if (con->limit && queries == con->limit)
DBUG_RETURN(0);
}
- if (limit && queries < limit)
+ if (con->limit && queries < con->limit)
goto limit_not_met;
my_lock(lock_file, F_UNLCK, 0, F_TO_EOF, MYF(0));