Initial Windows support. Huge thanks to Vladislav Vaintroub for the patch.

This commit is contained in:
Alexey Kopytov
2008-09-29 16:22:42 +00:00
parent 04d168dd50
commit 2d63c9073d
31 changed files with 1085 additions and 197 deletions

20
README-WIN.txt Normal file
View File

@ -0,0 +1,20 @@
How to build on Windows
You need CMake (download from http://www.cmake.org/) and Visual Studio 2005 or
later (free Express edition should work ok)
1.Open Visual Studio command line prompt
2.To build with MySQL support, you will need mysql.h header file and client
library libmysqld.lib
One can get them e.g by downloading and unpacking the "zip" distribution of mysql
- Append directory where libmysql.lib is located to environment variable LIB, e.g
set LIB=%LIB%;G:\mysql-noinstall-6.0.6-alpha-win32\mysql-6.0.6-alpha-win32\lib\opt
- Append directory where mysql.h is located to environment variable INCLUDE, e.g
set INCLUDE=%INCLUDE%;G:\mysql-noinstall-6.0.6-alpha-win32\mysql-6.0.6-alpha-win32\include
3.In the sysbench directory, execute cmake -G "Visual Studio 9 2008"
4.Open sysbench.sln in Explorer and build Relwithdebinfo target.
Alternatively, from the command line, issue
vcbuild /useenv sysbench.sln "Relwithdebinfo|Win32"

109
sysbench/CMakeLists.txt Normal file
View File

@ -0,0 +1,109 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
cmake_minimum_required(VERSION 2.6)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
project(sysbench)
add_executable(sysbench
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_win.c
sb_win.h
)
if(MSVC)
# Link C runtime statically to avoid hassle with CRT dll redistribution.
STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELEASE ${CMAKE_C_FLAGS_RELEASE})
STRING(REPLACE "/MD" "/MT" CMAKE_C_FLAGS_RELWITHDEBINFO ${CMAKE_C_FLAGS_RELWITHDEBINFO})
STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG ${CMAKE_C_FLAGS_DEBUG})
STRING(REPLACE "/MDd" "/MTd" CMAKE_C_FLAGS_DEBUG_INIT ${CMAKE_C_FLAGS_DEBUG_INIT})
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
STRING(REPLACE "/MD" "/MT" CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO})
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
STRING(REPLACE "/MDd" "/MTd" CMAKE_CXX_FLAGS_DEBUG_INIT ${CMAKE_CXX_FLAGS_DEBUG_INIT})
#Silence "deprecated API" warnings.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4996")
#Look for mysql.h in INCLUDE paths
find_path(MYSQLH_PATH mysql.h ENV INCLUDE)
message("mysql.h directory = ${MYSQLH_PATH}")
#Looks for libmysql.lib in LIB paths
find_file(LIBMYSQL_LIB libmysql.lib ENV LIB)
message("libmysql.lib = ${LIBMYSQL_LIB}")
#Look for libmysql.dll
find_file(LIBMYSQL_DLL libmysql.dll ENV LIB ENV PATH)
message("libmysql.dll = ${LIBMYSQL_DLL}")
#If mysql header file and client library are found, build with mysql
if(MYSQLH_PATH AND LIBMYSQL_LIB)
set(USE_MYSQL 1)
#If libmysql.dll found, copy it next to sysbench.exe in the postbuild step
if(LIBMYSQL_DLL)
file(TO_NATIVE_PATH ${LIBMYSQL_DLL} LIBMYSQL_DLL)
ADD_CUSTOM_COMMAND(
TARGET sysbench
POST_BUILD
COMMAND copy /y ${LIBMYSQL_DLL} $(OutDir)
)
endif(LIBMYSQL_DLL)
endif(MYSQLH_PATH AND LIBMYSQL_LIB)
endif(MSVC)
if(USE_MYSQL)
message("using mysql driver")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DUSE_MYSQL")
include_directories(${MYSQLH_PATH})
add_subdirectory(drivers/mysql)
target_link_libraries (sysbench sbmysql)
target_link_libraries (sysbench ${LIBMYSQL_LIB})
endif(USE_MYSQL)
add_subdirectory(tests/cpu)
target_link_libraries (sysbench sbcpu)
add_subdirectory(tests/fileio)
target_link_libraries (sysbench sbfileio)
add_subdirectory(tests/mutex)
target_link_libraries (sysbench sbmutex)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_LUA -DUSE_LUA")
add_subdirectory(scripting)
target_link_libraries(sysbench sbscript lua)
add_subdirectory(tests/threads)
target_link_libraries (sysbench sbthreads)
add_subdirectory(tests/memory)
target_link_libraries (sysbench sbmemory)

View File

@ -18,7 +18,9 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#ifdef STDC_HEADERS
# include <ctype.h>
#endif
@ -681,7 +683,7 @@ void db_free_row(db_row_t *row)
int db_bulk_insert_init(db_conn_t *con, const char *query)
{
drv_caps_t driver_caps;
unsigned int query_len;
size_t query_len;
if (con->driver == NULL)
return 1;

View File

@ -0,0 +1,2 @@
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
ADD_LIBRARY(sbmysql drv_mysql.c)

View File

@ -21,6 +21,9 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
#include <winsock2.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
@ -117,11 +120,11 @@ db_mysql_bind_map_t db_mysql_bind_map[] =
static drv_caps_t mysql_drv_caps =
{
.multi_rows_insert = 1,
.prepared_statements = 0,
.auto_increment = 1,
.serial = 0,
.unsigned_int = 1,
1,
0,
1,
0,
1,
};
@ -157,10 +160,9 @@ static int mysql_drv_done(void);
static db_driver_t mysql_driver =
{
.sname = "mysql",
.lname = "MySQL driver",
.args = mysql_drv_args,
.ops =
"mysql",
"MySQL driver",
mysql_drv_args,
{
mysql_drv_init,
mysql_drv_describe,
@ -179,7 +181,7 @@ static db_driver_t mysql_driver =
mysql_drv_store_results,
mysql_drv_done
},
.listitem = {NULL, NULL}
{0,0}
};
@ -232,6 +234,8 @@ int mysql_drv_init(void)
use_ps = 1;
#endif
mysql_library_init(-1, NULL, NULL);
return 0;
}
@ -809,6 +813,8 @@ int mysql_drv_close(db_stmt_t *stmt)
/* Uninitialize driver */
int mysql_drv_done(void)
{
mysql_library_end();
return 0;
}

View File

@ -19,14 +19,16 @@
#define SB_LIST_H
typedef struct sb_list_item sb_list_t;
typedef struct sb_list_item sb_list_item_t;
struct sb_list_item
typedef struct sb_list_item_t
{
sb_list_item_t *next_p;
sb_list_item_t *prev_p;
};
// char c;
struct sb_list_item_t *next_p;
struct sb_list_item_t *prev_p;
}
sb_list_item_t;
typedef sb_list_item_t sb_list_item;
typedef sb_list_item_t sb_list_t ;
#ifndef offsetof
# define offsetof(type, member) ((size_t) &((type *)0)->member)

View File

@ -18,6 +18,9 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#ifdef STDC_HEADERS
# include <stdio.h>
@ -107,13 +110,13 @@ static sb_arg_t text_handler_args[] =
static log_handler_t text_handler = {
.ops = {
.init = &text_handler_init,
.process = &text_handler_process,
.done = NULL,
{
&text_handler_init,
&text_handler_process,
NULL,
},
.args = text_handler_args,
.listitem = {NULL, NULL}
text_handler_args,
{0,0}
};
/* Operation start/stop messages handler */
@ -131,13 +134,13 @@ static sb_arg_t oper_handler_args[] =
};
static log_handler_t oper_handler = {
.ops = {
.init = oper_handler_init,
.process = &oper_handler_process,
.done = oper_handler_done,
{
oper_handler_init,
&oper_handler_process,
oper_handler_done,
},
.args = oper_handler_args,
.listitem = {NULL, NULL}
oper_handler_args,
{0,0}
};
@ -310,19 +313,30 @@ void log_errno(log_msg_priority_t priority, const char *fmt, ...)
int n;
int old_errno;
char *tmp;
#ifdef _WIN32
LPVOID lpMsgBuf;
old_errno = GetLastError();
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, old_errno,
0, (LPTSTR)&lpMsgBuf, 0, NULL);
tmp = (char *)lpMsgBuf;
#else
old_errno = errno;
#ifdef HAVE_STRERROR_R
#ifdef STRERROR_R_CHAR_P
tmp = strerror_r(old_errno, errbuf, ERROR_BUFFER_SIZE);
tmp = strerror_r(old_errno, errbuf, sizeof(errbuf));
#else
strerror_r(old_errno, errbuf, ERROR_BUFFER_SIZE);
strerror_r(old_errno, errbuf, sizeof(errbuf));
tmp = errbuf;
#endif /* STRERROR_R_CHAR_P */
#else /* !HAVE_STRERROR_P */
strncpy(errbuf, strerror(old_errno), sizeof(errbuf));
tmp = errbuf;
#endif
#endif /* HAVE_STRERROR_P */
#endif /* WIN32 */
va_start(ap, fmt);
n = vsnprintf(buf, TEXT_BUFFER_SIZE, fmt, ap);
@ -331,6 +345,10 @@ void log_errno(log_msg_priority_t priority, const char *fmt, ...)
return;
snprintf(buf + n, TEXT_BUFFER_SIZE - n, " errno = %d (%s)", old_errno,
tmp);
#ifdef _WIN32
LocalFree(lpMsgBuf);
#endif
log_text(priority, "%s", buf);
}
@ -406,7 +424,8 @@ int text_handler_process(log_msg_t *msg)
}
printf("%s%s", prefix, text_msg->text);
fflush(stdout);
return 0;
}

View File

@ -18,6 +18,9 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
# include "sb_win.h"
#endif
#ifdef STDC_HEADERS
# include <stdio.h>

View File

@ -23,9 +23,7 @@
#include "config.h"
#endif
#ifdef STDC_HEADERS
#include <stdio.h>
#endif
#include "sb_list.h"

View File

@ -22,6 +22,10 @@
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>

244
sysbench/sb_win.c Normal file
View File

@ -0,0 +1,244 @@
/* Copyright (C) 2008 MySQL AB
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/*
This file contains Windows port of Posix functionality used in sysbench
(partial implementation of pthreads, gettimeofday() and random()
*/
#define _CRT_RAND_S /* for rand_s */
#include <stdlib.h>
#include <windows.h>
#include <errno.h>
#include "sb_win.h"
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
{
cond->waiting= 0;
InitializeCriticalSection(&cond->lock_waiting);
cond->events[SIGNAL]= CreateEvent(NULL, FALSE, FALSE, NULL);
cond->events[BROADCAST]= CreateEvent(NULL, TRUE, FALSE, NULL);
cond->broadcast_block_event= CreateEvent(NULL, TRUE, TRUE, NULL);
if( cond->events[SIGNAL] == NULL ||
cond->events[BROADCAST] == NULL ||
cond->broadcast_block_event == NULL )
return ENOMEM;
return 0;
}
int pthread_cond_destroy(pthread_cond_t *cond)
{
DeleteCriticalSection(&cond->lock_waiting);
if (CloseHandle(cond->events[SIGNAL]) == 0 ||
CloseHandle(cond->events[BROADCAST]) == 0 ||
CloseHandle(cond->broadcast_block_event) == 0)
return EINVAL;
return 0;
}
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
{
return pthread_cond_timedwait(cond,mutex,NULL);
}
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime)
{
int result;
long timeout;
union {
FILETIME ft;
long long i64;
}now;
if( abstime != NULL )
{
long long stoptime_nanos = (abstime->tv_sec*1000000000 + abstime->tv_nsec);
long long now_nanos;
long long timeout_nanos;
GetSystemTimeAsFileTime(&now.ft);
now_nanos = now.i64 *100;
timeout_nanos = stoptime_nanos - now_nanos;
timeout = (long)(timeout_nanos /1000000);
}
else
{
/* No time specified; don't expire */
timeout= INFINITE;
}
/*
Block access if previous broadcast hasn't finished.
This is just for safety and should normally not
affect the total time spent in this function.
*/
WaitForSingleObject(cond->broadcast_block_event, INFINITE);
EnterCriticalSection(&cond->lock_waiting);
cond->waiting++;
LeaveCriticalSection(&cond->lock_waiting);
LeaveCriticalSection(mutex);
result= WaitForMultipleObjects(2, cond->events, FALSE, timeout);
EnterCriticalSection(&cond->lock_waiting);
cond->waiting--;
if (cond->waiting == 0 && result == (WAIT_OBJECT_0+BROADCAST))
{
/*
We're the last waiter to be notified or to stop waiting, so
reset the manual event.
*/
/* Close broadcast gate */
ResetEvent(cond->events[BROADCAST]);
/* Open block gate */
SetEvent(cond->broadcast_block_event);
}
LeaveCriticalSection(&cond->lock_waiting);
EnterCriticalSection(mutex);
return result == WAIT_TIMEOUT ? ETIMEDOUT : 0;
}
int pthread_cond_signal(pthread_cond_t *cond)
{
EnterCriticalSection(&cond->lock_waiting);
if(cond->waiting > 0)
SetEvent(cond->events[SIGNAL]);
LeaveCriticalSection(&cond->lock_waiting);
return 0;
}
int pthread_cond_broadcast(pthread_cond_t *cond)
{
EnterCriticalSection(&cond->lock_waiting);
/*
The mutex protect us from broadcasting if
there isn't any thread waiting to open the
block gate after this call has closed it.
*/
if(cond->waiting > 0)
{
/* Close block gate */
ResetEvent(cond->broadcast_block_event);
/* Open broadcast gate */
SetEvent(cond->events[BROADCAST]);
}
LeaveCriticalSection(&cond->lock_waiting);
return 0;
}
int pthread_attr_init(pthread_attr_t *attr)
{
attr->stacksize = 0;
return 0;
}
int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
InitializeCriticalSection(mutex);
return 0;
}
int pthread_mutex_lock(pthread_mutex_t *mutex)
{
EnterCriticalSection(mutex);
return 0;
}
int pthread_mutex_unlock(pthread_mutex_t *mutex)
{
LeaveCriticalSection(mutex);
return 0;
}
int pthread_mutex_destroy(pthread_mutex_t *mutex)
{
DeleteCriticalSection(mutex);
return 0;
}
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine)(void*), void *arg)
{
DWORD tid;
*thread = CreateThread(NULL, attr->stacksize,
(LPTHREAD_START_ROUTINE) start_routine, arg,
STACK_SIZE_PARAM_IS_A_RESERVATION, &tid);
if (*thread != NULL)
return 0;
return -1;
}
/* Minimal size of thread stack on Windows*/
#define PTHREAD_STACK_MIN 65536
int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize)
{
if(stacksize)
attr->stacksize = max(stacksize, PTHREAD_STACK_MIN);
return 0;
}
int pthread_join(pthread_t pthread, void **value_ptr)
{
if (WaitForSingleObject(pthread, INFINITE) != WAIT_OBJECT_0)
return -1;
if (value_ptr)
*value_ptr = 0;
return 0;
}
#include <time.h>
int gettimeofday(struct timeval * tp, void * tzp)
{
static long long qpf = 0, startup_time = 0;
long long qpc;
if(qpf == 0)
{
QueryPerformanceFrequency((LARGE_INTEGER *)&qpf);
}
if(startup_time == 0)
{
QueryPerformanceCounter((LARGE_INTEGER *)&qpc);
startup_time = time(NULL) - (qpc/qpf);
}
QueryPerformanceCounter((LARGE_INTEGER *)&qpc);
tp->tv_sec = (long)(startup_time + qpc/qpf);
tp->tv_usec = (long)((qpc%qpf)*1000000/qpf);
return 0;
}
int random()
{
int ret;
rand_s(&ret);
return ret;
}

103
sysbench/sb_win.h Normal file
View File

@ -0,0 +1,103 @@
#ifndef SB_WINPORT_H
#define SB_WINPORT_H
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0500
#endif
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <time.h>
#include <string.h>
#include <math.h>
#if (_MSC_VER < 1400)
#error "need Visual Studio 2005 or higher"
#endif
#ifndef PACKAGE
#define PACKAGE "sysbench"
#endif
#ifndef PACKAGE_VERSION
#define PACKAGE_VERSION "0.5"
#endif
#define snprintf(buffer, count, format,...) \
_snprintf_s(buffer,count, _TRUNCATE,format, __VA_ARGS__)
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#define srandom(seed) srand(seed)
typedef intptr_t ssize_t;
#ifdef _WIN64
#define SIZEOF_SIZE_T 8
#else
#define SIZEOF_SIZE_T 4
#endif
struct timespec
{
time_t tv_sec;
long long tv_nsec;
};
typedef HANDLE pthread_t;
typedef CRITICAL_SECTION pthread_mutex_t;
#define SIGNAL 0
#define BROADCAST 1
#define MAX_EVENTS 2
typedef struct _pthread_cond_t
{
int waiting;
CRITICAL_SECTION lock_waiting;
HANDLE events[MAX_EVENTS];
HANDLE broadcast_block_event;
}pthread_cond_t;
typedef struct
{
char unused;
}pthread_condattr_t;
typedef struct
{
DWORD stacksize;
}pthread_attr_t;
typedef struct
{
char unused;
}pthread_mutexattr_t;
extern int pthread_attr_init(pthread_attr_t *attr);
extern int pthread_cond_destroy(pthread_cond_t *cond);
extern int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
struct timespec *abstime);
extern int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
extern int pthread_cond_signal(pthread_cond_t *cond);
extern int pthread_mutex_lock(pthread_mutex_t *mutex);
extern int pthread_mutex_unlock(pthread_mutex_t *mutex);
extern int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
extern int pthread_mutex_destroy(pthread_mutex_t *mutex);
extern int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg);
extern int pthread_attr_setstacksize( pthread_attr_t *attr, size_t stacksize);
extern int pthread_join(pthread_t thread, void **value_ptr);
extern int gettimeofday(struct timeval * tp, void * tzp);
extern int random();
#define ETIMEDOUT 2204
static __inline int usleep(int micros)
{
Sleep(micros/1000);
return 0;
}
#define gmtime_r(a,b) gmtime_s(b,a)
#endif

View File

@ -0,0 +1,20 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
include_directories(lua/src ..)
add_subdirectory(lua/src)
add_library(sbscript sb_script.c sb_script.h script_lua.c script_lua.h)

View File

@ -0,0 +1,27 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
if(MSVC)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLUA_WIN")
endif(MSVC)
add_library(lua lapi.c lcode.c ldebug.c ldo.c ldump.c lfunc.c lgc.c llex.c lmem.c
lobject.c lopcodes.c lparser.c lstate.c lstring.c ltable.c ltm.c
lundump.c lvm.c lzio.c
lauxlib.c lbaselib.c ldblib.c liolib.c lmathlib.c loslib.c ltablib.c
lstrlib.c loadlib.c linit.c
lapi.h lcode.h ldo.h lgc.h llimits.h lobject.h lparser.h lstring.h ltm.h
luaconf.h lundump.h lzio.h lauxlib.h ldebug.h lfunc.h llex.h lmem.h lopcodes.h
lstate.h ltable.h lua.h lualib.h lvm.h)

View File

@ -32,7 +32,9 @@
#define LUA_ANSI
#endif
#ifndef _WIN32
#define LUA_USE_DLOPEN
#endif
/*
@@ LUA_PATH and LUA_CPATH are the names of the environment variables that

View File

@ -94,10 +94,16 @@ static int sb_lua_op_thread_done(int);
static void sb_lua_op_print_stats(void);
static sb_operations_t lua_ops = {
.init = &sb_lua_init,
.get_request = &sb_lua_get_request,
.execute_request = &sb_lua_op_execute_request,
.done = &sb_lua_done
&sb_lua_init,
NULL,
NULL,
NULL,
&sb_lua_get_request,
&sb_lua_op_execute_request,
NULL,
NULL,
NULL,
&sb_lua_done
};
/* Main (global) interpreter state */
@ -240,7 +246,7 @@ int sb_lua_op_execute_request(sb_request_t *sb_req, int thread_id)
{
log_msg_t msg;
log_msg_oper_t op_msg;
uint restart;
unsigned int restart;
lua_State *L = states[thread_id];
(void)sb_req; /* unused */

View File

@ -442,7 +442,9 @@ int run_test(sb_test_t *test)
/* initialize attr */
pthread_attr_init(&thread_attr);
#ifdef PTHREAD_SCOPE_SYSTEM
pthread_attr_setscope(&thread_attr,PTHREAD_SCOPE_SYSTEM);
#endif
pthread_attr_setstacksize(&thread_attr, thread_stack_size);
#ifdef HAVE_THR_SETCONCURRENCY
@ -468,7 +470,7 @@ int run_test(sb_test_t *test)
}
pthread_mutex_unlock(&thread_start_mutex);
log_text(LOG_INFO, "Threads started!");
log_text(LOG_NOTICE, "Threads started!\n");
for(i = 0; i < sb_globals.num_threads; i++)
{
if(pthread_join(threads[i].thread, NULL))
@ -545,7 +547,7 @@ int init(void)
return 1;
}
thread_stack_size = sb_get_value_int("thread-stack-size");
thread_stack_size = sb_get_value_size("thread-stack-size");
if (thread_stack_size <= 0)
{
log_text(LOG_FATAL, "Invalid value for thread-stack-size: %d.\n", thread_stack_size);

View File

@ -0,0 +1,2 @@
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
ADD_LIBRARY(sbtests sb_cpu.)

View File

@ -0,0 +1,18 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests)
ADD_LIBRARY(sbcpu sb_cpu.c)

View File

@ -18,6 +18,9 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
# include "sb_win.h"
#endif
#ifdef HAVE_MATH_H
# include <math.h>
@ -42,27 +45,24 @@ static int cpu_done(void);
static sb_test_t cpu_test =
{
.sname = "cpu",
.lname = "CPU performance test",
.ops = {
.init = cpu_init,
.prepare = NULL,
.thread_init = NULL,
.thread_done = NULL,
.cleanup = NULL,
.print_mode = cpu_print_mode,
.get_request = cpu_get_request,
.execute_request = cpu_execute_request,
.print_stats = cpu_print_stats,
.done = cpu_done
"cpu",
"CPU performance test",
{
cpu_init,
NULL,
NULL,
cpu_print_mode,
cpu_get_request,
cpu_execute_request,
cpu_print_stats,
NULL,
NULL,
cpu_done
},
.cmds = {
.prepare = NULL,
.help = NULL,
.run = NULL,
.cleanup = NULL
{
NULL,NULL,NULL,NULL
},
.args = cpu_args,
cpu_args,
{NULL, NULL}
};

View File

@ -0,0 +1,18 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests)
ADD_LIBRARY(sbfileio sb_fileio.c crc32.c)

View File

@ -26,7 +26,11 @@
#define OF(args) args
#include "crc32.h"
#ifndef _WIN32
#define ptrdiff_t long
#else
#include <stdlib.h>
#endif
/* Find a four-byte integer type for crc32_little() and crc32_big(). */
#ifndef NOBYFOUR

View File

@ -19,6 +19,10 @@
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#ifdef STDC_HEADERS
# include <stdio.h>
/* Required for memalign to be declared on Solaris */
@ -45,6 +49,14 @@
#ifdef HAVE_SYS_MMAN_H
# include <sys/mman.h>
#endif
#ifdef _WIN32
# include <io.h>
# include <fcntl.h>
# include <sys/stat.h>
# define S_IRUSR _S_IREAD
# define S_IWUSR _S_IWRITE
# define HAVE_MMAP
#endif
#include "sysbench.h"
#include "crc32.h"
@ -53,6 +65,24 @@
#define FILE_CHECKSUM_LENGTH sizeof(int)
#define FILE_OFFSET_LENGTH sizeof(long)
#ifdef _WIN32
typedef HANDLE FILE_DESCRIPTOR;
#define VALID_FILE(fd) (fd != INVALID_HANDLE_VALUE)
#define FD_FMT "%p"
#define MAP_SHARED 0
#define PROT_READ 1
#define PROT_WRITE 2
#define MAP_FAILED NULL
void *mmap(void *addr, size_t len, int prot, int flags,
FILE_DESCRIPTOR fd, long long off);
int munmap(void *addr, size_t size);
#else
typedef int FILE_DESCRIPTOR;
#define VALID_FILE(fd) (fd >= 0)
#define FD_FMT "%d"
#endif
/* Supported operations in request */
typedef enum
{
@ -102,8 +132,8 @@ static sb_aio_context_t *aio_ctxts;
/* Test options */
static unsigned int num_files;
static off_t total_size;
static off_t file_size;
static long long total_size;
static long long file_size;
static int file_block_size;
static int file_extra_flags;
static int file_fsync_freq;
@ -112,7 +142,7 @@ static int file_fsync_end;
static file_fsync_mode_t file_fsync_mode;
static float file_rw_ratio;
static int file_merged_requests;
static off_t file_max_request_size;
static long long file_max_request_size;
static file_io_mode_t file_io_mode;
#ifdef HAVE_LIBAIO
static unsigned int file_async_backlog;
@ -137,12 +167,12 @@ static unsigned long long bytes_written;
#ifdef HAVE_MMAP
/* Array of file mappings */
static void **mmaps;
static void **mmaps;
static unsigned long file_page_mask;
#endif
/* Array of file descriptors */
static int *files;
static FILE_DESCRIPTOR *files;
/* Buffer for all I/O operations */
static void *buffer;
@ -196,33 +226,31 @@ static void file_print_stats(void);
static sb_test_t fileio_test =
{
.sname = "fileio",
.lname = "File I/O test",
.ops =
"fileio",
"File I/O test",
{
.init = file_init,
.thread_init = NULL,
file_init,
file_prepare,
NULL,
file_print_mode,
file_get_request,
file_execute_request,
file_print_stats,
#ifdef HAVE_LIBAIO
.thread_done = file_thread_done,
file_thread_done,
#else
.thread_done = NULL,
NULL,
#endif
.prepare = file_prepare,
.cleanup = NULL,
.print_mode = file_print_mode,
.get_request = file_get_request,
.execute_request = file_execute_request,
.print_stats = file_print_stats,
.done = file_done
file_done
},
.cmds = {
.prepare = file_cmd_prepare,
.help = NULL,
.run = NULL,
.cleanup = file_cmd_cleanup
{
NULL,
file_cmd_prepare,
NULL,
file_cmd_cleanup
},
.args = fileio_args,
{NULL, NULL}
fileio_args,
{0,0}
};
@ -235,13 +263,13 @@ static sb_request_t file_get_rnd_request(void);
static void check_seq_req(sb_file_request_t *, sb_file_request_t *);
static const char *get_io_mode_str(file_io_mode_t mode);
static const char *get_test_mode_str(file_test_mode_t mode);
static void file_fill_buffer(unsigned char *, unsigned int, unsigned long);
static int file_validate_buffer(unsigned char *, unsigned int, unsigned long);
static void file_fill_buffer(unsigned char *, unsigned int, size_t);
static int file_validate_buffer(unsigned char *, unsigned int, size_t);
/* File operation wrappers */
static int file_fsync(unsigned int, int);
static ssize_t file_pread(unsigned int, void *, ssize_t, off_t, int);
static ssize_t file_pwrite(unsigned int, void *, ssize_t, off_t, int);
static ssize_t file_pread(unsigned int, void *, ssize_t, long long, int);
static ssize_t file_pwrite(unsigned int, void *, ssize_t, long long, int);
#ifdef HAVE_LIBAIO
static int file_async_init(void);
static int file_async_done(void);
@ -255,7 +283,9 @@ static int file_mmap_done(void);
/* Portability wrappers */
static unsigned long sb_getpagesize(void);
static unsigned long sb_get_allocation_granularity(void);
static void *sb_memalign(size_t size);
static void sb_free_memaligned(void *buf);
int register_test_fileio(sb_list_t *tests)
{
@ -270,7 +300,7 @@ int file_init(void)
if (parse_arguments())
return 1;
files = (int *)malloc(num_files * sizeof(int));
files = (FILE_DESCRIPTOR *)malloc(num_files * sizeof(FILE_DESCRIPTOR));
if (files == NULL)
{
log_text(LOG_FATAL, "Memory allocation failure.");
@ -301,10 +331,15 @@ int file_prepare(void)
unlink(file_name);
log_text(LOG_DEBUG, "Opening file: %s",file_name);
#ifndef _WIN32
files[i] = open(file_name, O_CREAT | O_RDWR | file_extra_flags,
S_IRUSR | S_IWUSR);
if (files[i] < 0)
#else
files[i] = CreateFile(file_name, GENERIC_READ|GENERIC_WRITE, 0, NULL,
OPEN_ALWAYS, file_extra_flags? file_extra_flags : FILE_ATTRIBUTE_NORMAL,
NULL);
#endif
if (!VALID_FILE(files[i]))
{
log_errno(LOG_FATAL, "Cannot open file");
return 1;
@ -327,7 +362,11 @@ int file_done(void)
unsigned int i;
for (i = 0; i < num_files; i++)
#ifndef _WIN32
close(files[i]);
#else
CloseHandle(files[i]);
#endif
#ifdef HAVE_LIBAIO
if (file_async_done())
@ -340,7 +379,7 @@ int file_done(void)
#endif
if (buffer != NULL)
free(buffer);
sb_free_memaligned(buffer);
pthread_mutex_destroy(&fsync_mutex);
@ -378,7 +417,7 @@ sb_request_t file_get_seq_request(void)
if (position + file_max_request_size <= file_size)
file_req->size = file_max_request_size;
else
file_req->size = file_size - position;
file_req->size = file_size - position;
file_req->file_id = current_file;
file_req->pos = position;
}
@ -445,7 +484,7 @@ sb_request_t file_get_rnd_request(void)
{
sb_request_t sb_req;
sb_file_request_t *file_req = &sb_req.u.file_request;
unsigned int rand;
unsigned int randnum;
unsigned long long tmppos;
int real_mode = test_mode;
int mode = test_mode;
@ -515,16 +554,16 @@ sb_request_t file_get_rnd_request(void)
}
}
rand=sb_rnd();
randnum=sb_rnd();
if (mode==MODE_RND_WRITE) /* mode shall be WRITE or RND_WRITE only */
file_req->operation = FILE_OP_TYPE_WRITE;
else
file_req->operation = FILE_OP_TYPE_READ;
tmppos = (long long)((double)rand / (double)SB_MAX_RND * (double)(total_size));
tmppos = (long long)((double)randnum / (double)SB_MAX_RND * (double)(total_size));
tmppos = tmppos - (tmppos % (long long)file_block_size);
file_req->file_id = (int)(tmppos / (long long)file_size);
file_req->pos = (off_t)(tmppos % (long long)file_size);
file_req->pos = (long long)(tmppos % (long long)file_size);
file_req->size = file_block_size;
req_performed++;
@ -537,12 +576,11 @@ sb_request_t file_get_rnd_request(void)
int file_execute_request(sb_request_t *sb_req, int thread_id)
{
int fd;
FILE_DESCRIPTOR fd;
sb_file_request_t *file_req = &sb_req->u.file_request;
log_msg_t msg;
log_msg_oper_t op_msg;
fd = files[file_req->file_id];
if (sb_globals.debug)
{
log_text(LOG_DEBUG,
@ -565,7 +603,7 @@ int file_execute_request(sb_request_t *sb_req, int thread_id)
log_text(LOG_FATAL, "Too large position discovered in request!");
return 1;
}
fd = files[file_req->file_id];
/* Prepare log message */
msg.type = LOG_MSG_TYPE_OPER;
msg.data = &op_msg;
@ -585,7 +623,7 @@ int file_execute_request(sb_request_t *sb_req, int thread_id)
thread_id)
!= (ssize_t)file_req->size)
{
log_errno(LOG_FATAL, "Failed to write file! file: %d pos: %lld",
log_errno(LOG_FATAL, "Failed to write file! file: " FD_FMT " pos: %lld",
fd, (long long)file_req->pos);
return 1;
}
@ -595,7 +633,7 @@ int file_execute_request(sb_request_t *sb_req, int thread_id)
{
if (file_fsync(file_req->file_id, thread_id))
{
log_errno(LOG_FATAL, "Failed to fsync file! file: %d", fd);
log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, fd);
return 1;
}
}
@ -617,7 +655,7 @@ int file_execute_request(sb_request_t *sb_req, int thread_id)
thread_id)
!= (ssize_t)file_req->size)
{
log_errno(LOG_FATAL, "Failed to read file! file: %d pos: %lld",
log_errno(LOG_FATAL, "Failed to read file! file: " FD_FMT " pos: %lld",
fd, (long long)file_req->pos);
return 1;
}
@ -628,8 +666,8 @@ int file_execute_request(sb_request_t *sb_req, int thread_id)
file_validate_buffer(buffer, file_req->size, file_req->pos))
{
log_text(LOG_FATAL,
"Validation failed on file %d, block offset 0x%x, exiting...",
file_req->file_id, file_req->pos);
"Validation failed on file " FD_FMT ", block offset 0x%x, exiting...",
file_req->file_id, file_req->pos);
return 1;
}
@ -647,7 +685,7 @@ int file_execute_request(sb_request_t *sb_req, int thread_id)
break;
if(file_fsync(file_req->file_id, thread_id))
{
log_errno(LOG_FATAL, "Failed to fsync file! file: %d", fd);
log_errno(LOG_FATAL, "Failed to fsync file! file: " FD_FMT, fd);
return 1;
}
@ -803,7 +841,7 @@ int create_files(void)
unsigned int i;
int fd;
char file_name[512];
off_t offset;
long long offset;
log_text(LOG_INFO, "%d files, %ldKb each, %ldMb total", num_files,
(long)(file_size / 1024),
@ -812,7 +850,6 @@ int create_files(void)
for (i=0; i < num_files; i++) {
snprintf(file_name, sizeof(file_name), "test_file.%d",i);
unlink(file_name);
fd = open(file_name, O_CREAT | O_WRONLY, S_IRUSR | S_IWUSR);
if (fd < 0)
{
@ -833,7 +870,11 @@ int create_files(void)
}
/* fsync files to prevent cache flush from affecting test results */
#ifndef _WIN32
fsync(fd);
#else
_commit(fd);
#endif
close(fd);
}
return 0;
@ -1111,18 +1152,37 @@ int file_mmap_prepare(void)
if (file_io_mode != FILE_IO_MODE_MMAP)
return 0;
file_page_mask = ~(sb_getpagesize() - 1);
file_page_mask = ~(sb_get_allocation_granularity() - 1);
/* Extend file sizes for sequential write test */
if (test_mode == MODE_WRITE)
for (i = 0; i < num_files; i++)
{
#ifdef _WIN32
HANDLE hFile = files[i];
LARGE_INTEGER offset;
offset.QuadPart = file_size;
if (!SetFilePointerEx(hFile ,offset ,NULL, FILE_BEGIN))
{
log_errno(LOG_FATAL, "SetFilePointerEx() failed on file %d", i);
return 1;
}
if (!SetEndOfFile(hFile))
{
log_errno(LOG_FATAL, "SetEndOfFile() failed on file %d", i);
return 1;
}
offset.QuadPart = 0;
SetFilePointerEx(hFile ,offset ,NULL, FILE_BEGIN);
#else
if (ftruncate(files[i], file_size))
{
log_errno(LOG_FATAL, "ftruncate() failed on file %d", i);
return 1;
}
#endif
}
#if SIZEOF_SIZE_T > 4
mmaps = (void **)malloc(num_files * sizeof(void *));
for (i = 0; i < num_files; i++)
@ -1168,7 +1228,7 @@ int file_mmap_done(void)
int file_fsync(unsigned int file_id, int thread_id)
{
int fd = files[file_id];
FILE_DESCRIPTOR fd = files[file_id];
#ifdef HAVE_LIBAIO
struct iocb iocb;
#else
@ -1188,7 +1248,11 @@ int file_fsync(unsigned int file_id, int thread_id)
)
{
if (file_fsync_mode == FSYNC_ALL)
#ifndef _WIN32
return fsync(fd);
#else
return !FlushFileBuffers(fd);
#endif
#ifdef HAVE_FDATASYNC
return fdatasync(fd);
@ -1214,22 +1278,128 @@ int file_fsync(unsigned int file_id, int thread_id)
/* Use msync on file on 64-bit architectures */
else if (file_io_mode == FILE_IO_MODE_MMAP)
{
#ifndef _WIN32
msync(mmaps[file_id], file_size, MS_SYNC | MS_INVALIDATE);
#else
FlushViewOfFile(mmaps[file_id], (size_t)file_size);
#endif
}
#endif
return 1; /* Unknown I/O mode */
}
#ifdef _WIN32
ssize_t pread(HANDLE hFile, void *buf, ssize_t count, long long offset)
{
DWORD nBytesRead;
OVERLAPPED ov = {0};
LARGE_INTEGER li;
if(!count)
return 0;
#ifdef _WIN64
if(count > UINT_MAX)
count= UINT_MAX;
#endif
li.QuadPart = offset;
ov.Offset = li.LowPart;
ov.OffsetHigh = li.HighPart;
if(!ReadFile(hFile, buf, (DWORD)count, &nBytesRead, &ov))
{
DWORD lastError = GetLastError();
if(lastError == ERROR_HANDLE_EOF)
return 0;
return -1;
}
return nBytesRead;
}
ssize_t pwrite(HANDLE hFile, const void *buf, size_t count,
long long offset)
{
DWORD nBytesWritten;
OVERLAPPED ov = {0};
LARGE_INTEGER li;
if(!count)
return 0;
#ifdef _WIN64
if(count > UINT_MAX)
count= UINT_MAX;
#endif
li.QuadPart = offset;
ov.Offset = li.LowPart;
ov.OffsetHigh= li.HighPart;
if(!WriteFile(hFile, buf, (DWORD)count, &nBytesWritten, &ov))
{
return -1;
}
else
return nBytesWritten;
}
#define MAP_SHARED 0
#define PROT_READ 1
#define PROT_WRITE 2
#define MAP_FAILED NULL
void *mmap(void *addr, size_t len, int prot, int flags,
FILE_DESCRIPTOR fd, long long off)
{
DWORD flProtect;
DWORD flMap;
void *retval;
LARGE_INTEGER li;
HANDLE hMap;
switch(prot)
{
case PROT_READ:
flProtect = PAGE_READONLY;
flMap = FILE_MAP_READ;
break;
case PROT_READ|PROT_WRITE:
flProtect = PAGE_READWRITE;
flMap = FILE_MAP_ALL_ACCESS;
break;
default:
return MAP_FAILED;
}
hMap = CreateFileMapping(fd, NULL, flProtect, 0 , 0, NULL);
if(hMap == INVALID_HANDLE_VALUE)
return MAP_FAILED;
li.QuadPart = off;
retval = MapViewOfFileEx(hMap, flMap, li.HighPart, li.LowPart, len, NULL);
CloseHandle(hMap);
return retval;
}
int munmap(void *start, size_t len)
{
(void) len; /* unused */
if(UnmapViewOfFile(start))
return 0;
return -1;
}
#endif
ssize_t file_pread(unsigned int file_id, void *buf, ssize_t count,
off_t offset, int thread_id)
long long offset, int thread_id)
{
int fd = files[file_id];
FILE_DESCRIPTOR fd = files[file_id];
#ifdef HAVE_MMAP
void *start;
off_t page_addr;
off_t page_offset;
long long page_addr;
long long page_offset;
#endif
#ifdef HAVE_LIBAIO
struct iocb iocb;
@ -1264,7 +1434,6 @@ ssize_t file_pread(unsigned int file_id, void *buf, ssize_t count,
return 0;
memcpy(buffer, (char *)start + page_offset, count);
munmap(start, count + page_offset);
return count;
# else
(void)start; /* unused */
@ -1284,9 +1453,9 @@ ssize_t file_pread(unsigned int file_id, void *buf, ssize_t count,
ssize_t file_pwrite(unsigned int file_id, void *buf, ssize_t count,
off_t offset, int thread_id)
long long offset, int thread_id)
{
int fd = files[file_id];
FILE_DESCRIPTOR fd = files[file_id];
#ifdef HAVE_MMAP
void *start;
size_t page_addr;
@ -1321,6 +1490,7 @@ ssize_t file_pwrite(unsigned int file_id, void *buf, ssize_t count,
page_offset = offset - page_addr;
start = mmap(NULL, count + page_offset, PROT_READ | PROT_WRITE, MAP_SHARED,
fd, page_addr);
if (start == MAP_FAILED)
return 0;
memcpy((char *)start + page_offset, buffer, count);
@ -1453,7 +1623,13 @@ int parse_arguments(void)
if (mode == NULL || !strlen(mode))
file_extra_flags = 0;
else if (!strcmp(mode, "sync"))
{
#ifdef _WIN32
file_extra_flags = FILE_FLAG_WRITE_THROUGH;
#else
file_extra_flags = O_SYNC;
#endif
}
else if (!strcmp(mode, "dsync"))
{
#ifdef O_DSYNC
@ -1465,7 +1641,9 @@ int parse_arguments(void)
}
else if (!strcmp(mode, "direct"))
{
#ifdef O_DIRECT
#ifdef _WIN32
file_extra_flags = FILE_FLAG_NO_BUFFERING;
#elif defined(O_DIRECT)
file_extra_flags = O_DIRECT;
#else
log_text(LOG_FATAL, "O_DIRECT is not supported on this platform.");
@ -1572,15 +1750,34 @@ unsigned long sb_getpagesize(void)
{
#ifdef _SC_PAGESIZE
return sysconf(_SC_PAGESIZE);
#elif defined _WIN32
SYSTEM_INFO info;
GetSystemInfo(&info);
return info.dwPageSize;
#else
return getpagesize();
#endif
}
/*
Alignment requirement for mmap(). The same as page size, except on Windows
(on Windows it has to be 64KB, even if pagesize is only 4 or 8KB)
*/
unsigned long sb_get_allocation_granularity(void)
{
#ifdef _WIN32
SYSTEM_INFO info;
GetSystemInfo(&info);
return info.dwAllocationGranularity;
#else
return sb_getpagesize();
#endif
}
/* Allocate a buffer of a specified size and align it to the page size */
/*
Allocate a buffer of a specified size and align it to the allocation
granularity
*/
void *sb_memalign(size_t size)
{
unsigned long page_size;
@ -1595,6 +1792,9 @@ void *sb_memalign(size_t size)
#elif defined(HAVE_VALLOC)
(void)page_size; /* unused */
buffer = valloc(size);
#elif defined (_WIN32)
(void)page_size; /* unused */
buffer = VirtualAlloc(NULL, size, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
#else
(void)page_size; /* unused */
log_text(LOG_WARNING, "None of valloc(), memalign and posix_memalign() is available, doing unaligned IO!");
@ -1604,12 +1804,20 @@ void *sb_memalign(size_t size)
return buffer;
}
static void sb_free_memaligned(void *buf)
{
#ifdef _WIN32
VirtualFree(buf,0,MEM_FREE);
#else
free(buf);
#endif
}
/* Fill buffer with random values and write checksum */
void file_fill_buffer(unsigned char *buf, unsigned int len,
unsigned long offset)
size_t offset)
{
unsigned int i;
@ -1627,7 +1835,7 @@ void file_fill_buffer(unsigned char *buf, unsigned int len,
/* Validate checksum and offset of block read from disk */
int file_validate_buffer(unsigned char *buf, unsigned int len, unsigned long offset)
int file_validate_buffer(unsigned char *buf, unsigned int len, size_t offset)
{
unsigned int checksum;
unsigned int cs_offset;
@ -1644,11 +1852,11 @@ int file_validate_buffer(unsigned char *buf, unsigned int len, unsigned long of
return 1;
}
if (offset != *(unsigned long *)(buf + cs_offset + FILE_CHECKSUM_LENGTH))
if (offset != *(size_t *)(buf + cs_offset + FILE_CHECKSUM_LENGTH))
{
log_text(LOG_FATAL, "Offset mismatch in block:");
log_text(LOG_FATAL, " Actual offset: %ld Stored offset: %ld",
offset, *(unsigned long *)(buf + cs_offset + FILE_CHECKSUM_LENGTH));
offset, *(size_t *)(buf + cs_offset + FILE_CHECKSUM_LENGTH));
return 1;
}

View File

@ -0,0 +1,18 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests)
add_library(sbmemory sb_memory.c)

View File

@ -18,6 +18,9 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#include "sysbench.h"
@ -58,35 +61,34 @@ static void memory_print_stats(void);
static sb_test_t memory_test =
{
.sname = "memory",
.lname = "Memory functions speed test",
.ops =
"memory",
"Memory functions speed test",
{
.init = memory_init,
.prepare = NULL,
.thread_init = NULL,
.thread_done = NULL,
.cleanup = NULL,
.print_mode = memory_print_mode,
.get_request = memory_get_request,
.execute_request = memory_execute_request,
.print_stats = memory_print_stats,
.done = NULL
memory_init,
NULL,
NULL,
memory_print_mode,
memory_get_request,
memory_execute_request,
memory_print_stats,
NULL,
NULL,
NULL
},
.cmds = {
.help = NULL,
.prepare = NULL,
.run = NULL,
.cleanup = NULL
{
NULL,
NULL,
NULL,
NULL
},
.args = memory_args,
memory_args,
{NULL, NULL}
};
/* Test arguments */
static ssize_t memory_block_size;
static off_t memory_total_size;
static size_t memory_total_size;
static unsigned int memory_scope;
static unsigned int memory_oper;
static unsigned int memory_access_rnd;
@ -96,7 +98,7 @@ static unsigned int memory_hugetlb;
/* Statistics */
static unsigned int total_ops;
static off_t total_bytes;
static size_t total_bytes;
/* Array of per-thread buffers */
static int **buffers;

View File

@ -0,0 +1,18 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests)
add_library(sbmutex sb_mutex.c)

View File

@ -19,6 +19,10 @@
# include "config.h"
#endif
#ifdef _WIN32
# include "sb_win.h"
#endif
#ifdef HAVE_PTHREAD_H
# include <pthread.h>
#endif
@ -52,27 +56,26 @@ static int mutex_done(void);
static sb_test_t mutex_test =
{
.sname = "mutex",
.lname = "Mutex performance test",
.ops = {
.init = mutex_init,
.prepare = NULL,
.thread_init = NULL,
.thread_done = NULL,
.print_mode = mutex_print_mode,
.print_stats = NULL,
.get_request = mutex_get_request,
.execute_request = mutex_execute_request,
.cleanup = NULL,
.done = mutex_done
"mutex",
"Mutex performance test",
{
mutex_init,
NULL,
NULL,
mutex_print_mode,
mutex_get_request,
mutex_execute_request,
NULL,
NULL,
mutex_done
},
.cmds = {
.help = NULL,
.prepare = NULL,
.run = NULL,
.cleanup = NULL
{
NULL,
NULL,
NULL,
NULL
},
.args = mutex_args,
mutex_args,
{NULL, NULL}
};
@ -141,7 +144,7 @@ sb_request_t mutex_get_request(void)
int mutex_execute_request(sb_request_t *sb_req, int thread_id)
{
unsigned int i;
unsigned int c;
unsigned int c=0;
unsigned int current_lock;
sb_mutex_request_t *mutex_req = &sb_req->u.mutex_request;
log_msg_t msg;

View File

@ -18,6 +18,10 @@
#ifndef SB_FILEIO_H
#define SB_FILEIO_H
#ifdef _WIN32
#include "sb_win.h" /* ssize_t defined*/
#endif
/* File operation types */
typedef enum
{
@ -32,7 +36,7 @@ typedef enum
typedef struct
{
unsigned int file_id;
off_t pos;
long long pos;
ssize_t size;
sb_file_op_t operation;
} sb_file_request_t;

View File

@ -40,7 +40,7 @@ typedef enum
typedef struct
{
sb_mem_op_t type;
unsigned long block_size;
size_t block_size;
sb_mem_scope_t scope;
} sb_mem_request_t;

View File

@ -0,0 +1,18 @@
# Copyright (C) 2008 MySQL AB
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
include_directories(${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/tests)
add_library(sbthreads sb_threads.c)

View File

@ -19,6 +19,10 @@
# include "config.h"
#endif
#ifdef _WIN32
# include "sb_win.h"
#endif
#ifdef HAVE_PTHREAD_H
# include <pthread.h>
#endif
@ -28,6 +32,8 @@
/* How to test scheduler pthread_yield or sched_yield */
#ifdef HAVE_PTHREAD_YIELD
#define YIELD pthread_yield
#elif defined (_WIN32)
#define YIELD SwitchToThread
#else
#define YIELD sched_yield
#endif
@ -53,27 +59,27 @@ static int threads_cleanup(void);
static sb_test_t threads_test =
{
.sname = "threads",
.lname = "Threads subsystem performance test",
.ops = {
.init = threads_init,
.prepare = threads_prepare,
.thread_init = NULL,
.thread_done = NULL,
.print_mode = threads_print_mode,
.print_stats = NULL,
.get_request = threads_get_request,
.execute_request = threads_execute_request,
.cleanup = threads_cleanup,
.done = NULL
"threads",
"Threads subsystem performance test",
{
threads_init,
threads_prepare,
NULL,
threads_print_mode,
threads_get_request,
threads_execute_request,
NULL,
NULL,
NULL,
threads_cleanup,
},
.cmds = {
.help = NULL,
.prepare = NULL,
.run = NULL,
.cleanup = NULL
{
NULL,
NULL,
NULL,
NULL
},
.args = threads_args,
threads_args,
{NULL, NULL}
};