!47 first commit of Sysbench4RedisAndMot

Merge pull request !47 from 熊小军/master
This commit is contained in:
opengauss-bot 2023-05-30 08:53:24 +00:00 committed by Gitee
commit 384e4aa4f4
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
903 changed files with 237663 additions and 0 deletions

88
Sysbench4RedisAndMot/.gitignore vendored Normal file
View File

@ -0,0 +1,88 @@
*.o
*.a
Makefile
Makefile.in
aclocal.m4
autom4te.cache
/config/config.h
/config/ltmain.sh
/config/stamp-h1
/doc/manual.html
/config.log
/config.status
/configure
/libtool
/doc/xsl/catalog.xml
/src/.deps
/src/.libs
/src/sysbench
/src/drivers/mysql/.deps
/src/drivers/oracle/.deps
/src/drivers/pgsql/.deps
/src/tests/cpu/.deps
/src/tests/fileio/.deps
/src/tests/memory/.deps
/src/tests/mutex/.deps
/src/tests/oltp/.deps
/src/tests/threads/.deps
/TAGS
/backup.bzr
/config/config.guess
/config/config.h.in
/config/config.sub
/src/TAGS
/src/drivers/TAGS
/src/drivers/mysql/TAGS
/src/tests/TAGS
/src/tests/cpu/TAGS
/src/tests/fileio/TAGS
/src/tests/memory/TAGS
/src/tests/mutex/TAGS
/src/tests/oltp/TAGS
/src/tests/threads/TAGS
/config/compile
/config/depcomp
/config/install-sh
/config/missing
/m4/libtool.m4
/m4/ltoptions.m4
/m4/ltsugar.m4
/m4/ltversion.m4
/m4/lt~obsolete.m4
/src/drivers/drizzle/.deps
/src/scripting/.deps
/src/scripting/lua/src/.deps
GPATH
GRTAGS
GTAGS
/config/ar-lib
/src/drivers/attachsql/.deps/
/config/test-driver
*.DS_Store
/tests/*.log
/tests/*.trs
*.gcda
*.gcno
/tests/include/config.sh
/third_party/concurrency_kit/include/
/third_party/concurrency_kit/lib/
/third_party/concurrency_kit/share/
/third_party/concurrency_kit/tmp/
third_party/luajit/bin/
third_party/luajit/inc/
third_party/luajit/lib/
third_party/luajit/share/
third_party/luajit/tmp/
src/lua/internal/sysbench.lua.h
src/lua/internal/sysbench.sql.lua.h
/src/lua/internal/sysbench.rand.lua.h
/src/lua/internal/sysbench.opt.lua.h
tests/t/*.err
/src/lua/internal/sysbench.cmdline.lua.h
/src/lua/internal/sysbench.compat.lua.h
/src/lua/internal/sysbench.histogram.lua.h
parts
prime
stage
*.snap
/snap/snapcraft.yaml

View File

@ -0,0 +1,292 @@
# vim ft=yaml
#
# Travis CI configuration
arch:
- amd64
- arm64
dist: trusty
sudo: required
services:
- docker
- mysql
- postgresql
git:
depth: 100500
language: c
os:
- linux
- osx
compiler:
- gcc
- clang
env:
matrix:
- TARGET=distcheck
- TARGET=test
- TARGET=coverage
- OS=el DIST=6
- OS=el DIST=7
- OS=el DIST=8
- OS=fedora DIST=29
- OS=fedora DIST=30
- OS=fedora DIST=31
- OS=ubuntu DIST=xenial
- OS=ubuntu DIST=bionic
- OS=ubuntu DIST=eoan
- OS=ubuntu DIST=focal
- OS=debian DIST=jessie
- OS=debian DIST=stretch
- OS=debian DIST=buster
- OS=debian DIST=sid
- OS=ubuntu DIST=xenial ARCH=i386
- OS=ubuntu DIST=bionic ARCH=i386
- OS=ubuntu DIST=eoan ARCH=i386
- OS=debian DIST=jessie ARCH=i386
- OS=debian DIST=stretch ARCH=i386
- OS=debian DIST=buster ARCH=i386
- OS=debian DIST=sid ARCH=i386
matrix:
exclude:
- env: OS=el DIST=6
compiler: clang
- env: OS=el DIST=7
compiler: clang
- env: OS=el DIST=8
compiler: clang
- env: OS=fedora DIST=29
compiler: clang
- env: OS=fedora DIST=30
compiler: clang
- env: OS=fedora DIST=31
compiler: clang
- env: OS=ubuntu DIST=xenial
compiler: clang
- env: OS=ubuntu DIST=bionic
compiler: clang
- env: OS=ubuntu DIST=disco
compiler: clang
- env: OS=ubuntu DIST=eoan
compiler: clang
- env: OS=ubuntu DIST=focal
compiler: clang
- env: OS=debian DIST=jessie
compiler: clang
- env: OS=debian DIST=stretch
compiler: clang
- env: OS=debian DIST=buster
compiler: clang
- env: OS=debian DIST=sid
compiler: clang
- env: OS=ubuntu DIST=xenial ARCH=i386
compiler: clang
- env: OS=ubuntu DIST=bionic ARCH=i386
compiler: clang
- env: OS=ubuntu DIST=disco ARCH=i386
compiler: clang
- env: OS=ubuntu DIST=eoan ARCH=i386
compiler: clang
- env: OS=debian DIST=jessie ARCH=i386
compiler: clang
- env: OS=debian DIST=stretch ARCH=i386
compiler: clang
- env: OS=debian DIST=buster ARCH=i386
compiler: clang
- env: OS=debian DIST=sid ARCH=i386
compiler: clang
- env: OS=ubuntu DIST=xenial ARCH=i386
arch: arm64
- env: OS=ubuntu DIST=bionic ARCH=i386
arch: arm64
- env: OS=ubuntu DIST=disco ARCH=i386
arch: arm64
- env: OS=ubuntu DIST=eoan ARCH=i386
arch: arm64
- env: OS=debian DIST=jessie ARCH=i386
arch: arm64
- env: OS=debian DIST=stretch ARCH=i386
arch: arm64
- env: OS=debian DIST=buster ARCH=i386
arch: arm64
- env: OS=debian DIST=sid ARCH=i386
arch: arm64
- env: OS=el DIST=6
arch: arm64
- env: OS=el DIST=6
os: osx
- env: OS=el DIST=7
os: osx
- env: OS=el DIST=8
os: osx
- env: OS=fedora DIST=29
os: osx
- env: OS=fedora DIST=30
os: osx
- env: OS=fedora DIST=31
os: osx
- env: OS=ubuntu DIST=xenial
os: osx
- env: OS=ubuntu DIST=bionic
os: osx
- env: OS=ubuntu DIST=disco
os: osx
- env: OS=ubuntu DIST=eoan
os: osx
- env: OS=ubuntu DIST=focal
os: osx
- env: OS=debian DIST=jessie
os: osx
- env: OS=debian DIST=stretch
os: osx
- env: OS=debian DIST=buster
os: osx
- env: OS=debian DIST=sid
os: osx
- env: TARGET=distcheck
compiler: clang
- env: TARGET=distcheck
os: osx
- env: TARGET=distcheck
arch: arm64
- env: TARGET=coverage
os: osx
- env: TARGET=coverage
compiler: clang
- env: TARGET=coverage
arch: arm64
- os: osx
compiler: gcc
- os: osx
arch: arm64
- arch: arm64
compiler: clang
- env: OS=debian DIST=jessie
arch: arm64
addons:
apt:
packages:
- libmysqlclient-dev
- libpq-dev
- libaio-dev
- clang-3.6
before_install:
# Upload builds corresponding to release tags to the 'sysbench'
# repository, push other ones to 'sysbench-prereleases'
- git describe --long --always
- commits=$(git describe --long --always | sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
- >
if [ ${commits:-0} = 0 ]; then
export VERSION=$(git describe)
PACKAGECLOUD_REPO=sysbench
else
PACKAGECLOUD_REPO=sysbench-prereleases
fi
- >
if [ "x$TARGET" = "xtest" ]; then
case "${TRAVIS_OS_NAME:-linux}" in
osx)
brew update
brew install mysql postgresql
# OS X requires servers to be started explicitly
brew services start mysql
brew postgresql-upgrade-database
brew services start postgresql
echo "Starting PostgreSQL"
pg_ctl -wD /usr/local/var/postgres start
echo "Creating user postgres"
createuser -s postgres
;;
linux)
export ASAN_OPTIONS="detect_leaks=0"
if [ "${CC}" = "clang" ]; then
CC=clang-3.6
fi
;;
esac
fi
install:
- >
case "${TRAVIS_OS_NAME:-linux}" in
osx)
# OS X requires this for user-local pip packages
export PATH=~/Library/Python/2.7/bin:$PATH
;;
linux)
pip install --user cpp-coveralls
;;
esac
before_script:
- mysql -u root -e 'CREATE DATABASE sbtest'
- psql -U postgres -c 'CREATE DATABASE sbtest'
script:
- >
if [ -n "$TARGET" ]; then
case "$TARGET" in
test)
./autogen.sh && ./configure --with-mysql --with-pgsql
make
SBTEST_MYSQL_ARGS="--mysql-user=root" SBTEST_PGSQL_ARGS="--pgsql-user=postgres" make test
;;
distcheck)
./autogen.sh && ./configure --without-mysql
make
make distcheck
;;
coverage)
./autogen.sh && ./configure --enable-coverage --enable-asan --enable-msan --with-mysql --with-pgsql
make -j2
SBTEST_MYSQL_ARGS="--mysql-user=root" SBTEST_PGSQL_ARGS="--pgsql-user=postgres" make test
;;
esac
else
# To avoid name conflicts, deploy source packages only for
# "default", i.e. x86_64 architecture
if [[ -z "$ARCH" && "$TRAVIS_CPU_ARCH" == amd64 ]]; then
PACKAGECLOUD_GLOB='build/*.{rpm,deb,dsc}'
else
# Exclude *.src.rpm and *.dsc
PACKAGECLOUD_GLOB='build/*{[^c].rpm,.deb}'
fi
git clone https://github.com/akopytov/packpack.git packpack
packpack/packpack
fi
deploy:
# Deploy packages to PackageCloud
- provider: packagecloud
username: "${PACKAGECLOUD_USER}"
repository: "${PACKAGECLOUD_REPO}"
token: "${PACKAGECLOUD_TOKEN}"
dist: "${OS}/${DIST}"
package_glob: "${PACKAGECLOUD_GLOB}"
skip_cleanup: true
on:
all_branches: true
condition: -n "$OS" && -n "$DIST" && -n "$PACKAGECLOUD_TOKEN" && "$DIST" != "rawhide" && "$DIST" != "sid"
after_success:
- >
if [ "x$TARGET" = "xcoverage" ]; then
coveralls --exclude third_party/ --gcov-options '\-lp'
fi
# Local variables:
# mode: yaml
# End:

View File

@ -0,0 +1,339 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.

View File

@ -0,0 +1,493 @@
2020-04-24 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.20
* build/CI/packaging: Add arm64 to Travis CI matrix (#358)
* build/CI/packaging: add Ubuntu Focal
* build/CI/packaging: remove Fedora Rawhide from CI matrix
* build/CI/packaging: fix regression tests to work with MySQL 8.0.19+
* build/CI/packaging: fix macOS builds in Travis
* build/CI/packaging: remove Ubuntu Disco (EOL)
2019-12-08 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.19
* build/CI/packaging: fix Ubuntu packaging for Bionic and later versions
* regression tests: compatibility fix for PostgreSQL 12
* build/CI/packaging: fix macOs builds in Travis
* build/CI/packaging: add Fedora 31.
2019-10-21 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.18
* build/CI/packaging: add Ubuntu Eoan.
* build/CI/packaging: remove Ubuntu Cosmic (EOL).
* build/CI/packaging: add CentOS 8.
* build/CI/packaging: add Ubuntu Disco.
* build/CI/packaging: remove Ubuntu Trusty (EOL).
* build/CI/packaging: remove Fedora 28 (EOL).
* build/CI/packaging: add Fedora 30.
* build/CI/packaging: cherry-pick fix for LuaJIT/LuaJIT#484 to
fix builds on macOS Mojave.
* build/CI/packaging: add Debian Buster
2019-03-15 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.17
* build/CI/packaging: update RPM spec to support RHEL8-beta
(thanks to Alexey Bychko for the patch)
* regression tests: remove unnecessary error leading to opt_rate.t instability.
* --rate mode: return a non-zero exit code on event queue
overflow.
* --rate mode: fix a bogus error about eventgen thread termination
2018-12-16 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.16
* build/CI/packaging: add Ubuntu Cosmic.
* build/CI/packaging: add Fedora 29.
* build/CI/packaging: remove Fedora 27 (EOL).
* SQL API: fix GH-282 (Mysql's fetch_row() is broken)
* --rate mode: fix latency stats skew on low rates
* Lua: Add /usr/share/lua/5.1 to LUA_PATH and /usr/lib/lua/5.1
to LUA_CPATH.
* build/CI/packaging: add -Wvla to default compiler flags.
* build/CI/packaging: fix debian/changelog format
* build/CI/packaging: fix buildpack.sh to not push multiple file
types to packagecloud.
* build/CI/packaging: add libaio-dev to Debian/Ubuntu build
dependencies.
2018-07-03 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.15
* CI/build/packaging: add Fedora 28
* CI/build/packaging: add Ubuntu Bionic
* CI/build/packaging: remove Fedora 26 (EOL)
* CI/build/packaging: remove Debian Wheezy (EOL)
* fileio: fix GH-229 (--file-fsync-freq=0 seems to prevent
fsync() at the end of the test)
* command line: improve parsing of boolean command line options
* tests: fix GH-220 (Testsuite api_sql_mysql.t failed ...)
* tests: fix GH-223 (test failure on ppc64)
* tests: fix opt_help.t to pass when the binary is not
configured with MySQL support
* MySQL driver: use it by default in DB benchmarks
2018-04-01 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.14
* reports: fix JSON stats reporter to produce valid JSON
(GH-195)
* Lua SQL API: don't crash when query_row() is called with a
SELECT returning empty result set
* Lua SQL API: don't crash when bulk insert API calls are used
out of order
* regression tests: make PostgreSQL tests compatible with the
new dump format introduced in 10.3
* regression tests: minor stability and coverage improvements
2018-02-17 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.13
* remove Ubuntu Zesty from CI/build/packaging matrices (EOL)
* minor cleanups in build scripts
* improve report formatting for long latency values
* fileio: --file-extra-flags now accepts a list of flags rather
than just a single value
* OLTP: re-prepare prepared statements after reconnects, i.e. in
cases when a server connection is lost and sysbench is
configured to ignore such errors
2018-01-17 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.12
* improve --rate mode precision for high argument values
* add Fedora Rawhide and Debian Sid to CI matrix
* fix compile-time architecture detection for some Broadwell
CPUs which were incorrectly identified as Core 2.
* remove build dependency on xxd (and vim-minimal package)
* fix Lua API to correctly stop the benchmark when event()
returns a value other than nil or false (thanks to caojiafeng
for the patch)
* fix the fileio benchmark when the specified file size is not a
multiple of block size
* fix the fileio benchmark to throw a descriptive error when the
specified file size does not match the size of files created by
'prepare'
* remove Fedora 25 from CI/build/packaging matrices (EOL)
* minor improvements in tests and documentation.
2017-12-09 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.11
* add Debian Stretch to CI/build/packaging matrices
* add Fedora 27 to CI/build/packaging matrices
* make statistic counters usable from Lua scripts
* fix the PostgreSQL driver to be compatible with CockroachDB
(GH-180)
* fix oltp_insert.lua to work correctly when both --tables and
--threads are greater than 1 (GH-178)
* fix FreeBSD builds by adding -rdynamic to the default linker
flags (GH-174)
* minor documentation updates
2017-10-25 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.10
* fixed PK conflicts in oltp_insert.lua by creating empty tables
on 'prepare'
* made sysbench.opt available to init()/done() by exporting it
to the global Lua state
* added Fedora 26 (both x86_64 and AArch64) to the list of
supported and tested distributions
* fixed GH-172: sysbench 1.0.9 doesn't build with mariadb 10.2.8
* add the /usr/local LuaRocks root directory to default LUA_PATH
and LUA_CPATH
* removed Fedora 24, Ubuntu Precise, Yakkety from default build
matrices
* added Ubuntu Artful to default build matrices
2017-09-05 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.9
* fixed oltp_delete.lua to not use INSERT statements for
consistency with other oltp_* benchmarks (GH-168)
* added a workaround for MySQL bug #87337 "8.0.2 reintroduces
my_bool to client API"
* fixed building on on Debian GNU/kFreeBSD (GH-161)
* fixed building against MariaDB 10.2 (thanks to Xavier Bachelot
for the patch, GH-160)
2017-07-04 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.8
* fixed api_report test for slow machines (thanks to @jcfp)
* fileio: suggest to run prepare step on missing files (thanks
to Heinrich Schuchardt)
* JSON reports: removed an erroneous trailing comma (GH-139)
* added events per second to the CPU benchmark report (GH-140)
* fixed db_connect() in legacy SQL API to use the default value
for --db-driver (GH-146)
* removed busy-wait in the bounded event generation mode
(--rate) to avoid CPU hogging
2017-05-15 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.7
* Ubuntu Zesty added to package build matrix
* fixed GH-130: Mutex Benchmark Documentation
* fixed latency reports in the --rate mode
* fixed compiler warnings when building against MySQL 8.0 client
libraries
2017-04-13 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.6
* no functional changes
* many build- and packaging-related improvements
* Linux packages are now automatically built using Travis CI and
packpack, hosted by packagecloud.io
2017-04-02 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.5
* various build-related documentation updates
* benchmark can now be specified by a module name on the command
line
* memory benchmark: performance and scalability improvements
* fix ARMv6 builds with system ConcurrencyKit
* fix GH-123: Table already exists error on prepare
* fix GH-121: make buildhost cpudetection optional
2017-03-13 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.4
* fixed a number of compilation errors and warnings that were
specific to 32-bit platforms
* bundle cram (regression tests framework) and use it by default
in 'make test'
* bundled ConcurrencyKit updated to 0.6.0
2017-02-26 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.3
* LuaJIT scalability improvements for non-x86 architectures
* performance optimizations in oltp_read_write.lua to avoid Lua
string management
* fixed Illumos builds (thanks to Dillon Amburgey)
2017-02-17 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.2
* improved scalability for --report-checkpoints mode
* fix builds on CentoOS 6 and autoconf 2.63
* support for Snap (http://snapcraft.io) packages
2017-02-05 Alexey Kopytov <akopytov@gmail.com>
* version 1.0.1
* fix clock_gettime runtime failure built with macOS 10.11 and
Xcode 8.x
2017-02-04 Aleksei Kopytov <akopytov@gmail.com>
* version 1.0.0
* too much time and too many changes since the previous formal
release, so briefly:
* Lua scripts instead of hard-coded C tests for database
("oltp") benchmarks + ability to create custom workloads
* much better single-threaded performance
* much better scalability
* improvements and cleanups in command line syntax and options
* latency histograms in cumulative statistic reports
* report hooks to print statistics in custom formats
(CSV/JSON/XML/etc.)
* Dropped Windows support
* Dropped support for Oracle, Drizzle and libattachsql drivers
2006-10-10 Alexey Kopytov <alexeyk@mysql.com>
* Removed the debugging code in OLTP test which got into 0.4.7 by mistake
* Handle ER_CHECKREAD in the same way as deadlocks in the MySQL driver
* version 0.4.8
2006-05-28 Alexey Kopytov <alexeyk@mysql.com>
* count fsync() time as request execution time in file-fsync-all mode
2006-05-24 Alexey Kopytov <alexeyk@mysql.com>
* Added --oltp-reconnect option
2006-05-18 Alexey Kopytov <alexeyk@mysql.com>
* Allow build with non-gcc compilers
* Fixed random numbers generation on Solaris
* Added --mysql-ssl option
* version 0.4.7
2006-04-03 Alexey Kopytov <alexeyk@mysql.com>
* Added a warning for inaccurate gettimeofday() implementations
* version 0.4.6
2006-03-10 Alexey Kopytov <alexeyk@mysql.com>
* Fixed crash at the end of OLTP test
2006-03-03 Alexey Kopytov <alexeyk@mysql.com>
* Made auto_increment id column optional
* Use TYPE= or ENGINE= in MySQL driver depending on the version of client libraries
2006-01-17 Alexey Kopytov <alexeyk@mysql.com>
* version 0.4.5
* Added several hosts capability to MySQL driver
* Fixed several memory leaks in OLTP test
2005-12-14 Alexey Kopytov <alexeyk@mysql.com>
* Renamed option 'mysql-table-type' to 'mysql-table-engine'
* It's now possible to pass arbitrary engine names to MySQL driver
* Transactions support must be explicitly specified with
'mysql-engine-trx' option for those engines, which are unknown to SysBench
2005-09-27 Alexey Kopytov <alexeyk@mysql.com>
* Changed 'thread fairness' calculation from percents to stddev
* Added validation mode to OLTP test (--validate switch)
* Remove auto_increment from the 'id' field before running OLTP tests
* Print separate time for query execution and result fetching in --debug mode
* version 0.4.3
2005-07-25 Alexey Kopytov <alexeyk@mysql.com>
* Minor cleanups in help messages
* Several FreeBSD-related fixes
* Fixed the Oracle driver
* Version 0.4.1
2005-03-04 Alexey Kopytov <alexeyk@mysql.com>
* Fixed a lot of small bugs, including portability issues on Mac OS X,
64-bit platforms and old MySQL versions
* Documentation added to the main tree
* New validation mode in fileio test
2005-01-27 Alexey Kopytov <alexeyk@mysql.com>
* Fixed compilation on Solaris
* Added call to thr_setconcurrency() on Solaris
* Fixed an overflow bug in sb_timer_current()
* Changed the default number of threads to 1
* Added non-transactional mode to the OLTP test
* Fixed bug with excessive number of connections in OLTP test
* Handle ER_LOCK_WAIT_TIMEOUT in the same way as ER_LOCK_DEADLOCK
* Version 0.3.2
2004-07-27 Alexey Kopytov <alexeyk@mysql.com>
* Fixed MySQL driver to use new PS API in MySQL >= 4.1.2
2004-07-12 Alexey Kopytov <alexeyk@mysql.com>
* Fixed final fsync in random I/O requests
* Fixed several race conditions
2004-07-09 Alexey Kopytov <alexeyk@mysql.com>
* Removed --oltp-time-limit option (obsoleted by --max-time)
2004-07-06 Alexey Kopytov <alexeyk@mysql.com>
* Changed statistics output to more human-readable format
2004-07-04 Alexey Kopytov <alexeyk@mysql.com>
* Added new logger interface to internal API
* Modified all tests to use the new logger interface
2004-06-17 Alexey Kopytov <alexeyk@mysql.com>
* Fixed table type autodetection with MySQL >= 4.1
2004-06-06 Alexey Kopytov <alexeyk@mysql.com>
* Added preliminary support of prepared statements to DB API
2004-05-31 Alexey Kopytov <alexeyk@mysql.com>
* Added slow-mmap mode for 32-bit boxes in fileio test
2004-05-30 Alexey Kopytov <alexeyk@mysql.com>
* Fixed compilation with gcc >= 3.3
* Fixed 'prepare' command for sequential write test
2004-05-26 Alexey Kopytov <alexeyk@mysql.com>
* Changed formatting of file sizes in output
* Fixed type cast warning on SuSE 8.1
2004-05-21 Alexey Kopytov <alexeyk@mysql.com>
* Added mutex performance benchmark
2004-05-12 Alexey Kopytov <alexeyk@mysql.com>
* Extended memory benchmark to calculate more useful results
2004-05-10 Alexey Kopytov <alexeyk@mysql.com>
* Split test file creation, test running and cleaning up into separate
commands (prepare, run, cleanup) for fileio test
2004-05-05 Alexey Kopytov <alexeyk@mysql.com>
* Removed limit on maximum block size for fileio test
2004-05-04 Alexey Kopytov <alexeyk@mysql.com>
* added --max-time option to limit total test execution time
2004-05-03 Alexey Kopytov <alexeyk@mysql.com>
* Fixed compilation with --without-mysql option.
2004-04-13 Alexey Kopytov <alexeyk@mysql.com>
* Added mmaped I/O support to fileio test
2004-04-11 Alexey Kopytov <alexeyk@mysql.com>
* Changed default table size to a lower value in OLTP test
2004-04-07 Alexey Kopytov <alexeyk@mysql.com>
* Added automatic table type detection to MySQL driver
* Changed the default table type for MySQL driver to InnoDB
* Added support for BDB and NDB table types
2004-04-06 Alexey Kopytov <alexeyk@mysql.com>
* Added autoconf macro to handle older (incompatible) version of
libaio.h
2004-04-05 Alexey Kopytov <alexeyk@mysql.com>
* Fixed compilation on 64-bit systems
* Replaced Linux AIO calls with more portable equivalents
2004-04-04 Alexey Kopytov <alexeyk@mysql.com>
* Added parameter to specify maximum number of queued operations
in fileio async mode (file-async-backlog)
* Added parameter to specify extra open() flags (file-extra-flags)
* Fixed memory allocation bug in command line parser
2004-04-02 Alexey Kopytov <alexeyk@mysql.com>
* Added Linux asynchronous I/O support to fileio test
* Fixed bug with statistic counters
2004-04-01 Alexey Kopytov <alexeyk@mysql.com>
* Added test file creation to fileio test
* Added read-only mode to OLTP test
2004-03-31 Alexey Kopytov <alexeyk@mysql.com>
* Close database connections in OLTP test
* Added file-fsync-all mode for fileio test
2004-03-30 Alexey Kopytov <alexeyk@mysql.com>
* Added myisam-max-rows option for MySQL driver
* Fixed configure.ac for cases when no MySQL libraries found
2004-03-10 Alexey Kopytov <alexeyk@mysql.com>
* Implement proper handling of table locks in OLTP test
2004-03-09 Alexey Kopytov <alexeyk@mysql.com>
* Recognize MySQL table type when creating test database
* Fix driver-specific options
* Now it's possible to pass MySQL root directory in --with-mysql option
* Trim trailing '.libs' if user passed it in --with-mysql-libs option
to configure
2004-03-08 Alexey Kopytov <alexeyk@mysql.com>
* Build drivers and tests as separate libraries (first step to
dynamically loaded modules)
* Display help when required arguments are missing in fileio test
* Changed code formatting to match MySQL coding guidelines
2004-03-04 Alexey Kopytov <alexeyk@mysql.com>
* Generalized DB-dependent code
* Added 'database capabilities' feature
2004-02-28 Alexey Kopytov <alexeyk@mysql.com>
* Fixed possible memory leak in sql request generator
2004-03-27 Alexey Kopytov <alexeyk@mysql.com>
* Split OLTP code into DB-independent part and MySQL driver
2004-02-23 Alexey Kopytov <alexeyk@mysql.com>
* Use libtool for linking with external libraries
* Statically link external libraries when they are not installed
2004-02-19 Alexey Kopytov <alexeyk@mysql.com>
* Print more info when configure finds no MySQL development files
* Added --with-mysql-includes and --with-mysql-libs to configure
* Fixed compilation error when compiling without MySQL support
* Combine several inserts into one query to speed up database creation

View File

@ -0,0 +1,46 @@
# Copyright (C) 2004 MySQL AB
# Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
ACLOCAL_AMFLAGS = -I m4
AM_DISTCHECK_CONFIGURE_FLAGS = --without-mysql
if USE_BUNDLED_LUAJIT
LUAJIT_DIR = third_party/luajit
endif
if USE_BUNDLED_CK
CK_DIR = third_party/concurrency_kit
endif
SUBDIRS = doc $(LUAJIT_DIR) $(CK_DIR) src tests
EXTRA_DIST = autogen.sh README.md README-WIN.txt README-Oracle.md ChangeLog \
snap/snapcraft.yaml.in third_party/cram \
debian/changelog debian/compat debian/control debian/copyright \
debian/dirs debian/docs debian/install debian/rules \
debian/source/format \
rpm/sysbench.spec \
scripts/buildpack.sh
dist-hook:
$(MAKE) -C $(distdir)/third_party/cram clean
test:
cd tests && $(MAKE) test
clean-local:
$(MAKE) -C $(top_srcdir)/third_party/cram clean

View File

@ -0,0 +1,56 @@
**WARNING: Oracle support is unmaintained as of sysbench 1.0. You may
want to
try [sysbench 0.5](https://github.com/akopytov/sysbench/tree/0.5)
instead. The corresponding code and instructions below are still in the
source tree in case somebody wants to update them. Patches are always
welcome! **
--------------------------------------------------------------
Oracle Build steps
--------------------------------------------------------------
Using Ubuntu 14.04 - intructions dated for 21/09/2016 (Was built on AWS
in an r3.xlarge These actions were done against 0.5 checkout)
* Setup Oracle Instant Client -
https://help.ubuntu.com/community/Oracle%20Instant%20Client download
from
http://www.oracle.com/technetwork/database/features/instant-client/index-097480.html.
The following RPM's and upload them to the server:
- oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
- oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm
```
alien -i oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm
alien -i oracle-instantclient12.1-devel-12.1.0.2.0-1.x86_64.rpm
```
* Install Cuda - http://www.r-tutor.com/gpu-computing/cuda-installation/cuda7.5-ubuntu
```
wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1404/x86_64/cuda-repo-ubuntu1404_7.5-18_amd64.deb
sudo dpkg -i cuda-repo-ubuntu1404_7.5-18_amd64.deb
sudo apt-get update
sudo apt-get install cuda
export CUDA_HOME=/usr/local/cuda-7.5
export LD_LIBRARY_PATH=${CUDA_HOME}/lib64
PATH=${CUDA_HOME}/bin:${PATH}
export PATH
echo "/usr/lib/oracle/12.1/client64/lib" > /etc/ld.so.conf.d/oracle-client-12.1.conf
ldconfig
```
* Build sysbench
Use the following `configure` option to build with Oracle support:
```
./configure --with-oracle="/usr/lib/oracle/12.1/client64"
```
Run the following commands to allow sysbench use the full number of cores:
```
sudo sh -c 'for x in /sys/class/net/eth0/queues/rx-*; do echo ffffffff> $x/rps_cpus; done'
sudo sh -c "echo 32768 > /proc/sys/net/core/rps_sock_flow_entries"
sudo sh -c "echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt"
```

View File

@ -0,0 +1,11 @@
As of sysbench 1.0 support for native Windows builds was dropped. It may
be re-introduced in later versions.
Currently, the recommended way to build sysbench on Windows is using
Windows Subsystem for Linux available in Windows 10:
https://msdn.microsoft.com/en-us/commandline/wsl/about
After installing WSL and getting a bash prompt, following Debian/Ubuntu
build instructions is sufficient.
Alternatively, one can build and use sysbench 0.5 natively for Windows.

View File

@ -0,0 +1,290 @@
[![Latest Release][release-badge]][release-url]
[![Build Status][travis-badge]][travis-url]
[![Debian Packages][deb-badge]][deb-url]
[![RPM Packages][rpm-badge]][rpm-url]
[![Coverage Status][coveralls-badge]][coveralls-url]
[![License][license-badge]][license-url]
<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->
**Table of Contents**
- [sysbench](#sysbench)
- [Features](#features)
- [Installing from Binary Packages](#installing-from-binary-packages)
- [Linux](#linux)
- [macOS](#macos)
- [Windows](#windows)
- [Building and Installing From Source](#building-and-installing-from-source)
- [Build Requirements](#build-requirements)
- [Windows](#windows)
- [Debian/Ubuntu](#debianubuntu)
- [RHEL/CentOS](#rhelcentos)
- [Fedora](#fedora)
- [macOS](#macos)
- [Build and Install](#build-and-install)
- [Usage](#usage)
- [General Syntax](#general-syntax)
- [General Command Line Options](#general-command-line-options)
- [Versioning](#versioning)
<!-- markdown-toc end -->
# sysbench
sysbench is a scriptable multi-threaded benchmark tool based on
LuaJIT. It is most frequently used for database benchmarks, but can also
be used to create arbitrarily complex workloads that do not involve a
database server.
sysbench comes with the following bundled benchmarks:
- `oltp_*.lua`: a collection of OLTP-like database benchmarks
- `fileio`: a filesystem-level benchmark
- `cpu`: a simple CPU benchmark
- `memory`: a memory access benchmark
- `threads`: a thread-based scheduler benchmark
- `mutex`: a POSIX mutex benchmark
## Features
- extensive statistics about rate and latency is available, including
latency percentiles and histograms;
- low overhead even with thousands of concurrent threads. sysbench is
capable of generating and tracking hundreds of millions of events per
second;
- new benchmarks can be easily created by implementing pre-defined hooks
in user-provided Lua scripts;
- can be used as a general-purpose Lua interpreter as well, simply
replace `#!/usr/bin/lua` with `#!/usr/bin/sysbench` in your script.
# Installing from Binary Packages
## Linux
The easiest way to download and install sysbench on Linux is using
binary package repositories hosted by
[packagecloud](https://packagecloud.io). The repositories are
automatically updated on each sysbench release. Currently x86_64, i386
and aarch64 binaries are available.
Multiple methods to download and install sysbench packages are available and
described at <https://packagecloud.io/akopytov/sysbench/install>.
Quick install instructions:
- Debian/Ubuntu
``` shell
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash
sudo apt -y install sysbench
```
- RHEL/CentOS:
``` shell
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench
```
- Fedora:
``` shell
curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo dnf -y install sysbench
```
## macOS
On macOS, up-to-date sysbench packages are available from Homebrew:
```shell
# Add --with-postgresql if you need PostgreSQL support
brew install sysbench
```
## Windows
As of sysbench 1.0 support for native Windows builds was dropped. It may
be re-introduced in later releases. Currently, the recommended way to
obtain sysbench on Windows is
using
[Windows Subsystem for Linux available in Windows 10](https://msdn.microsoft.com/en-us/commandline/wsl/about).
After installing WSL and getting into he bash prompt on Windows
following Debian/Ubuntu installation instructions is
sufficient. Alternatively, one can use WSL to build and install sysbench
from source, or use an older sysbench release to build a native binary.
# Building and Installing From Source
It is recommended to install sysbench from the official binary
packages as described in
[Installing from Binary Packages](#installing-from-binary-packages). Below
are instruction for cases when you want to use sysbench on an
architecture for which no binary packages are available.
## Build Requirements
### Windows
As of sysbench 1.0 support for native Windows builds was
dropped. It may be re-introduced in later versions. Currently, the
recommended way to build sysbench on Windows is using
[Windows Subsystem for Linux available in Windows 10](https://msdn.microsoft.com/en-us/commandline/wsl/about).
After installing WSL and getting into bash prompt on Windows, following
Debian/Ubuntu build instructions is sufficient. Alternatively, one can
build and use an older 0.5 release on Windows.
### Debian/Ubuntu
``` shell
apt -y install make automake libtool pkg-config libaio-dev
# For MySQL support
apt -y install libmysqlclient-dev libssl-dev
# For PostgreSQL support
apt -y install libpq-dev
```
### RHEL/CentOS
``` shell
yum -y install make automake libtool pkgconfig libaio-devel
# For MySQL support, replace with mysql-devel on RHEL/CentOS 5
yum -y install mariadb-devel openssl-devel
# For PostgreSQL support
yum -y install postgresql-devel
```
### Fedora
``` shell
dnf -y install make automake libtool pkgconfig libaio-devel
# For MySQL support
dnf -y install mariadb-devel openssl-devel
# For PostgreSQL support
dnf -y install postgresql-devel
```
### macOS
Assuming you have Xcode (or Xcode Commane Line Tools) and Homebrew installed:
``` shell
brew install automake libtool openssl pkg-config
# For MySQL support
brew install mysql
# For PostgreSQL support
brew install postgresql
# openssl is not linked by Homebrew, this is to avoid "ld: library not found for -lssl"
export LDFLAGS=-L/usr/local/opt/openssl/lib
```
## Build and Install
``` shell
./autogen.sh
# Add --with-pgsql to build with PostgreSQL support
./configure
make -j
make install
```
The above will build sysbench with MySQL support by default. If you have
MySQL headers and libraries in non-standard locations (and no
`mysql_config` can be found in the `PATH`), you can specify them
explicitly with `--with-mysql-includes` and `--with-mysql-libs` options
to `./configure`.
To compile sysbench without MySQL support, use `--without-mysql`. If no
database drivers are available database-related scripts will not work,
but other benchmarks will be functional.
See [README-Oracle.md](README-Oracle.md) for instructions on building
with Oracle client libraries.
# Usage
## General Syntax
The general command line syntax for sysbench is:
sysbench [options]... [testname] [command]
- *testname* is an optional name of a built-in test (e.g. `fileio`,
`memory`, `cpu`, etc.), or a name of one of the bundled Lua scripts
(e.g. `oltp_read_only`), or a *path* to a custom Lua script. If no
test name is specified on the command line (and thus, there is no
*command* too, as in that case it would be parsed as a *testname*), or
the test name is a dash ("`-`"), then sysbench expects a Lua script to
execute on its standard input.
- *command* is an optional argument that will be passed by sysbench to
the built-in test or script specified with *testname*. *command*
defines the *action* that must be performed by the test. The list of
available commands depends on a particular test. Some tests also
implement their own custom commands.
Below is a description of typical test commands and their purpose:
+ `prepare`: performs preparative actions for those tests which need
them, e.g. creating the necessary files on disk for the `fileio`
test, or filling the test database for database benchmarks.
+ `run`: runs the actual test specified with the *testname*
argument. This command is provided by all tests.
+ `cleanup`: removes temporary data after the test run in those
tests which create one.
+ `help`: displays usage information for the test specified with the
*testname* argument. This includes the full list of commands
provided by the test, so it should be used to get the available
commands.
- *options* is a list of zero or more command line options starting with
`'--'`. As with commands, the `sysbench testname help` command
should be used to describe available options provided by a
particular test.
See [General command line options](README.md#general-command-line-options)
for a description of general options provided by sysbench itself.
You can use `sysbench --help` to display the general command line syntax
and options.
## General Command Line Options
The table below lists the supported common options, their descriptions and default values:
*Option* | *Description* | *Default value*
----------------------|---------------|----------------
| `--threads` | The total number of worker threads to create | 1 |
| `--events` | Limit for total number of requests. 0 (the default) means no limit | 0 |
| `--time` | Limit for total execution time in seconds. 0 means no limit | 10 |
| `--rate` | Average transactions rate. The number specifies how many events (transactions) per seconds should be executed by all threads on average. 0 (default) means unlimited rate, i.e. events are executed as fast as possible | 0 |
| `--thread-stack-size` | Size of stack for each thread | 32K |
| `--report-interval` | Periodically report intermediate statistics with a specified interval in seconds. Note that statistics produced by this option is per-interval rather than cumulative. 0 disables intermediate reports | 0 |
| `--debug` | Print more debug info | off |
| `--validate` | Perform validation of test results where possible | off |
| `--help` | Print help on general syntax or on a test mode specified with --test, and exit | off |
| `--verbosity` | Verbosity level (0 - only critical messages, 5 - debug) | 4 |
| `--percentile` | sysbench measures execution times for all processed requests to display statistical information like minimal, average and maximum execution time. For most benchmarks it is also useful to know a request execution time value matching some percentile (e.g. 95% percentile means we should drop 5% of the most long requests and choose the maximal value from the remaining ones). This option allows to specify a percentile rank of query execution times to count | 95 |
Note that numerical values for all *size* options (like `--thread-stack-size` in this table) may be specified by appending the corresponding multiplicative suffix (K for kilobytes, M for megabytes, G for gigabytes and T for terabytes).
# Versioning
For transparency and insight into its release cycle, and for striving to maintain backward compatibility, sysbench will be maintained under the Semantic Versioning guidelines as much as possible.
Releases will be numbered with the following format:
`<major>.<minor>.<patch>`
And constructed with the following guidelines:
* Breaking backward compatibility bumps the major (and resets the minor and patch)
* New additions without breaking backward compatibility bumps the minor (and resets the patch)
* Bug fixes and misc changes bumps the patch
For more information on SemVer, please visit [http://semver.org/](http://semver.org/).
[coveralls-badge]: https://coveralls.io/repos/github/akopytov/sysbench/badge.svg?branch=1.0
[coveralls-url]: https://coveralls.io/github/akopytov/sysbench?branch=1.0
[travis-badge]: https://travis-ci.org/akopytov/sysbench.svg?branch=1.0
[travis-url]: https://travis-ci.org/akopytov/sysbench?branch=1.0
[license-badge]: https://img.shields.io/badge/license-GPLv2-blue.svg
[license-url]: COPYING
[release-badge]: https://img.shields.io/github/release/akopytov/sysbench.svg
[release-url]: https://github.com/akopytov/sysbench/releases/latest
[deb-badge]: https://img.shields.io/badge/Packages-Debian-red.svg?style=flat
[deb-url]: https://packagecloud.io/akopytov/sysbench?filter=debs
[rpm-badge]: https://img.shields.io/badge/Packages-RPM-blue.svg?style=flat
[rpm-url]: https://packagecloud.io/akopytov/sysbench?filter=rpms

View File

@ -0,0 +1,98 @@
#!/usr/bin/env bash
# Taken from lighthttpd server (BSD). Thanks Jan!
# Run this to generate all the initial makefiles, etc.
die() { echo "$@"; exit 1; }
ACLOCAL_FLAGS="-I m4"
LIBTOOLIZE_FLAGS="--copy --force"
AUTOMAKE_FLAGS="-c --foreign --add-missing"
ARGV0=$0
ARGS="$@"
run() {
echo "$ARGV0: running \`$@' $ARGS"
$@ $ARGS
}
## jump out if one of the programs returns 'false'
set -e
if test x$ACLOCAL = x; then
if test \! "x`which aclocal-1.10 2> /dev/null | grep -v '^no'`" = x; then
ACLOCAL=aclocal-1.10
elif test \! "x`which aclocal110 2> /dev/null | grep -v '^no'`" = x; then
ACLOCAL=aclocal110
elif test \! "x`which aclocal 2> /dev/null | grep -v '^no'`" = x; then
ACLOCAL=aclocal
else
echo "automake 1.10.x (aclocal) wasn't found, exiting"; exit 1
fi
fi
if test x$LIBTOOLIZE = x; then
if test \! "x`which libtoolize15 2> /dev/null | grep -v '^no'`" = x; then
LIBTOOLIZE=libtoolize15
elif test \! "x`which libtoolize14 2> /dev/null | grep -v '^no'`" = x; then
LIBTOOLIZE=libtoolize14
elif test \! "x`which glibtoolize 2> /dev/null | grep -v '^no'`" = x; then
LIBTOOLIZE=glibtoolize
elif test \! "x`which libtoolize 2> /dev/null | grep -v '^no'`" = x; then
LIBTOOLIZE=libtoolize
else
echo "libtoolize 1.4+ wasn't found, exiting"; exit 1
fi
fi
if test x$AUTOMAKE = x; then
if test \! "x`which automake-1.10 2> /dev/null | grep -v '^no'`" = x; then
AUTOMAKE=automake-1.10
elif test \! "x`which automake110 2> /dev/null | grep -v '^no'`" = x; then
AUTOMAKE=automake110
elif test \! "x`which automake 2> /dev/null | grep -v '^no'`" = x; then
AUTOMAKE=automake
else
echo "automake 1.10.x wasn't found, exiting"; exit 1
fi
fi
## macosx has autoconf-2.59 and autoconf-2.60
if test x$AUTOCONF = x; then
if test \! "x`which autoconf-2.59 2> /dev/null | grep -v '^no'`" = x; then
AUTOCONF=autoconf-2.59
elif test \! "x`which autoconf259 2> /dev/null | grep -v '^no'`" = x; then
AUTOCONF=autoconf259
elif test \! "x`which autoconf 2> /dev/null | grep -v '^no'`" = x; then
AUTOCONF=autoconf
else
echo "autoconf 2.59+ wasn't found, exiting"; exit 1
fi
fi
if test x$AUTOHEADER = x; then
if test \! "x`which autoheader-2.59 2> /dev/null | grep -v '^no'`" = x; then
AUTOHEADER=autoheader-2.59
elif test \! "x`which autoheader259 2> /dev/null | grep -v '^no'`" = x; then
AUTOHEADER=autoheader259
elif test \! "x`which autoheader 2> /dev/null | grep -v '^no'`" = x; then
AUTOHEADER=autoheader
else
echo "autoconf 2.59+ (autoheader) wasn't found, exiting"; exit 1
fi
fi
run $LIBTOOLIZE $LIBTOOLIZE_FLAGS || die "Can't execute libtoolize"
run $ACLOCAL $ACLOCAL_FLAGS || die "Can't execute aclocal"
run $AUTOHEADER || die "Can't execute autoheader"
run $AUTOMAKE $AUTOMAKE_FLAGS || die "Can't execute automake"
run $AUTOCONF || die "Can't execute autoconf"
echo -n "Libtoolized with: "
$LIBTOOLIZE --version | head -1
echo -n "Automade with: "
$AUTOMAKE --version | head -1
echo -n "Configured with: "
$AUTOCONF --version | head -1

View File

@ -0,0 +1,666 @@
#! /bin/sh
# Output a system dependent set of variables, describing how to set the
# run time search path of shared libraries in an executable.
#
# Copyright 1996-2007 Free Software Foundation, Inc.
# Taken from GNU libtool, 2001
# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
#
# This file is free software; the Free Software Foundation gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.
#
# The first argument passed to this file is the canonical host specification,
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
# or
# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
# should be set by the caller.
#
# The set of defined variables is at the end of this script.
# Known limitations:
# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
# than 256 bytes, otherwise the compiler driver will dump core. The only
# known workaround is to choose shorter directory names for the build
# directory and/or the installation directory.
# All known linkers require a `.a' archive for static linking (except MSVC,
# which needs '.lib').
libext=a
shrext=.so
host="$1"
host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
# Code taken from libtool.m4's _LT_CC_BASENAME.
for cc_temp in $CC""; do
case $cc_temp in
compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
\-*) ;;
*) break;;
esac
done
cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
wl=
if test "$GCC" = yes; then
wl='-Wl,'
else
case "$host_os" in
aix*)
wl='-Wl,'
;;
darwin*)
case $cc_basename in
xlc*)
wl='-Wl,'
;;
esac
;;
mingw* | cygwin* | pw32* | os2*)
;;
hpux9* | hpux10* | hpux11*)
wl='-Wl,'
;;
irix5* | irix6* | nonstopux*)
wl='-Wl,'
;;
newsos6)
;;
linux* | k*bsd*-gnu)
case $cc_basename in
icc* | ecc*)
wl='-Wl,'
;;
pgcc | pgf77 | pgf90)
wl='-Wl,'
;;
ccc*)
wl='-Wl,'
;;
como)
wl='-lopt='
;;
*)
case `$CC -V 2>&1 | sed 5q` in
*Sun\ C*)
wl='-Wl,'
;;
esac
;;
esac
;;
osf3* | osf4* | osf5*)
wl='-Wl,'
;;
rdos*)
;;
solaris*)
wl='-Wl,'
;;
sunos4*)
wl='-Qoption ld '
;;
sysv4 | sysv4.2uw2* | sysv4.3*)
wl='-Wl,'
;;
sysv4*MP*)
;;
sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
wl='-Wl,'
;;
unicos*)
wl='-Wl,'
;;
uts4*)
;;
esac
fi
# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
hardcode_libdir_flag_spec=
hardcode_libdir_separator=
hardcode_direct=no
hardcode_minus_L=no
case "$host_os" in
cygwin* | mingw* | pw32*)
# FIXME: the MSVC++ port hasn't been tested in a loooong time
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
if test "$GCC" != yes; then
with_gnu_ld=no
fi
;;
interix*)
# we just hope/assume this is gcc and not c89 (= MSVC++)
with_gnu_ld=yes
;;
openbsd*)
with_gnu_ld=no
;;
esac
ld_shlibs=yes
if test "$with_gnu_ld" = yes; then
# Set some defaults for GNU ld with shared library support. These
# are reset later if shared libraries are not supported. Putting them
# here allows them to be overridden if necessary.
# Unlike libtool, we use -rpath here, not --rpath, since the documented
# option of GNU ld is called -rpath, not --rpath.
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
case "$host_os" in
aix3* | aix4* | aix5*)
# On AIX/PPC, the GNU linker is very broken
if test "$host_cpu" != ia64; then
ld_shlibs=no
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
# that the semantics of dynamic libraries on AmigaOS, at least up
# to version 4, is to share data among multiple programs linked
# with the same dynamic library. Since this doesn't match the
# behavior of shared libraries on other platforms, we cannot use
# them.
ld_shlibs=no
;;
beos*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
cygwin* | mingw* | pw32*)
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec='-L$libdir'
if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
interix[3-9]*)
hardcode_direct=no
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
gnu* | linux* | k*bsd*-gnu)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
netbsd*)
;;
solaris*)
if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
ld_shlibs=no
elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
case `$LD -v 2>&1` in
*\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
ld_shlibs=no
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
else
ld_shlibs=no
fi
;;
esac
;;
sunos4*)
hardcode_direct=yes
;;
*)
if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
:
else
ld_shlibs=no
fi
;;
esac
if test "$ld_shlibs" = no; then
hardcode_libdir_flag_spec=
fi
else
case "$host_os" in
aix3*)
# Note: this linker hardcodes the directories in LIBPATH if there
# are no directories specified by -L.
hardcode_minus_L=yes
if test "$GCC" = yes; then
# Neither direct hardcoding nor static linking is supported with a
# broken collect2.
hardcode_direct=unsupported
fi
;;
aix4* | aix5*)
if test "$host_cpu" = ia64; then
# On IA64, the linker does run time linking by default, so we don't
# have to do anything special.
aix_use_runtimelinking=no
else
aix_use_runtimelinking=no
# Test if we are trying to use run time linking or normal
# AIX style linking. If -brtl is somewhere in LDFLAGS, we
# need to do runtime linking.
case $host_os in aix4.[23]|aix4.[23].*|aix5*)
for ld_flag in $LDFLAGS; do
if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
aix_use_runtimelinking=yes
break
fi
done
;;
esac
fi
hardcode_direct=yes
hardcode_libdir_separator=':'
if test "$GCC" = yes; then
case $host_os in aix4.[012]|aix4.[012].*)
collect2name=`${CC} -print-prog-name=collect2`
if test -f "$collect2name" && \
strings "$collect2name" | grep resolve_lib_name >/dev/null
then
# We have reworked collect2
:
else
# We have old collect2
hardcode_direct=unsupported
hardcode_minus_L=yes
hardcode_libdir_flag_spec='-L$libdir'
hardcode_libdir_separator=
fi
;;
esac
fi
# Begin _LT_AC_SYS_LIBPATH_AIX.
echo 'int main () { return 0; }' > conftest.c
${CC} ${LDFLAGS} conftest.c -o conftest
aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
if test -z "$aix_libpath"; then
aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; }
}'`
fi
if test -z "$aix_libpath"; then
aix_libpath="/usr/lib:/lib"
fi
rm -f conftest.c conftest
# End _LT_AC_SYS_LIBPATH_AIX.
if test "$aix_use_runtimelinking" = yes; then
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
else
if test "$host_cpu" = ia64; then
hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
else
hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
fi
fi
;;
amigaos*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
# see comment about different semantics on the GNU ld section
ld_shlibs=no
;;
bsdi[45]*)
;;
cygwin* | mingw* | pw32*)
# When not using gcc, we currently assume that we are using
# Microsoft Visual C++.
# hardcode_libdir_flag_spec is actually meaningless, as there is
# no search path for DLLs.
hardcode_libdir_flag_spec=' '
libext=lib
;;
darwin* | rhapsody*)
hardcode_direct=no
if test "$GCC" = yes ; then
:
else
case $cc_basename in
xlc*)
;;
*)
ld_shlibs=no
;;
esac
fi
;;
dgux*)
hardcode_libdir_flag_spec='-L$libdir'
;;
freebsd1*)
ld_shlibs=no
;;
freebsd2.2*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
freebsd2*)
hardcode_direct=yes
hardcode_minus_L=yes
;;
freebsd* | dragonfly*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
hpux9*)
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
hpux10*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
fi
;;
hpux11*)
if test "$with_gnu_ld" = no; then
hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
hardcode_libdir_separator=:
case $host_cpu in
hppa*64*|ia64*)
hardcode_direct=no
;;
*)
hardcode_direct=yes
# hardcode_minus_L: Not really in the search PATH,
# but as the default location of the library.
hardcode_minus_L=yes
;;
esac
fi
;;
irix5* | irix6* | nonstopux*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
netbsd*)
hardcode_libdir_flag_spec='-R$libdir'
hardcode_direct=yes
;;
newsos6)
hardcode_direct=yes
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
openbsd*)
if test -f /usr/libexec/ld.so; then
hardcode_direct=yes
if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
else
case "$host_os" in
openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
hardcode_libdir_flag_spec='-R$libdir'
;;
*)
hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
;;
esac
fi
else
ld_shlibs=no
fi
;;
os2*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_minus_L=yes
;;
osf3*)
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
hardcode_libdir_separator=:
;;
osf4* | osf5*)
if test "$GCC" = yes; then
hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
else
# Both cc and cxx compiler support -rpath directly
hardcode_libdir_flag_spec='-rpath $libdir'
fi
hardcode_libdir_separator=:
;;
solaris*)
hardcode_libdir_flag_spec='-R$libdir'
;;
sunos4*)
hardcode_libdir_flag_spec='-L$libdir'
hardcode_direct=yes
hardcode_minus_L=yes
;;
sysv4)
case $host_vendor in
sni)
hardcode_direct=yes # is this really true???
;;
siemens)
hardcode_direct=no
;;
motorola)
hardcode_direct=no #Motorola manual says yes, but my tests say they lie
;;
esac
;;
sysv4.3*)
;;
sysv4*MP*)
if test -d /usr/nec; then
ld_shlibs=yes
fi
;;
sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
;;
sysv5* | sco3.2v5* | sco5v6*)
hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
hardcode_libdir_separator=':'
;;
uts4*)
hardcode_libdir_flag_spec='-L$libdir'
;;
*)
ld_shlibs=no
;;
esac
fi
# Check dynamic linker characteristics
# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
# Unlike libtool.m4, here we don't care about _all_ names of the library, but
# only about the one the linker finds when passed -lNAME. This is the last
# element of library_names_spec in libtool.m4, or possibly two of them if the
# linker has special search rules.
library_names_spec= # the last element of library_names_spec in libtool.m4
libname_spec='lib$name'
case "$host_os" in
aix3*)
library_names_spec='$libname.a'
;;
aix4* | aix5*)
library_names_spec='$libname$shrext'
;;
amigaos*)
library_names_spec='$libname.a'
;;
beos*)
library_names_spec='$libname$shrext'
;;
bsdi[45]*)
library_names_spec='$libname$shrext'
;;
cygwin* | mingw* | pw32*)
shrext=.dll
library_names_spec='$libname.dll.a $libname.lib'
;;
darwin* | rhapsody*)
shrext=.dylib
library_names_spec='$libname$shrext'
;;
dgux*)
library_names_spec='$libname$shrext'
;;
freebsd1*)
;;
freebsd* | dragonfly*)
case "$host_os" in
freebsd[123]*)
library_names_spec='$libname$shrext$versuffix' ;;
*)
library_names_spec='$libname$shrext' ;;
esac
;;
gnu*)
library_names_spec='$libname$shrext'
;;
hpux9* | hpux10* | hpux11*)
case $host_cpu in
ia64*)
shrext=.so
;;
hppa*64*)
shrext=.sl
;;
*)
shrext=.sl
;;
esac
library_names_spec='$libname$shrext'
;;
interix[3-9]*)
library_names_spec='$libname$shrext'
;;
irix5* | irix6* | nonstopux*)
library_names_spec='$libname$shrext'
case "$host_os" in
irix5* | nonstopux*)
libsuff= shlibsuff=
;;
*)
case $LD in
*-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
*-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
*-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
*) libsuff= shlibsuff= ;;
esac
;;
esac
;;
linux*oldld* | linux*aout* | linux*coff*)
;;
linux* | k*bsd*-gnu)
library_names_spec='$libname$shrext'
;;
knetbsd*-gnu)
library_names_spec='$libname$shrext'
;;
netbsd*)
library_names_spec='$libname$shrext'
;;
newsos6)
library_names_spec='$libname$shrext'
;;
nto-qnx*)
library_names_spec='$libname$shrext'
;;
openbsd*)
library_names_spec='$libname$shrext$versuffix'
;;
os2*)
libname_spec='$name'
shrext=.dll
library_names_spec='$libname.a'
;;
osf3* | osf4* | osf5*)
library_names_spec='$libname$shrext'
;;
rdos*)
;;
solaris*)
library_names_spec='$libname$shrext'
;;
sunos4*)
library_names_spec='$libname$shrext$versuffix'
;;
sysv4 | sysv4.3*)
library_names_spec='$libname$shrext'
;;
sysv4*MP*)
library_names_spec='$libname$shrext'
;;
sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
library_names_spec='$libname$shrext'
;;
uts4*)
library_names_spec='$libname$shrext'
;;
esac
sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
# How to pass a linker flag through the compiler.
wl="$escaped_wl"
# Static library suffix (normally "a").
libext="$libext"
# Shared library suffix (normally "so").
shlibext="$shlibext"
# Format of library name prefix.
libname_spec="$escaped_libname_spec"
# Library names that the linker finds when passed -lNAME.
library_names_spec="$escaped_library_names_spec"
# Flag to hardcode \$libdir into a binary during linking.
# This must work even if \$libdir does not exist.
hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
# Whether we need a single -rpath flag with a separated argument.
hardcode_libdir_separator="$hardcode_libdir_separator"
# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
# resulting binary.
hardcode_direct="$hardcode_direct"
# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
# resulting binary.
hardcode_minus_L="$hardcode_minus_L"
EOF

View File

@ -0,0 +1,537 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.63)
AC_INIT([sysbench],[1.0.20],[https://github.com/akopytov/sysbench/issues],
[sysbench], [https://github.com/akopytov/sysbench])
AC_CONFIG_AUX_DIR([config])
# Define m4_ifblank and m4_ifnblank macros from introduced in
# autotools 2.64 m4sugar.m4 if using an earlier autotools.
m4_ifdef([m4_ifblank], [], [
m4_define([m4_ifblank],
[m4_if(m4_translit([[$1]], [ ][ ][
]), [], [$2], [$3])])
])
m4_ifdef([m4_ifnblank], [], [
m4_define([m4_ifnblank],
[m4_if(m4_translit([[$1]], [ ][ ][
]), [], [$3], [$2])])
])
# Setting CFLAGS here prevents AC_CANONICAL_TARGET from injecting them
SAVE_CFLAGS=${CFLAGS}
SAVE_CXXFLAGS=${CXXFLAGS}
CFLAGS=
CXXFLAGS=
AC_CANONICAL_TARGET
CFLAGS=${SAVE_CFLAGS}
CXXFLAGS=${SAVE_CXXFLAGS}
AM_INIT_AUTOMAKE([-Wall -Werror foreign])
AC_CONFIG_SRCDIR([src/sysbench.c])
AC_CONFIG_HEADER([config/config.h])
AC_CONFIG_MACRO_DIR([m4])
m4_pattern_forbid([^PKG_[A-Z_]+$],
[pkg-config has to be installed to build sysbench])
ACX_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_PROG_CC_C99
AC_PROG_CPP
AM_PROG_CC_C_O
if test x"$ac_cv_prog_cc_c99" = xno; then
AC_MSG_ERROR([a C99 compiler is required to build sysbench])
fi
# Try to guess the most optimal compiler architecture flag, unless it's already
# been specified by the user via CFLAGS (or --without-gcc-arch is passed to
# configure)
AS_CASE([$CFLAGS],
[*-march=*],,
[AX_GCC_ARCHFLAG([no])]
)
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
AC_PROG_LIBTOOL
AC_CHECK_PROG(sb_have_pkg_config, pkg-config, yes, no)
if test x"$sb_have_pkg_config" = xno; then
AC_MSG_ERROR([the pkg-config package is required to build sysbench])
fi
AX_COMPILER_VENDOR
# Checks for user arguments
AC_LIB_PREFIX()
# Additional linker flags
AC_ARG_WITH([extra-ldflags],
AS_HELP_STRING([--with-extra-ldflags],[additional linker flags, e.g. -all-static]),
EXTRA_LDFLAGS=$withval
)
AC_SUBST(EXTRA_LDFLAGS)
CPPFLAGS="-D_GNU_SOURCE ${CPPFLAGS}"
# Mac OS X requires _DARWIN_C_SOURCE for valloc(3) to be visible
case "${host_cpu}-${host_os}" in
*-darwin*) CPPFLAGS="-D_DARWIN_C_SOURCE ${CPPFLAGS}";;
esac
# Build optimized or debug version ?
# First check for gcc and g++
if test "$GCC" = "yes"
then
CFLAGS="-ggdb3 ${CFLAGS}"
DEBUG_CFLAGS="-O0"
OPTIMIZE_CFLAGS="-O2 -funroll-loops"
GCOV_CFLAGS="-O0 --coverage"
GCOV_LDFLAGS="-coverage"
ASAN_CFLAGS="-fsanitize=address"
ASAN_LDFLAGS="${ASAN_CFLAGS}"
MSAN_CFLAGS="-fsanitize=memory"
MSAN_LDFLAGS="${MSAN_LDFLAGS}"
fi
if test "$ax_cv_c_compiler_vendor" = "sun"
then
isainfo_k=`isainfo -k`
if test "$target_cpu" = "sparc"
then
MEMALIGN_FLAGS="-xmemalign=8s"
IS_64="-m64"
LDFLAGS="${LDFLAGS} -L/usr/lib/${isainfo_k} -L/usr/local/lib/${isainfo_k}"
else
if test "$isainfo_k" = "amd64"
then
IS_64="-m64"
LDFLAGS="${LDFLAGS} -L/usr/lib/${isainfo_k} -L/usr/local/lib/${isainfo_k}"
fi
fi
CPPFLAGS="${CPPFLAGS} -I/usr/local/include"
CFLAGS="-g -mt ${IS_64} ${MEMALIGN_FLAGS} ${CFLAGS}"
DEBUG_CFLAGS="-xO0"
OPTIMIZE_CFLAGS="-xO2 -xlibmil -xdepend -Xa -mt -xstrconst"
# TODO: Set flags for Gcov-enabled builds, if supported by Sun Studio
fi
# Check if we should compile with MySQL support
AC_ARG_WITH([mysql],
AS_HELP_STRING([--with-mysql],
[compile with MySQL support (default is enabled)]),
[], [with_mysql=yes])
AC_MSG_CHECKING([whether to compile with MySQL support])
AS_IF([test "x$with_mysql" != "xno"],
[mysql_support=yes],
[mysql_support=no])
AC_MSG_RESULT([$mysql_support])
# Check if we should compile with Drizzle support
AC_ARG_WITH([drizzle],
AS_HELP_STRING([--with-drizzle],
[compile with Drizzle support (default is disabled)]),
[], [with_drizzle=no])
AC_MSG_CHECKING([whether to compile with Drizzle support])
AS_IF([test "x$with_drizzle" != "xno"],
[drizzle_support=yes],
[drizzle_support=no])
AC_MSG_RESULT([$drizzle_support])
# Check if we should compile with libattachsql support
AC_ARG_WITH([attachsql],
AS_HELP_STRING([--with-attachsql],
[compile with libattachsql support (default is disabled)]),
[], [with_attachsql=no])
AC_MSG_CHECKING([whether to compile with libattachsql support])
AS_IF([test "x$with_attachsql" != "xno"],
[attachsql_support=yes],
[attachsql_support=no])
AC_MSG_RESULT([$attachsql_support])
# Check if we should compile with Oracle support
AC_ARG_WITH([oracle],
AS_HELP_STRING([--with-oracle],
[compile with Oracle support (default is disabled)]),
[], [with_oracle=no])
AC_MSG_CHECKING([whether to compile with Oracle support])
AS_IF([test "x$with_oracle" != "xno"],
[oracle_support=yes],
[oracle_support=no])
AC_MSG_RESULT([$oracle_support])
# Check if we should compile with PostgreSQL support
AC_ARG_WITH([pgsql],
AS_HELP_STRING([--with-pgsql],
[compile with PostgreSQL support (default is disabled)]),
[], [with_pgsql=no])
AC_MSG_CHECKING([whether to compile with PostgreSQL support])
AS_IF([test "x$with_pgsql" != "xno"],
[pgsql_support=yes],
[pgsql_support=no])
AC_MSG_RESULT([$pgsql_support])
# Set LuaJIT flags
SB_LUAJIT
# Set Concurrency Kit flags
SB_CONCURRENCY_KIT
# Check if we should enable large files support
AC_ARG_ENABLE(largefile,
AS_HELP_STRING([--enable-largefile],[enable large files support (default is enabled)]), ,
enable_largefile=yes
)
# For SHM_HUGETLB on Linux
AC_CHECK_DECLS(SHM_HUGETLB,
AC_DEFINE([HAVE_LARGE_PAGES], [1],
[Define if you have large pages support])
AC_DEFINE([HUGETLB_USE_PROC_MEMINFO], [1],
[Define if /proc/meminfo shows the huge page size (Linux only)])
, ,
[
#include <sys/shm.h>
]
)
# Check if we should enable Linux AIO support
AC_ARG_ENABLE(aio,
AS_HELP_STRING([--enable-aio],[enable Linux asynchronous I/O support (default is enabled)]), ,
enable_aio=yes
)
AC_CHECK_DECLS(O_SYNC, ,
AC_DEFINE([O_SYNC], [O_FSYNC],
[Define to the appropriate value for O_SYNC on your platform]),
[
#include <fcntl.h>
]
)
# Checks for programs.
AX_CHECK_DOCBOOK
# Checks for libraries.
ACX_PTHREAD
AC_CHECK_LIB(m, sqrt)
SB_CHECK_MYSQL
AS_IF([test "x$with_drizzle" != xno], [
AC_LIB_HAVE_LINKFLAGS(drizzle,,
[#include <libdrizzle/drizzle.h>],
[
int x= DRIZZLE_RETURN_ERROR_CODE;
const char *version= drizzle_version();
])
AS_IF([test "x$ac_cv_libdrizzle" = xyes], [
AC_DEFINE([USE_DRIZZLE],1,
[Define to 1 if you want to compile with Drizzle support])
])
])
AM_CONDITIONAL(USE_DRIZZLE, test x$ac_cv_libdrizzle = xyes)
AS_IF([test "x$with_attachsql" != xno], [
AC_LIB_HAVE_LINKFLAGS(attachsql,,
[#include <libattachsql-1.0/attachsql.h>],
[
const char *version= attachsql_get_library_version();
])
AS_IF([test "x$ac_cv_libattachsql" = xyes], [
AC_DEFINE(USE_ATTACHSQL,1,
[Define to 1 if you want to compile with libattachsql support])
])
])
AM_CONDITIONAL(USE_ATTACHSQL, test x$ac_cv_libattachsql = xyes)
AS_IF([test x$with_oracle != xno], [
AC_DEFINE(USE_ORACLE,1,[Define to 1 if you want to compile with Oracle support])
ORA_LIBS="-L${sb_with_oracle}/lib -lclntsh"
ORA_CFLAGS="-I${with_oracle}/include -I${with_oracle}/rdbms/demo -I${with_oracle}/rdbms/public"
AC_SUBST([ORA_LIBS])
AC_SUBST([ORA_CFLAGS])
])
AM_CONDITIONAL(USE_ORACLE, test x$with_oracle != xno)
AS_IF([test x$with_pgsql != xno], [
AC_CHECK_PGSQL([$with_pgsql])
USE_PGSQL=1
AC_DEFINE(USE_PGSQL,1,[Define to 1 if you want to compile with PostgreSQL support])
AC_SUBST([PGSQL_LIBS])
AC_SUBST([PGSQL_CFLAGS])
])
AM_CONDITIONAL(USE_PGSQL, test x$with_pgsql != xno)
AC_SUBST([USE_PGSQL])
# Check for libaio
AC_CHECK_AIO
AM_CONDITIONAL(USE_AIO, test x$enable_aio = xyes)
# Check for advanced memory allocation libraries
AC_CHECK_LIB([umem], [malloc], [EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lumem"],
AC_CHECK_LIB([mtmalloc], [malloc], [EXTRA_LDFLAGS="$EXTRA_LDFLAGS -lmtmalloc"])
)
# Checks for header files.
AC_HEADER_STDC
AC_CHECK_HEADERS([ \
errno.h \
fcntl.h \
math.h \
pthread.h \
sched.h \
signal.h \
stdlib.h \
string.h \
sys/aio.h \
sys/ipc.h \
sys/time.h \
sys/mman.h \
sys/shm.h \
thread.h \
unistd.h \
limits.h \
libgen.h \
])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_OFF_T
AC_HEADER_TIME
AX_TLS([],
AC_MSG_ERROR([thread-local storage is not suppored by the target platform!])
)
# Define HAVE_FUNC_ATTRIBUTE_FORMAT if compiler supports the
# __attribute__((format...)) function attribute
AX_GCC_FUNC_ATTRIBUTE(format)
# Define HAVE_FUNC_ATTRIBUTE_UNUSED if compiler supports the
# __attribute__((unused)) function attribute
AX_GCC_FUNC_ATTRIBUTE(unused)
if test "$enable_largefile" = yes; then
AC_SYS_LARGEFILE
fi
AC_CHECK_SIZEOF(size_t)
AC_CHECK_SIZEOF(bool,,
[
#include <stdbool.h>
])
# Checks for library functions.
AC_FUNC_MMAP
AC_FUNC_STRERROR_R
AC_SEARCH_LIBS([clock_gettime], [rt])
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_CHECK_FUNCS([ \
alarm \
clock_gettime \
directio \
fdatasync \
gettimeofday \
isatty \
memalign \
memset \
posix_memalign \
pthread_yield \
setvbuf \
sqrt \
strdup \
thr_setconcurrency \
valloc \
])
AC_CHECK_FUNC(pthread_once, ,
AC_MSG_ERROR([*** pthread_once() is not available on this platform ***])
)
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_ARG_WITH([debug],
[AS_HELP_STRING([--with-debug],
[Add debug code/turns off optimizations (yes|no) @<:@default=no@:>@])],
[with_debug=$withval],
[with_debug=no])
AC_ARG_ENABLE([coverage],
[AS_HELP_STRING([--enable-coverage],
[Toggle coverage @<:@default=no@:>@])],
[ac_coverage="$enableval"],
[ac_coverage="no"])
AC_ARG_ENABLE([asan],
[AS_HELP_STRING([--enable-asan],
[Enable AddressSanitizer @<:@default=no@:>@])],
[ac_asan="$enableval"],
[ac_asan="no"])
AC_ARG_ENABLE([msan],
[AS_HELP_STRING([--enable-msan],
[Enable MemorySanitizer @<:@default=no@:>@])],
[ac_msan="$enableval"],
[ac_msan="no"])
AC_ARG_ENABLE([fail],
[AS_HELP_STRING([--disable-fail],
[Turn warnings into failures @<:@default=no@:>@])],
[ac_warn_fail="$enableval"],
[ac_warn_fail="no"])
if test "$with_debug" = "yes"
then
# Debugging. No optimization.
CFLAGS="${DEBUG_CFLAGS} -DDEBUG ${CFLAGS}"
elif test "$ac_coverage" = "yes"
then
# Gcov-enabled build. No optimization.
CFLAGS="${GCOV_CFLAGS} ${CFLAGS}"
LDFLAGS="${GCOV_LDFLAGS} ${LDFLAGS}"
else
# Optimized version. No debug
CFLAGS="${OPTIMIZE_CFLAGS} ${CFLAGS}"
fi
if test "$ac_asan" = "yes"
then
# Add -fsanitize=address to CFLAGS/LDFLAGS if supported by the compiler
AX_CHECK_COMPILE_FLAG([-fsanitize=address],
[
CFLAGS="${ASAN_CFLAGS} ${CFLAGS}"
LDFLAGS="${ASAN_LDFLAGS} ${LDFLAGS}"
])
fi
if test "$ac_msan" = "yes"
then
# Add -fsanitize=memory to CFLAGS/LDFLAGS if supported by the compiler
AX_CHECK_COMPILE_FLAG([-fsanitize=memory],
[
CFLAGS="${MSAN_CFLAGS} ${CFLAGS}"
LDFLAGS="${MSAN_CFLAGS} ${LDFLAGS}"
])
fi
if test "$GCC" = "yes"
then
if test "$ac_warn_fail" = "yes"
then
W_FAIL="-Werror"
fi
CC_WARNINGS="-Wall -Wextra -Wpointer-arith -Wbad-function-cast \
-Wstrict-prototypes -Wnested-externs -Wno-format-zero-length \
-Wundef -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \
-Wredundant-decls -Wcast-align -Wvla ${W_FAIL}"
fi
if test "$ax_cv_c_compiler_vendor" = "sun"
then
CC_WARNINGS="-v -errtags=yes -errwarn=%all -erroff=E_INTEGER_OVERFLOW_DETECTED -erroff=E_STATEMENT_NOT_REACHED"
fi
AM_CFLAGS="${CC_WARNINGS} ${AM_CFLAGS} ${PTHREAD_CFLAGS}"
AM_CPPFLAGS="${AM_CPPFLAGS} -I\$(top_srcdir)/src ${LUAJIT_CFLAGS} ${CK_CFLAGS}"
AM_LDFLAGS="$PTHREAD_LIBS"
AC_SUBST(AM_CFLAGS)
AC_SUBST(AM_CPPFLAGS)
AC_SUBST(AM_LDFLAGS)
# Define SB_GIT_SHA
git=$(which git)
if test -n "$git"
then
SB_GIT_SHA=$(git rev-parse --short HEAD 2>/dev/null)
if test -n "$SB_GIT_SHA"
then
SB_GIT_SHA="-$SB_GIT_SHA"
fi
fi
AC_DEFINE_UNQUOTED([SB_GIT_SHA], ["$SB_GIT_SHA"], [Git commit hash, if available.])
AC_SUBST([SB_GIT_SHA])
AC_CONFIG_FILES([
Makefile
doc/xsl/Makefile
doc/xsl/catalog.xml
doc/Makefile
third_party/luajit/Makefile
third_party/concurrency_kit/Makefile
src/Makefile
src/drivers/Makefile
src/drivers/mysql/Makefile
src/drivers/drizzle/Makefile
src/drivers/oracle/Makefile
src/drivers/pgsql/Makefile
src/drivers/attachsql/Makefile
src/tests/Makefile
src/tests/cpu/Makefile
src/tests/fileio/Makefile
src/tests/memory/Makefile
src/tests/threads/Makefile
src/tests/mutex/Makefile
src/lua/Makefile
src/lua/internal/Makefile
tests/Makefile
tests/include/config.sh
snap/snapcraft.yaml
])
AC_OUTPUT
AC_MSG_RESULT([===============================================================================])
AC_MSG_RESULT([sysbench version : ${PACKAGE_VERSION}${SB_GIT_SHA}])
AC_MSG_RESULT([CC : ${CC}])
AC_MSG_RESULT([CFLAGS : ${CFLAGS} ${AM_CFLAGS}])
AC_MSG_RESULT([CPPFLAGS : ${CPPFLAGS} ${AM_CPPFLAGS}])
AC_MSG_RESULT([LDFLAGS : ${LDFLAGS} ${AM_LDFLAGS}])
AC_MSG_RESULT([LIBS : ${LIBS}])
AC_MSG_RESULT([EXTRA_LDFLAGS : ${EXTRA_LDFLAGS}])
AC_MSG_RESULT([])
AC_MSG_RESULT([prefix : $(eval echo ${prefix})])
AC_MSG_RESULT([bindir : $(eval echo ${bindir})])
AC_MSG_RESULT([libexecdir : $(eval echo ${libexecdir})])
AC_MSG_RESULT([mandir : $(eval echo ${mandir})])
AC_MSG_RESULT([datadir : $(eval echo ${datadir})])
AC_MSG_RESULT([])
AC_MSG_RESULT([MySQL support : ${mysql_support}])
AC_MSG_RESULT([Drizzle support : ${drizzle_support}])
AC_MSG_RESULT([AttachSQL support : ${attachsql_support}])
AC_MSG_RESULT([Oracle support : ${oracle_support}])
AC_MSG_RESULT([PostgreSQL support : ${pgsql_support}])
AC_MSG_RESULT([])
AC_MSG_RESULT([LuaJIT : ${sb_use_luajit}])
AC_MSG_RESULT([LUAJIT_CFLAGS : ${LUAJIT_CFLAGS}])
AC_MSG_RESULT([LUAJIT_LIBS : ${LUAJIT_LIBS}])
AC_MSG_RESULT([LUAJIT_LDFLAGS : ${LUAJIT_LDFLAGS}])
AC_MSG_RESULT([])
AC_MSG_RESULT([Concurrency Kit : ${sb_use_ck}])
if test "$sb_use_ck" = bundled; then
AC_MSG_RESULT([CK_CFLAGS : ${CK_CFLAGS}])
AC_MSG_RESULT([CK_LIBS : ${CK_LIBS}])
AC_MSG_RESULT([configure flags : ${CK_CONFIGURE_FLAGS}])
fi
AC_MSG_RESULT([===============================================================================])

View File

@ -0,0 +1,43 @@
sysbench (1.0.18-1) unstable; urgency=low
* add libssl-dev to build dependencies
-- Alexey Kopytov <akopytov@gmail.com> Sun, 08 Dec 2019 14:02:01 +0300
sysbench (1.0.15-2) unstable; urgency=low
* add libaio-dev to build dependencies
-- Alexey Kopytov <akopytov@gmail.com> Sat, 09 Jul 2018 09:24:42 +0300
sysbench (1.0.12-1) unstable; urgency=low
* remove vim-common from build dependencies
-- Alexey Kopytov <akopytov@gmail.com> Sat, 06 Jan 2018 10:59:42 +0300
sysbench (1.0.11-1) unstable; urgency=low
* add Debian Stretch support by adding optional build dependency on
default-libmysqlclient-dev and replacing python-minimal with python
(as minimal does not provide the shlex module required by cram)
-- Alexey Kopytov <akopytov@gmail.com> Sat, 09 Dec 2017 19:52:23 +0300
sysbench (1.0.6-1) unstable; urgency=low
* Add pkg-config, vim-common and python-minimal and libpq-dev to build dependencies.
* Fix 'clean' target in rules.
* Add ChangeLog and COPYING to docs.
* Remove tests/db/*.lua from install.
* Pass --without-gcc-arch to configure to not override compiler flags
passed by the build system
-- Alexey Kopytov <akopytov@gmail.com> Thu, 13 Apr 2017 23:04:34 +0300
sysbench (1.0-1) unstable; urgency=low
* Initial release
-- Alexey Kopytov <akopytov@gmail.com> Wed, 10 Aug 2016 18:04:53 +0300

View File

@ -0,0 +1 @@
7

View File

@ -0,0 +1,25 @@
Source: sysbench
Section: misc
Priority: extra
Maintainer: Alexey Kopytov <akopytov@gmail.com>
Build-Depends: debhelper, autoconf, automake, libaio-dev, libtool, libmysqlclient-dev | default-libmysqlclient-dev, libpq-dev, pkg-config, python, libssl-dev
Standards-Version: 3.9.5
Homepage: https://github.com/akopytov/sysbench
Package: sysbench
Architecture: any
Depends: ${shlibs:Depends}, ${misc:Depends}
Description: Scriptable database and system performance benchmark
sysbench is a scriptable multi-threaded benchmark tool based on
LuaJIT. It is most frequently used for database benchmarks, but can also
be used to create arbitrarily complex workloads that do not involve a
database server.
.
sysbench comes with the following bundled benchmarks:
.
- oltp_*.lua: a collection of OLTP-like database benchmarks
- fileio: a filesystem-level benchmark
- cpu: a simple CPU benchmark
- memory: a memory access benchmark
- threads: a thread-based scheduler benchmark
- mutex: a POSIX mutex benchmark

View File

@ -0,0 +1,15 @@
Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat
Upstream-Name: sysbench
Upstream-Maintainer: Alexey Kopytov <akopytov@gmail.com>
Upstream-Source: https://github.com/akopytov/sysbench
Files: *
Copyright: 2016 Alexey Kopytov
License: GPL-2
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
.
On Debian systems, the complete text of the GNU General
Public License can be found in `/usr/share/common-licenses/GPL-2'.

View File

@ -0,0 +1 @@
usr/bin

View File

@ -0,0 +1,3 @@
README.md
ChangeLog
COPYING

View File

View File

@ -0,0 +1,12 @@
#!/usr/bin/make -f
%:
dh $@
override_dh_auto_configure:
dh_testdir
autoreconf -vif
dh_auto_configure -- --with-mysql --with-pgsql --without-gcc-arch
override_dh_compress:
dh_compress -X.lua

View File

@ -0,0 +1 @@
3.0 (quilt)

View File

@ -0,0 +1,34 @@
XSLTPROC=xsltproc
XSLTPROC_FLAGS=@XSLTPROC_FLAGS@
XHTML_STYLESHEET=$(srcdir)/xsl/xhtml.xsl
CHUNK_XHTML_STYLESHEET=$(srcdir)/xsl/xhtml-chunk.xsl
XML_CATALOG_FILES=$(srcdir)/xsl/catalog.xml
dist_html_DATA = manual.html
EXTRA_DIST=manual.xml
SUBDIRS = xsl
if have_xsltproc
manual.html: ${top_srcdir}/doc/manual.xml
XML_CATALOG_FILES=$(XML_CATALOG_FILES) $(XSLTPROC) $(XSLTPROC_FLAGS) -o $@ $(XHTML_STYLESHEET) $<
chunk: ${top_srcdir}/doc/manual.xml
$(XSLTPROC) $(XSLTPROC_FLAGS) $(CHUNK_XHTML_STYLESHEET) $<
else
chunk:
manual.html:
touch $@
endif
clean-local:
$(RM) -f *.html
distclean-local:
$(RM) -f xsl/catalog.xml

View File

@ -0,0 +1,788 @@
<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<book id="sysbench-guide">
<bookinfo>
<title>sysbench manual</title>
<authorgroup>
<author>
<firstname>Alexey</firstname>
<surname>Kopytov</surname>
<affiliation>
<address><email>kaamos@users.sourceforge.net</email></address>
</affiliation>
</author>
</authorgroup>
<copyright>
<year>2004-2006</year>
<holder>MySQL AB</holder>
</copyright></bookinfo>
<toc></toc>
<chapter id="about">
<title>About this document</title>
<para>
This document is a user manual for sysbench, a multi-threaded
benchmark tool available from <ulink
url="http://launchpad.net/sysbench">http://launchpad.net/sysbench</ulink>.
This document describes features provided by the 0.4.x development
branch of sysbench. New features available in the newer 0.5.x
branch are not covered by this document.
</para>
<section id="translations">
<title> Translations </title>
<para>
The following translations of this document are currently
available:
<variablelist>
<varlistentry>
<term>Serbo-Croatian</term>
<listitem><para>
<ulink url="http://science.webhostinggeeks.com/sysbench-manual">http://science.webhostinggeeks.com/sysbench-manual/</ulink>.
</para></listitem>
</varlistentry>
</variablelist>
</para>
</section>
<section id="acknowledgments">
<title> Acknowledgments </title>
<para>
Thanks to Vera Djuraskovic
<email>veradjuraskovic@webhostinggeeks.com</email> for
contributing a Serbo-Croatian translation of this document.
</para>
</section>
</chapter>
<chapter id="introduction">
<title>Introduction</title>
<para>
sysbench is a modular, cross-platform and multi-threaded benchmark tool for evaluating OS parameters
that are important for a system running a database under intensive load.
</para>
<para>
The idea of this benchmark suite is to quickly get an impression about system performance without setting up
complex database benchmarks or even without installing a database at all.
</para>
<section id="features">
<title>Features of sysbench</title>
<para>
Current features allow to test the following system parameters:
<itemizedlist>
<listitem><para>file I/O performance</para></listitem>
<listitem><para>scheduler performance</para></listitem>
<listitem><para>memory allocation and transfer speed</para></listitem>
<listitem><para>POSIX threads implementation performance</para></listitem>
<listitem><para>database server performance</para></listitem>
</itemizedlist>
</para>
</section>
<section id="design">
<title>Design</title>
<para>
The design is very simple. sysbench runs a specified number of threads and they all execute requests in parallel.
The actual workload produced by requests depends on the specified test mode. You can limit either the total number of
requests or the total time for the benchmark, or both.
</para>
<para>
Available test modes are implemented by compiled-in modules, and sysbench was designed to make adding new test modes
an easy task. Each test mode may have additional (or workload-specific) options.
</para>
</section>
<section id="links">
<title>Links</title>
<variablelist>
<varlistentry>
<term>Home page</term>
<listitem><para>
<ulink url="http://sysbench.sf.net/">http://sysbench.sf.net/</ulink>.
</para></listitem>
</varlistentry>
<varlistentry>
<term>Download</term>
<listitem><para>
<ulink url="http://sf.net/projects/sysbench/">http://sf.net/projects/sysbench/</ulink>.
</para></listitem>
</varlistentry>
<varlistentry>
<term>Mailing lists</term>
<listitem><para>
<ulink url="http://sourceforge.net/mail/?group_id=102348">sysbench-general</ulink>
</para></listitem>
</varlistentry>
<varlistentry>
<term>Web forums</term>
<listitem><para>
<itemizedlist>
<listitem>
<ulink url="http://sourceforge.net/forum/forum.php?forum_id=353125">Developers</ulink>
</listitem>
<listitem>
<ulink url="http://sourceforge.net/forum/forum.php?forum_id=353124">Help</ulink>
</listitem>
<listitem>
<ulink url="http://sourceforge.net/forum/forum.php?forum_id=353123">Open discussion</ulink>
</listitem>
</itemizedlist>
</para></listitem>
</varlistentry>
<varlistentry>
<term>Bug tracking system</term>
<listitem><para>
<itemizedlist>
<listitem>
<ulink url="http://sourceforge.net/tracker/?atid=631676&amp;group_id=102348&amp;func=browse">
Bug reports
</ulink>
</listitem>
<listitem>
<ulink url="http://sourceforge.net/tracker/?atid=631679&amp;group_id=102348&amp;func=browse">
Feature requests
</ulink>
</listitem>
</itemizedlist>
</para></listitem>
</varlistentry>
</variablelist>
</section>
<section id="install">
<title>Installation</title>
<para>
If you are building sysbench from a Bazaar repository rather than from a release tarball,
you should run <command>./autogen.sh</command> before building.
</para>
<para>
The following standart procedure will be sufficient to build sysbench in most cases:
<synopsis>
<command>./configure</command>
<command>make</command>
<command>make install</command>
</synopsis>
The above procedure will try to compile sysbench with MySQL support by default. If you have MySQL headers and libraries
in non-standard locations (and no <command>mysql_config</command> can be found in the <constant>PATH</constant>
environmental variable), then you can specify them explicitly with <option>--with-mysql-includes</option> and
<option>--with-mysql-libs</option> options to <command>./configure</command>.
</para>
<para>
To compile sysbench without MySQL support, use <option>--without-mysql</option>. In this case all database-related
test modes will be unavailable.
</para>
<para>
If you are running on a 64-bit platform, make sure to build a 64-bit binary by passing the proper target platform and compiler options to <command>configure</command> script. You can also consult the INSTALL file for generic installation instructions.
</para>
</section>
</chapter>
<chapter id="usage">
<title>Usage</title>
<section id="general_syntax">
<title>General syntax</title>
<para>
The general syntax for sysbench is as follows:
<screen>
sysbench <emphasis>[common-options]</emphasis> --test=<emphasis>name</emphasis> <emphasis>[test-options]</emphasis> <emphasis>command</emphasis>
</screen>
See <xref linkend="common_options"/> for a description of common options and documentation for particular test mode for a list
of test-specific options.
</para>
<para>
Below is a brief description of available commands and their purpose:
<variablelist>
<varlistentry>
<term><command>prepare</command></term>
<listitem>Performs preparative actions for those tests which need them, e.g. creating the necessary
files on disk for the <option>fileio</option> test, or filling the test database for the
<option>oltp</option> test.
</listitem>
</varlistentry>
<varlistentry>
<term><command>run</command></term>
<listitem>Runs the actual test specified with the <option>--test=<emphasis>name</emphasis></option> option.
</listitem>
</varlistentry>
<varlistentry>
<term><command>cleanup</command></term>
<listitem>Removes temporary data after the test run in those tests which create one.
</listitem>
</varlistentry>
<varlistentry>
<term><command>help</command></term>
<listitem>Displays usage information for a test specified with the
<option>--test=<emphasis>name</emphasis></option> option.
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Also you can use <command>sysbench help</command> to display the brief usage summary and the list of available test modes.
</para>
</section>
<section id="common_options">
<title>General command line options</title>
<para>
The table below lists the supported common options, their descriptions and default values:
</para>
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--num-threads</option></entry><entry>The total number of worker threads to create</entry><entry>1</entry></row>
<row><entry><option>--max-requests</option></entry><entry>Limit for total number of requests. 0 means unlimited</entry><entry>10000</entry></row>
<row><entry><option>--max-time</option></entry><entry>Limit for total execution time in seconds. 0 (default) means unlimited</entry><entry>0</entry></row>
<row><entry><option>--thread-stack-size</option></entry><entry>Size of stack for each thread</entry><entry>32K</entry></row>
<row><entry><option>--init-rng</option></entry><entry>Specifies if random numbers generator should be initialized from timer before the test start</entry><entry>off</entry></row>
<row><entry><option>--report-interval</option></entry><entry>Periodically report intermediate statistics with a specified interval in seconds. Note that statistics produced by this option is per-interval rather than cumulative. 0 disables intermediate reports</entry><entry>0</entry></row>
<row><entry><option>--test</option></entry><entry>Name of the test mode to run</entry><entry><emphasis>Required</emphasis></entry></row>
<row><entry><option>--debug</option></entry><entry>Print more debug info</entry><entry>off</entry></row>
<row><entry><option>--validate</option></entry><entry>Perform
validation of test results where possible </entry><entry>off</entry></row>
<row><entry><option>--help</option></entry><entry>Print help on general syntax or on a test mode specified with --test, and exit</entry><entry>off</entry></row>
<row><entry><option>--verbosity</option></entry><entry>Verbosity level (0 - only critical messages, 5 - debug)</entry><entry>4</entry></row>
<row><entry><option>--percentile</option></entry>
<entry>
<para>
sysbench measures execution times for all processed
requests to display statistical information like minimal, average and
maximum execution time. For most benchmarks it is also useful to know
a request execution time value matching some percentile (e.g. 95%
percentile means we should drop 5% of the most long requests and
choose the maximal value from the remaining ones).
</para>
<para>
This option allows to specify a percentile rank of query
execution times to count
</para>
</entry>
<entry>95</entry></row>
<row><entry><option>--validate</option></entry><entry>Perform validation of test results where possible</entry><entry>off</entry></row>
</tbody>
</tgroup>
</informaltable>
<para>
Note that numerical values for all <emphasis>size</emphasis> options
(like <option>--thread-stack-size</option> in this table) may be
specified by appending the corresponding multiplicative suffix (K for
kilobytes, M for megabytes, G for gigabytes and T for terabytes).
</para>
</section>
<section id="test_modes">
<title>Test modes</title>
This section gives a detailed description for each test mode available
in sysbench.
<section id="cpu_mode">
<title><option>cpu</option></title>
</section>
<para>
The <option>cpu</option> is one of the most simple benchmarks in
sysbench. In this mode each request consists in calculation of prime numbers up to a value
specified by the <option>--cpu-max-primes</option> option. All calculations are performed using 64-bit integers.
</para>
<para>
Each thread executes the requests concurrently until either the total number of requests or the total execution
time exceed the limits specified with the common command line options.
</para>
<para>
Example:
<screen>
sysbench --test=cpu --cpu-max-prime=20000 run
</screen>
</para>
<section id="threads_mode">
<title><option>threads</option></title>
</section>
<para>
This test mode was written to benchmark scheduler performance, more specifically the cases
when a scheduler has a large number of threads competing for some set of mutexes.
</para>
<para>
sysbench creates a specified number of threads and a specified number of mutexes. Then each thread
starts running the requests consisting of locking the mutex, yielding the CPU, so the thread is
placed in the run queue by the scheduler, then unlocking the mutex when the thread is rescheduled back
to execution. For each request, the above actions are run several times in a loop, so the more iterations
is performed, the more concurrency is placed on each mutex.
</para>
<para>
The following options are available in this test mode:
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--thread-yields</option></entry><entry>Number of <emphasis>lock/yield/unlock</emphasis> loops to execute per each request</entry><entry>1000</entry></row>
<row><entry><option>--thread-locks</option></entry><entry>Number of mutexes to create</entry><entry>8</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
<para>
Example:
<screen>
sysbench --num-threads=64 --test=threads --thread-yields=100 --thread-locks=2 run
</screen>
</para>
<section id="mutex_mode">
<title><option>mutex</option></title>
</section>
<para>
This test mode was written to emulate a situation when all threads run concurrently most of the time,
acquiring the mutex lock only for a short period of time (incrementing a global variable). So the purpose
of this benchmarks is to examine the performance of mutex implementation.
</para>
<para>
The following options are available in this test mode:
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--mutex-num</option></entry><entry>Number of mutexes. The actual mutex to lock is chosen randomly before each lock</entry><entry>4096</entry></row>
<row><entry><option>--mutex-locks</option></entry><entry>Number of mutex locks to acquire per each request</entry><entry>50000</entry></row>
<row><entry><option>--mutex-loops</option></entry><entry>Number of iterations for an empty loop to perform before acquiring the lock</entry><entry>10000</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
<section id="memory_mode">
<title><option>memory</option></title>
<para>
This test mode can be used to benchmark sequential memory reads or writes. Depending on command line
options each thread can access either a global or a local block for all memory operations.
</para>
<para>
The following options are available in this test mode:
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--memory-block-size</option></entry><entry>Size of memory block to use</entry><entry>1K</entry></row>
<row><entry><option>--memory-scope</option></entry><entry>
Possible values: <option>global</option>, <option>local</option>. Specifies whether each thread will
use a globally allocated memory block, or a local one.
</entry><entry>global</entry></row>
<row><entry><option>--memory-total-size</option></entry><entry>Total size of data to transfer</entry><entry>100G</entry></row>
<row><entry><option>--memory-oper</option></entry><entry>
Type of memory operations. Possible values: <option>read</option>, <option>write</option>.
</entry><entry>100G</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
</section>
<section id="fileio_mode">
<title><option>fileio</option></title>
<para>
This test mode can be used to produce various kinds of file I/O workloads. At the <option>prepare</option>
stage sysbench creates a specified number of files with a specified total size, then at the <option>run</option>
stage, each thread performs specified I/O operations on this set of files.
</para>
<para>
When the global <option>--validate</option> option is used with the <option>fileio</option> test mode, sysbench
performs checksums validation on all data read from the disk. On each write operation the block is filled with random values,
then the checksum is calculated
and stored in the block along with the offset of this block within a file. On each read operation the block is validated
by comparing the stored offset with the real offset, and the stored checksum with the real calculated checksum.
</para>
<para>
The following I/O operations are supported:
<variablelist>
<varlistentry>
<term><command>seqwr</command></term>
<listitem>sequential write
</listitem>
</varlistentry>
<varlistentry>
<term><command>seqrewr</command></term>
<listitem>sequential rewrite
</listitem>
</varlistentry>
<varlistentry>
<term><command>seqrd</command></term>
<listitem>sequential read
</listitem>
</varlistentry>
<varlistentry>
<term><command>rndrd</command></term>
<listitem>random read
</listitem>
</varlistentry>
<varlistentry>
<term><command>rndwr</command></term>
<listitem>random write
</listitem>
</varlistentry>
<varlistentry>
<term><command>rndrw</command></term>
<listitem>combined random read/write
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Also, the following file access modes can be specified, if the underlying platform supports them:
<variablelist>
<varlistentry>
<term>Asynchronous I/O mode</term>
<listitem>
At the moment only Linux AIO implementation is supported. When running in asynchronous mode,
sysbench queues a specified number of I/O requests using Linux AIO API, then waits for
at least one of submitted requests to complete. After that a new series of I/O requests
is submitted.
</listitem>
</varlistentry>
<varlistentry>
<term>Slow <option>mmap()</option> mode</term>
<listitem>In this mode sysbench will use <option>mmap</option>'ed I/O. However, a separate
<option>mmap</option> will be used for each I/O request due to the limitation of 32-bit
architectures (we cannot <option>mmap()</option> the whole file, as its size migth possibly
exceed the maximum of 2 GB of the process address space).
</listitem>
</varlistentry>
<varlistentry>
<term>Fast <option>mmap()</option> mode</term>
<listitem>On 64-bit architectures it is possible to <option>mmap()</option> the whole file
into the process address space, avoiding the limitation of 2 GB on 32-bit platforms.
</listitem>
</varlistentry>
<varlistentry>
<term>Using <option>fdatasync()</option> instead of <option>fsync()</option></term>
Flush only data buffers, but not the metadata.
<listitem>
</listitem>
</varlistentry>
<varlistentry>
<term>Additional flags to <option>open(2)</option></term>
<listitem>sysbench can use additional flags to <option>open(2)</option>, such as <option>O_SYNC</option>,
<option>O_DSYNC</option> and <option>O_DIRECT</option>.
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Below is a list of test-specific option for the <command>fileio</command> mode:
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--file-num</option></entry><entry>Number of files to create</entry><entry>128</entry></row>
<row><entry><option>--file-block-size</option></entry><entry>
Block size to use in all I/O operations
</entry><entry>16K</entry></row>
<row><entry><option>--file-total-size</option></entry><entry>Total size of files</entry><entry>2G</entry></row>
<row><entry><option>--file-test-mode</option></entry><entry>
Type of workload to produce. Possible values: <option>seqwr</option>, <option>seqrewr</option>,
<option>seqrd</option>, <option>rndrd</option>, <option>rndwr</option>, <option>rndwr</option> (see above)
</entry><entry><emphasis>required</emphasis></entry></row>
<row><entry><option>--file-io-mode</option></entry><entry>
I/O mode. Possible values: <option>sync</option>, <option>async</option>, <option>map</option>,
</entry><entry>sync</entry></row>
<row><entry><option>--file-async-backlog</option></entry><entry>
Number of asynchronous operations to queue per thread (only for <option>--file-io-mode=async</option>, see above)
</entry><entry>128</entry></row>
<row><entry><option> --file-extra-flags</option></entry><entry>
Additional flags to use with <option>open(2)</option>
</entry><entry></entry></row>
<row><entry><option>--file-fsync-freq</option></entry><entry>
Do <option>fsync()</option> after this number of requests (0 - don't use <option>fsync()</option>)
</entry><entry>100</entry></row>
<row><entry><option>--file-fsync-all</option></entry><entry>
Do <option>fsync()</option> after each write operation
</entry><entry>no</entry></row>
<row><entry><option>--file-fsync-end</option></entry><entry>
Do <option>fsync()</option> at the end of the test
</entry><entry>yes</entry></row>
<row><entry><option>--file-fsync-mode</option></entry><entry>
Which method to use for synchronization. Possible values: <option>fsync</option>, <option>fdatasync</option> (see above)
</entry><entry>fsync</entry></row>
<row><entry><option>--file-merged-requests</option></entry><entry>
Merge at most this number of I/O requests if possible (0 - don't merge)
</entry><entry>0</entry></row>
<row><entry><option>--file-rw-ratio</option></entry><entry>
reads/writes ration for combined random read/write test
</entry><entry>1.5</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
<para>
Usage example:
<screen>
$ sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw prepare
$ sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw run
$ sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw cleanup
</screen>
In the above example the first command creates 128 files with the total size of 3 GB in the current directory, the
second command runs the actual benchmark and displays the results upon completion, and the third one removes the files
used for the test.
</para>
</section>
<section id="database_mode">
<title><option>oltp</option></title>
</section>
<para>
This test mode was written to benchmark a real database performance. At the <command>prepare</command> stage
the following table is created in the specified database (<option>sbtest</option> by default):
<screen>
CREATE TABLE `sbtest` (
`id` int(10) unsigned NOT NULL auto_increment,
`k` int(10) unsigned NOT NULL default '0',
`c` char(120) NOT NULL default '',
`pad` char(60) NOT NULL default '',
PRIMARY KEY (`id`),
KEY `k` (`k`);
</screen>
Then this table is filled with a specified number of rows.
</para>
<para>
The following execution modes are available at the <command>run</command> stage:
<variablelist>
<varlistentry>
<term>Simple</term>
<listitem>
<para>
In this mode each thread runs simple queries of the following form:
<screen> SELECT c FROM sbtest WHERE id=<emphasis>N</emphasis> </screen>
where <emphasis>N</emphasis> takes a random value in range 1..<emphasis>&lt;table size&gt;</emphasis>
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Advanced transactional</term>
<listitem>
<para>
Each thread performs transactions on the test table. If the test table and database support transactions
(e.g. InnoDB engine in MySQL), then <option>BEGIN</option>/<option>COMMIT</option> statements will be used
to start/stop a transaction. Otherwise, sysbench will use <option>LOCK TABLES</option>/<option>UNLOCK TABLES
</option> statements (e.g. for MyISAM engine in MySQL). If some rows are deleted in a transaction,
the same rows will be inserted within the same transaction, so this test mode does not destruct any data
in the test table and can be run multiple times on the same table.
</para>
Depending on the command line options, each transaction may contain the following statements:
<itemizedlist>
<listitem>Point queries: <screen>SELECT c FROM sbtest WHERE id=<emphasis>N</emphasis></screen></listitem>
<listitem>
Range queries: <screen>SELECT c FROM sbtest WHERE id BETWEEN <emphasis>N</emphasis> AND <emphasis>M</emphasis> </screen> </listitem>
<listitem>
Range SUM() queries: <screen>SELECT SUM(K) FROM sbtest WHERE id BETWEEN <emphasis>N</emphasis> and <emphasis>M</emphasis></screen></listitem>
<listitem>Range ORDER BY queries:<screen>SELECT c FROM sbtest WHERE id between <emphasis>N</emphasis> and <emphasis>M</emphasis> ORDER BY c</screen></listitem>
<listitem>Range DISTINCT queries:<screen>SELECT DISTINCT c FROM sbtest WHERE id BETWEEN <emphasis>N</emphasis> and <emphasis>M</emphasis> ORDER BY c</screen> </listitem>
<listitem>UPDATEs on index column:<screen>UPDATE sbtest SET k=k+1 WHERE id=<emphasis>N</emphasis> </screen> </listitem>
<listitem>UPDATEs on non-index column:<screen>UPDATE sbtest SET c=<emphasis>N</emphasis> WHERE id=<emphasis>M</emphasis> </screen> </listitem>
<listitem>DELETE queries:<screen>DELETE FROM sbtest WHERE id=<emphasis>N</emphasis> </screen> </listitem>
<listitem>INSERT queries:<screen>INSERT INTO sbtest VALUES (<emphasis>...</emphasis>) </screen> </listitem>
</itemizedlist>
</listitem>
</varlistentry>
<varlistentry>
<term>Non-transactional</term>
<listitem>
<para>
This mode is similar to <command>Simple</command>, but you can also choose the query to run. Note that unlike the
<command>Advanced transactional</command> mode, this one does not preserve the test table between requests, so
you should recreate it with the appropriate <command>cleanup</command>/<command>prepare</command> commands between
consecutive benchmarks.
</para>
<para>
Below is a list of possible queries:
<itemizedlist>
<listitem>
Point queries:
<screen>SELECT pad FROM sbtest WHERE id=<emphasis>N</emphasis></screen>
</listitem>
<listitem>
UPDATEs on index column:
<screen>UPDATE sbtest SET k=k+1 WHERE id=<emphasis>N</emphasis></screen>
</listitem>
<listitem>
UPDATEs on non-index column:
<screen>UPDATE sbtest SET c=<emphasis>N</emphasis> WHERE id=<emphasis>M</emphasis></screen>
</listitem>
<listitem>
DELETE queries:
<screen>DELETE FROM sbtest WHERE id=<emphasis>N</emphasis></screen>
The generated row IDs are unique over each test run, so no row is deleted twice.
</listitem>
<listitem>
INSERT queries:
<screen>INSERT INTO sbtest (k, c, pad) VALUES(<emphasis>N</emphasis>, <emphasis>M</emphasis>, <emphasis>S</emphasis>)</screen>
</listitem>
</itemizedlist>
</para>
</listitem>
</varlistentry>
</variablelist>
</para>
<para>
Below is a list of options available for the database test mode:
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--oltp-test-mode</option></entry><entry>Execution mode (see above). Possible values: <option>simpe</option> (simple), <option>complex</option> (advanced transactional) and <option>nontrx</option> (non-transactional)</entry><entry><option>complex</option></entry></row>
<row><entry><option>--oltp-read-only</option></entry><entry>
Read-only mode. No <option>UPDATE</option>, <option>DELETE</option> or <option>INSERT</option> queries will be performed.
</entry><entry>off</entry></row>
<row><entry><option>--oltp-reconnect</option></entry><entry>
Re-connect to serveron each transaction.
</entry><entry>off</entry></row>
<row><entry><option>--oltp-range-size</option></entry><entry>Range size for range queries</entry><entry>100</entry></row>
<row><entry><option>--oltp-point-selects</option></entry><entry>
Number of point select queries in a single transaction
</entry><entry>10</entry></row>
<row><entry><option>--oltp-simple-ranges</option></entry><entry>
Number of simple range queries in a single transaction
</entry><entry>1</entry></row>
<row><entry><option>--oltp-sum-ranges</option></entry><entry>
Number of SUM range queries in a single transaction
</entry><entry>1</entry></row>
<row><entry><option>--oltp-order-ranges</option></entry><entry>
Number of ORDER range queries in a single transaction
</entry><entry>1</entry></row>
<row><entry><option>--oltp-distinct-ranges</option></entry><entry>
Number of DISTINCT range queries in a single transaction
</entry><entry>1</entry></row>
<row><entry><option>--oltp-index-updates</option></entry><entry>
Number of index UPDATE queries in a single transaction
</entry><entry>1</entry></row>
<row><entry><option>--oltp-non-index-updates</option></entry><entry>
Number of non-index UPDATE queries in a single transaction
</entry><entry>1</entry></row>
<row><entry><option> --oltp-nontrx-mode</option></entry><entry>
Type of queries for non-transactional execution mode (see above). Possible values: <option>select</option>,
<option>update_key</option>, <option>update_nokey</option>, <option>insert</option>, <option>delete</option>.
</entry><entry><option>select</option></entry></row>
<row><entry><option>--oltp-connect-delay</option></entry><entry>
Time in microseconds to sleep after each connection to database
</entry><entry>10000</entry></row>
<row><entry><option>--oltp-user-delay-min</option></entry><entry>
Minimum time in microseconds to sleep after each request
</entry><entry>0</entry></row>
<row><entry><option>--oltp-user-delay-max</option></entry><entry>
Maximum time in microseconds to sleep after each request
</entry><entry>0</entry></row>
<row><entry><option>--oltp-table-name</option></entry><entry>
Name of the test table
</entry><entry>sbtest</entry></row>
<row><entry><option>--oltp-table-size</option></entry><entry>
Number of rows in the test table
</entry><entry>10000</entry></row>
<row><entry><option>--oltp-dist-type</option></entry><entry>
<para>
Distribution of random numbers. Possible values: <option>uniform</option> (uniform distribution),
<option>gauss</option> (gaussian distribution) and <option>special</option>.
</para>
<para>
With special distribution a specified percent of numbers is generated in a specified percent of cases (see options below).
</para>
</entry><entry><option>special</option></entry></row>
<row><entry><option>--oltp-dist-pct</option></entry><entry>
Percentage of values to be treated as 'special' (for special distribution)
</entry><entry>1</entry></row>
<row><entry><option>--oltp-dist-res</option></entry><entry>
Percentage of cases when 'special' values are generated (for special distribution)
</entry><entry>75</entry></row>
<row><entry><option>--db-ps-mode</option></entry><entry>
If the database driver supports Prepared Statements API, sysbench will use server-side prepared statements for all queries
where possible. Otherwise, client-side (or emulated) prepared statements will be used. This option allows to force using
emulation even when PS API is available. Possible values: <option>disable</option>, <option>auto</option>.
</entry><entry><option>auto</option></entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
<para>
Also, each database driver may provide its own options. Currently only MySQL driver is available. Below is a list of MySQL-specific options:
<informaltable frame="all">
<tgroup cols='3'>
<tbody>
<row><entry><emphasis>Option</emphasis></entry><entry><emphasis>Description</emphasis></entry><entry><emphasis>Default value</emphasis></entry></row>
<row><entry><option>--mysql-host</option></entry>
<entry>
<para>
MySQL server host.
</para>
<para>
Starting from version 0.4.5 you may specify a list of hosts separated by commas. In this case sysbench will distribute connections between specified MySQL hosts on a round-robin basis. Note that all connection ports and passwords must be the same on all hosts. Also, databases and tables must be prepared explicitely on each host before executing the benchmark.
</para>
</entry><entry><option>localhost</option></entry></row>
<row><entry><option>--mysql-port</option></entry><entry>
MySQL server port (in case TCP/IP connection should be used)
</entry><entry>3306</entry></row>
<row><entry><option>--mysql-socket</option></entry><entry>Unix socket file to communicate with the MySQL server</entry><entry></entry></row>
<row><entry><option>--mysql-user</option></entry><entry>
MySQL user
</entry><entry>user</entry></row>
<row><entry><option>--mysql-password</option></entry><entry>
MySQL password
</entry><entry></entry></row>
<row><entry><option>--mysql-db</option></entry><entry>
MySQL database name. Note sysbench will not automatically create this database. You should create it manually and grant
the appropriate privileges to a user which will be used to access the test table.
</entry><entry>sbtest</entry></row>
<row><entry><option>--mysql-table-type</option></entry><entry>
Type of the test table. Possible values: <option>myisam</option>, <option>innodb</option>, <option>heap</option>,
<option>ndbcluster</option>, <option>bdb</option>.
</entry><entry>innodb</entry></row>
<row><entry><option>--myisam-max-rows</option></entry><entry>
MAX_ROWS option for MyISAM tables (required for big tables)
</entry><entry>1000000</entry></row>
</tbody>
</tgroup>
</informaltable>
</para>
<para>
Example usage:
<screen>
$ sysbench --test=oltp --mysql-table-engine=myisam --oltp-table-size=1000000 --mysql-socket=/tmp/mysql.sock prepare
$ sysbench --num-threads=16 --max-requests=100000 --test=oltp --oltp-table-size=1000000 --mysql-socket=/tmp/mysql.sock --oltp-read-only=on run
</screen>
The first command will create a MyISAM table 'sbtest' in a database 'sbtest' on a MySQL server using <option>/tmp/mysql.sock</option> socket, then fill this table with 1M records. The second command will run the actual benchmark with 16 client threads, limiting the total number of request by 100,000.
</para>
</section>
</chapter>
</book>

View File

@ -0,0 +1,18 @@
# Copyright (C) 2008 MySQL AB
# Copyright (C) 2008 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
EXTRA_DIST=catalog.xml.in xhtml-chunk.xsl xhtml-common.xsl xhtml.xsl

View File

@ -0,0 +1,16 @@
<?xml version="1.0"?>
<!DOCTYPE catalog PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<nextCatalog catalog="@XML_CATALOG@" />
@CAT_ENTRY_START@
<uri name="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"
uri="@DOCBOOK_ROOT@/xhtml/docbook.xsl"/>
<uri name="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"
uri="@DOCBOOK_ROOT@/xhtml/chunk.xsl"/>
@CAT_ENTRY_END@
<uri name="xsl/xhtml-common.xsl" uri="@top_srcdir@/doc/xsl/xhtml-common.xsl"/>
</catalog>

View File

@ -0,0 +1,52 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/chunk.xsl"/>
<xsl:import href="xhtml-common.xsl"/>
<xsl:template name="process-chunk">
<xsl:param name="prev" select="."/>
<xsl:param name="next" select="."/>
<xsl:variable name="ischunk">
<xsl:call-template name="chunk"/>
</xsl:variable>
<xsl:variable name="chunkfn">
<xsl:if test="$ischunk='1'">
<xsl:apply-templates mode="chunk-filename" select="."/>
</xsl:if>
</xsl:variable>
<xsl:if test="$ischunk='0'">
<xsl:message>
<xsl:text>Error </xsl:text>
<xsl:value-of select="name(.)"/>
<xsl:text> is not a chunk!</xsl:text>
</xsl:message>
</xsl:if>
<xsl:variable name="filename">
<xsl:call-template name="make-relative-filename">
<xsl:with-param name="base.dir" select="$base.dir"/>
<xsl:with-param name="base.name" select="$chunkfn"/>
</xsl:call-template>
</xsl:variable>
<!-- FIXME: use Strict when the problems with width on td/th are
sorted out. Not yet. -->
<xsl:call-template name="write.chunk.with.doctype">
<xsl:with-param name="filename" select="$filename"/>
<xsl:with-param name="indent" select="'yes'"/>
<xsl:with-param name="doctype-public">-//W3C//DTD XHTML 1.0 Transitional//EN</xsl:with-param>
<xsl:with-param name="doctype-system">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd</xsl:with-param>
<xsl:with-param name="content">
<xsl:call-template name="chunk-element-content">
<xsl:with-param name="prev" select="$prev"/>
<xsl:with-param name="next" select="$next"/>
</xsl:call-template>
</xsl:with-param>
</xsl:call-template>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,50 @@
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:param name="use.id.as.filename" select="1"/>
<xsl:param name="section.autolabel" select="1"/>
<xsl:param name="chapter.autolabel" select="1"/>
<xsl:param name="ulink.target" select="''"/>
<!-- Custom template for programlisting, screen and synopsis to generate a gray
background to the item. -->
<xsl:template match="programlisting|screen|synopsis">
<xsl:param name="suppress-numbers" select="'0'"/>
<xsl:variable name="vendor" select="system-property('xsl:vendor')"/>
<xsl:variable name="id"><xsl:call-template name="object.id"/></xsl:variable>
<xsl:if test="@id">
<a href="{$id}"/>
</xsl:if>
<xsl:choose>
<xsl:when test="$suppress-numbers = '0'
and @linenumbering = 'numbered'
and $use.extensions != '0'
and $linenumbering.extension != '0'">
<xsl:variable name="rtf">
<xsl:apply-templates/>
</xsl:variable>
<!-- Change the color background color in the line below. -->
<table border="0" style="background: #E0E0E0;" width="90%">
<tr><td>
<pre class="{name(.)}">
<xsl:call-template name="number.rtf.lines">
<xsl:with-param name="rtf" select="$rtf"/>
</xsl:call-template>
</pre>
</td></tr></table>
</xsl:when>
<xsl:otherwise>
<!-- Change the color background color in the line below. -->
<table border="0" style="background: #E0E0E0;" width="90%">
<tr><td>
<pre class="{name(.)}">
<xsl:apply-templates/>
</pre>
</td></tr></table>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>

View File

@ -0,0 +1,13 @@
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:doc="http://nwalsh.com/xsl/documentation/1.0" version="1.0">
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"/>
<xsl:import href="xhtml-common.xsl"/>
<xsl:output method="xml" encoding="ISO-8859-1" indent="yes"
doctype-public="-//W3C//DTD XHTML 1.0 Strict//EN"
doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"
/>
</xsl:stylesheet>

View File

@ -0,0 +1,294 @@
#!/bin/sh
#
# install - install a program, script, or datafile
#
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""
while [ x"$1" != x ]; do
case $1 in
-c) instcmd=$cpprog
shift
continue;;
-d) dir_arg=true
shift
continue;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;
-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;
*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done
if [ x"$src" = x ]
then
echo "$0: no input file specified" >&2
exit 1
else
:
fi
if [ x"$dir_arg" != x ]; then
dst=$src
src=""
if [ -d "$dst" ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "$0: $src does not exist" >&2
exit 1
fi
if [ x"$dst" = x ]
then
echo "$0: no destination specified" >&2
exit 1
else
:
fi
# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic
if [ -d "$dst" ]
then
dst=$dst/`basename "$src"`
else
:
fi
fi
## this sed command emulates the dirname command
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script
# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS
pathcomp=''
while [ $# -ne 0 ] ; do
pathcomp=$pathcomp$1
shift
if [ ! -d "$pathcomp" ] ;
then
$mkdirprog "$pathcomp"
else
:
fi
pathcomp=$pathcomp/
done
fi
if [ x"$dir_arg" != x ]
then
$doit $instcmd "$dst" &&
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
else
# If we're going to rename the final executable, determine the name now.
if [ x"$transformarg" = x ]
then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename |
sed $transformarg`$transformbasename
fi
# don't allow the sed command to completely eliminate the filename
if [ x"$dstfile" = x ]
then
dstfile=`basename "$dst"`
else
:
fi
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up temp files at exit.
trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15
# Move or copy the file name to the temp name
$doit $instcmd "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.
if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&
# Now remove or move aside any old file at destination location. We try this
# two ways since rm can't unlink itself on some systems and the destination
# file might be busy for other reasons. In this case, the final cleanup
# might fail but the new file should still install successfully.
{
if [ -f "$dstdir/$dstfile" ]
then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
{
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
fi &&
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit
}

View File

@ -0,0 +1,38 @@
dnl ---------------------------------------------------------------------------
dnl Macro: AC_CHECK_AIO
dnl Check for Linux AIO availability on the target system
dnl Also, check the version of libaio library (at the moment, there are two
dnl versions with incompatible interfaces).
dnl ---------------------------------------------------------------------------
AC_DEFUN([AC_CHECK_AIO],[
if test x$enable_aio = xyes; then
AC_CHECK_HEADER([libaio.h],
[AC_DEFINE(HAVE_LIBAIO_H,1,[Define to 1 if your system has <libaio.h> header file])],
[enable_aio=no])
fi
if test x$enable_aio = xyes; then
AC_CHECK_LIB([aio], [io_queue_init], , [enable_aio=no])
fi
if test x$enable_aio = xyes; then
AC_MSG_CHECKING(if io_getevents() has an old interface)
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#ifdef HAVE_LIBAIO_H
# include <libaio.h>
#endif
struct io_event event;
io_context_t ctxt;
]],
[[
(void)io_getevents(ctxt, 1, &event, NULL);
]] )
], [
AC_DEFINE([HAVE_OLD_GETEVENTS], 1, [Define to 1 if libaio has older getevents() interface])
AC_MSG_RESULT(yes)
],
[AC_MSG_RESULT(no)]
)
fi
])

View File

@ -0,0 +1,71 @@
dnl ---------------------------------------------------------------------------
dnl Macro: AC_CHECK_PGSQL
dnl First check for custom PostgreSQL paths in --with-pgsql-* options.
dnl If some paths are missing, check if pg_config exists.
dnl ---------------------------------------------------------------------------
AC_DEFUN([AC_CHECK_PGSQL],[
# Check for custom includes path
if test [ -z "$ac_cv_pgsql_includes" ]
then
AC_ARG_WITH([pgsql-includes],
AC_HELP_STRING([--with-pgsql-includes], [path to PostgreSQL header files]),
[ac_cv_pgsql_includes=$withval])
fi
if test [ -n "$ac_cv_pgsql_includes" ]
then
AC_CACHE_CHECK([PostgreSQL includes], [ac_cv_pgsql_includes], [ac_cv_pgsql_includes=""])
PGSQL_CFLAGS="-I$ac_cv_pgsql_includes"
fi
# Check for custom library path
if test [ -z "$ac_cv_pgsql_libs" ]
then
AC_ARG_WITH([pgsql-libs],
AC_HELP_STRING([--with-pgsql-libs], [path to PostgreSQL libraries]),
[ac_cv_pgsql_libs=$withval])
fi
if test [ -n "$ac_cv_pgsql_libs" ]
then
AC_CACHE_CHECK([PostgreSQL libraries], [ac_cv_pgsql_libs], [ac_cv_pgsql_libs=""])
PGSQL_LIBS="-L$ac_cv_pgsql_libs -lpq"
fi
# If some path is missing, try to autodetermine with pgsql_config
if test [ -z "$ac_cv_pgsql_includes" -o -z "$ac_cv_pgsql_libs" ]
then
if test [ -z "$pgconfig" ]
then
AC_PATH_PROG(pgconfig,pg_config)
fi
if test [ -z "$pgconfig" ]
then
AC_MSG_ERROR([pg_config executable not found
********************************************************************************
ERROR: cannot find PostgreSQL libraries. If you want to compile with PosgregSQL support,
you must either specify file locations explicitly using
--with-pgsql-includes and --with-pgsql-libs options, or make sure path to
pg_config is listed in your PATH environment variable. If you want to
disable PostgreSQL support, use --without-pgsql option.
********************************************************************************
])
else
if test [ -z "$ac_cv_pgsql_includes" ]
then
AC_MSG_CHECKING(PostgreSQL C flags)
PGSQL_CFLAGS="-I`${pgconfig} --includedir`"
AC_MSG_RESULT($PGSQL_CFLAGS)
fi
if test [ -z "$ac_cv_pgsql_libs" ]
then
AC_MSG_CHECKING(PostgreSQL linker flags)
PGSQL_LIBS="-L`${pgconfig} --libdir` -lpq"
AC_MSG_RESULT($PGSQL_LIBS)
fi
fi
fi
])

View File

@ -0,0 +1,276 @@
##### http://autoconf-archive.cryp.to/acx_pthread.html
#
# SYNOPSIS
#
# ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])
#
# DESCRIPTION
#
# This macro figures out how to build C programs using POSIX threads.
# It sets the PTHREAD_LIBS output variable to the threads library and
# linker flags, and the PTHREAD_CFLAGS output variable to any special
# C compiler flags that are needed. (The user can also force certain
# compiler flags/libs to be tested by setting these environment
# variables.)
#
# Also sets PTHREAD_CC to any special C compiler that is needed for
# multi-threaded programs (defaults to the value of CC otherwise).
# (This is necessary on AIX to use the special cc_r compiler alias.)
#
# NOTE: You are assumed to not only compile your program with these
# flags, but also link it with them as well. e.g. you should link
# with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS
# $LIBS
#
# If you are only building threads programs, you may wish to use
# these variables in your default LIBS, CFLAGS, and CC:
#
# LIBS="$PTHREAD_LIBS $LIBS"
# CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# CC="$PTHREAD_CC"
#
# In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute
# constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to
# that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).
#
# ACTION-IF-FOUND is a list of shell commands to run if a threads
# library is found, and ACTION-IF-NOT-FOUND is a list of commands to
# run it if it is not found. If ACTION-IF-FOUND is not specified, the
# default action will define HAVE_PTHREAD.
#
# Please let the authors know if this macro fails on any platform, or
# if you have any other suggestions or comments. This macro was based
# on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/)
# (with help from M. Frigo), as well as ac_pthread and hb_pthread
# macros posted by Alejandro Forero Cuervo to the autoconf macro
# repository. We are also grateful for the helpful feedback of
# numerous users.
#
# LAST MODIFICATION
#
# 2006-05-29
#
# COPYLEFT
#
# Copyright (c) 2006 Steven G. Johnson <stevenj@alum.mit.edu>
#
# 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.
#
# As a special exception, the respective Autoconf Macro's copyright
# owner gives unlimited permission to copy, distribute and modify the
# configure scripts that are the output of Autoconf when processing
# the Macro. You need not follow the terms of the GNU General Public
# License when using or distributing such scripts, even though
# portions of the text of the Macro appear in them. The GNU General
# Public License (GPL) does govern all other use of the material that
# constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the
# Autoconf Macro released by the Autoconf Macro Archive. When you
# make and distribute a modified version of the Autoconf Macro, you
# may extend this special exception to the GPL to apply to your
# modified version as well.
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_PUSH([C])
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
# requires special compiler flags (e.g. on True64 or Sequent).
# It gets checked for in the link test anyway.
# First of all, check if the user has set any of the PTHREAD_LIBS,
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
# names; the ordering is very important because some systems
# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
# libraries is broken (non-POSIX).
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
# pthreads: AIX (must check this before -lpthread)
# none: in case threads are in libc; should be tried before -Kthread and
# other compiler flags to prevent continual compiler warnings
# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
# -pthreads: Solaris/gcc
# -mthreads: Mingw32/gcc, Lynx/gcc
# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
# doesn't hurt to check since this sometimes defines pthreads too;
# also defines -D_REENTRANT)
# ... -mt is also the pthreads flag for HP/aCC
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
# On Solaris (at least, for some versions), libc contains stubbed
# (non-functional) versions of the pthreads routines, so link-based
# tests will erroneously succeed. (We need to link with -pthreads/-mt/
# -lpthread.) (The stubs are missing pthread_cleanup_push, or rather
# a function called by this macro, so we could check for that, but
# who knows whether they'll stub that too in a future libc.) So,
# we'll just look for -pthreads and -lpthread first:
acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
;;
esac
if test x"$acx_pthread_ok" = xno; then
for flag in $acx_pthread_flags; do
case $flag in
none)
AC_MSG_CHECKING([whether pthreads work without any flags])
;;
-*)
AC_MSG_CHECKING([whether pthreads work with $flag])
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
;;
esac
save_LIBS="$LIBS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
# need a special flag -Kthread to make this header compile.)
# We check for pthread_join because it is in -lpthread on IRIX
# while pthread_create is in libc. We check for pthread_attr_init
# due to DEC craziness with -lpthreads. We check for
# pthread_cleanup_push because it is one of the few pthread
# functions on Solaris that doesn't have a non-functional libc stub.
# We try pthread_create on general principles.
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[pthread_t th; pthread_join(th, 0);
pthread_attr_init(0); pthread_cleanup_push(0, 0);
pthread_create(0,0,0,0); pthread_cleanup_pop(0); ]])],[acx_pthread_ok=yes],[])
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
break;
fi
PTHREAD_LIBS=""
PTHREAD_CFLAGS=""
done
fi
# Various other checks:
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[int attr=$attr; return attr;]])],[attr_name=$attr; break],[])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
PTHREAD_CFLAGS="$flag $PTHREAD_CFLAGS"
fi
LIBS="$save_LIBS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with xlc_r or cc_r
if test x"$GCC" != xyes; then
AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})
else
PTHREAD_CC=$CC
fi
else
PTHREAD_CC="$CC"
fi
AC_SUBST(PTHREAD_LIBS)
AC_SUBST(PTHREAD_CFLAGS)
AC_SUBST(PTHREAD_CC)
# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
if test x"$acx_pthread_ok" = xyes; then
ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])
:
else
acx_pthread_ok=no
$2
fi
AC_LANG_POP([])
])dnl ACX_PTHREAD

View File

@ -0,0 +1,74 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])
#
# DESCRIPTION
#
# Check whether the given FLAG works with the current language's compiler
# or gives an error. (Warnings, however, are ignored)
#
# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on
# success/failure.
#
# If EXTRA-FLAGS is defined, it is added to the current language's default
# flags (e.g. CFLAGS) when the check is done. The check is thus made with
# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to
# force the compiler to issue an error when a bad flag is given.
#
# INPUT gives an alternative input source to AC_COMPILE_IFELSE.
#
# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this
# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.
#
# LICENSE
#
# Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>
# Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 5
AC_DEFUN([AX_CHECK_COMPILE_FLAG],
[
AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl
AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [
ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS
_AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1"
AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],
[AS_VAR_SET(CACHEVAR,[yes])],
[AS_VAR_SET(CACHEVAR,[no])])
_AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])
AS_VAR_IF(CACHEVAR,yes,
[m4_default([$2], :)],
[m4_default([$3], :)])
AS_VAR_POPDEF([CACHEVAR])dnl
])dnl AX_CHECK_COMPILE_FLAGS

View File

@ -0,0 +1,65 @@
dnl ---------------------------------------------------------------------------
dnl Macro: AX_CHECK_DOCBOOK
dnl Check for availability of various DocBook utilities and perform necessary
dnl substitutions
dnl ---------------------------------------------------------------------------
AC_DEFUN([AX_CHECK_DOCBOOK], [
# It's just rude to go over the net to build
XSLTPROC_FLAGS=--nonet
DOCBOOK_ROOT=
for i in /etc/xml/catalog /usr/local/etc/xml/catalog /opt/local/etc/xml/catalog ;
do
if test -f $i; then
XML_CATALOG="$i"
fi
done
if test -z "$XML_CATALOG" ; then
for i in /usr/share/sgml/docbook/stylesheet/xsl/nwalsh /usr/share/sgml/docbook/xsl-stylesheets/ /opt/local/share/xsl/docbook-xsl/xhtml/ ;
do
if test -d "$i"; then
DOCBOOK_ROOT=$i
fi
done
# Last resort - try net
if test -z "$DOCBOOK_ROOT"; then
XSLTPROC_FLAGS=
fi
else
CAT_ENTRY_START='<!--'
CAT_ENTRY_END='-->'
fi
AC_CHECK_PROG(XSLTPROC,xsltproc,xsltproc,)
XSLTPROC_WORKS=no
if test -n "$XSLTPROC"; then
AC_MSG_CHECKING([whether xsltproc works])
if test -n "$XML_CATALOG"; then
DB_FILE="http://docbook.sourceforge.net/release/xsl/current/xhtml/docbook.xsl"
else
DB_FILE="$DOCBOOK_ROOT/docbook.xsl"
fi
$XSLTPROC $XSLTPROC_FLAGS $DB_FILE >/dev/null 2>&1 << END
<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN" "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
<book id="test">
</book>
END
if test "$?" = 0; then
XSLTPROC_WORKS=yes
fi
AC_MSG_RESULT($XSLTPROC_WORKS)
fi
AM_CONDITIONAL(have_xsltproc, test "$XSLTPROC_WORKS" = "yes")
AC_SUBST(XML_CATALOG)
AC_SUBST(XSLTPROC_FLAGS)
AC_SUBST(DOCBOOK_ROOT)
AC_SUBST(CAT_ENTRY_START)
AC_SUBST(CAT_ENTRY_END)
])

View File

@ -0,0 +1,87 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_COMPILER_VENDOR
#
# DESCRIPTION
#
# Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,
# hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,
# watcom, etc. The vendor is returned in the cache variable
# $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2008 Matteo Frigo
#
# 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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 16
AC_DEFUN([AX_COMPILER_VENDOR],
[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,
dnl Please add if possible support to ax_compiler_version.m4
[# note: don't check for gcc first since some other compilers define __GNUC__
vendors="intel: __ICC,__ECC,__INTEL_COMPILER
ibm: __xlc__,__xlC__,__IBMC__,__IBMCPP__
pathscale: __PATHCC__,__PATHSCALE__
clang: __clang__
cray: _CRAYC
fujitsu: __FUJITSU
gnu: __GNUC__
sun: __SUNPRO_C,__SUNPRO_CC
hp: __HP_cc,__HP_aCC
dec: __DECC,__DECCXX,__DECC_VER,__DECCXX_VER
borland: __BORLANDC__,__CODEGEARC__,__TURBOC__
comeau: __COMO__
kai: __KCC
lcc: __LCC__
sgi: __sgi,sgi
microsoft: _MSC_VER
metrowerks: __MWERKS__
watcom: __WATCOMC__
portland: __PGI
tcc: __TINYC__
unknown: UNKNOWN"
for ventest in $vendors; do
case $ventest in
*:) vendor=$ventest; continue ;;
*) vencpp="defined("`echo $ventest | sed 's/,/) || defined(/g'`")" ;;
esac
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[
#if !($vencpp)
thisisanerror;
#endif
])], [break])
done
ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`
])
])

View File

@ -0,0 +1,263 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])
#
# DESCRIPTION
#
# This macro tries to guess the "native" arch corresponding to the target
# architecture for use with gcc's -march=arch or -mtune=arch flags. If
# found, the cache variable $ax_cv_gcc_archflag is set to this flag and
# ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to
# "unknown" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is
# to add $ax_cv_gcc_archflag to the end of $CFLAGS.
#
# PORTABLE? should be either [yes] (default) or [no]. In the former case,
# the flag is set to -mtune (or equivalent) so that the architecture is
# only used for tuning, but the instruction set used is still portable. In
# the latter case, the flag is set to -march (or equivalent) so that
# architecture-specific instructions are enabled.
#
# The user can specify --with-gcc-arch=<arch> in order to override the
# macro's choice of architecture, or --without-gcc-arch to disable this.
#
# When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is
# called unless the user specified --with-gcc-arch manually.
#
# Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID
#
# (The main emphasis here is on recent CPUs, on the principle that doing
# high-performance computing on old hardware is uncommon.)
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2008 Matteo Frigo
# Copyright (c) 2014 Tsukasa Oi
# Copyright (c) 2017-2018 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 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 21
AC_DEFUN([AX_GCC_ARCHFLAG],
[AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_PROG_SED])
AC_REQUIRE([AX_COMPILER_VENDOR])
AC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],
ax_gcc_arch=$withval, ax_gcc_arch=yes)
AC_MSG_CHECKING([for gcc architecture flag])
AC_MSG_RESULT([])
AC_CACHE_VAL(ax_cv_gcc_archflag,
[
ax_cv_gcc_archflag="unknown"
if test "$GCC" = yes; then
if test "x$ax_gcc_arch" = xyes; then
ax_gcc_arch=""
if test "$cross_compiling" = no; then
case $host_cpu in
i[[3456]]86*|x86_64*|amd64*) # use cpuid codes
AX_GCC_X86_CPUID(0)
AX_GCC_X86_CPUID(1)
case $ax_cv_gcc_x86_cpuid_0 in
*:756e6547:6c65746e:49656e69) # Intel
case $ax_cv_gcc_x86_cpuid_1 in
*5[[4578]]?:*:*:*) ax_gcc_arch="pentium-mmx pentium" ;;
*5[[123]]?:*:*:*) ax_gcc_arch=pentium ;;
*0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;;
*0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch="pentium2 pentiumpro" ;;
*0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch="pentium3 pentiumpro" ;;
*0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch="pentium-m pentium3 pentiumpro" ;;
*0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch="yonah pentium-m pentium3 pentiumpro" ;;
*0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch="core2 pentium-m pentium3 pentiumpro" ;;
*1?6[[7d]]?:*:*:*) ax_gcc_arch="penryn core2 pentium-m pentium3 pentiumpro" ;;
*1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch="nehalem corei7 core2 pentium-m pentium3 pentiumpro" ;;
*2?6[[5cf]]?:*:*:*) ax_gcc_arch="westmere corei7 core2 pentium-m pentium3 pentiumpro" ;;
*2?6[[ad]]?:*:*:*) ax_gcc_arch="sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
*3?6[[ae]]?:*:*:*) ax_gcc_arch="ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
*3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch="haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
*3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch="broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro" ;;
*1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch="bonnell atom core2 pentium-m pentium3 pentiumpro" ;;
*3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch="silvermont atom core2 pentium-m pentium3 pentiumpro" ;;
*000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;
*000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch="nocona prescott pentium4 pentiumpro" ;;
# fallback
*5??:*:*:*) ax_gcc_arch=pentium ;;
*??6??:*:*:*) ax_gcc_arch="core2 pentiumpro" ;;
*6??:*:*:*) ax_gcc_arch=pentiumpro ;;
*00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch="pentium4 pentiumpro" ;;
esac ;;
*:68747541:444d4163:69746e65) # AMD
case $ax_cv_gcc_x86_cpuid_1 in
*5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;
*5[[8]]?:*:*:*) ax_gcc_arch="k6-2 k6" ;;
*5[[9d]]?:*:*:*) ax_gcc_arch="k6-3 k6" ;;
*6[[12]]?:*:*:*) ax_gcc_arch="athlon k7" ;;
*6[[34]]?:*:*:*) ax_gcc_arch="athlon-tbird k7" ;;
*6[[678a]]?:*:*:*) ax_gcc_arch="athlon-xp athlon-4 athlon k7" ;;
*000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch="athlon64 k8" ;;
*002?f[[13457bcf]]?:*:*:*|2?f[[13457bcf]]?:*:*:*|*004?f[[138bcf]]?:*:*:*|4?f[[138bcf]]?:*:*:*|*005?f[[df]]?:*:*:*|5?f[[df]]?:*:*:*|*006?f[[8bcf]]?:*:*:*|6?f[[8bcf]]?:*:*:*|*007?f[[cf]]?:*:*:*|7?f[[cf]]?:*:*:*|*00c?f1?:*:*:*|c?f1?:*:*:*|*020?f3?:*:*:*|20?f3?:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;
*010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;
*050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
*060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
*060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;
*063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;
*07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;
# fallback
*0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch="barcelona amdfam10 k8" ;;
*020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch="athlon64-sse3 k8-sse3 athlon64 k8" ;;
*05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch="btver1 amdfam10 k8" ;;
*060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch="bdver1 amdfam10 k8" ;;
*061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch="bdver2 bdver1 amdfam10 k8" ;;
*06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch="bdver3 bdver2 bdver1 amdfam10 k8" ;;
*070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch="btver2 btver1 amdfam10 k8" ;;
*???f??:*:*:*) ax_gcc_arch="amdfam10 k8" ;;
esac ;;
*:746e6543:736c7561:48727561) # IDT / VIA (Centaur)
case $ax_cv_gcc_x86_cpuid_1 in
*54?:*:*:*) ax_gcc_arch=winchip-c6 ;;
*5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;;
*66?:*:*:*) ax_gcc_arch=winchip2 ;;
*6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;
*6[[9adf]]?:*:*:*) ax_gcc_arch="c3-2 c3" ;;
esac ;;
esac
if test x"$ax_gcc_arch" = x; then # fallback
case $host_cpu in
i586*) ax_gcc_arch=pentium ;;
i686*) ax_gcc_arch=pentiumpro ;;
esac
fi
;;
sparc*)
AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])
cputype=`(((grep cpu /proc/cpuinfo | cut -d: -f2) ; ($PRTDIAG -v |grep -i sparc) ; grep -i cpu /var/run/dmesg.boot ) | head -n 1) 2> /dev/null`
cputype=`echo "$cputype" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters`
case $cputype in
*ultrasparciv*) ax_gcc_arch="ultrasparc4 ultrasparc3 ultrasparc v9" ;;
*ultrasparciii*) ax_gcc_arch="ultrasparc3 ultrasparc v9" ;;
*ultrasparc*) ax_gcc_arch="ultrasparc v9" ;;
*supersparc*|*tms390z5[[05]]*) ax_gcc_arch="supersparc v8" ;;
*hypersparc*|*rt62[[056]]*) ax_gcc_arch="hypersparc v8" ;;
*cypress*) ax_gcc_arch=cypress ;;
esac ;;
alphaev5) ax_gcc_arch=ev5 ;;
alphaev56) ax_gcc_arch=ev56 ;;
alphapca56) ax_gcc_arch="pca56 ev56" ;;
alphapca57) ax_gcc_arch="pca57 pca56 ev56" ;;
alphaev6) ax_gcc_arch=ev6 ;;
alphaev67) ax_gcc_arch=ev67 ;;
alphaev68) ax_gcc_arch="ev68 ev67" ;;
alphaev69) ax_gcc_arch="ev69 ev68 ev67" ;;
alphaev7) ax_gcc_arch="ev7 ev69 ev68 ev67" ;;
alphaev79) ax_gcc_arch="ev79 ev7 ev69 ev68 ev67" ;;
powerpc*)
cputype=`((grep cpu /proc/cpuinfo | head -n 1 | cut -d: -f2 | cut -d, -f1 | $SED 's/ //g') ; /usr/bin/machine ; /bin/machine; grep CPU /var/run/dmesg.boot | head -n 1 | cut -d" " -f2) 2> /dev/null`
cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'`
case $cputype in
*750*) ax_gcc_arch="750 G3" ;;
*740[[0-9]]*) ax_gcc_arch="$cputype 7400 G4" ;;
*74[[4-5]][[0-9]]*) ax_gcc_arch="$cputype 7450 G4" ;;
*74[[0-9]][[0-9]]*) ax_gcc_arch="$cputype G4" ;;
*970*) ax_gcc_arch="970 G5 power4";;
*POWER4*|*power4*|*gq*) ax_gcc_arch="power4 970";;
*POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch="power5 power4 970";;
603ev|8240) ax_gcc_arch="$cputype 603e 603";;
*) ax_gcc_arch=$cputype ;;
esac
ax_gcc_arch="$ax_gcc_arch powerpc"
;;
aarch64)
cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d " " | head -n 1`
case $cpuimpl in
0x42) case $cpuarch in
8) case $cpuvar in
0x0) ax_gcc_arch="thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native" ;;
esac
;;
esac
;;
0x43) case $cpuarch in
8) case $cpuvar in
0x0) ax_gcc_arch="thunderx armv8-a native" ;;
0x1) ax_gcc_arch="thunderx+lse armv8.1-a armv8-a+lse armv8-a native" ;;
esac
;;
esac
;;
esac
;;
esac
fi # not cross-compiling
fi # guess arch
if test "x$ax_gcc_arch" != x -a "x$ax_gcc_arch" != xno; then
if test "x[]m4_default([$1],yes)" = xyes; then # if we require portable code
flag_prefixes="-mtune="
if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then flag_prefixes="-march="; fi
# -mcpu=$arch and m$arch generate nonportable code on every arch except
# x86. And some other arches (e.g. Alpha) don't accept -mtune. Grrr.
case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes="$flag_prefixes -mcpu= -m";; esac
else
flag_prefixes="-march= -mcpu= -m"
fi
for flag_prefix in $flag_prefixes; do
for arch in $ax_gcc_arch; do
flag="$flag_prefix$arch"
AX_CHECK_COMPILE_FLAG($flag, [if test "x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor" = xclang; then
if test "x[]m4_default([$1],yes)" = xyes; then
if test "x$flag" = "x-march=$arch"; then flag=-mtune=$arch; fi
fi
fi; ax_cv_gcc_archflag=$flag; break])
done
test "x$ax_cv_gcc_archflag" = xunknown || break
done
fi
fi # $GCC=yes
])
AC_MSG_CHECKING([for gcc architecture flag])
AC_MSG_RESULT($ax_cv_gcc_archflag)
if test "x$ax_cv_gcc_archflag" = xunknown; then
m4_default([$3],:)
else
m4_default([$2], [CFLAGS="$CFLAGS $ax_cv_gcc_archflag"])
fi
])

View File

@ -0,0 +1,238 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)
#
# DESCRIPTION
#
# This macro checks if the compiler supports one of GCC's function
# attributes; many other compilers also provide function attributes with
# the same syntax. Compiler warnings are used to detect supported
# attributes as unsupported ones are ignored by default so quieting
# warnings when using this macro will yield false positives.
#
# The ATTRIBUTE parameter holds the name of the attribute to be checked.
#
# If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.
#
# The macro caches its result in the ax_cv_have_func_attribute_<attribute>
# variable.
#
# The macro currently supports the following function attributes:
#
# alias
# aligned
# alloc_size
# always_inline
# artificial
# cold
# const
# constructor
# constructor_priority for constructor attribute with priority
# deprecated
# destructor
# dllexport
# dllimport
# error
# externally_visible
# fallthrough
# flatten
# format
# format_arg
# gnu_inline
# hot
# ifunc
# leaf
# malloc
# noclone
# noinline
# nonnull
# noreturn
# nothrow
# optimize
# pure
# sentinel
# sentinel_position
# unused
# used
# visibility
# warning
# warn_unused_result
# weak
# weakref
#
# Unsupported function attributes will be tested with a prototype
# returning an int and not accepting any arguments and the result of the
# check might be wrong or meaningless so use with care.
#
# LICENSE
#
# Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>
#
# Copying and distribution of this file, with or without modification, are
# permitted in any medium without royalty provided the copyright notice
# and this notice are preserved. This file is offered as-is, without any
# warranty.
#serial 9
AC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [
AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])
AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [
AC_LINK_IFELSE([AC_LANG_PROGRAM([
m4_case([$1],
[alias], [
int foo( void ) { return 0; }
int bar( void ) __attribute__(($1("foo")));
],
[aligned], [
int foo( void ) __attribute__(($1(32)));
],
[alloc_size], [
void *foo(int a) __attribute__(($1(1)));
],
[always_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[artificial], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[cold], [
int foo( void ) __attribute__(($1));
],
[const], [
int foo( void ) __attribute__(($1));
],
[constructor_priority], [
int foo( void ) __attribute__((__constructor__(65535/2)));
],
[constructor], [
int foo( void ) __attribute__(($1));
],
[deprecated], [
int foo( void ) __attribute__(($1("")));
],
[destructor], [
int foo( void ) __attribute__(($1));
],
[dllexport], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[dllimport], [
int foo( void ) __attribute__(($1));
],
[error], [
int foo( void ) __attribute__(($1("")));
],
[externally_visible], [
int foo( void ) __attribute__(($1));
],
[fallthrough], [
int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }};
],
[flatten], [
int foo( void ) __attribute__(($1));
],
[format], [
int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));
],
[format_arg], [
char *foo(const char *p) __attribute__(($1(1)));
],
[gnu_inline], [
inline __attribute__(($1)) int foo( void ) { return 0; }
],
[hot], [
int foo( void ) __attribute__(($1));
],
[ifunc], [
int my_foo( void ) { return 0; }
static int (*resolve_foo(void))(void) { return my_foo; }
int foo( void ) __attribute__(($1("resolve_foo")));
],
[leaf], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[malloc], [
void *foo( void ) __attribute__(($1));
],
[noclone], [
int foo( void ) __attribute__(($1));
],
[noinline], [
__attribute__(($1)) int foo( void ) { return 0; }
],
[nonnull], [
int foo(char *p) __attribute__(($1(1)));
],
[noreturn], [
void foo( void ) __attribute__(($1));
],
[nothrow], [
int foo( void ) __attribute__(($1));
],
[optimize], [
__attribute__(($1(3))) int foo( void ) { return 0; }
],
[pure], [
int foo( void ) __attribute__(($1));
],
[sentinel], [
int foo(void *p, ...) __attribute__(($1));
],
[sentinel_position], [
int foo(void *p, ...) __attribute__(($1(1)));
],
[returns_nonnull], [
void *foo( void ) __attribute__(($1));
],
[unused], [
int foo( void ) __attribute__(($1));
],
[used], [
int foo( void ) __attribute__(($1));
],
[visibility], [
int foo_def( void ) __attribute__(($1("default")));
int foo_hid( void ) __attribute__(($1("hidden")));
int foo_int( void ) __attribute__(($1("internal")));
int foo_pro( void ) __attribute__(($1("protected")));
],
[warning], [
int foo( void ) __attribute__(($1("")));
],
[warn_unused_result], [
int foo( void ) __attribute__(($1));
],
[weak], [
int foo( void ) __attribute__(($1));
],
[weakref], [
static int foo( void ) { return 0; }
static int bar( void ) __attribute__(($1("foo")));
],
[
m4_warn([syntax], [Unsupported attribute $1, the test may fail])
int foo( void ) __attribute__(($1));
]
)], [])
],
dnl GCC doesn't exit with an error if an unknown attribute is
dnl provided but only outputs a warning, so accept the attribute
dnl only if no warning were issued.
[AS_IF([test -s conftest.err],
[AS_VAR_SET([ac_var], [no])],
[AS_VAR_SET([ac_var], [yes])])],
[AS_VAR_SET([ac_var], [no])])
])
AS_IF([test yes = AS_VAR_GET([ac_var])],
[AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,
[Define to 1 if the system has the `$1' function attribute])], [])
AS_VAR_POPDEF([ac_var])
])

View File

@ -0,0 +1,89 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_GCC_X86_CPUID(OP)
# AX_GCC_X86_CPUID_COUNT(OP, COUNT)
#
# DESCRIPTION
#
# On Pentium and later x86 processors, with gcc or a compiler that has a
# compatible syntax for inline assembly instructions, run a small program
# that executes the cpuid instruction with input OP. This can be used to
# detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT
# parameter that gets passed into register ECX before calling cpuid.
#
# On output, the values of the eax, ebx, ecx, and edx registers are stored
# as hexadecimal strings as "eax:ebx:ecx:edx" in the cache variable
# ax_cv_gcc_x86_cpuid_OP.
#
# If the cpuid instruction fails (because you are running a
# cross-compiler, or because you are not using gcc, or because you are on
# a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP
# is set to the string "unknown".
#
# This macro mainly exists to be used in AX_GCC_ARCHFLAG.
#
# LICENSE
#
# Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>
# Copyright (c) 2008 Matteo Frigo
# Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 10
AC_DEFUN([AX_GCC_X86_CPUID],
[AX_GCC_X86_CPUID_COUNT($1, 0)
])
AC_DEFUN([AX_GCC_X86_CPUID_COUNT],
[AC_REQUIRE([AC_PROG_CC])
AC_LANG_PUSH([C])
AC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,
[AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [
int op = $1, level = $2, eax, ebx, ecx, edx;
FILE *f;
__asm__ __volatile__ ("xchg %%ebx, %1\n"
"cpuid\n"
"xchg %%ebx, %1\n"
: "=a" (eax), "=r" (ebx), "=c" (ecx), "=d" (edx)
: "a" (op), "2" (level));
f = fopen("conftest_cpuid", "w"); if (!f) return 1;
fprintf(f, "%x:%x:%x:%x\n", eax, ebx, ecx, edx);
fclose(f);
return 0;
])],
[ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],
[ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],
[ax_cv_gcc_x86_cpuid_$1=unknown])])
AC_LANG_POP([C])
])

View File

@ -0,0 +1,74 @@
# ===========================================================================
# https://www.gnu.org/software/autoconf-archive/ax_tls.html
# ===========================================================================
#
# SYNOPSIS
#
# AX_TLS([action-if-found], [action-if-not-found])
#
# DESCRIPTION
#
# Provides a test for the compiler support of thread local storage (TLS)
# extensions. Defines TLS if it is found. Currently knows about C++11,
# GCC/ICC, and MSVC. I think SunPro uses the same as GCC, and Borland
# apparently supports either.
#
# LICENSE
#
# Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk>
# Copyright (c) 2010 Diego Elio Petteno` <flameeyes@gmail.com>
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation, either version 3 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, see <https://www.gnu.org/licenses/>.
#
# As a special exception, the respective Autoconf Macro's copyright owner
# gives unlimited permission to copy, distribute and modify the configure
# scripts that are the output of Autoconf when processing the Macro. You
# need not follow the terms of the GNU General Public License when using
# or distributing such scripts, even though portions of the text of the
# Macro appear in them. The GNU General Public License (GPL) does govern
# all other use of the material that constitutes the Autoconf Macro.
#
# This special exception to the GPL applies to versions of the Autoconf
# Macro released by the Autoconf Archive. When you make and distribute a
# modified version of the Autoconf Macro, you may extend this special
# exception to the GPL to apply to your modified version as well.
#serial 14
AC_DEFUN([AX_TLS], [
AC_MSG_CHECKING([for thread local storage (TLS) class])
AC_CACHE_VAL([ac_cv_tls],
[for ax_tls_keyword in thread_local _Thread_local __thread '__declspec(thread)' none; do
AS_CASE([$ax_tls_keyword],
[none], [ac_cv_tls=none ; break],
[AC_TRY_COMPILE(
[#include <stdlib.h>
static void
foo(void) {
static ] $ax_tls_keyword [ int bar;
exit(1);
}],
[],
[ac_cv_tls=$ax_tls_keyword ; break],
ac_cv_tls=none
)])
done
])
AC_MSG_RESULT([$ac_cv_tls])
AS_IF([test "$ac_cv_tls" != "none"],
[AC_DEFINE_UNQUOTED([TLS],[$ac_cv_tls],[If the compiler supports a TLS storage class define it to that here])
m4_ifnblank([$1],[$1])],
[m4_ifnblank([$2],[$2])])
])

View File

@ -0,0 +1,37 @@
dnl Provide AC_USE_SYSTEM_EXTENSIONS for old autoconf machines.
AC_DEFUN([ACX_USE_SYSTEM_EXTENSIONS],[
ifdef([AC_USE_SYSTEM_EXTENSIONS],[
AC_USE_SYSTEM_EXTENSIONS
],[
AC_BEFORE([$0], [AC_COMPILE_IFELSE])
AC_BEFORE([$0], [AC_RUN_IFELSE])
AC_REQUIRE([AC_GNU_SOURCE])
AC_REQUIRE([AC_AIX])
AC_REQUIRE([AC_MINIX])
AH_VERBATIM([__EXTENSIONS__],
[/* Enable extensions on Solaris. */
#ifndef __EXTENSIONS__
# undef __EXTENSIONS__
#endif
#ifndef _POSIX_PTHREAD_SEMANTICS
# undef _POSIX_PTHREAD_SEMANTICS
#endif
#ifndef _TANDEM_SOURCE
# undef _TANDEM_SOURCE
#endif])
AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__],
[ac_cv_safe_to_define___extensions__],
[AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM([
# define __EXTENSIONS__ 1
AC_INCLUDES_DEFAULT])],
[ac_cv_safe_to_define___extensions__=yes],
[ac_cv_safe_to_define___extensions__=no])])
test $ac_cv_safe_to_define___extensions__ = yes &&
AC_DEFINE([__EXTENSIONS__])
AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])
AC_DEFINE([_TANDEM_SOURCE])
])
])

View File

@ -0,0 +1,110 @@
# lib-ld.m4 serial 3 (gettext-0.13)
dnl Copyright (C) 1996-2003 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl Subroutines of libtool.m4,
dnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision
dnl with libtool.m4.
dnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.
AC_DEFUN([AC_LIB_PROG_LD_GNU],
[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,
[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
case `$LD -v 2>&1 </dev/null` in
*GNU* | *'with BFD'*)
acl_cv_prog_gnu_ld=yes ;;
*)
acl_cv_prog_gnu_ld=no ;;
esac])
with_gnu_ld=$acl_cv_prog_gnu_ld
])
dnl From libtool-1.4. Sets the variable LD.
AC_DEFUN([AC_LIB_PROG_LD],
[AC_ARG_WITH(gnu-ld,
[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
AC_REQUIRE([AC_PROG_CC])dnl
AC_REQUIRE([AC_CANONICAL_HOST])dnl
# Prepare PATH_SEPARATOR.
# The user is always right.
if test "${PATH_SEPARATOR+set}" != set; then
echo "#! /bin/sh" >conf$$.sh
echo "exit 0" >>conf$$.sh
chmod +x conf$$.sh
if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
PATH_SEPARATOR=';'
else
PATH_SEPARATOR=:
fi
rm -f conf$$.sh
fi
ac_prog=ld
if test "$GCC" = yes; then
# Check if gcc -print-prog-name=ld gives a path.
AC_MSG_CHECKING([for ld used by GCC])
case $host in
*-*-mingw*)
# gcc leaves a trailing carriage return which upsets mingw
ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;;
*)
ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;
esac
case $ac_prog in
# Accept absolute paths.
[[\\/]* | [A-Za-z]:[\\/]*)]
[re_direlt='/[^/][^/]*/\.\./']
# Canonicalize the path of ld
ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
done
test -z "$LD" && LD="$ac_prog"
;;
"")
# If it fails, then pretend we aren't using GCC.
ac_prog=ld
;;
*)
# If it is relative, then search for the first ld in PATH.
with_gnu_ld=unknown
;;
esac
elif test "$with_gnu_ld" = yes; then
AC_MSG_CHECKING([for GNU ld])
else
AC_MSG_CHECKING([for non-GNU ld])
fi
AC_CACHE_VAL(acl_cv_path_LD,
[if test -z "$LD"; then
IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
for ac_dir in $PATH; do
test -z "$ac_dir" && ac_dir=.
if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
acl_cv_path_LD="$ac_dir/$ac_prog"
# Check to see if the program is GNU ld. I'd rather use --version,
# but apparently some GNU ld's only accept -v.
# Break only if it was the GNU/non-GNU ld that we prefer.
case `"$acl_cv_path_LD" -v 2>&1 < /dev/null` in
*GNU* | *'with BFD'*)
test "$with_gnu_ld" != no && break ;;
*)
test "$with_gnu_ld" != yes && break ;;
esac
fi
done
IFS="$ac_save_ifs"
else
acl_cv_path_LD="$LD" # Let the user override the test with a path.
fi])
LD="$acl_cv_path_LD"
if test -n "$LD"; then
AC_MSG_RESULT($LD)
else
AC_MSG_RESULT(no)
fi
test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
AC_LIB_PROG_LD_GNU
])

View File

@ -0,0 +1,709 @@
# lib-link.m4 serial 13 (gettext-0.17)
dnl Copyright (C) 2001-2007 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
AC_PREREQ(2.54)
dnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and
dnl augments the CPPFLAGS variable.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
define([Name],[translit([$1],[./-], [___])])
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [
AC_LIB_LINKFLAGS_BODY([$1], [$2])
ac_cv_lib[]Name[]_libs="$LIB[]NAME"
ac_cv_lib[]Name[]_ltlibs="$LTLIB[]NAME"
ac_cv_lib[]Name[]_cppflags="$INC[]NAME"
ac_cv_lib[]Name[]_prefix="$LIB[]NAME[]_PREFIX"
])
LIB[]NAME="$ac_cv_lib[]Name[]_libs"
LTLIB[]NAME="$ac_cv_lib[]Name[]_ltlibs"
INC[]NAME="$ac_cv_lib[]Name[]_cppflags"
LIB[]NAME[]_PREFIX="$ac_cv_lib[]Name[]_prefix"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the
dnl results of this search when this library appears as a dependency.
HAVE_LIB[]NAME=yes
undefine([Name])
undefine([NAME])
])
dnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)
dnl searches for libname and the libraries corresponding to explicit and
dnl implicit dependencies, together with the specified include files and
dnl the ability to compile and link the specified testcode. If found, it
dnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and
dnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and
dnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs
dnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.
dnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname
dnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_HAVE_LINKFLAGS],
[
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
AC_REQUIRE([AC_LIB_RPATH])
define([Name],[translit([$1],[./-], [___])])
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME
dnl accordingly.
AC_LIB_LINKFLAGS_BODY([$1], [$2])
dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,
dnl because if the user has installed lib[]Name and not disabled its use
dnl via --without-lib[]Name-prefix, he wants to use it.
ac_save_CPPFLAGS="$CPPFLAGS"
AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)
AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [
ac_save_LIBS="$LIBS"
LIBS="$LIBS $LIB[]NAME"
AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])
LIBS="$ac_save_LIBS"
])
if test "$ac_cv_lib[]Name" = yes; then
HAVE_LIB[]NAME=yes
AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])
AC_MSG_CHECKING([how to link with lib[]$1])
AC_MSG_RESULT([$LIB[]NAME])
else
HAVE_LIB[]NAME=no
dnl If $LIB[]NAME didn't lead to a usable library, we don't need
dnl $INC[]NAME either.
CPPFLAGS="$ac_save_CPPFLAGS"
LIB[]NAME=
LTLIB[]NAME=
LIB[]NAME[]_PREFIX=
fi
AC_SUBST([HAVE_LIB]NAME)
AC_SUBST([LIB]NAME)
AC_SUBST([LTLIB]NAME)
AC_SUBST([LIB]NAME[_PREFIX])
undefine([Name])
undefine([NAME])
])
dnl Determine the platform dependent parameters needed to use rpath:
dnl acl_libext,
dnl acl_shlibext,
dnl acl_hardcode_libdir_flag_spec,
dnl acl_hardcode_libdir_separator,
dnl acl_hardcode_direct,
dnl acl_hardcode_minus_L.
AC_DEFUN([AC_LIB_RPATH],
[
dnl Tell automake >= 1.10 to complain if config.rpath is missing.
m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])
AC_REQUIRE([AC_PROG_CC]) dnl we use $CC, $GCC, $LDFLAGS
AC_REQUIRE([AC_LIB_PROG_LD]) dnl we use $LD, $with_gnu_ld
AC_REQUIRE([AC_CANONICAL_HOST]) dnl we use $host
AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir
AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [
CC="$CC" GCC="$GCC" LDFLAGS="$LDFLAGS" LD="$LD" with_gnu_ld="$with_gnu_ld" \
${CONFIG_SHELL-/bin/sh} "$ac_aux_dir/config.rpath" "$host" > conftest.sh
. ./conftest.sh
rm -f ./conftest.sh
acl_cv_rpath=done
])
wl="$acl_cv_wl"
acl_libext="$acl_cv_libext"
acl_shlibext="$acl_cv_shlibext"
acl_libname_spec="$acl_cv_libname_spec"
acl_library_names_spec="$acl_cv_library_names_spec"
acl_hardcode_libdir_flag_spec="$acl_cv_hardcode_libdir_flag_spec"
acl_hardcode_libdir_separator="$acl_cv_hardcode_libdir_separator"
acl_hardcode_direct="$acl_cv_hardcode_direct"
acl_hardcode_minus_L="$acl_cv_hardcode_minus_L"
dnl Determine whether the user wants rpath handling at all.
AC_ARG_ENABLE(rpath,
[ --disable-rpath do not hardcode runtime library paths],
:, enable_rpath=yes)
])
dnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and
dnl the libraries corresponding to explicit and implicit dependencies.
dnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.
dnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found
dnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.
AC_DEFUN([AC_LIB_LINKFLAGS_BODY],
[
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],
[ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])
dnl Autoconf >= 2.61 supports dots in --with options.
define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_LIB_ARG_WITH([lib]N_A_M_E[-prefix],
[ --with-lib]N_A_M_E[-prefix[=DIR] search for lib$1 in DIR/include and DIR/lib
--without-lib]N_A_M_E[-prefix don't search for lib$1 in includedir and libdir],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
fi
fi
])
dnl Search the library and its dependencies in $additional_libdir and
dnl $LDFLAGS. Using breadth-first-seach.
LIB[]NAME=
LTLIB[]NAME=
INC[]NAME=
LIB[]NAME[]_PREFIX=
rpathdirs=
ltrpathdirs=
names_already_handled=
names_next_round='$1 $2'
while test -n "$names_next_round"; do
names_this_round="$names_next_round"
names_next_round=
for name in $names_this_round; do
already_handled=
for n in $names_already_handled; do
if test "$n" = "$name"; then
already_handled=yes
break
fi
done
if test -z "$already_handled"; then
names_already_handled="$names_already_handled $name"
dnl See if it was already located by an earlier AC_LIB_LINKFLAGS
dnl or AC_LIB_HAVE_LINKFLAGS call.
uppername=`echo "$name" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`
eval value=\"\$HAVE_LIB$uppername\"
if test -n "$value"; then
if test "$value" = yes; then
eval value=\"\$LIB$uppername\"
test -z "$value" || LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$value"
eval value=\"\$LTLIB$uppername\"
test -z "$value" || LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$value"
else
dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined
dnl that this library doesn't exist. So just drop it.
:
fi
else
dnl Search the library lib$name in $additional_libdir and $LDFLAGS
dnl and the already constructed $LIBNAME/$LTLIBNAME.
found_dir=
found_la=
found_so=
found_a=
eval libname=\"$acl_libname_spec\" # typically: libname=lib$name
if test -n "$acl_shlibext"; then
shrext=".$acl_shlibext" # typically: shrext=.so
else
shrext=
fi
if test $use_additional = yes; then
dir="$additional_libdir"
dnl The same code as in the loop below:
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
fi
if test "X$found_dir" = "X"; then
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
case "$x" in
-L*)
dir=`echo "X$x" | sed -e 's/^X-L//'`
dnl First look for a shared library.
if test -n "$acl_shlibext"; then
if test -f "$dir/$libname$shrext"; then
found_dir="$dir"
found_so="$dir/$libname$shrext"
else
if test "$acl_library_names_spec" = '$libname$shrext$versuffix'; then
ver=`(cd "$dir" && \
for f in "$libname$shrext".*; do echo "$f"; done \
| sed -e "s,^$libname$shrext\\\\.,," \
| sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \
| sed 1q ) 2>/dev/null`
if test -n "$ver" && test -f "$dir/$libname$shrext.$ver"; then
found_dir="$dir"
found_so="$dir/$libname$shrext.$ver"
fi
else
eval library_names=\"$acl_library_names_spec\"
for f in $library_names; do
if test -f "$dir/$f"; then
found_dir="$dir"
found_so="$dir/$f"
break
fi
done
fi
fi
fi
dnl Then look for a static library.
if test "X$found_dir" = "X"; then
if test -f "$dir/$libname.$acl_libext"; then
found_dir="$dir"
found_a="$dir/$libname.$acl_libext"
fi
fi
if test "X$found_dir" != "X"; then
if test -f "$dir/$libname.la"; then
found_la="$dir/$libname.la"
fi
fi
;;
esac
if test "X$found_dir" != "X"; then
break
fi
done
fi
if test "X$found_dir" != "X"; then
dnl Found the library.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name"
if test "X$found_so" != "X"; then
dnl Linking with a shared library. We attempt to hardcode its
dnl directory into the executable's runpath, unless it's the
dnl standard /usr/lib.
if test "$enable_rpath" = no || test "X$found_dir" = "X/usr/$acl_libdirstem"; then
dnl No hardcoding is needed.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $found_dir"
fi
dnl The hardcoding into $LIBNAME is system dependent.
if test "$acl_hardcode_direct" = yes; then
dnl Using DIR/libNAME.so during linking hardcodes DIR into the
dnl resulting binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode DIR into the resulting
dnl binary.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $found_dir"
fi
else
dnl Rely on "-L$found_dir".
dnl But don't add it if it's already contained in the LDFLAGS
dnl or the already constructed $LIBNAME
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$found_dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir"
fi
if test "$acl_hardcode_minus_L" != no; then
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_so"
else
dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH
dnl here, because this doesn't fit in flags passed to the
dnl compiler. So give up. No hardcoding. This affects only
dnl very old systems.
dnl FIXME: Not sure whether we should use
dnl "-L$found_dir -l$name" or "-L$found_dir $found_so"
dnl here.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
fi
fi
fi
fi
else
if test "X$found_a" != "X"; then
dnl Linking with a static library.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$found_a"
else
dnl We shouldn't come here, but anyway it's good to have a
dnl fallback.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name"
fi
fi
dnl Assume the include files are nearby.
additional_includedir=
case "$found_dir" in
*/$acl_libdirstem | */$acl_libdirstem/)
basedir=`echo "X$found_dir" | sed -e 's,^X,,' -e "s,/$acl_libdirstem/"'*$,,'`
LIB[]NAME[]_PREFIX="$basedir"
additional_includedir="$basedir/include"
;;
esac
if test "X$additional_includedir" != "X"; then
dnl Potentially add $additional_includedir to $INCNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's /usr/local/include and we are using GCC on Linux,
dnl 3. if it's already present in $CPPFLAGS or the already
dnl constructed $INCNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
for x in $CPPFLAGS $INC[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $INCNAME.
INC[]NAME="${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir"
fi
fi
fi
fi
fi
dnl Look for dependencies.
if test -n "$found_la"; then
dnl Read the .la file. It defines the variables
dnl dlname, library_names, old_library, dependency_libs, current,
dnl age, revision, installed, dlopen, dlpreopen, libdir.
save_libdir="$libdir"
case "$found_la" in
*/* | *\\*) . "$found_la" ;;
*) . "./$found_la" ;;
esac
libdir="$save_libdir"
dnl We use only dependency_libs.
for dep in $dependency_libs; do
case "$dep" in
-L*)
additional_libdir=`echo "X$dep" | sed -e 's/^X-L//'`
dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's /usr/local/lib and we are using GCC on Linux,
dnl 3. if it's already present in $LDFLAGS or the already
dnl constructed $LIBNAME,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
haveit=
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
haveit=
for x in $LDFLAGS $LIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LIBNAME.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir"
fi
fi
haveit=
for x in $LDFLAGS $LTLIB[]NAME; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LTLIBNAME.
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir"
fi
fi
fi
fi
;;
-R*)
dir=`echo "X$dep" | sed -e 's/^X-R//'`
if test "$enable_rpath" != no; then
dnl Potentially add DIR to rpathdirs.
dnl The rpathdirs will be appended to $LIBNAME at the end.
haveit=
for x in $rpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
rpathdirs="$rpathdirs $dir"
fi
dnl Potentially add DIR to ltrpathdirs.
dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.
haveit=
for x in $ltrpathdirs; do
if test "X$x" = "X$dir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
ltrpathdirs="$ltrpathdirs $dir"
fi
fi
;;
-l*)
dnl Handle this in the next round.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's/^X-l//'`
;;
*.la)
dnl Handle this in the next round. Throw away the .la's
dnl directory; it is already contained in a preceding -L
dnl option.
names_next_round="$names_next_round "`echo "X$dep" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\.la$,,'`
;;
*)
dnl Most likely an immediate library name.
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$dep"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep"
;;
esac
done
fi
else
dnl Didn't find the library; assume it is in the system directories
dnl known to the linker and runtime loader. (All the system
dnl directories known to the linker should also be known to the
dnl runtime loader, otherwise the system is severely misconfigured.)
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }-l$name"
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name"
fi
fi
fi
done
done
if test "X$rpathdirs" != "X"; then
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user must
dnl pass all path elements in one option. We can arrange that for a
dnl single library, but not when more than one $LIBNAMEs are used.
alldirs=
for found_dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir"
done
dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
else
dnl The -rpath options are cumulative.
for found_dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$found_dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
LIB[]NAME="${LIB[]NAME}${LIB[]NAME:+ }$flag"
done
fi
fi
if test "X$ltrpathdirs" != "X"; then
dnl When using libtool, the option that works for both libraries and
dnl executables is -R. The -R options are cumulative.
for found_dir in $ltrpathdirs; do
LTLIB[]NAME="${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir"
done
fi
])
dnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,
dnl unless already present in VAR.
dnl Works only for CPPFLAGS, not for LIB* variables because that sometimes
dnl contains two or three consecutive elements that belong together.
AC_DEFUN([AC_LIB_APPENDTOVAR],
[
for element in [$2]; do
haveit=
for x in $[$1]; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X$element"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
[$1]="${[$1]}${[$1]:+ }$element"
fi
done
])
dnl For those cases where a variable contains several -L and -l options
dnl referring to unknown libraries and directories, this macro determines the
dnl necessary additional linker options for the runtime path.
dnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])
dnl sets LDADDVAR to linker options needed together with LIBSVALUE.
dnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,
dnl otherwise linking without libtool is assumed.
AC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],
[
AC_REQUIRE([AC_LIB_RPATH])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
$1=
if test "$enable_rpath" != no; then
if test -n "$acl_hardcode_libdir_flag_spec" && test "$acl_hardcode_minus_L" = no; then
dnl Use an explicit option to hardcode directories into the resulting
dnl binary.
rpathdirs=
next=
for opt in $2; do
if test -n "$next"; then
dir="$next"
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem"; then
rpathdirs="$rpathdirs $dir"
fi
next=
else
case $opt in
-L) next=yes ;;
-L*) dir=`echo "X$opt" | sed -e 's,^X-L,,'`
dnl No need to hardcode the standard /usr/lib.
if test "X$dir" != "X/usr/$acl_libdirstem"; then
rpathdirs="$rpathdirs $dir"
fi
next= ;;
*) next= ;;
esac
fi
done
if test "X$rpathdirs" != "X"; then
if test -n ""$3""; then
dnl libtool is used for linking. Use -R options.
for dir in $rpathdirs; do
$1="${$1}${$1:+ }-R$dir"
done
else
dnl The linker is used for linking directly.
if test -n "$acl_hardcode_libdir_separator"; then
dnl Weird platform: only the last -rpath option counts, the user
dnl must pass all path elements in one option.
alldirs=
for dir in $rpathdirs; do
alldirs="${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir"
done
acl_save_libdir="$libdir"
libdir="$alldirs"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="$flag"
else
dnl The -rpath options are cumulative.
for dir in $rpathdirs; do
acl_save_libdir="$libdir"
libdir="$dir"
eval flag=\"$acl_hardcode_libdir_flag_spec\"
libdir="$acl_save_libdir"
$1="${$1}${$1:+ }$flag"
done
fi
fi
fi
fi
fi
AC_SUBST([$1])
])

View File

@ -0,0 +1,185 @@
# lib-prefix.m4 serial 5 (gettext-0.15)
dnl Copyright (C) 2001-2005 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl From Bruno Haible.
dnl AC_LIB_ARG_WITH is synonymous to AC_ARG_WITH in autoconf-2.13, and
dnl similar to AC_ARG_WITH in autoconf 2.52...2.57 except that is doesn't
dnl require excessive bracketing.
ifdef([AC_HELP_STRING],
[AC_DEFUN([AC_LIB_ARG_WITH], [AC_ARG_WITH([$1],[[$2]],[$3],[$4])])],
[AC_DEFUN([AC_][LIB_ARG_WITH], [AC_ARG_WITH([$1],[$2],[$3],[$4])])])
dnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed
dnl to access previously installed libraries. The basic assumption is that
dnl a user will want packages to use other packages he previously installed
dnl with the same --prefix option.
dnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate
dnl libraries, but is otherwise very convenient.
AC_DEFUN([AC_LIB_PREFIX],
[
AC_BEFORE([$0], [AC_LIB_LINKFLAGS])
AC_REQUIRE([AC_PROG_CC])
AC_REQUIRE([AC_CANONICAL_HOST])
AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])
AC_REQUIRE([AC_LIB_PREPARE_PREFIX])
dnl By default, look in $includedir and $libdir.
use_additional=yes
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
AC_LIB_ARG_WITH([lib-prefix],
[ --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib
--without-lib-prefix don't search for libraries in includedir and libdir],
[
if test "X$withval" = "Xno"; then
use_additional=no
else
if test "X$withval" = "X"; then
AC_LIB_WITH_FINAL_PREFIX([
eval additional_includedir=\"$includedir\"
eval additional_libdir=\"$libdir\"
])
else
additional_includedir="$withval/include"
additional_libdir="$withval/$acl_libdirstem"
fi
fi
])
if test $use_additional = yes; then
dnl Potentially add $additional_includedir to $CPPFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/include,
dnl 2. if it's already present in $CPPFLAGS,
dnl 3. if it's /usr/local/include and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_includedir" != "X/usr/include"; then
haveit=
for x in $CPPFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-I$additional_includedir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_includedir" = "X/usr/local/include"; then
if test -n "$GCC"; then
case $host_os in
linux* | gnu* | k*bsd*-gnu) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_includedir"; then
dnl Really add $additional_includedir to $CPPFLAGS.
CPPFLAGS="${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir"
fi
fi
fi
fi
dnl Potentially add $additional_libdir to $LDFLAGS.
dnl But don't add it
dnl 1. if it's the standard /usr/lib,
dnl 2. if it's already present in $LDFLAGS,
dnl 3. if it's /usr/local/lib and we are using GCC on Linux,
dnl 4. if it doesn't exist as a directory.
if test "X$additional_libdir" != "X/usr/$acl_libdirstem"; then
haveit=
for x in $LDFLAGS; do
AC_LIB_WITH_FINAL_PREFIX([eval x=\"$x\"])
if test "X$x" = "X-L$additional_libdir"; then
haveit=yes
break
fi
done
if test -z "$haveit"; then
if test "X$additional_libdir" = "X/usr/local/$acl_libdirstem"; then
if test -n "$GCC"; then
case $host_os in
linux*) haveit=yes;;
esac
fi
fi
if test -z "$haveit"; then
if test -d "$additional_libdir"; then
dnl Really add $additional_libdir to $LDFLAGS.
LDFLAGS="${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir"
fi
fi
fi
fi
fi
])
dnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,
dnl acl_final_exec_prefix, containing the values to which $prefix and
dnl $exec_prefix will expand at the end of the configure script.
AC_DEFUN([AC_LIB_PREPARE_PREFIX],
[
dnl Unfortunately, prefix and exec_prefix get only finally determined
dnl at the end of configure.
if test "X$prefix" = "XNONE"; then
acl_final_prefix="$ac_default_prefix"
else
acl_final_prefix="$prefix"
fi
if test "X$exec_prefix" = "XNONE"; then
acl_final_exec_prefix='${prefix}'
else
acl_final_exec_prefix="$exec_prefix"
fi
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
eval acl_final_exec_prefix=\"$acl_final_exec_prefix\"
prefix="$acl_save_prefix"
])
dnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the
dnl variables prefix and exec_prefix bound to the values they will have
dnl at the end of the configure script.
AC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],
[
acl_save_prefix="$prefix"
prefix="$acl_final_prefix"
acl_save_exec_prefix="$exec_prefix"
exec_prefix="$acl_final_exec_prefix"
$1
exec_prefix="$acl_save_exec_prefix"
prefix="$acl_save_prefix"
])
dnl AC_LIB_PREPARE_MULTILIB creates a variable acl_libdirstem, containing
dnl the basename of the libdir, either "lib" or "lib64".
AC_DEFUN([AC_LIB_PREPARE_MULTILIB],
[
dnl There is no formal standard regarding lib and lib64. The current
dnl practice is that on a system supporting 32-bit and 64-bit instruction
dnl sets or ABIs, 64-bit libraries go under $prefix/lib64 and 32-bit
dnl libraries go under $prefix/lib. We determine the compiler's default
dnl mode by looking at the compiler's library search path. If at least
dnl of its elements ends in /lib64 or points to a directory whose absolute
dnl pathname ends in /lib64, we assume a 64-bit ABI. Otherwise we use the
dnl default, namely "lib".
acl_libdirstem=lib
searchpath=`(LC_ALL=C $CC -print-search-dirs) 2>/dev/null | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`
if test -n "$searchpath"; then
acl_save_IFS="${IFS= }"; IFS=":"
for searchdir in $searchpath; do
if test -d "$searchdir"; then
case "$searchdir" in
*/lib64/ | */lib64 ) acl_libdirstem=lib64 ;;
*) searchdir=`cd "$searchdir" && pwd`
case "$searchdir" in
*/lib64 ) acl_libdirstem=lib64 ;;
esac ;;
esac
fi
done
IFS="$acl_save_IFS"
fi
])

View File

@ -0,0 +1,13 @@
# ---------------------------------------------------------------------------
# Provide various compatibility macros for older Autoconf machines
# Definitions were copied from the Autoconf source code.
# ---------------------------------------------------------------------------
m4_ifdef([AS_VAR_IF],,m4_define([AS_VAR_IF],
[AS_LITERAL_WORD_IF([$1],
[AS_IF(m4_ifval([$2], [[test "x$$1" = x[]$2]], [[${$1:+false} :]])],
[AS_VAR_COPY([as_val], [$1])
AS_IF(m4_ifval([$2], [[test "x$as_val" = x[]$2]], [[${as_val:+false} :]])],
[AS_IF(m4_ifval([$2],
[[eval test \"x\$"$1"\" = x"_AS_ESCAPE([$2], [`], [\"$])"]],
[[eval \${$1:+false} :]])]),
[$3], [$4])]))dnl

View File

@ -0,0 +1,138 @@
dnl ---------------------------------------------------------------------------
dnl Macro: SB_CHECK_MYSQL
dnl First check if the MySQL root directory is specified with --with-mysql.
dnl Otherwise check for custom MySQL paths in --with-mysql-includes and
dnl --with-mysql-libs. If some paths are not specified explicitly, try to get
dnl them from mysql_config.
dnl ---------------------------------------------------------------------------
AC_DEFUN([SB_CHECK_MYSQL],[
AS_IF([test "x$with_mysql" != xno], [
# Check for custom MySQL root directory
if test [ "x$with_mysql" != xyes -a "x$with_mysql" != xno ]
then
ac_cv_mysql_root=`echo "$with_mysql" | sed -e 's+/$++'`
if test [ -d "$ac_cv_mysql_root/include" -a \
-d "$ac_cv_mysql_root/libmysql_r" ]
then
ac_cv_mysql_includes="$ac_cv_mysql_root/include"
ac_cv_mysql_libs="$ac_cv_mysql_root/libmysql_r"
elif test [ -x "$ac_cv_mysql_root/bin/mysql_config" ]
then
mysqlconfig="$ac_cv_mysql_root/bin/mysql_config"
else
AC_MSG_ERROR([invalid MySQL root directory: $ac_cv_mysql_root])
fi
fi
# Check for custom includes path
if test [ -z "$ac_cv_mysql_includes" ]
then
AC_ARG_WITH([mysql-includes],
AC_HELP_STRING([--with-mysql-includes], [path to MySQL header files]),
[ac_cv_mysql_includes=$withval])
fi
if test [ -n "$ac_cv_mysql_includes" ]
then
AC_CACHE_CHECK([MySQL includes], [ac_cv_mysql_includes], [ac_cv_mysql_includes=""])
MYSQL_CFLAGS="-I$ac_cv_mysql_includes"
fi
# Check for custom library path
if test [ -z "$ac_cv_mysql_libs" ]
then
AC_ARG_WITH([mysql-libs],
AC_HELP_STRING([--with-mysql-libs], [path to MySQL libraries]),
[ac_cv_mysql_libs=$withval])
fi
if test [ -n "$ac_cv_mysql_libs" ]
then
# Trim trailing '.libs' if user passed it in --with-mysql-libs option
ac_cv_mysql_libs=`echo ${ac_cv_mysql_libs} | sed -e 's/.libs$//' \
-e 's+.libs/$++'`
AC_CACHE_CHECK([MySQL libraries], [ac_cv_mysql_libs], [ac_cv_mysql_libs=""])
save_LDFLAGS="$LDFLAGS"
save_LIBS="$LIBS"
LDFLAGS="-L$ac_cv_mysql_libs"
LIBS=""
# libmysqlclient_r has been removed in MySQL 5.7
AC_SEARCH_LIBS([mysql_real_connect],
[mysqlclient_r mysqlclient],
[],
AC_MSG_ERROR([cannot find MySQL client libraries in $ac_cv_mysql_libs]))
MYSQL_LIBS="$LDFLAGS $LIBS"
LIBS="$save_LIBS"
LDFLAGS="$save_LDFLAGS"
fi
# If some path is missing, try to autodetermine with mysql_config
if test [ -z "$ac_cv_mysql_includes" -o -z "$ac_cv_mysql_libs" ]
then
if test [ -z "$mysqlconfig" ]
then
AC_PATH_PROG(mysqlconfig,mysql_config)
fi
if test [ -z "$mysqlconfig" ]
then
AC_MSG_ERROR([mysql_config executable not found
********************************************************************************
ERROR: cannot find MySQL libraries. If you want to compile with MySQL support,
please install the package containing MySQL client libraries and headers.
On Debian-based systems the package name is libmysqlclient-dev.
On RedHat-based systems, it is mysql-devel.
If you have those libraries installed in non-standard locations,
you must either specify file locations explicitly using
--with-mysql-includes and --with-mysql-libs options, or make sure path to
mysql_config is listed in your PATH environment variable. If you want to
disable MySQL support, use --without-mysql option.
********************************************************************************
])
else
if test [ -z "$ac_cv_mysql_includes" ]
then
AC_MSG_CHECKING(MySQL C flags)
MYSQL_CFLAGS=`${mysqlconfig} --cflags`
AC_MSG_RESULT($MYSQL_CFLAGS)
fi
if test [ -z "$ac_cv_mysql_libs" ]
then
AC_MSG_CHECKING(MySQL linker flags)
MYSQL_LIBS=`${mysqlconfig} --libs_r`
AC_MSG_RESULT($MYSQL_LIBS)
fi
fi
fi
AC_DEFINE([USE_MYSQL], 1,
[Define to 1 if you want to compile with MySQL support])
USE_MYSQL=1
AC_SUBST([MYSQL_LIBS])
AC_SUBST([MYSQL_CFLAGS])
AC_MSG_CHECKING([if mysql.h defines MYSQL_OPT_SSL_MODE])
SAVE_CFLAGS="${CFLAGS}"
CFLAGS="${CFLAGS} ${MYSQL_CFLAGS}"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM(
[[
#include <mysql.h>
enum mysql_option opt = MYSQL_OPT_SSL_MODE;
]])], [
AC_DEFINE([HAVE_MYSQL_OPT_SSL_MODE], 1,
[Define to 1 if mysql.h defines MYSQL_OPT_SSL_MODE])
AC_MSG_RESULT([yes])
], [AC_MSG_RESULT([no])])
])
CFLAGS="${SAVE_CFLAGS}"
AM_CONDITIONAL([USE_MYSQL], test "x$with_mysql" != xno)
AC_SUBST([USE_MYSQL])
])

View File

@ -0,0 +1,99 @@
# Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
# ---------------------------------------------------------------------------
# Macro: SB_CONCURRENCY_KIT
# ---------------------------------------------------------------------------
AC_DEFUN([SB_CONCURRENCY_KIT], [
AC_ARG_WITH([system-ck],
AC_HELP_STRING([--with-system-ck],
[Use system-provided Concurrency Kit headers and library (requires pkg-config)]),
[sb_use_ck="system"],
[sb_use_ck="bundled"])
AC_CACHE_CHECK([whether to build with system or bundled Concurrency Kit],
[sb_cv_lib_ck], [
AS_IF([test "x$sb_use_ck" = "xsystem"],
[
sb_cv_lib_ck=[system]
], [
sb_cv_lib_ck=[bundled]
])
])
AS_IF([test "x$sb_cv_lib_ck" = "xsystem"],
# let PKG_CHECK_MODULES set CK_CFLAGS and CK_LIBS for system libck
[PKG_CHECK_MODULES([CK], [ck])],
# Set CK_CFLAGS and CK_LIBS manually for bundled libck
[
CK_CFLAGS="-I\$(abs_top_builddir)/third_party/concurrency_kit/include"
CK_LIBS="\$(abs_top_builddir)/third_party/concurrency_kit/lib/libck.a"
case $target_cpu in
powerpc*|aarch64)
# Assume 128-byte cache line on AArch64 and PowerPC
CPPFLAGS="${CPPFLAGS} -DCK_MD_CACHELINE=128"
;;
# Force --platform=i*86 for CK, otherwise its configure script
# autodetects target based on 'uname -m' which doesn't work for
# cross-compiliation
i486*|i586*)
CK_CONFIGURE_FLAGS="--platform=i586"
;;
i686*)
CK_CONFIGURE_FLAGS="--platform=i686"
;;
mips64*)
CK_CONFIGURE_FLAGS="--use-cc-builtins"
;;
esac
# Add --enable-lse to CK build flags, if LSE instructions are supported by
# the target architecture
if test "$cross_compiling" = no -a "$host_cpu" = aarch64; then
AC_MSG_CHECKING([whether LSE instructions are supported])
AC_COMPILE_IFELSE(
[AC_LANG_PROGRAM(,
[[
unsigned long long d = 1, a = 1;
unsigned long long *t = &a;
__asm__ __volatile__(
"stadd %0, [%1];"
: "+&r" (d)
: "r" (t)
: "memory");
]])],
[
CK_CONFIGURE_FLAGS="--enable-lse"
AC_MSG_RESULT([yes])
],
[
CK_CONFIGURE_FLAGS=""
AC_MSG_RESULT([no])
]
)
AC_SUBST([CK_CONFIGURE_FLAGS])
fi
]
)
AC_DEFINE_UNQUOTED([SB_WITH_CK], ["$sb_use_ck"],
[Whether system or bundled Concurrency Ki is used])
AM_CONDITIONAL([USE_BUNDLED_CK], [test "x$sb_use_ck" = xbundled])
])

View File

@ -0,0 +1,72 @@
# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
# ---------------------------------------------------------------------------
# Macro: SB_LUAJIT
# ---------------------------------------------------------------------------
AC_DEFUN([SB_LUAJIT], [
AC_ARG_WITH([system-luajit],
AC_HELP_STRING([--with-system-luajit],
[Use system-provided LuaJIT headers and library (requires pkg-config)]),
[sb_use_luajit="system"],
[sb_use_luajit="bundled"])
AC_CACHE_CHECK([whether to build with system or bundled LuaJIT],
[sb_cv_lib_luajit], [
AS_IF([test "x$sb_use_luajit" = "xsystem"],
[
sb_cv_lib_luajit=[system]
], [
sb_cv_lib_luajit=[bundled]
])
])
AS_IF([test "x$sb_cv_lib_luajit" = "xsystem"],
# let PKG_CHECK_MODULES set LUAJIT_CFLAGS and LUAJIT_LIBS for system libluajit
[PKG_CHECK_MODULES([LUAJIT], [luajit])],
# Set LUAJIT_CFLAGS and LUAJIT_LIBS manually for bundled libluajit
[
LUAJIT_CFLAGS="-I\$(abs_top_builddir)/third_party/luajit/inc"
LUAJIT_LIBS="\$(abs_top_builddir)/third_party/luajit/lib/libluajit-5.1.a"
]
)
AC_DEFINE_UNQUOTED([SB_WITH_LUAJIT], ["$sb_use_luajit"],
[Whether system or bundled LuaJIT is used])
AM_CONDITIONAL([USE_BUNDLED_LUAJIT], [test "x$sb_use_luajit" = xbundled])
AS_CASE([$host_os:$host_cpu],
# Add extra flags when building a 64-bit application on OS X,
# http://luajit.org/install.html
[*darwin*:x86_64],
[LUAJIT_LDFLAGS="-pagezero_size 10000 -image_base 100000000"],
# -ldl and -rdynamic are required on Linux
[*linux*:*],
[
LUAJIT_LIBS="$LUAJIT_LIBS -ldl"
LUAJIT_LDFLAGS="-rdynamic"
],
# -rdynamic is required on FreeBSD
[*freebsd*:*],
[
LUAJIT_LDFLAGS="-rdynamic"
]
)
AC_SUBST([LUAJIT_LDFLAGS])
])

View File

@ -0,0 +1,336 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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, 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.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing 0.4 - GNU automake"
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
aclocal*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;
tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0

View File

@ -0,0 +1,111 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain
errstatus=0
dirmode=""
usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."
# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage" 1>&2
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done
for file
do
if test -d "$file"; then
shift
else
break
fi
done
case $# in
0) exit 0 ;;
esac
case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi
;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi
;;
esac
for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift
pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac
if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"
mkdir "$pathcomp" || lasterr=$?
if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?
if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi
pathcomp="$pathcomp/"
done
done
exit $errstatus
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# End:
# mkinstalldirs ends here

View File

@ -0,0 +1,181 @@
Summary: Scriptable database and system performance benchmark
Name: sysbench
# Version will be replaced by packpack
Version: x.y.z
Release: 1%{?dist}
License: GPLv2+
Group: Applications/System
Source0: https://github.com/akopytov/%{name}/archive/%{version}/%{name}-%{version}.tar.gz
URL: https://github.com/akopytov/sysbench/
%if 0%{?rhel} < 7
BuildRequires: mysql-devel
%else
BuildRequires: mariadb-devel
%endif
BuildRequires: postgresql-devel
BuildRequires: make
BuildRequires: automake
BuildRequires: libtool
BuildRequires: pkgconfig
BuildRequires: libaio-devel
# Use bundled cram for tests
%if 0%{?rhel} > 7
BuildRequires: python2
%else
BuildRequires: python
%endif
ExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64
%description
sysbench is a scriptable multi-threaded benchmark tool based on
LuaJIT. It is most frequently used for database benchmarks, but can also
be used to create arbitrarily complex workloads that do not involve a
database server.
sysbench comes with the following bundled benchmarks:
- oltp_*.lua: a collection of OLTP-like database benchmarks
- fileio: a filesystem-level benchmark
- cpu: a simple CPU benchmark
- memory: a memory access benchmark
- threads: a thread-based scheduler benchmark
- mutex: a POSIX mutex benchmark
%prep
%setup -q
%build
export CFLAGS="%{optflags}"
autoreconf -vif
%configure --with-mysql \
--with-pgsql \
--without-gcc-arch
%if 0%{?el6}
make -j2
%else
%make_build
%endif
%install
%make_install
rm -f %{buildroot}%{_docdir}/sysbench/manual.html
%check
make test
%files
%doc ChangeLog COPYING README.md
%if 0%{?el6}
%else
%license COPYING
%endif
%{_bindir}/*
%{_datadir}/%{name}
%changelog
* Fri Mar 15 2019 Alexey Bychko <abychko@gmail.com> - 1.0.16-1
- Updated build dependencies for RHEL8-Beta.
* Sat Jan 6 2018 Alexey Kopytov <akopytov@gmail.com> - 1.0.12-1
- Remove vim-common from build dependencies.
* Sun Apr 09 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1
- Add --without-gcc-arch to configure flags
* Sat Apr 08 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1
- Workarounds for make_build and license macros which are not available on EL 6.
* Fri Apr 07 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1
- Depend on mysql-devel rather than mariadb-devel on EL 6.
- Use bundled cram for tests, because it's not available on EL 6.
* Thu Apr 06 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1
- Reuse downstream Fedora spec with modifications (prefer bundled libraries)
* Mon Mar 13 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.4-2
- Don't build aarch64 on el7.
* Mon Mar 13 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.4-1
- Fix build for i686.
- Drop bundled cram.
* Wed Mar 08 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.3-1
- Update to 1.0.3 (RHBZ#1424670).
- Restrict arches to the same ones as luajit.
- Add --with-gcc-arch=native to configure for %%{arm} and aarch64.
- Ignore test suite results for aarch64, it segfaults in koji.
* Sat Feb 25 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.2-2
- Run test suite.
* Sat Feb 25 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.2-1
- Update to 1.0.2 (RHBZ#1424670).
* Sun Feb 12 2017 Honza Horak <hhorak@redhat.com> - 1.0.0-1
- Update to the first proper release 1.0.0
* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.4.12-15
- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.4.12-14
- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-13
- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
* Thu Sep 04 2014 Xavier Bachelot <xavier@bachelot.org> 0.4.12-12
- Modernize specfile.
* Mon Aug 18 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-11
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-10
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
* Sun Aug 04 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild
* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-8
- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild
* Sat Jul 21 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-7
- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-6
- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
* Tue Sep 06 2011 Xavier Bachelot <xavier@bachelot.org> 0.4.12-5
- Add BR: libaio-devel (rhbz#735882).
* Wed Mar 23 2011 Dan Horák <dan@danny.cz> - 0.4.12-4
- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)
* Wed Feb 09 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-3
- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
* Fri Dec 24 2010 Xavier Bachelot <xavier@bachelot.org> 0.4.12-2
- Rebuild against new mysql.
* Wed Jul 07 2010 Xavier Bachelot <xavier@bachelot.org> 0.4.12-1
- Update to 0.4.12.
* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 0.4.10-5
- rebuilt with new openssl
* Sun Jul 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.10-4
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
* Wed Mar 18 2009 Xavier Bachelot <xavier@bachelot.org> 0.4.10-3
- License is GPLv2+, not GPLv2.
* Sat Mar 14 2009 Xavier Bachelot <xavier@bachelot.org> 0.4.10-2
- Make postgres support optional, the version in rhel4 is too old.
- Drop TODO and manual.html from %%doc, they are empty.
* Thu Mar 05 2009 Xavier Bachelot <xavier@bachelot.org> 0.4.10-1
- Adapt original spec file taken from PLD.

View File

@ -0,0 +1,197 @@
#!/usr/bin/env bash
#
# Copyright (C) 2017-2019 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
# Build packages for a specified architecture and upload them to packagecloud.io
# Expects the following environment variables to be defined:
#
# ARCH - architecture. 'aarch64', 'x86_64 and 'i386' are currently supported
# values. If not set, the script behaves as if it was sequentially
# called with 'x86_64' and 'i386' values
#
# OS/DIST - distribution specification for packpack. When empty (the default)
# use all disitributions available for ARCH
#
# PACKAGECLOUD_TOKEN - packagecloud.io API token
#
# PACKAGECLOUD_USER - packagecloud.io user name, defaults to 'akopytov'
#
# PACKAGECLOUD_REPO - packagecloud.io repository. The default is 'sysbench'
# for releases (i.e. if git HEAD corresponds to a tag),
# and 'sysbench-prereleases' otherwise.
#
# PACKAGECLOUD_EXTRA_ARGS - extra arguments to pass to the package_cloud
# utility. Empty by default. Can be used to pass the
# --skip-errors flag to ignore deploy errors.
#
# PACKPACK_REPO - packpack repository to use. Defaults to akopytov/packpack.
set -eu
PACKAGECLOUD_USER=${PACKAGECLOUD_USER:-"akopytov"}
PACKAGECLOUD_EXTRA_ARGS=${PACKAGECLOUD_EXTRA_ARGS:-}
PACKPACK_REPO=${PACKPACK_REPO:-akopytov/packpack}
distros_x86_64=(
"el 6 x86_64"
"el 7 x86_64"
"el 8 x86_64"
"fedora 29 x86_64"
"fedora 30 x86_64"
"fedora 31 x86_64"
"ubuntu xenial x86_64"
"ubuntu bionic x86_64"
"ubuntu eoan x86_64"
"ubuntu focal x86_64"
"debian jessie x86_64"
"debian stretch x86_64"
"debian buster x86_64"
)
distros_i386=(
"ubuntu xenial i386"
"ubuntu bionic i386"
"ubuntu eoan i386"
"debian jessie i386"
"debian stretch i386"
"debian buster i386"
)
distros_aarch64=(
"el 7 aarch64"
"fedora 29 aarch64"
"fedora 30 aarch64"
"fedora 31 aarch64"
"ubuntu bionic aarch64"
"ubuntu eoan aarch64"
"ubuntu focal aarch64"
"ubuntu xenial aarch64"
"debian jessie aarch64"
"debian stretch aarch64"
"debian buster aarch64"
)
main()
{
if [ ! -r configure.ac ]; then
echo "This script should be executed from the source root directory."
exit 1
fi
if [ -z "${PACKAGECLOUD_TOKEN+x}" ]; then
echo "This script expects PACKAGECLOUD_TOKEN to be defined."
exit 1
fi
if [ ! which package_cloud >/dev/null 2>&1 ]; then
echo "This script requires package_cloud. You can install it by running:"
echo " gem install package_cloud"
fi
if [ ! -d packpack ]; then
git clone https://github.com/${PACKPACK_REPO} packpack
fi
if [ -z "${PACKAGECLOUD_REPO+x}" ]; then
# Upload builds corresponding to release tags to the 'sysbench'
# repository, push other ones to 'sysbench-prereleases'
if ! git describe --long --always >/dev/null 2>&1 ; then
echo "Either run this script from a git repository, or specify "
echo "the packagecloud repository explicitly with PACKAGECLOUD_REPO"
exit 1
fi
local commits=$(git describe --long --always |
sed -n 's/^\([0-9\.]*\)-\([0-9]*\)-\([a-z0-9]*\)/\2/p')
if [ ${commits:-0} = 0 ]; then
export PACKAGECLOUD_REPO=sysbench
# Use short version numbers for release builds
export VERSION=$(git describe)
else
export PACKAGECLOUD_REPO=sysbench-prereleases
fi
fi
declare -a distros
OS=${OS:-}
DIST=${DIST:-}
if [ -n "${OS}" -a -n "${DIST}" ]; then
distros=( "${OS} ${DIST} ${ARCH:-x86_64}" )
elif [ -z "${ARCH+x}" ]; then
distros=("${distros_x86_64[@]}" "${distros_i386[@]}")
else
case "$ARCH" in
x86_64)
distros=( "${distros_x86_64[@]}" )
;;
i386)
distros=( "${distros_i386[@]}" )
;;
aarch64)
distros=( "${distros_aarch64[@]}" )
;;
*)
echo "Invalid ARCH value: $ARCH"
exit 1
;;
esac
fi
export PRODUCT=sysbench
export CHANGELOG_NAME=sysbench
export CHANGELOG_EMAIL=akopytov@gmail.com
for d in "${distros[@]}"; do
echo "*** Building package for $d ***"
local t=( $d )
export OS=${t[0]}
export DIST=${t[1]}
export ARCH=${t[2]}
# Replace "el" with "centos" for packpack, as there is no "el-*" docker
# images for some architectures
local PPOS=${OS/#el/centos}
OS="$PPOS" packpack/packpack
# To avoid name conflicts, deploy source packages only for
# "default", i.e. x86_64 architecture
if [ "${ARCH}" = "x86_64" ]; then
files="$(ls build/*.{rpm,deb,dsc} 2>/dev/null || :)"
else
files="$(ls build/*{[^c].rpm,.deb} 2>/dev/null || :)"
fi
if [ -z "$files" ]; then
echo "No package files to push"
exit 1
fi
echo "Pushing packages to ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO}"
for f in $files ; do
echo $f
package_cloud push ${PACKAGECLOUD_EXTRA_ARGS} \
${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO}/${OS}/${DIST} \
$f
done
OS=${PPOS} packpack/packpack clean
done
}
main

View File

@ -0,0 +1,36 @@
name: sysbench
version: @PACKAGE_VERSION@
summary: Scriptable database and system performance benchmark
description: |
sysbench is a scriptable multi-threaded benchmark tool based on
LuaJIT. It is most frequently used for database benchmarks, but can also
be used to create arbitrarily complex workloads that do not involve a
database server.
sysbench comes with the following bundled benchmarks:
- oltp_*.lua: a collection of OLTP-like database benchmarks
- fileio: a filesystem-level benchmark
- cpu: a simple CPU benchmark
- memory: a memory access benchmark
- threads: a thread-based scheduler benchmark
- mutex: a POSIX mutex benchmark
grade: stable
confinement: classic
apps:
sysbench:
command: sysbench
plugs:
- network
parts:
sysbench:
source: .
plugin: autotools
build-packages:
- libmysqlclient-dev
stage-packages:
- libmysqlclient20
- libaio1

View File

@ -0,0 +1,113 @@
# Copyright (C) 2008 MySQL AB
# Copyright (C) 2008-2017 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
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_histogram.c
sb_histogram.h
sb_list.h
db_driver.h
db_driver.c
sb_win.c
sb_win.h
sb_rand.c
sb_rand.h
sb_thread.c
sb_thread.h
sb_barrier.c
sb_barrier.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)
add_subdirectory(tests/threads)
target_link_libraries (sysbench sbthreads)
add_subdirectory(tests/memory)
target_link_libraries (sysbench sbmemory)

View File

@ -0,0 +1,65 @@
# Copyright (C) 2004 MySQL AB
# Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
SUBDIRS = drivers tests lua .
AM_CPPFLAGS += -DDATADIR=\"$(pkgdatadir)\" -DLIBDIR=\"$(pkglibdir)\"
bin_PROGRAMS = sysbench
EXTRA_LDFLAGS = @EXTRA_LDFLAGS@
# The following check will be extended as new database drivers will be added
if USE_MYSQL
mysql_ldadd = drivers/mysql/libsbmysql.a $(MYSQL_LIBS)
endif
if USE_DRIZZLE
drizzle_ldadd = drivers/drizzle/libsbdrizzle.a $(LIBDRIZZLE)
endif
if USE_ATTACHSQL
attachsql_ldadd = drivers/attachsql/libsbattachsql.a $(LIBATTACHSQL)
endif
if USE_ORACLE
ora_ldadd = drivers/oracle/libsboracle.a $(ORA_LIBS)
endif
if USE_PGSQL
pgsql_ldadd = drivers/pgsql/libsbpgsql.a $(PGSQL_LIBS)
endif
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_histogram.c sb_histogram.h sb_rand.c sb_rand.h \
sb_thread.c sb_thread.h sb_barrier.c sb_barrier.h sb_lua.c \
sb_ck_pr.h \
sb_lua.h sb_util.h sb_util.c sb_counter.h sb_counter.c \
lua/internal/sysbench.lua.h lua/internal/sysbench.sql.lua.h \
lua/internal/sysbench.rand.lua.h lua/internal/sysbench.cmdline.lua.h \
lua/internal/sysbench.compat.lua.h lua/internal/sysbench.histogram.lua.h \
xoroshiro128plus.h
sysbench_LDADD = tests/fileio/libsbfileio.a tests/threads/libsbthreads.a \
tests/memory/libsbmemory.a tests/cpu/libsbcpu.a \
tests/mutex/libsbmutex.a \
$(mysql_ldadd) $(drizzle_ldadd) $(attachsql_ldadd) $(pgsql_ldadd) \
$(ora_ldadd) $(LUAJIT_LIBS) $(CK_LIBS)
sysbench_LDFLAGS = $(EXTRA_LDFLAGS) $(mysql_ldflags) $(attachsql_ldflags) \
$(pgsql_ldflags) $(ora_ldflags) $(LUAJIT_LDFLAGS)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,346 @@
/* Copyright (C) 2004 MySQL AB
Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifndef DB_DRIVER_H
#define DB_DRIVER_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "sysbench.h"
#include "sb_list.h"
#include "sb_histogram.h"
#include "sb_counter.h"
/* Prepared statements usage modes */
typedef enum
{
DB_PS_MODE_AUTO,
DB_PS_MODE_DISABLE,
} db_ps_mode_t;
/* Global DB API options */
typedef struct
{
db_ps_mode_t ps_mode; /* Requested prepared statements usage mode */
char *driver; /* Requested database driver */
unsigned char debug; /* debug flag */
} db_globals_t;
/* Driver capabilities definition */
typedef struct
{
char multi_rows_insert; /* 1 if database supports multi-row inserts */
char prepared_statements; /* 1 if database supports prepared statements */
char auto_increment; /* 1 if database supports AUTO_INCREMENT clause */
char needs_commit; /* 1 if database needs explicit commit after INSERTs */
char serial; /* 1 if database supports SERIAL clause */
char unsigned_int; /* 1 if database supports UNSIGNED INTEGER types */
} drv_caps_t;
/* Database errors definition */
typedef enum
{
DB_ERROR_NONE, /* no error(s) */
DB_ERROR_IGNORABLE, /* error should be ignored as defined by command
line arguments or a custom error handler */
DB_ERROR_FATAL /* non-ignorable error */
} db_error_t;
/* Available buffer types (for parameters binding) */
typedef enum
{
DB_TYPE_NONE,
DB_TYPE_TINYINT,
DB_TYPE_SMALLINT,
DB_TYPE_INT,
DB_TYPE_BIGINT,
DB_TYPE_FLOAT,
DB_TYPE_DOUBLE,
DB_TYPE_TIME,
DB_TYPE_DATE,
DB_TYPE_DATETIME,
DB_TYPE_TIMESTAMP,
DB_TYPE_CHAR,
DB_TYPE_VARCHAR
} db_bind_type_t;
/* Structure used to represent DATE, TIME, DATETIME and TIMESTAMP values */
typedef struct
{
unsigned int year;
unsigned int month;
unsigned int day;
unsigned int hour;
unsigned int minute;
unsigned int second;
} db_time_t;
/* Structure used to bind data for prepared statements */
typedef struct
{
db_bind_type_t type;
void *buffer;
unsigned long *data_len;
unsigned long max_len;
char *is_null;
} db_bind_t;
/* Forward declarations */
struct db_conn;
struct db_stmt;
struct db_result;
struct db_row;
/* Driver operations definition */
typedef int drv_op_init(void);
typedef int drv_op_thread_init(int);
typedef int drv_op_describe(drv_caps_t *);
typedef int drv_op_connect(struct db_conn *);
typedef int drv_op_reconnect(struct db_conn *);
typedef int drv_op_disconnect(struct db_conn *);
typedef int drv_op_prepare(struct db_stmt *, const char *, size_t);
typedef int drv_op_bind_param(struct db_stmt *, db_bind_t *, size_t);
typedef int drv_op_bind_result(struct db_stmt *, db_bind_t *, size_t);
typedef db_error_t drv_op_execute(struct db_stmt *, struct db_result *);
typedef int drv_op_fetch(struct db_result *);
typedef int drv_op_fetch_row(struct db_result *, struct db_row *);
typedef db_error_t drv_op_query(struct db_conn *, const char *, size_t,
struct db_result *);
typedef int drv_op_free_results(struct db_result *);
typedef int drv_op_close(struct db_stmt *);
typedef int drv_op_thread_done(int);
typedef int drv_op_done(void);
typedef struct
{
drv_op_init *init; /* initializate driver */
drv_op_thread_init *thread_init; /* thread-local driver initialization */
drv_op_describe *describe; /* describe database capabilities */
drv_op_connect *connect; /* connect to database */
drv_op_disconnect *disconnect; /* disconnect from database */
drv_op_reconnect *reconnect; /* reconnect with the same parameters */
drv_op_prepare *prepare; /* prepare statement */
drv_op_bind_param *bind_param; /* bind params for prepared statement */
drv_op_bind_result *bind_result; /* bind results for prepared statement */
drv_op_execute *execute; /* execute prepared statement */
drv_op_fetch *fetch; /* fetch row for prepared statement */
drv_op_fetch_row *fetch_row; /* fetch row for queries */
drv_op_free_results *free_results; /* free result set */
drv_op_close *close; /* close prepared statement */
drv_op_query *query; /* execute non-prepared statement */
drv_op_thread_done *thread_done; /* thread-local driver deinitialization */
drv_op_done *done; /* uninitialize driver */
} drv_ops_t;
/* Database driver definition */
typedef struct
{
const char *sname; /* short name */
const char *lname; /* long name */
sb_arg_t *args; /* driver command line arguments */
drv_ops_t ops; /* driver operations */
sb_list_item_t listitem; /* can be linked in a list */
bool initialized;
pthread_mutex_t mutex;
} db_driver_t;
/* Row value definition */
typedef struct {
uint32_t len; /* Value length */
const char *ptr; /* Value string */
} db_value_t;
/* Result set row definition */
typedef struct db_row
{
void *ptr; /* Driver-specific row data */
db_value_t *values; /* Array of column values */
} db_row_t;
/* Result set definition */
typedef struct db_result
{
sb_counter_type_t counter; /* Statistical counter type */
uint32_t nrows; /* Number of affected rows */
uint32_t nfields; /* Number of fields */
struct db_stmt *statement; /* Pointer to prepared statement (if used) */
void *ptr; /* Pointer to driver-specific data */
db_row_t row; /* Last fetched row */
} db_result_t;
typedef enum {
DB_CONN_READY,
DB_CONN_RESULT_SET,
DB_CONN_INVALID
} db_conn_state_t;
/* Database connection structure */
typedef struct db_conn
{
db_error_t error; /* Database-independent error code */
int sql_errno; /* Database-specific error code */
const char *sql_state; /* Database-specific SQL state */
const char *sql_errmsg; /* Database-specific error message */
db_driver_t *driver; /* DB driver for this connection */
void *ptr; /* Driver-specific data */
db_result_t rs; /* Result set */
db_conn_state_t state; /* Connection state */
int thread_id; /* Thread this connection belongs to */
unsigned int bulk_cnt; /* Current number of rows in bulk insert buffer */
unsigned int bulk_buflen; /* Current length of bulk_buffer */
char *bulk_buffer; /* Bulk insert query buffer */
unsigned int bulk_ptr; /* Current position in bulk_buffer */
unsigned int bulk_values; /* Save value of bulk_ptr */
unsigned int bulk_commit_cnt; /* Current value of uncommitted rows */
unsigned int bulk_commit_max; /* Maximum value of uncommitted rows */
char pad[SB_CACHELINE_PAD(sizeof(db_error_t) +
sizeof(int) +
sizeof(void *) +
sizeof(void *) +
sizeof(void *) +
sizeof(void *) +
sizeof(db_result_t) +
sizeof(db_conn_state_t) +
sizeof(int) +
sizeof(int) * 2 +
sizeof(void *) +
sizeof(int) * 4
)];
} db_conn_t;
/* Prepared statement definition */
typedef struct db_stmt
{
db_conn_t *connection; /* Connection which this statement belongs to */
char *query; /* Query string for emulated PS */
db_bind_t *bound_param; /* Array of bound parameters for emulated PS */
unsigned int bound_param_len; /* Length of the bound_param array */
db_bind_t *bound_res; /* Array of bound results for emulated PS */
db_bind_t *bound_res_len; /* Length of the bound_res array */
char emulated; /* Should this statement be emulated? */
sb_counter_type_t counter; /* Query type */
void *ptr; /* Pointer to driver-specific data structure */
} db_stmt_t;
extern db_globals_t db_globals;
/* Database abstraction layer calls */
int db_register(void);
void db_print_help(void);
db_driver_t *db_create(const char *);
int db_destroy(db_driver_t *);
int db_describe(db_driver_t *, drv_caps_t *);
db_conn_t *db_connection_create(db_driver_t *);
int db_connection_close(db_conn_t *);
int db_connection_reconnect(db_conn_t *con);
void db_connection_free(db_conn_t *con);
db_stmt_t *db_prepare(db_conn_t *, const char *, size_t);
int db_bind_param(db_stmt_t *, db_bind_t *, size_t);
int db_bind_result(db_stmt_t *, db_bind_t *, size_t);
db_result_t *db_execute(db_stmt_t *);
db_row_t *db_fetch_row(db_result_t *);
db_result_t *db_query(db_conn_t *, const char *, size_t len);
int db_free_results(db_result_t *);
int db_store_results(db_result_t *);
int db_close(db_stmt_t *);
void db_done(void);
int db_print_value(db_bind_t *, char *, int);
/* Initialize multi-row insert operation */
int db_bulk_insert_init(db_conn_t *, const char *, size_t);
/* Add row to multi-row insert operation */
int db_bulk_insert_next(db_conn_t *, const char *, size_t);
/* Finish multi-row insert operation */
int db_bulk_insert_done(db_conn_t *);
/* Print database-specific test stats */
void db_report_intermediate(sb_stat_t *);
void db_report_cumulative(sb_stat_t *);
/* DB drivers registrars */
#ifdef USE_MYSQL
int register_driver_mysql(sb_list_t *);
#endif
#ifdef USE_DRIZZLE
int register_driver_drizzle(sb_list_t *);
#endif
#ifdef USE_ATTACHSQL
int register_driver_attachsql(sb_list_t *);
#endif
#ifdef USE_DRIZZLECLIENT
int register_driver_drizzleclient(sb_list_t *);
#endif
#ifdef USE_ORACLE
int register_driver_oracle(sb_list_t *);
#endif
#ifdef USE_PGSQL
int register_driver_pgsql(sb_list_t *);
#endif
#endif /* DB_DRIVER_H */

View File

@ -0,0 +1,38 @@
# Copyright (C) 2004 MySQL AB
# Copyright (C) 2004-2014 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
if USE_MYSQL
MYSQL_DIR = mysql
endif
if USE_DRIZZLE
DRIZZLE_DIR = drizzle
endif
if USE_ATTACHSQL
ATTACHSQL_DIR = attachsql
endif
if USE_ORACLE
ORACLE_DIR = oracle
endif
if USE_PGSQL
PGSQL_DIR = pgsql
endif
SUBDIRS = $(MYSQL_DIR) $(ORACLE_DIR) $(PGSQL_DIR) $(DRIZZLE_DIR) $(ATTACHSQL_DIR)

View File

@ -0,0 +1,21 @@
# Copyright 2014 Hewlett-Packard Development Company, L.P.
# based on the Drizzle driver:
# Copyright (C) 2009 Sun Microsystems, Inc.
#
# 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
noinst_LIBRARIES = libsbattachsql.a
libsbattachsql_a_SOURCES = drv_attachsql.c

View File

@ -0,0 +1,622 @@
/* Copyright 2014 Hewlett-Packard Development Company, L.P.
based on the Drizzle driver:
Copyright (C) 2009 Sun Microsystems, Inc.
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <libattachsql-1.0/attachsql.h>
#include "sb_options.h"
#include "db_driver.h"
#define DEBUG(format, ...) do { if (db_globals.debug) log_text(LOG_DEBUG, format, __VA_ARGS__); } while (0)
/* Drizzle driver arguments */
static sb_arg_t attachsql_drv_args[] =
{
{"attachsql-host", "libAttachSQL server host", SB_ARG_TYPE_LIST, "localhost"},
{"attachsql-port", "libAttachSQL server port", SB_ARG_TYPE_INT, "4427"},
{"attachsql-socket", "libAttachSQL socket", SB_ARG_TYPE_STRING, NULL},
{"attachsql-user", "libAttachSQL user", SB_ARG_TYPE_STRING, ""},
{"attachsql-password", "libAttachSQL password", SB_ARG_TYPE_STRING, ""},
{"attachsql-db", "libAttachSQL database name", SB_ARG_TYPE_STRING, "sbtest"},
{NULL, NULL, SB_ARG_TYPE_NULL, NULL}
};
typedef struct
{
sb_list_t *hosts;
unsigned int port;
char *socket;
char *user;
char *password;
char *db;
} attachsql_drv_args_t;
/* AttachSQL driver capabilities
* At a later date we will add prepared statements to this
*/
static drv_caps_t attachsql_drv_caps =
{
.multi_rows_insert = 1,
.prepared_statements = 1,
.auto_increment = 1,
.serial = 0,
.unsigned_int = 0,
};
static attachsql_drv_args_t args; /* driver args */
static sb_list_item_t *hosts_pos;
static pthread_mutex_t hosts_mutex;
/* libAttachSQL driver operations */
static int attachsql_drv_init(void);
static int attachsql_drv_describe(drv_caps_t *);
static int attachsql_drv_connect(db_conn_t *);
static int attachsql_drv_disconnect(db_conn_t *);
static int attachsql_drv_prepare(db_stmt_t *, const char *, size_t);
static int attachsql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t);
static int attachsql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t);
static db_error_t attachsql_drv_execute(db_stmt_t *, db_result_t *);
static int attachsql_drv_fetch(db_result_t *);
static int attachsql_drv_fetch_row(db_result_t *, db_row_t *);
static db_error_t attachsql_drv_query(db_conn_t *, const char *, size_t,
db_result_t *);
static int attachsql_drv_free_results(db_result_t *);
static int attachsql_drv_close(db_stmt_t *);
static int attachsql_drv_store_results(db_result_t *);
static int attachsql_drv_done(void);
/* libAttachSQL driver definition */
static db_driver_t attachsql_driver =
{
.sname = "attachsql",
.lname = "libAttachSQL driver",
.args = attachsql_drv_args,
.ops =
{
.init = attachsql_drv_init,
.describe = attachsql_drv_describe,
.connect = attachsql_drv_connect,
.disconnect = attachsql_drv_disconnect,
.prepare = attachsql_drv_prepare,
.bind_param = attachsql_drv_bind_param,
.bind_result = attachsql_drv_bind_result,
.execute = attachsql_drv_execute,
.fetch = attachsql_drv_fetch,
.fetch_row = attachsql_drv_fetch_row,
.free_results = attachsql_drv_free_results,
.close = attachsql_drv_close,
.query = attachsql_drv_query,
.store_results = attachsql_drv_store_results,
.done = attachsql_drv_done
}
};
/* Local functions */
/* Register libAttachSQL driver */
int register_driver_attachsql(sb_list_t *drivers)
{
SB_LIST_ADD_TAIL(&attachsql_driver.listitem, drivers);
return 0;
}
/* libAttachSQL driver initialization */
int attachsql_drv_init(void)
{
args.hosts = sb_get_value_list("attachsql-host");
if (SB_LIST_IS_EMPTY(args.hosts))
{
log_text(LOG_FATAL, "No libAttachSQL hosts specified, aborting");
return 1;
}
hosts_pos = args.hosts;
pthread_mutex_init(&hosts_mutex, NULL);
args.port = (unsigned int)sb_get_value_int("attachsql-port");
args.socket = sb_get_value_string("attachsql-socket");
args.user = sb_get_value_string("attachsql-user");
args.password = sb_get_value_string("attachsql-password");
args.db = sb_get_value_string("attachsql-db");
attachsql_library_init();
return 0;
}
/* Describe database capabilities (possibly depending on table type) */
int attachsql_drv_describe(drv_caps_t *caps )
{
*caps = attachsql_drv_caps;
return 0;
}
/* Connect to libAttachSQL database */
int attachsql_drv_connect(db_conn_t *sb_conn)
{
attachsql_connect_t *con= NULL;
const char *host;
attachsql_error_t *error= NULL;
attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
if (args.socket)
{
DEBUG("attachsql_connect_create(\"%s\", \"%s\", \"%s\", \"%s\")",
args.socket,
args.user,
args.password,
args.db);
con= attachsql_connect_create(args.socket,
0,
args.user,
args.password,
args.db,
&error);
} else {
pthread_mutex_lock(&hosts_mutex);
hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);
if (hosts_pos == args.hosts)
hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);
host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data;
pthread_mutex_unlock(&hosts_mutex);
DEBUG("attachsql_connect_create(\"%s\", %u, \"%s\", \"%s\", \"%s\")",
host,
args.port,
args.user,
args.password,
args.db);
con= attachsql_connect_create(host,
args.port,
args.user,
args.password,
args.db,
&error);
}
if (con == NULL)
{
log_text(LOG_FATAL, "unable to Add libAttachSQL Connection, aborting...");
log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
return 1;
}
attachsql_connect_set_option(con, ATTACHSQL_OPTION_SEMI_BLOCKING, NULL);
if (!attachsql_connect(con, &error))
{
log_text(LOG_FATAL, "unable to connect to libAttachSQL server");
log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
attachsql_connect_destroy(con);
return 1;
}
while (aret != ATTACHSQL_RETURN_IDLE)
{
aret = attachsql_connect_poll(con, &error);
if (error)
{
log_text(LOG_FATAL, "unable to connect to libAttachSQL server");
log_text(LOG_FATAL, "error %d: %s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
attachsql_connect_destroy(con);
return 1;
}
}
sb_conn->ptr = con;
return 0;
}
/* Disconnect from libAttachSQL database */
int attachsql_drv_disconnect(db_conn_t *sb_conn)
{
attachsql_connect_t *con = (attachsql_connect_t *)sb_conn->ptr;
if (con != NULL)
{
DEBUG("attachsql_connect_destroy(%p)", con);
attachsql_connect_destroy(con);
}
return 0;
}
/* Prepare statement */
int attachsql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len)
{
attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr;
attachsql_error_t *error= NULL;
attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
attachsql_statement_prepare(con, len, query, &error);
while(aret != ATTACHSQL_RETURN_EOF)
{
aret= attachsql_connect_poll(con, &error);
if (error)
{
log_text(LOG_ALERT, "libAttachSQL Prepare Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
return DB_ERROR_FATAL;
}
}
return 0;
}
/* Bind parameters for prepared statement */
int attachsql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len)
{
/* libAttachSQL doesn't do this, you do this during execute
* this is because sysbench doesn't set the values until that time
*/
if (stmt->bound_param != NULL)
free(stmt->bound_param);
stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t));
if (stmt->bound_param == NULL)
return 1;
memcpy(stmt->bound_param, params, len * sizeof(db_bind_t));
stmt->bound_param_len = len;
return 0;
}
/* Bind results for prepared statement */
int attachsql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len)
{
(void)stmt;
(void)params;
(void)len;
/* libAttachSQL doesn't do this, you get after execute */
return 0;
}
/* Execute prepared statement */
db_error_t attachsql_drv_execute(db_stmt_t *stmt, db_result_t *rs)
{
(void) rs;
attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr;
attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
attachsql_error_t *error= NULL;
uint16_t i;
int8_t tinyint;
int16_t smallint;
int32_t normalint;
int64_t bigint;
float float_type;
double double_type;
db_time_t *time_data;
if (con == NULL)
return 1;
for (i= 0; i < stmt->bound_param_len; i++)
{
db_bind_t *param= &stmt->bound_param[i];
switch(param->type)
{
case DB_TYPE_TINYINT:
tinyint= *(int8_t*)param->buffer;
attachsql_statement_set_int(con, i, tinyint, NULL);
break;
case DB_TYPE_SMALLINT:
smallint= *(int16_t*)param->buffer;
attachsql_statement_set_int(con, i, smallint, NULL);
break;
case DB_TYPE_INT:
normalint= *(int32_t*)param->buffer;
attachsql_statement_set_int(con, i, normalint, NULL);
break;
case DB_TYPE_BIGINT:
bigint= *(int64_t*)param->buffer;
attachsql_statement_set_bigint(con, i, bigint, NULL);
break;
case DB_TYPE_FLOAT:
float_type= *(float*)param->buffer;
attachsql_statement_set_float(con, i, float_type, NULL);
break;
case DB_TYPE_DOUBLE:
double_type= *(double*)param->buffer;
attachsql_statement_set_double(con, i, double_type, NULL);
break;
case DB_TYPE_TIME:
time_data= (db_time_t*)param->buffer;
attachsql_statement_set_time(con, i, time_data->hour, time_data->minute, time_data->second, 0, false, NULL);
break;
case DB_TYPE_DATE:
case DB_TYPE_DATETIME:
case DB_TYPE_TIMESTAMP:
time_data= (db_time_t*)param->buffer;
attachsql_statement_set_datetime(con, i, time_data->year, time_data->month, time_data->day, time_data->hour, time_data->minute, time_data->second, 0, NULL);
break;
case DB_TYPE_CHAR:
case DB_TYPE_VARCHAR:
attachsql_statement_set_string(con, i, param->max_len, param->buffer, NULL);
case DB_TYPE_NONE:
default:
attachsql_statement_set_null(con, i, NULL);
/* Not supported */
}
}
attachsql_statement_execute(con, &error);
while(aret != ATTACHSQL_RETURN_EOF)
{
aret= attachsql_connect_poll(con, &error);
if (aret == ATTACHSQL_RETURN_ROW_READY)
{
return 0;
}
if (error)
{
log_text(LOG_ALERT, "libAttachSQL Execute Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
return DB_ERROR_FATAL;
}
}
return DB_ERROR_NONE;
}
/* Execute SQL query */
db_error_t attachsql_drv_query(db_conn_t *sb_conn, const char *query,
size_t len, db_result_t *rs)
{
(void) rs;
attachsql_connect_t *con = sb_conn->ptr;
unsigned int rc;
attachsql_error_t *error= NULL;
attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
/* Close any previous query */
attachsql_query_close(con);
DEBUG("attachsql_query(%p, \"%s\", %u)",
con,
query,
len);
attachsql_query(con, len, query, 0, NULL, &error);
while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY))
{
aret= attachsql_connect_poll(con, &error);
if (error)
{
rc= attachsql_error_code(error);
if (rc == 1213 || rc == 1205 || rc == 1020)
{
attachsql_error_free(error);
return DB_ERROR_IGNORABLE;
}
log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
return DB_ERROR_FATAL;
}
}
//rs->connection->ptr= con;
DEBUG("attachsql_query \"%s\" returned %d", query, aret);
return DB_ERROR_NONE;
}
/* Fetch row from result set of a prepared statement */
int attachsql_drv_fetch(db_result_t *rs)
{
/* NYI */
attachsql_connect_t *con = rs->connection->ptr;
size_t tmp_len;
uint16_t columns, col;
attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
attachsql_error_t *error= NULL;
while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY))
{
aret= attachsql_connect_poll(con, &error);
if (error)
{
log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
return 1;
}
}
if (aret == ATTACHSQL_RETURN_EOF)
{
return 1;
}
attachsql_statement_row_get(con, NULL);
columns= attachsql_query_column_count(con);
for (col= 0; col < columns; col++)
{
switch (attachsql_statement_get_column_type(con, col))
{
case ATTACHSQL_COLUMN_TYPE_TINY:
case ATTACHSQL_COLUMN_TYPE_SHORT:
case ATTACHSQL_COLUMN_TYPE_LONG:
case ATTACHSQL_COLUMN_TYPE_YEAR:
case ATTACHSQL_COLUMN_TYPE_INT24:
attachsql_statement_get_int(con, col, &error);
break;
case ATTACHSQL_COLUMN_TYPE_LONGLONG:
attachsql_statement_get_bigint(con, col, &error);
break;
case ATTACHSQL_COLUMN_TYPE_FLOAT:
attachsql_statement_get_float(con, col, &error);
break;
case ATTACHSQL_COLUMN_TYPE_DOUBLE:
attachsql_statement_get_double(con, col, &error);
break;
default:
attachsql_statement_get_char(con, col, &tmp_len, &error);
break;
}
}
attachsql_query_row_next(con);
return 0;
}
/* Fetch row from result set of a query */
int attachsql_drv_fetch_row(db_result_t *rs, db_row_t *row)
{
attachsql_error_t *error= NULL;
attachsql_return_t aret= ATTACHSQL_RETURN_NONE;
/* NYI */
attachsql_connect_t *con = rs->connection->ptr;
while((aret != ATTACHSQL_RETURN_EOF) && (aret != ATTACHSQL_RETURN_ROW_READY))
{
aret= attachsql_connect_poll(con, &error);
if (error)
{
log_text(LOG_ALERT, "libAttachSQL Query Failed: %u:%s", attachsql_error_code(error), attachsql_error_message(error));
attachsql_error_free(error);
return 1;
}
}
if (aret == ATTACHSQL_RETURN_EOF)
{
return 1;
}
row->ptr= attachsql_query_row_get(con, NULL);
attachsql_query_row_next(con);
return 0;
}
/* Store results from the last query */
int attachsql_drv_store_results(db_result_t *rs)
{
int ret= 0;
db_row_t row;
/* libAttachSQL can't do things in this order */
while (ret == 0)
{
if (rs->statement != NULL)
{
ret= attachsql_drv_fetch(rs);
}
else
{
ret= attachsql_drv_fetch_row(rs, &row);
}
}
return DB_ERROR_NONE;
}
/* Free result set */
int attachsql_drv_free_results(db_result_t *rs)
{
if (rs->connection->ptr != NULL)
{
DEBUG("attachsql_query_close(%p)", rs->connection->ptr);
attachsql_query_close(rs->connection->ptr);
rs->connection->ptr = NULL;
return 0;
}
return 1;
}
/* Close prepared statement */
int attachsql_drv_close(db_stmt_t *stmt)
{
attachsql_connect_t *con= (attachsql_connect_t *)stmt->connection->ptr;
attachsql_statement_close(con);
return 0;
}
/* Uninitialize driver */
int attachsql_drv_done(void)
{
return 0;
}

View File

@ -0,0 +1,19 @@
# Copyright (C) 2009 Sun Microsystems, Inc.
#
# 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
noinst_LIBRARIES = libsbdrizzle.a
libsbdrizzle_a_SOURCES = drv_drizzle.c

View File

@ -0,0 +1,706 @@
/* Copyright (C) 2009 Sun Microsystems, Inc.
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdio.h>
#include <libdrizzle/drizzle_client.h>
#include "sb_options.h"
#include "db_driver.h"
#define DEBUG(format, ...) do { if (db_globals.debug) log_text(LOG_DEBUG, format, __VA_ARGS__); } while (0)
/* Drizzle driver arguments */
static sb_arg_t drizzle_drv_args[] =
{
{"drizzle-host", "Drizzle server host", SB_ARG_TYPE_LIST, "localhost"},
{"drizzle-port", "Drizzle server port", SB_ARG_TYPE_INT, "4427"},
{"drizzle-socket", "Drizzle socket", SB_ARG_TYPE_STRING, NULL},
{"drizzle-user", "Drizzle user", SB_ARG_TYPE_STRING, ""},
{"drizzle-password", "Drizzle password", SB_ARG_TYPE_STRING, ""},
{"drizzle-db", "Drizzle database name", SB_ARG_TYPE_STRING, "sbtest"},
{"drizzle-buffer", "Level of library buffering (none, field, row, all)", SB_ARG_TYPE_STRING, "none"},
{"drizzle-mysql", "Use MySQL Protocol", SB_ARG_TYPE_BOOL, "off"},
{NULL, NULL, SB_ARG_TYPE_NULL, NULL}
};
typedef enum
{
BUFFER_NONE,
BUFFER_FIELD,
BUFFER_ROW,
BUFFER_ALL
} buffer_level;
typedef struct
{
sb_list_t *hosts;
unsigned int port;
char *socket;
char *user;
char *password;
char *db;
buffer_level buffer;
int mysql;
} drizzle_drv_args_t;
/* Drizzle driver capabilities */
static drv_caps_t drizzle_drv_caps =
{
.multi_rows_insert = 1,
.prepared_statements = 0,
.auto_increment = 1,
.serial = 0,
.unsigned_int = 0,
};
static drizzle_drv_args_t args; /* driver args */
static sb_list_item_t *hosts_pos;
static pthread_mutex_t hosts_mutex;
static void column_info(drizzle_column_st *column);
/* Drizzle driver operations */
static int drizzle_drv_init(void);
static int drizzle_drv_describe(drv_caps_t *);
static int drizzle_drv_connect(db_conn_t *);
static int drizzle_drv_disconnect(db_conn_t *);
static int drizzle_drv_prepare(db_stmt_t *, const char *, size_t);
static int drizzle_drv_bind_param(db_stmt_t *, db_bind_t *, size_t);
static int drizzle_drv_bind_result(db_stmt_t *, db_bind_t *, size_t);
static db_error_t drizzle_drv_execute(db_stmt_t *, db_result_t *);
static int drizzle_drv_fetch(db_result_t *);
static int drizzle_drv_fetch_row(db_result_t *, db_row_t *);
static db_error_t drizzle_drv_query(db_conn_t *, const char *, size_t,
db_result_t *);
static int drizzle_drv_free_results(db_result_t *);
static int drizzle_drv_close(db_stmt_t *);
static int drizzle_drv_store_results(db_result_t *);
static int drizzle_drv_done(void);
/* Drizzle driver definition */
static db_driver_t drizzle_driver =
{
.sname = "drizzle",
.lname = "Drizzle driver",
.args = drizzle_drv_args,
.ops =
{
.init = drizzle_drv_init,
.describe = drizzle_drv_describe,
.connect = drizzle_drv_connect,
.disconnect = drizzle_drv_disconnect,
.prepare = drizzle_drv_prepare,
.bind_param = drizzle_drv_bind_param,
.bind_result = drizzle_drv_bind_result,
.execute = drizzle_drv_execute,
.fetch = drizzle_drv_fetch,
.fetch_row = drizzle_drv_fetch_row,
.free_results = drizzle_drv_free_results,
.close = drizzle_drv_close,
.query = drizzle_drv_query,
.store_results = drizzle_drv_store_results,
.done = drizzle_drv_done
},
};
/* Local functions */
/* Register Drizzle driver */
int register_driver_drizzle(sb_list_t *drivers)
{
SB_LIST_ADD_TAIL(&drizzle_driver.listitem, drivers);
return 0;
}
/* Drizzle driver initialization */
int drizzle_drv_init(void)
{
char *s;
args.hosts = sb_get_value_list("drizzle-host");
if (SB_LIST_IS_EMPTY(args.hosts))
{
log_text(LOG_FATAL, "No Drizzle hosts specified, aborting");
return 1;
}
hosts_pos = args.hosts;
pthread_mutex_init(&hosts_mutex, NULL);
args.port = (unsigned int)sb_get_value_int("drizzle-port");
args.socket = sb_get_value_string("drizzle-socket");
args.user = sb_get_value_string("drizzle-user");
args.password = sb_get_value_string("drizzle-password");
args.db = sb_get_value_string("drizzle-db");
s= sb_get_value_string("drizzle-buffer");
if (!strcasecmp(s, "none"))
args.buffer= BUFFER_NONE;
else if (!strcasecmp(s, "field"))
args.buffer= BUFFER_FIELD;
else if (!strcasecmp(s, "row"))
args.buffer= BUFFER_ROW;
else if (!strcasecmp(s, "all"))
args.buffer= BUFFER_ALL;
args.mysql= sb_get_value_flag("drizzle-mysql");
return 0;
}
/* Describe database capabilities (possibly depending on table type) */
int drizzle_drv_describe(drv_caps_t *caps )
{
*caps = drizzle_drv_caps;
return 0;
}
/* Connect to Drizzle database */
int drizzle_drv_connect(db_conn_t *sb_conn)
{
drizzle_st *drizzle_lib= NULL;
drizzle_con_st *con= NULL;
const char *host;
drizzle_return_t ret;
drizzle_lib= drizzle_create(drizzle_lib);
if (args.socket)
{
DEBUG("drizzle_con_add_uds(%p, %p \"%s\", \"%s\", \"%s\", \"%s\", %d)",
drizzle_lib,
con,
args.socket,
args.user,
args.password,
args.db,
args.mysql ? DRIZZLE_CON_MYSQL : 0);
con= drizzle_con_add_uds(drizzle_lib,
con,
args.socket,
args.user,
args.password,
args.db,
args.mysql ? DRIZZLE_CON_MYSQL : 0);
} else {
pthread_mutex_lock(&hosts_mutex);
hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);
if (hosts_pos == args.hosts)
hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);
host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data;
pthread_mutex_unlock(&hosts_mutex);
DEBUG("drizzle_con_add_tcp(%p, %p \"%s\", %u, \"%s\", \"%s\", \"%s\", %d)",
drizzle_lib,
con,
host,
args.port,
args.user,
args.password,
args.db,
args.mysql ? DRIZZLE_CON_MYSQL : 0);
con= drizzle_con_add_tcp(drizzle_lib,
con,
host,
args.port,
args.user,
args.password,
args.db,
args.mysql ? DRIZZLE_CON_MYSQL : 0);
}
if (con == NULL)
{
log_text(LOG_FATAL, "unable to Add Drizzle Connection, aborting...");
log_text(LOG_FATAL, "error %d: %s", drizzle_errno(drizzle_lib),
drizzle_error(drizzle_lib));
return 1;
}
if ((ret= drizzle_con_connect(con)) != DRIZZLE_RETURN_OK)
{
log_text(LOG_FATAL, "unable to connect to Drizzle server: %d", ret);
log_text(LOG_FATAL, "error %d: %s", drizzle_errno(drizzle_lib),
drizzle_error(drizzle_lib));
free(con);
return 1;
}
sb_conn->ptr = con;
return 0;
}
/* Disconnect from Drizzle database */
int drizzle_drv_disconnect(db_conn_t *sb_conn)
{
drizzle_con_st *con = (drizzle_con_st *)sb_conn->ptr;
if (con != NULL)
{
DEBUG("drizzle_close(%p)", con);
drizzle_con_close(con);
free(con);
}
return 0;
}
/* Prepare statement */
int drizzle_drv_prepare(db_stmt_t *stmt, const char *query, size_t len)
{
(void) len; /* unused */
/* Use client-side PS */
stmt->emulated = 1;
stmt->query = strdup(query);
return 0;
}
/* Bind parameters for prepared statement */
int drizzle_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len)
{
drizzle_con_st *con = (drizzle_con_st *)stmt->connection->ptr;
if (con == NULL)
return 1;
/* Use emulation */
if (stmt->bound_param != NULL)
free(stmt->bound_param);
stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t));
if (stmt->bound_param == NULL)
return 1;
memcpy(stmt->bound_param, params, len * sizeof(db_bind_t));
stmt->bound_param_len = len;
return 0;
}
/* Bind results for prepared statement */
int drizzle_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len)
{
(void)stmt;
(void)params;
(void)len;
return 0;
}
/* Execute prepared statement */
db_error_t drizzle_drv_execute(db_stmt_t *stmt, db_result_t *rs)
{
db_conn_t *con = stmt->connection;
char *buf = NULL;
unsigned int buflen = 0;
unsigned int i, j, vcnt;
char need_realloc;
int n;
/* Use emulation */
/* Build the actual query string from parameters list */
need_realloc = 1;
vcnt = 0;
for (i = 0, j = 0; stmt->query[i] != '\0'; i++)
{
again:
if (j+1 >= buflen || need_realloc)
{
buflen = (buflen > 0) ? buflen * 2 : 256;
buf = realloc(buf, buflen);
if (buf == NULL)
{
log_text(LOG_DEBUG, "ERROR: exiting drizzle_drv_execute(), memory allocation failure");
return DB_ERROR_FATAL;
}
need_realloc = 0;
}
if (stmt->query[i] != '?')
{
buf[j++] = stmt->query[i];
continue;
}
n = db_print_value(stmt->bound_param + vcnt, buf + j, (int)(buflen - j));
if (n < 0)
{
need_realloc = 1;
goto again;
}
j += (unsigned int)n;
vcnt++;
}
buf[j] = '\0';
con->error = drizzle_drv_query(con, buf, j, rs);
free(buf);
if (con->error != DB_ERROR_NONE)
{
log_text(LOG_DEBUG, "ERROR: exiting drizzle_drv_execute(), database error");
return con->error;
}
return DB_ERROR_NONE;
}
/* Execute SQL query */
db_error_t drizzle_drv_query(db_conn_t *sb_conn, const char *query, size_t len,
db_result_t *rs)
{
drizzle_con_st *con = sb_conn->ptr;
unsigned int rc;
drizzle_return_t ret;
drizzle_result_st *result= NULL;
DEBUG("drizzle_query(%p, %p, \"%s\", %u, %p)",
con,
result,
query,
len,
&ret);
result= drizzle_query(con, NULL, query, len, &ret);
DEBUG("drizzle_query(%p) == %d", con, ret);
if (ret == DRIZZLE_RETURN_ERROR_CODE)
{
rc= drizzle_result_error_code(result);
/* Error code constants haven't been added yet to libdrizzle
ER_LOCK_DEADLOCK==1213
ER_LOCK_WAIT_TIMEOUT==1205
ER_CHECKREAD==1020
*/
if (rc == 1213 || rc == 1205 ||
rc == 1020)
return DB_ERROR_IGNORABLE;
log_text(LOG_ALERT, "Drizzle Query Failed: %u:%s",
drizzle_result_error_code(result),
drizzle_result_error(result));
return DB_ERROR_FATAL;
}
else if (ret != DRIZZLE_RETURN_OK)
{
rc = drizzle_con_errno(con);
DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc);
log_text(LOG_ALERT, "failed to execute Drizzle query: len==%d `%s`:",
strlen(query), query);
log_text(LOG_ALERT, "Error %d %s", drizzle_con_errno(con),
drizzle_con_error(con));
return DB_ERROR_FATAL;
}
DEBUG("drizzle_query \"%s\" returned %d", query, ret);
if (result == NULL)
{
DEBUG("drizzle_query(%p, \"%s\") == NULL",con,query);
return DB_ERROR_FATAL;
}
rs->ptr= result;
rs->nrows= drizzle_result_row_count(result);
DEBUG("drizzle_result_row_count(%p) == %d",result,rs->nrows);
return DB_ERROR_NONE;
}
/* Fetch row from result set of a prepared statement */
int drizzle_drv_fetch(db_result_t *rs)
{
/* NYI */
(void)rs;
printf("in drizzle_drv_fetch_row!\n");
return 1;
}
/* Fetch row from result set of a query */
int drizzle_drv_fetch_row(db_result_t *rs, db_row_t *row)
{
/* NYI */
printf("in drizzle_drv_fetch_row!\n");
(void)rs; /* unused */
(void)row; /* unused */
return 1;
}
/* Store results from the last query */
int drizzle_drv_store_results(db_result_t *rs)
{
drizzle_con_st *con = rs->connection->ptr;
drizzle_result_st *res = rs->ptr;
drizzle_return_t ret;
drizzle_column_st *column= NULL;
unsigned int rc;
if (con == NULL || res == NULL)
return DB_ERROR_FATAL;
if (args.buffer == BUFFER_ALL)
{
ret= drizzle_result_buffer(res);
DEBUG("drizzle_result_buffer(%p) = %d", res, ret);
if (ret != DRIZZLE_RETURN_OK)
{
rc = drizzle_con_errno(con);
DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc);
log_text(LOG_ALERT, "drizzle_result_buffer failed: `%p`:", res);
log_text(LOG_ALERT, "Error %d %s",
drizzle_con_errno(con),
drizzle_con_error(con));
return DB_ERROR_FATAL;
}
while ((column = drizzle_column_next(res)) != NULL)
column_info(column);
}
else if (drizzle_result_column_count(res) > 0)
{
drizzle_row_t row;
drizzle_field_t field;
uint64_t row_num;
size_t offset= 0;
size_t length;
size_t total;
/* Read column meta-info */
while (1)
{
column= drizzle_column_read(res, column, &ret);
DEBUG("drizzle_column_read(%p,%p,%p) == %d",res, column, &ret, ret);
if (ret != DRIZZLE_RETURN_OK)
{
rc = drizzle_con_errno(con);
DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc);
log_text(LOG_ALERT, "drizzle_column_read failed: `%p`:", res);
log_text(LOG_ALERT, "Error %d %s",
drizzle_con_errno(con),
drizzle_con_error(con));
return DB_ERROR_FATAL;
}
if (column == NULL)
break;
column_info(column);
drizzle_column_free(column);
}
/* Actually fetch rows */
while (1) /* Loop for rows */
{
if (args.buffer == BUFFER_ROW)
{
row= drizzle_row_buffer(res, &ret);
DEBUG("drizzle_row_buffer(%p, %p) == %p, %d",res, &ret, row, ret);
if (ret != DRIZZLE_RETURN_OK)
{
rc = drizzle_con_errno(con);
DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc);
log_text(LOG_ALERT, "drizzle_row_buffer failed: `%p`:", res);
log_text(LOG_ALERT, "Error %d %s",
drizzle_con_errno(con),
drizzle_con_error(con));
return DB_ERROR_FATAL;
}
if (row == NULL)
break;
DEBUG("drizzle_row_free(%p, %p)",res,row);
drizzle_row_free(res, row);
}
else if (args.buffer == BUFFER_NONE || args.buffer == BUFFER_FIELD)
{
row_num= drizzle_row_read(res, &ret);
DEBUG("drizzle_row_read(%p, %p) == %"PRIu64", %d",
res, &ret, row_num, ret);
if (ret != DRIZZLE_RETURN_OK)
{
rc = drizzle_con_errno(con);
DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc);
log_text(LOG_ALERT, "drizzle_row_read failed: `%p`:", res);
log_text(LOG_ALERT, "Error %d %s",
drizzle_con_errno(con),
drizzle_con_error(con));
return DB_ERROR_FATAL;
}
if (row_num == 0)
break;
while (1) /* Loop for fields */
{
if (args.buffer == BUFFER_FIELD)
{
/* Since an entire field is buffered, we don't need to worry about
partial reads. */
field= drizzle_field_buffer(res, &total, &ret);
DEBUG("drizzle_field_buffer(%p, &p, %p) == %p, %x, %d",
res, &total, &ret, field, total, ret);
length= total;
}
else
{
field= drizzle_field_read(res, &offset, &length, &total, &ret);
DEBUG("drizzle_field_read(%p, %p, %p, %p, %p) == "
"%p, %x, %x, %x, %d",
res, &offset, &length, &total, &ret,
field, offset, length, total, ret);
}
if (ret == DRIZZLE_RETURN_ROW_END)
break;
else if (ret != DRIZZLE_RETURN_OK)
{
rc = drizzle_con_errno(con);
DEBUG("drizzle_errno(%p) = %u", drizzle_con_drizzle(con), rc);
log_text(LOG_ALERT, "drizzle_field_(buffer|read) failed: `%p`:",
res);
log_text(LOG_ALERT, "Error %d %s",
drizzle_con_errno(con),
drizzle_con_error(con));
return DB_ERROR_FATAL;
}
if (args.buffer == BUFFER_FIELD)
drizzle_field_free(field);
} /* while (1) Loop for fields */
} /* if (args.buffer) */
} /* while (1) */
}
return DB_ERROR_NONE;
}
/* Free result set */
int drizzle_drv_free_results(db_result_t *rs)
{
if (rs->ptr != NULL)
{
DEBUG("drizzle_result_free(%p)", rs->ptr);
drizzle_result_free(rs->ptr);
rs->ptr = NULL;
return 0;
}
return 1;
}
/* Close prepared statement */
int drizzle_drv_close(db_stmt_t *stmt)
{
(void)stmt;
return 0;
}
/* Uninitialize driver */
int drizzle_drv_done(void)
{
return 0;
}
void column_info(drizzle_column_st *column)
{
DEBUG("Field: catalog=%s\n"
" db=%s\n"
" table=%s\n"
" org_table=%s\n"
" name=%s\n"
" org_name=%s\n"
" charset=%u\n"
" size=%u\n"
" type=%u\n"
" flags=%u\n",
drizzle_column_catalog(column), drizzle_column_db(column),
drizzle_column_table(column), drizzle_column_orig_table(column),
drizzle_column_name(column), drizzle_column_orig_name(column),
drizzle_column_charset(column), drizzle_column_size(column),
drizzle_column_type(column), drizzle_column_flags(column));
}

View File

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

View File

@ -0,0 +1,21 @@
# Copyright (C) 2004 MySQL AB
# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
noinst_LIBRARIES = libsbmysql.a
libsbmysql_a_SOURCES = drv_mysql.c
libsbmysql_a_CPPFLAGS = $(MYSQL_CFLAGS) $(AM_CPPFLAGS)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
# Copyright (C) 2005 MySQL AB
# Copyright (C) 2005-2008 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
noinst_LIBRARIES = libsboracle.a
libsboracle_a_SOURCES = drv_oracle.c
libsboracle_a_CPPFLAGS = $(ORA_CFLAGS) $(AM_CPPFLAGS)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
# Copyright (C) 2005 MySQL AB
# Copyright (C) 2005-2015 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
noinst_LIBRARIES = libsbpgsql.a
libsbpgsql_a_SOURCES = drv_pgsql.c
libsbpgsql_a_CPPFLAGS = -g $(PGSQL_CFLAGS) $(AM_CPPFLAGS)

View File

@ -0,0 +1,821 @@
/* Copyright (C) 2005 MySQL AB
Copyright (C) 2005-2017 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <libpq-fe.h>
#include "sb_options.h"
#include "db_driver.h"
#include "sb_rand.h"
#define xfree(ptr) ({ if (ptr) free((void *)ptr); ptr = NULL; })
/* Maximum length of text representation of bind parameters */
#define MAX_PARAM_LENGTH 256UL
/* PostgreSQL driver arguments */
static sb_arg_t pgsql_drv_args[] =
{
SB_OPT("pgsql-host", "PostgreSQL server host", "localhost", STRING),
SB_OPT("pgsql-port", "PostgreSQL server port", "5432", INT),
SB_OPT("pgsql-user", "PostgreSQL user", "sbtest", STRING),
SB_OPT("pgsql-password", "PostgreSQL password", "", STRING),
SB_OPT("pgsql-db", "PostgreSQL database name", "sbtest", STRING),
SB_OPT_END
};
typedef struct
{
char *host;
char *port;
char *user;
char *password;
char *db;
} pgsql_drv_args_t;
/* Structure used for DB-to-PgSQL bind types map */
typedef struct
{
db_bind_type_t db_type;
int pg_type;
} db_pgsql_bind_map_t;
/* DB-to-PgSQL bind types map */
db_pgsql_bind_map_t db_pgsql_bind_map[] =
{
{DB_TYPE_TINYINT, 0},
{DB_TYPE_SMALLINT, 21},
{DB_TYPE_INT, 23},
{DB_TYPE_BIGINT, 20},
{DB_TYPE_FLOAT, 700},
{DB_TYPE_DOUBLE, 701},
{DB_TYPE_DATETIME, 0},
{DB_TYPE_TIMESTAMP, 1114},
{DB_TYPE_CHAR, 18},
{DB_TYPE_VARCHAR, 1043},
{DB_TYPE_NONE, 0}
};
/* PgSQL driver capabilities */
static drv_caps_t pgsql_drv_caps =
{
1, /* multi_rows_insert */
1, /* prepared_statements */
0, /* auto_increment */
0, /* needs_commit */
1, /* serial */
0, /* unsigned int */
};
/* Describes the PostgreSQL prepared statement */
typedef struct pg_stmt
{
char *name;
int prepared;
int nparams;
Oid *ptypes;
char **pvalues;
} pg_stmt_t;
static pgsql_drv_args_t args; /* driver args */
static char use_ps; /* whether server-side prepared statemens should be used */
/* PgSQL driver operations */
static int pgsql_drv_init(void);
static int pgsql_drv_describe(drv_caps_t *);
static int pgsql_drv_connect(db_conn_t *);
static int pgsql_drv_disconnect(db_conn_t *);
static int pgsql_drv_prepare(db_stmt_t *, const char *, size_t);
static int pgsql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t);
static int pgsql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t);
static db_error_t pgsql_drv_execute(db_stmt_t *, db_result_t *);
static int pgsql_drv_fetch(db_result_t *);
static int pgsql_drv_fetch_row(db_result_t *, db_row_t *);
static db_error_t pgsql_drv_query(db_conn_t *, const char *, size_t,
db_result_t *);
static int pgsql_drv_free_results(db_result_t *);
static int pgsql_drv_close(db_stmt_t *);
static int pgsql_drv_done(void);
/* PgSQL driver definition */
static db_driver_t pgsql_driver =
{
.sname = "pgsql",
.lname = "PostgreSQL driver",
.args = pgsql_drv_args,
.ops =
{
.init = pgsql_drv_init,
.describe = pgsql_drv_describe,
.connect = pgsql_drv_connect,
.disconnect = pgsql_drv_disconnect,
.prepare = pgsql_drv_prepare,
.bind_param = pgsql_drv_bind_param,
.bind_result = pgsql_drv_bind_result,
.execute = pgsql_drv_execute,
.fetch = pgsql_drv_fetch,
.fetch_row = pgsql_drv_fetch_row,
.free_results = pgsql_drv_free_results,
.close = pgsql_drv_close,
.query = pgsql_drv_query,
.done = pgsql_drv_done
}
};
/* Local functions */
static int get_pgsql_bind_type(db_bind_type_t);
static int get_unique_stmt_name(char *, int);
/* Register PgSQL driver */
int register_driver_pgsql(sb_list_t *drivers)
{
SB_LIST_ADD_TAIL(&pgsql_driver.listitem, drivers);
return 0;
}
/* PgSQL driver initialization */
int pgsql_drv_init(void)
{
args.host = sb_get_value_string("pgsql-host");
args.port = sb_get_value_string("pgsql-port");
args.user = sb_get_value_string("pgsql-user");
args.password = sb_get_value_string("pgsql-password");
args.db = sb_get_value_string("pgsql-db");
use_ps = 0;
pgsql_drv_caps.prepared_statements = 1;
if (db_globals.ps_mode != DB_PS_MODE_DISABLE)
use_ps = 1;
return 0;
}
/* Describe database capabilities */
int pgsql_drv_describe(drv_caps_t *caps)
{
PGconn *con;
*caps = pgsql_drv_caps;
/* Determine the server version */
con = PQsetdbLogin(args.host,
args.port,
NULL,
NULL,
args.db,
args.user,
args.password);
if (PQstatus(con) != CONNECTION_OK)
{
log_text(LOG_FATAL, "Connection to database failed: %s",
PQerrorMessage(con));
PQfinish(con);
return 1;
}
/* Support for multi-row INSERTs is not available before 8.2 */
if (PQserverVersion(con) < 80200)
caps->multi_rows_insert = 0;
PQfinish(con);
return 0;
}
static void empty_notice_processor(void *arg, const char *msg)
{
(void) arg; /* unused */
(void) msg; /* unused */
}
/* Connect to database */
int pgsql_drv_connect(db_conn_t *sb_conn)
{
PGconn *con;
con = PQsetdbLogin(args.host,
args.port,
NULL,
NULL,
args.db,
args.user,
args.password);
if (PQstatus(con) != CONNECTION_OK)
{
log_text(LOG_FATAL, "Connection to database failed: %s",
PQerrorMessage(con));
PQfinish(con);
return 1;
}
/* Silence the default notice receiver spitting NOTICE message to stderr */
PQsetNoticeProcessor(con, empty_notice_processor, NULL);
sb_conn->ptr = con;
return 0;
}
/* Disconnect from database */
int pgsql_drv_disconnect(db_conn_t *sb_conn)
{
PGconn *con = (PGconn *)sb_conn->ptr;
/* These might be allocated in pgsql_check_status() */
xfree(sb_conn->sql_state);
xfree(sb_conn->sql_errmsg);
if (con != NULL)
PQfinish(con);
return 0;
}
/* Prepare statement */
int pgsql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len)
{
PGconn *con = (PGconn *)stmt->connection->ptr;
PGresult *pgres;
pg_stmt_t *pgstmt;
char *buf = NULL;
unsigned int vcnt;
unsigned int need_realloc;
unsigned int i,j;
unsigned int buflen;
int n;
char name[32];
(void) len; /* unused */
if (con == NULL)
return 1;
if (!use_ps)
{
/* Use client-side PS */
stmt->emulated = 1;
stmt->query = strdup(query);
return 0;
}
/* Convert query to PgSQL-style named placeholders */
need_realloc = 1;
vcnt = 1;
buflen = 0;
for (i = 0, j = 0; query[i] != '\0'; i++)
{
again:
if (j+1 >= buflen || need_realloc)
{
buflen = (buflen > 0) ? buflen * 2 : 256;
buf = realloc(buf, buflen);
if (buf == NULL)
goto error;
need_realloc = 0;
}
if (query[i] != '?')
{
buf[j++] = query[i];
continue;
}
n = snprintf(buf + j, buflen - j, "$%d", vcnt);
if (n < 0 || n >= (int)(buflen - j))
{
need_realloc = 1;
goto again;
}
j += n;
vcnt++;
}
buf[j] = '\0';
/* Store the query to be prepared later on the first bind_param call */
stmt->query = strdup(buf);
free(buf);
pgstmt = (pg_stmt_t *)calloc(1, sizeof(pg_stmt_t));
if (pgstmt == NULL)
goto error;
/* Generate random statement name */
get_unique_stmt_name(name, sizeof(name));
pgstmt->name = strdup(name);
pgstmt->nparams = vcnt - 1;
/*
Special keys for statements without parameters, since we don't need
to know the types of arguments, and no calls to bind_param() will be made
*/
if (pgstmt->nparams == 0)
{
/* Do prepare */
pgres = PQprepare(con, pgstmt->name, stmt->query, pgstmt->nparams,
NULL);
if (PQresultStatus(pgres) != PGRES_COMMAND_OK)
{
log_text(LOG_FATAL, "PQprepare() failed: %s", PQerrorMessage(con));
PQclear(pgres);
free(stmt->query);
free(pgstmt->name);
free(pgstmt);
return 1;
}
PQclear(pgres);
pgstmt->prepared = 1;
}
stmt->ptr = pgstmt;
return 0;
error:
return 1;
}
/* Bind parameters for prepared statement */
int pgsql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len)
{
PGconn *con = (PGconn *)stmt->connection->ptr;
PGresult *pgres;
pg_stmt_t *pgstmt;
unsigned int i;
if (con == NULL)
return 1;
if (stmt->bound_param != NULL)
free(stmt->bound_param);
stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t));
if (stmt->bound_param == NULL)
return 1;
memcpy(stmt->bound_param, params, len * sizeof(db_bind_t));
stmt->bound_param_len = len;
if (stmt->emulated)
return 0;
pgstmt = stmt->ptr;
if (pgstmt->prepared)
return 0;
/* Prepare statement here, since we need to know types of parameters */
/* Validate parameters count */
if ((unsigned)pgstmt->nparams != len)
{
log_text(LOG_ALERT, "wrong number of parameters in prepared statement");
log_text(LOG_DEBUG, "counted: %d, passed to bind_param(): %zd",
pgstmt->nparams, len);
return 1;
}
pgstmt->ptypes = (Oid *)malloc(len * sizeof(int));
if (pgstmt->ptypes == NULL)
return 1;
/* Convert sysbench data types to PgSQL ones */
for (i = 0; i < len; i++)
pgstmt->ptypes[i] = get_pgsql_bind_type(params[i].type);
/* Do prepare */
pgres = PQprepare(con, pgstmt->name, stmt->query, pgstmt->nparams,
pgstmt->ptypes);
if (PQresultStatus(pgres) != PGRES_COMMAND_OK)
{
log_text(LOG_FATAL, "PQprepare() failed: %s", PQerrorMessage(con));
return 1;
}
PQclear(pgres);
pgstmt->pvalues = (char **)calloc(len, sizeof(char *));
if (pgstmt->pvalues == NULL)
return 1;
/* Allocate buffers for bind parameters */
for (i = 0; i < len; i++)
{
if (pgstmt->pvalues[i] != NULL)
{
free(pgstmt->pvalues[i]);
}
pgstmt->pvalues[i] = (char *)malloc(MAX_PARAM_LENGTH);
if (pgstmt->pvalues[i] == NULL)
return 1;
}
pgstmt->prepared = 1;
return 0;
}
/* Bind results for prepared statement */
int pgsql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len)
{
/* unused */
(void)stmt;
(void)params;
(void)len;
return 0;
}
/* Check query execution status */
static db_error_t pgsql_check_status(db_conn_t *con, PGresult *pgres,
const char *funcname, const char *query,
db_result_t *rs)
{
ExecStatusType status;
db_error_t rc;
PGconn * const pgcon = con->ptr;
status = PQresultStatus(pgres);
switch(status) {
case PGRES_TUPLES_OK:
rs->nrows = PQntuples(pgres);
rs->nfields = PQnfields(pgres);
rs->counter = SB_CNT_READ;
rc = DB_ERROR_NONE;
break;
case PGRES_COMMAND_OK:
rs->nrows = strtoul(PQcmdTuples(pgres), NULL, 10);;
rs->counter = (rs->nrows > 0) ? SB_CNT_WRITE : SB_CNT_OTHER;
rc = DB_ERROR_NONE;
/*
Since we are not returning a result set, the SQL layer will never call
pgsql_drv_free_results(). So we must call PQclear() here.
*/
PQclear(pgres);
break;
case PGRES_FATAL_ERROR:
rs->nrows = 0;
rs->counter = SB_CNT_ERROR;
/*
Duplicate strings here, because PostgreSQL will deallocate them on
PQclear() call below. They will be deallocated either on subsequent calls
to pgsql_check_status() or in pgsql_drv_disconnect().
*/
xfree(con->sql_state);
xfree(con->sql_errmsg);
con->sql_state = strdup(PQresultErrorField(pgres, PG_DIAG_SQLSTATE));
con->sql_errmsg = strdup(PQresultErrorField(pgres, PG_DIAG_MESSAGE_PRIMARY));
if (!strcmp(con->sql_state, "40P01") /* deadlock_detected */ ||
!strcmp(con->sql_state, "23505") /* unique violation */ ||
!strcmp(con->sql_state, "40001"))/* serialization_failure */
{
PGresult *tmp;
tmp = PQexec(pgcon, "ROLLBACK");
PQclear(tmp);
rc = DB_ERROR_IGNORABLE;
}
else
{
log_text(LOG_FATAL, "%s() failed: %d %s", funcname, status,
con->sql_errmsg);
if (query != NULL)
log_text(LOG_FATAL, "failed query was: %s", query);
rc = DB_ERROR_FATAL;
}
PQclear(pgres);
break;
default:
rs->nrows = 0;
rs->counter = SB_CNT_ERROR;
rc = DB_ERROR_FATAL;
}
return rc;
}
/* Execute prepared statement */
db_error_t pgsql_drv_execute(db_stmt_t *stmt, db_result_t *rs)
{
db_conn_t *con = stmt->connection;
PGconn *pgcon = (PGconn *)con->ptr;
PGresult *pgres;
pg_stmt_t *pgstmt;
char *buf = NULL;
unsigned int buflen = 0;
unsigned int i, j, vcnt;
char need_realloc;
int n;
db_error_t rc;
unsigned long len;
con->sql_errno = 0;
xfree(con->sql_state);
xfree(con->sql_errmsg);
if (!stmt->emulated)
{
pgstmt = stmt->ptr;
if (pgstmt == NULL)
{
log_text(LOG_DEBUG,
"ERROR: exiting mysql_drv_execute(), uninitialized statement");
return DB_ERROR_FATAL;
}
/* Convert sysbench bind structures to PgSQL data */
for (i = 0; i < (unsigned)pgstmt->nparams; i++)
{
if (stmt->bound_param[i].is_null && *(stmt->bound_param[i].is_null))
continue;
switch (stmt->bound_param[i].type) {
case DB_TYPE_CHAR:
case DB_TYPE_VARCHAR:
len = stmt->bound_param[i].data_len[0];
memcpy(pgstmt->pvalues[i], stmt->bound_param[i].buffer,
SB_MIN(MAX_PARAM_LENGTH, len));
/* PostgreSQL requires a zero-terminated string */
pgstmt->pvalues[i][len] = '\0';
break;
default:
db_print_value(stmt->bound_param + i, pgstmt->pvalues[i],
MAX_PARAM_LENGTH);
}
}
pgres = PQexecPrepared(pgcon, pgstmt->name, pgstmt->nparams,
(const char **)pgstmt->pvalues, NULL, NULL, 1);
rc = pgsql_check_status(con, pgres, "PQexecPrepared", NULL, rs);
rs->ptr = (rs->counter == SB_CNT_READ) ? (void *) pgres : NULL;
return rc;
}
/* Use emulation */
/* Build the actual query string from parameters list */
need_realloc = 1;
vcnt = 0;
for (i = 0, j = 0; stmt->query[i] != '\0'; i++)
{
again:
if (j+1 >= buflen || need_realloc)
{
buflen = (buflen > 0) ? buflen * 2 : 256;
buf = realloc(buf, buflen);
if (buf == NULL)
return DB_ERROR_FATAL;
need_realloc = 0;
}
if (stmt->query[i] != '?')
{
buf[j++] = stmt->query[i];
continue;
}
n = db_print_value(stmt->bound_param + vcnt, buf + j, buflen - j);
if (n < 0)
{
need_realloc = 1;
goto again;
}
j += n;
vcnt++;
}
buf[j] = '\0';
rc = pgsql_drv_query(con, buf, j, rs);
free(buf);
return rc;
}
/* Execute SQL query */
db_error_t pgsql_drv_query(db_conn_t *sb_conn, const char *query, size_t len,
db_result_t *rs)
{
PGconn *pgcon = sb_conn->ptr;
PGresult *pgres;
db_error_t rc;
(void)len; /* unused */
sb_conn->sql_errno = 0;
xfree(sb_conn->sql_state);
xfree(sb_conn->sql_errmsg);
pgres = PQexec(pgcon, query);
rc = pgsql_check_status(sb_conn, pgres, "PQexec", query, rs);
rs->ptr = (rs->counter == SB_CNT_READ) ? (void *) pgres : NULL;
return rc;
}
/* Fetch row from result set of a prepared statement */
int pgsql_drv_fetch(db_result_t *rs)
{
/* NYI */
(void)rs;
return 1;
}
/* Fetch row from result set of a query */
int pgsql_drv_fetch_row(db_result_t *rs, db_row_t *row)
{
intptr_t rownum;
int i;
/*
Use row->ptr as a row number, rather than a pointer to avoid dynamic
memory management.
*/
rownum = (intptr_t) row->ptr;
if (rownum >= (int) rs->nrows)
return DB_ERROR_IGNORABLE;
for (i = 0; i < (int) rs->nfields; i++)
{
/*
PQgetvalue() returns an empty string, not a NULL value for a NULL
field. Callers of this function expect a NULL pointer in this case.
*/
if (PQgetisnull(rs->ptr, rownum, i))
row->values[i].ptr = NULL;
else
{
row->values[i].len = PQgetlength(rs->ptr, rownum, i);
row->values[i].ptr = PQgetvalue(rs->ptr, rownum, i);
}
}
row->ptr = (void *) (rownum + 1);
return DB_ERROR_NONE;
}
/* Free result set */
int pgsql_drv_free_results(db_result_t *rs)
{
if (rs->ptr != NULL)
{
PQclear((PGresult *)rs->ptr);
rs->ptr = NULL;
rs->row.ptr = 0;
return 0;
}
return 1;
}
/* Close prepared statement */
int pgsql_drv_close(db_stmt_t *stmt)
{
pg_stmt_t *pgstmt = stmt->ptr;
int i;
if (pgstmt == NULL)
return 1;
if (pgstmt->name != NULL)
free(pgstmt->name);
if (pgstmt->ptypes != NULL)
free(pgstmt->ptypes);
if (pgstmt->pvalues != NULL)
{
for (i = 0; i < pgstmt->nparams; i++)
if (pgstmt->pvalues[i] != NULL)
free(pgstmt->pvalues[i]);
free(pgstmt->pvalues);
}
xfree(stmt->ptr);
return 0;
}
/* Uninitialize driver */
int pgsql_drv_done(void)
{
return 0;
}
/* Map SQL data type to bind_type value in MYSQL_BIND */
int get_pgsql_bind_type(db_bind_type_t type)
{
unsigned int i;
for (i = 0; db_pgsql_bind_map[i].db_type != DB_TYPE_NONE; i++)
if (db_pgsql_bind_map[i].db_type == type)
return db_pgsql_bind_map[i].pg_type;
return -1;
}
int get_unique_stmt_name(char *name, int len)
{
return snprintf(name, len, "sbstmt%d%d",
(int) sb_rand_uniform_uint64(),
(int) sb_rand_uniform_uint64());
}

View File

@ -0,0 +1,31 @@
# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
SUBDIRS = internal
dist_pkgdata_SCRIPTS = bulk_insert.lua \
oltp_delete.lua \
oltp_insert.lua \
oltp_read_only.lua \
oltp_read_write.lua \
oltp_point_select.lua \
oltp_update_index.lua \
oltp_update_non_index.lua \
oltp_write_only.lua\
select_random_points.lua \
select_random_ranges.lua
dist_pkgdata_DATA = oltp_common.lua

View File

@ -0,0 +1,56 @@
#!/usr/bin/env sysbench
-- -------------------------------------------------------------------------- --
-- Bulk insert benchmark: do multi-row INSERTs concurrently in --threads
-- threads with each thread inserting into its own table. The number of INSERTs
-- executed by each thread is controlled by either --time or --events.
-- -------------------------------------------------------------------------- --
cursize=0
function thread_init()
drv = sysbench.sql.driver()
con = drv:connect()
end
function prepare()
local i
local drv = sysbench.sql.driver()
local con = drv:connect()
for i = 1, sysbench.opt.threads do
print("Creating table 'sbtest" .. i .. "'...")
con:query(string.format([[
CREATE TABLE IF NOT EXISTS sbtest%d (
id INTEGER NOT NULL,
k INTEGER DEFAULT '0' NOT NULL,
PRIMARY KEY (id))]], i))
end
end
function event()
if (cursize == 0) then
con:bulk_insert_init("INSERT INTO sbtest" .. thread_id+1 .. " VALUES")
end
cursize = cursize + 1
con:bulk_insert_next("(" .. cursize .. "," .. cursize .. ")")
end
function thread_done(thread_9d)
con:bulk_insert_done()
con:disconnect()
end
function cleanup()
local i
local drv = sysbench.sql.driver()
local con = drv:connect()
for i = 1, sysbench.opt.threads do
print("Dropping table 'sbtest" .. i .. "'...")
con:query("DROP TABLE IF EXISTS sbtest" .. i )
end
end

View File

@ -0,0 +1,36 @@
# Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# 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
BUILT_SOURCES = sysbench.lua.h sysbench.rand.lua.h sysbench.sql.lua.h \
sysbench.compat.lua.h sysbench.cmdline.lua.h \
sysbench.histogram.lua.h
CLEANFILES = $(BUILT_SOURCES)
EXTRA_DIST = $(BUILT_SOURCES:.h=)
SUFFIXES = .lua .lua.h
.lua.lua.h:
@echo "Creating $@ from $<"
@var=$$(echo $< | sed 's/\./_/g') && \
( echo "unsigned char $${var}[] =" && \
sed -e 's/\\/\\\\/g' \
-e 's/"/\\"/g' \
-e 's/^/ "/g' \
-e 's/$$/\\n"/g' $< && \
echo ";" && \
echo "size_t $${var}_len = sizeof($${var}) - 1;" ) > $@

View File

@ -0,0 +1,215 @@
-- Copyright (C) 2017-2018 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Command line option handling
-- ----------------------------------------------------------------------
ffi = require("ffi")
ffi.cdef[[
/* The following has been copied from sb_option.h */
typedef enum
{
SB_ARG_TYPE_NULL,
SB_ARG_TYPE_BOOL,
SB_ARG_TYPE_INT,
SB_ARG_TYPE_SIZE,
SB_ARG_TYPE_DOUBLE,
SB_ARG_TYPE_STRING,
SB_ARG_TYPE_LIST,
SB_ARG_TYPE_FILE,
SB_ARG_TYPE_MAX
} sb_arg_type_t;
/* Option validation function */
typedef bool sb_opt_validate_t(const char *, const char *);
/* Test option definition */
typedef struct
{
const char *name;
const char *desc;
const char *value;
sb_arg_type_t type;
sb_opt_validate_t *validate;
} sb_arg_t;
int sb_lua_set_test_args(sb_arg_t *args, size_t len);
]]
sysbench.cmdline.ARG_NULL = ffi.C.SB_ARG_TYPE_NULL
sysbench.cmdline.ARG_BOOL = ffi.C.SB_ARG_TYPE_BOOL
sysbench.cmdline.ARG_INT = ffi.C.SB_ARG_TYPE_INT
sysbench.cmdline.ARG_SIZE = ffi.C.SB_ARG_TYPE_SIZE
sysbench.cmdline.ARG_DOUBLE = ffi.C.SB_ARG_TYPE_DOUBLE
sysbench.cmdline.ARG_STRING = ffi.C.SB_ARG_TYPE_STRING
sysbench.cmdline.ARG_LIST = ffi.C.SB_ARG_TYPE_LIST
sysbench.cmdline.ARG_FILE = ffi.C.SB_ARG_TYPE_FILE
sysbench.cmdline.ARG_MAX = ffi.C.SB_ARG_TYPE_MAX
-- Attribute indicating that a custom command can be executed in parallel
sysbench.cmdline.PARALLEL_COMMAND = true
local arg_types = {
boolean = sysbench.cmdline.ARG_BOOL,
string = sysbench.cmdline.ARG_STRING,
number = sysbench.cmdline.ARG_DOUBLE,
table = sysbench.cmdline.ARG_LIST
}
local function __genOrderedIndex( t )
local orderedIndex = {}
for key in pairs(t) do
table.insert( orderedIndex, key )
end
table.sort( orderedIndex )
return orderedIndex
end
local function orderedNext(t, state)
local key = nil
if state == nil then
t.__orderedIndex = __genOrderedIndex( t )
key = t.__orderedIndex[1]
else
for i = 1,table.getn(t.__orderedIndex) do
if t.__orderedIndex[i] == state then
key = t.__orderedIndex[i+1]
end
end
end
if key then
return key, t[key]
end
t.__orderedIndex = nil
return
end
local function orderedPairs(t)
return orderedNext, t, nil
end
-- Parse command line options definitions, if present in the script as a
-- 'sysbench.cmdline.options' table. If no such table exists, or if there a
-- parsing error, return false. Return true on success. After parsing the
-- command line arguments, option values are available as the sysbench.opt
-- table.
function sysbench.cmdline.read_cmdline_options()
if sysbench.cmdline.options == nil then
return true
end
local t = type(sysbench.cmdline.options)
assert(t == "table", "wrong type for sysbench.cmdline.options: " .. t)
local i = 0
for name, def in pairs(sysbench.cmdline.options) do
i = i+1
end
local args = ffi.new('sb_arg_t[?]', i)
i = 0
for name, def in orderedPairs(sysbench.cmdline.options) do
-- name
assert(type(name) == "string" and type(def) == "table",
"wrong table structure in sysbench.cmdline.options")
args[i].name = name
-- description
assert(def[1] ~= nil, "nil description for option " .. name)
args[i].desc = def[1]
if type(def[2]) == "table" then
assert(type(def[3]) == "nil" or
type(def[3]) == sysbench.cmdline.ARG_LIST,
"wrong type for list option " .. name)
args[i].value = table.concat(def[2], ',')
else
if type(def[2]) == "boolean" then
args[i].value = def[2] and 'on' or 'off'
elseif type(def[2]) == "number" then
args[i].value = tostring(def[2])
else
args[i].value = def[2]
end
end
-- type
local t = def[3]
if t == nil then
if def[2] ~= nil then
-- Try to determine the type by the default value
t = arg_types[type(def[2])]
else
t = sysbench.cmdline.ARG_STRING
end
end
assert(t ~= nil, "cannot determine type for option " .. name)
args[i].type = t
-- validation function
args[i].validate = def[4]
i = i + 1
end
return ffi.C.sb_lua_set_test_args(args, i) == 0
end
function sysbench.cmdline.command_defined(name)
return type(sysbench.cmdline.commands) == "table" and
sysbench.cmdline.commands[name] ~= nil and
sysbench.cmdline.commands[name][1] ~= nil
end
function sysbench.cmdline.command_parallel(name)
return sysbench.cmdline.command_defined(name) and
sysbench.cmdline.commands[name][2] == sysbench.cmdline.PARALLEL_COMMAND
end
function sysbench.cmdline.call_command(name)
if not sysbench.cmdline.command_defined(name) then
return false
end
local rc = sysbench.cmdline.commands[name][1]()
if rc == nil then
-- handle the case when the command does not return and value as success
return true
else
-- otherwise return success for any returned value other than false
return rc and true or false
end
end
ffi.cdef[[
void sb_print_test_options(void);
]]
-- ----------------------------------------------------------------------
-- Print descriptions of command line options, if defined by
-- sysbench.cmdline.options
-- ----------------------------------------------------------------------
function sysbench.cmdline.print_test_options()
ffi.C.sb_print_test_options()
end

View File

@ -0,0 +1,75 @@
-- Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Compatibility wrappers/aliases. These may be removed in later versions
-- ----------------------------------------------------------------------
thread_id = sysbench.tid
test = sysbench.cmdline.script_path
function sb_rnd()
-- Keep lower 32 bits from sysbench.rand.uniform_uint64() and convert them to
-- a Lua number
return tonumber(sysbench.rand.uniform_uint64() % 4294967296)
end
sb_rand = sysbench.rand.default
sb_rand_str = sysbench.rand.string
sb_rand_uniform = sysbench.rand.uniform
sb_rand_gaussian = sysbench.rand.gaussian
sb_rand_special = sysbench.rand.special
function sb_rand_uniq(a, b)
local res
if type(a) == "nil" then
a = 0
end
if type(b) == "nil" then
b = 4294967295
end
repeat
res = sysbench.rand.unique()
until res >= a and res <= b
return res
end
db_connect = sysbench.db.connect
db_disconnect = sysbench.db.disconnect
db_query = sysbench.db.query
db_bulk_insert_init = sysbench.db.bulk_insert_init
db_bulk_insert_next = sysbench.db.bulk_insert_next
db_bulk_insert_done = sysbench.db.bulk_insert_done
db_prepare = sysbench.db.prepare
db_bind_param = sysbench.db.bind_param
db_bind_result = sysbench.db.bind_result
db_execute = sysbench.db.execute
db_store_results = sysbench.db.store_results
db_free_results = sysbench.db.free_results
db_close = sysbench.db.close
DB_ERROR_NONE = sysbench.db.DB_ERROR_NONE
DB_ERROR_RESTART_TRANSACTION = sysbench.db.DB_ERROR_RESTART_TRANSACTION
DB_ERROR_FAILED = sysbench.db.DB_ERROR_FAILED
mysql_table_engine = mysql_table_engine or "innodb"
myisam_max_rows = 1000000

View File

@ -0,0 +1,68 @@
-- Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Bounded histograms API
-- ----------------------------------------------------------------------
ffi = require("ffi")
sysbench.histogram = {}
ffi.cdef[[
typedef struct histogram sb_histogram_t;
/*
Allocate a new histogram and initialize it with sb_histogram_init().
*/
sb_histogram_t *sb_histogram_new(size_t size, double range_min,
double range_max);
/*
Deallocate a histogram allocated with sb_histogram_new().
*/
void sb_histogram_delete(sb_histogram_t *h);
/* Update histogram with a given value. */
void sb_histogram_update(sb_histogram_t *h, double value);
/*
Print a given histogram to stdout
*/
void sb_histogram_print(sb_histogram_t *h);
]]
local histogram = {}
function histogram:update(value)
ffi.C.sb_histogram_update(self, value)
end
function histogram:print()
ffi.C.sb_histogram_print(self)
end
local histogram_mt = {
__index = histogram,
__tostring = '<sb_histogram>'
}
ffi.metatype('sb_histogram_t', histogram_mt)
function sysbench.histogram.new(size, range_min, range_max)
local h = ffi.C.sb_histogram_new(size, range_min, range_max)
return ffi.gc(h, ffi.C.sb_histogram_delete)
end

View File

@ -0,0 +1,160 @@
-- Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
ffi = require("ffi")
ffi.cdef[[
void sb_event_start(int thread_id);
void sb_event_stop(int thread_id);
bool sb_more_events(int thread_id);
]]
-- ----------------------------------------------------------------------
-- Main event loop. This is a Lua version of sysbench.c:thread_run()
-- ----------------------------------------------------------------------
function thread_run(thread_id)
while ffi.C.sb_more_events(thread_id) do
ffi.C.sb_event_start(thread_id)
local success, ret
repeat
success, ret = pcall(event, thread_id)
if not success then
if type(ret) == "table" and
ret.errcode == sysbench.error.RESTART_EVENT
then
if sysbench.hooks.before_restart_event then
sysbench.hooks.before_restart_event(ret)
end
else
error(ret, 2) -- propagate unknown errors
end
end
until success
-- Stop the benchmark if event() returns a value other than nil or false
if ret then
break
end
ffi.C.sb_event_stop(thread_id)
end
end
-- ----------------------------------------------------------------------
-- Hooks
-- ----------------------------------------------------------------------
sysbench.hooks = {
-- sql_error_ignorable = <func>,
-- report_intermediate = <func>,
-- report_cumulative = <func>
}
-- Report statistics in the CSV format. Add the following to your
-- script to replace the default human-readable reports
--
-- sysbench.hooks.report_intermediate = sysbench.report_csv
function sysbench.report_csv(stat)
local seconds = stat.time_interval
print(string.format("%.0f,%u,%4.2f," ..
"%4.2f,%4.2f,%4.2f,%4.2f," ..
"%4.2f,%4.2f," ..
"%4.2f",
stat.time_total,
stat.threads_running,
stat.events / seconds,
(stat.reads + stat.writes + stat.other) / seconds,
stat.reads / seconds,
stat.writes / seconds,
stat.other / seconds,
stat.latency_pct * 1000,
stat.errors / seconds,
stat.reconnects / seconds
))
end
-- Report statistics in the JSON format. Add the following to your
-- script to replace the default human-readable reports
--
-- sysbench.hooks.report_intermediate = sysbench.report_json
function sysbench.report_json(stat)
if not gobj then
io.write('[\n')
-- hack to print the closing bracket when the Lua state of the reporting
-- thread is closed
gobj = newproxy(true)
getmetatable(gobj).__gc = function () io.write('\n]\n') end
else
io.write(',\n')
end
local seconds = stat.time_interval
io.write(([[
{
"time": %4.0f,
"threads": %u,
"tps": %4.2f,
"qps": {
"total": %4.2f,
"reads": %4.2f,
"writes": %4.2f,
"other": %4.2f
},
"latency": %4.2f,
"errors": %4.2f,
"reconnects": %4.2f
}]]):format(
stat.time_total,
stat.threads_running,
stat.events / seconds,
(stat.reads + stat.writes + stat.other) / seconds,
stat.reads / seconds,
stat.writes / seconds,
stat.other / seconds,
stat.latency_pct * 1000,
stat.errors / seconds,
stat.reconnects / seconds
))
end
-- Report statistics in the default human-readable format. You can use it if you
-- want to augment default reports with your own statistics. Call it from your
-- own report hook, e.g.:
--
-- function sysbench.hooks.report_intermediate(stat)
-- print("my stat: ", val)
-- sysbench.report_default(stat)
-- end
function sysbench.report_default(stat)
local seconds = stat.time_interval
print(string.format("[ %.0fs ] thds: %u tps: %4.2f qps: %4.2f " ..
"(r/w/o: %4.2f/%4.2f/%4.2f) lat (ms,%u%%): %4.2f " ..
"err/s %4.2f reconn/s: %4.2f",
stat.time_total,
stat.threads_running,
stat.events / seconds,
(stat.reads + stat.writes + stat.other) / seconds,
stat.reads / seconds,
stat.writes / seconds,
stat.other / seconds,
sysbench.opt.percentile,
stat.latency_pct * 1000,
stat.errors / seconds,
stat.reconnects / seconds
))
end

View File

@ -0,0 +1,74 @@
-- Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
ffi = require("ffi")
-- ----------------------------------------------------------------------
-- Pseudo-random number generation API
-- ----------------------------------------------------------------------
sysbench.rand = {}
ffi.cdef[[
uint64_t sb_rand_uniform_uint64(void);
uint32_t sb_rand_default(uint32_t, uint32_t);
uint32_t sb_rand_uniform(uint32_t, uint32_t);
uint32_t sb_rand_gaussian(uint32_t, uint32_t);
uint32_t sb_rand_special(uint32_t, uint32_t);
uint32_t sb_rand_pareto(uint32_t, uint32_t);
uint32_t sb_rand_unique(void);
void sb_rand_str(const char *, char *);
double sb_rand_uniform_double(void);
]]
function sysbench.rand.uniform_uint64()
return ffi.C.sb_rand_uniform_uint64()
end
function sysbench.rand.default(a, b)
return ffi.C.sb_rand_default(a, b)
end
function sysbench.rand.uniform(a, b)
return ffi.C.sb_rand_uniform(a, b)
end
function sysbench.rand.gaussian(a, b)
return ffi.C.sb_rand_gaussian(a, b)
end
function sysbench.rand.special(a, b)
return ffi.C.sb_rand_special(a, b)
end
function sysbench.rand.pareto(a, b)
return ffi.C.sb_rand_pareto(a, b)
end
function sysbench.rand.unique()
return ffi.C.sb_rand_unique()
end
function sysbench.rand.string(fmt)
local buflen = #fmt
local buf = ffi.new("uint8_t[?]", buflen)
ffi.C.sb_rand_str(fmt, buf)
return ffi.string(buf, buflen)
end
function sysbench.rand.uniform_double()
return ffi.C.sb_rand_uniform_double()
end

View File

@ -0,0 +1,492 @@
-- Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- SQL API
-- ----------------------------------------------------------------------
ffi = require("ffi")
sysbench.sql = {}
ffi.cdef[[
/*
The following definitions have been copied with modifications from db_driver.h
*/
typedef enum
{
DB_ERROR_NONE, /* no error(s) */
DB_ERROR_IGNORABLE, /* error should be ignored as defined by command
line arguments or a custom error handler */
DB_ERROR_FATAL /* non-ignorable error */
} sql_error_t;
typedef struct
{
const char *sname; /* short name */
const char *lname; /* long name */
const char opaque[?];
} sql_driver;
typedef struct {
uint32_t len; /* Value length */
const char *ptr; /* Value string */
} sql_value;
/* Result set row definition */
typedef struct
{
void *ptr; /* Driver-specific row data */
sql_value *values; /* Array of column values */
} sql_row;
/* Query type for statistics */
typedef enum
{
SB_CNT_OTHER,
SB_CNT_READ,
SB_CNT_WRITE,
SB_CNT_TRX,
SB_CNT_ERROR,
SB_CNT_RECONNECT,
SB_CNT_MAX
} sb_counter_type;
typedef struct
{
sql_error_t error; /* Driver-independent error code */
int sql_errno; /* Driver-specific error code */
const char *sql_state; /* Database-specific SQL state */
const char *sql_errmsg; /* Database-specific error message */
sql_driver *driver; /* DB driver for this connection */
const char opaque[?];
} sql_connection;
typedef struct
{
sql_connection *connection;
const char opaque[?];
} sql_statement;
/* Result set definition */
typedef struct
{
sb_counter_type counter; /* Statistical counter type */
uint32_t nrows; /* Number of affected rows */
uint32_t nfields; /* Number of fields */
sql_statement *statement; /* Pointer to prepared statement (if used) */
void *ptr; /* Pointer to driver-specific data */
sql_row row; /* Last fetched row */
} sql_result;
typedef enum
{
SQL_TYPE_NONE,
SQL_TYPE_TINYINT,
SQL_TYPE_SMALLINT,
SQL_TYPE_INT,
SQL_TYPE_BIGINT,
SQL_TYPE_FLOAT,
SQL_TYPE_DOUBLE,
SQL_TYPE_TIME,
SQL_TYPE_DATE,
SQL_TYPE_DATETIME,
SQL_TYPE_TIMESTAMP,
SQL_TYPE_CHAR,
SQL_TYPE_VARCHAR
} sql_bind_type_t;
typedef struct
{
sql_bind_type_t type;
void *buffer;
unsigned long *data_len;
unsigned long max_len;
char *is_null;
} sql_bind;
sql_driver *db_create(const char *);
int db_destroy(sql_driver *drv);
sql_connection *db_connection_create(sql_driver * drv);
int db_connection_close(sql_connection *con);
int db_connection_reconnect(sql_connection *con);
void db_connection_free(sql_connection *con);
int db_bulk_insert_init(sql_connection *, const char *, size_t);
int db_bulk_insert_next(sql_connection *, const char *, size_t);
int db_bulk_insert_done(sql_connection *);
sql_result *db_query(sql_connection *con, const char *query, size_t len);
sql_row *db_fetch_row(sql_result *rs);
sql_statement *db_prepare(sql_connection *con, const char *query, size_t len);
int db_bind_param(sql_statement *stmt, sql_bind *params, size_t len);
int db_bind_result(sql_statement *stmt, sql_bind *results, size_t len);
sql_result *db_execute(sql_statement *stmt);
int db_close(sql_statement *stmt);
int db_free_results(sql_result *);
]]
local sql_driver = ffi.typeof('sql_driver *')
local sql_connection = ffi.typeof('sql_connection *')
local sql_statement = ffi.typeof('sql_statement *')
local sql_bind = ffi.typeof('sql_bind');
local sql_result = ffi.typeof('sql_result');
local sql_value = ffi.typeof('sql_value');
local sql_row = ffi.typeof('sql_row');
sysbench.sql.type =
{
NONE = ffi.C.SQL_TYPE_NONE,
TINYINT = ffi.C.SQL_TYPE_TINYINT,
SMALLINT = ffi.C.SQL_TYPE_SMALLINT,
INT = ffi.C.SQL_TYPE_INT,
BIGINT = ffi.C.SQL_TYPE_BIGINT,
FLOAT = ffi.C.SQL_TYPE_FLOAT,
DOUBLE = ffi.C.SQL_TYPE_DOUBLE,
TIME = ffi.C.SQL_TYPE_TIME,
DATE = ffi.C.SQL_TYPE_DATE,
DATETIME = ffi.C.SQL_TYPE_DATETIME,
TIMESTAMP = ffi.C.SQL_TYPE_TIMESTAMP,
CHAR = ffi.C.SQL_TYPE_CHAR,
VARCHAR = ffi.C.SQL_TYPE_VARCHAR
}
-- Initialize a given SQL driver and return a handle to it to create
-- connections. A nil driver name (i.e. no function argument) initializes the
-- default driver, i.e. the one specified with --db-driver on the command line.
function sysbench.sql.driver(driver_name)
local drv = ffi.C.db_create(driver_name)
if (drv == nil) then
error("failed to initialize the DB driver", 2)
end
return ffi.gc(drv, ffi.C.db_destroy)
end
-- sql_driver methods
local driver_methods = {}
function driver_methods.connect(self)
local con = ffi.C.db_connection_create(self)
if con == nil then
error("connection creation failed", 2)
end
return ffi.gc(con, ffi.C.db_connection_free)
end
function driver_methods.name(self)
return ffi.string(self.sname)
end
-- sql_driver metatable
local driver_mt = {
__index = driver_methods,
__gc = ffi.C.db_destroy,
__tostring = function() return '<sql_driver>' end,
}
ffi.metatype("sql_driver", driver_mt)
-- sql_connection methods
local connection_methods = {}
function connection_methods.disconnect(self)
return assert(ffi.C.db_connection_close(self) == 0)
end
function connection_methods.reconnect(self)
return assert(ffi.C.db_connection_reconnect(self) == 0)
end
function connection_methods.check_error(self, rs, query)
if rs ~= nil or self.error == sysbench.sql.error.NONE then
return rs
end
if self.sql_state == nil or self.sql_errmsg == nil then
-- It must be an API error, don't bother trying to downgrade it an
-- ignorable error
error("SQL API error", 3)
end
local sql_state = ffi.string(self.sql_state)
local sql_errmsg = ffi.string(self.sql_errmsg)
-- Create an error descriptor containing connection, failed query, SQL error
-- number, state and error message provided by the SQL driver
errdesc = {
connection = self,
query = query,
sql_errno = self.sql_errno,
sql_state = sql_state,
sql_errmsg = sql_errmsg
}
-- Check if the error has already been marked as ignorable by the driver, or
-- there is an error hook that allows downgrading it to IGNORABLE
if (self.error == sysbench.sql.error.FATAL and
type(sysbench.hooks.sql_error_ignorable) == "function" and
sysbench.hooks.sql_error_ignorable(errdesc)) or
self.error == sysbench.sql.error.IGNORABLE
then
-- Throw a 'restart event' exception that can be caught by the user script
-- to do some extra steps to restart a transaction (e.g. reprepare
-- statements after a reconnect). Otherwise it will be caught by
-- thread_run() in sysbench.lua, in which case the entire current event
-- will be restarted without extra processing.
errdesc.errcode = sysbench.error.RESTART_EVENT
error(errdesc, 3)
end
-- Just throw a regular error message on a fatal error
error(string.format("SQL error, errno = %d, state = '%s': %s",
self.sql_errno, sql_state, sql_errmsg), 2)
end
function connection_methods.query(self, query)
local rs = ffi.C.db_query(self, query, #query)
return self:check_error(rs, query)
end
function connection_methods.bulk_insert_init(self, query)
return assert(ffi.C.db_bulk_insert_init(self, query, #query) == 0,
"db_bulk_insert_init() failed")
end
function connection_methods.bulk_insert_next(self, val)
return assert(ffi.C.db_bulk_insert_next(self, val, #val) == 0,
"db_bulk_insert_next() failed")
end
function connection_methods.bulk_insert_done(self)
return assert(ffi.C.db_bulk_insert_done(self) == 0,
"db_bulk_insert_done() failed")
end
function connection_methods.prepare(self, query)
local stmt = ffi.C.db_prepare(self, query, #query)
if stmt == nil then
self:check_error(nil, query)
end
return stmt
end
-- A convenience wrapper around sql_connection:query() and
-- sql_result:fetch_row(). Executes the specified query and returns the first
-- row from the result set, if available, or nil otherwise
function connection_methods.query_row(self, query)
local rs = self:query(query)
if rs == nil or rs.nrows == 0 then
return nil
end
return unpack(rs:fetch_row(), 1, rs.nfields)
end
-- sql_connection metatable
local connection_mt = {
__index = connection_methods,
__tostring = function() return '<sql_connection>' end,
__gc = ffi.C.db_connection_free,
}
ffi.metatype("sql_connection", connection_mt)
-- sql_param
local sql_param = {}
function sql_param.set(self, value)
local sql_type = sysbench.sql.type
local btype = self.type
if (value == nil) then
self.is_null[0] = true
return
end
self.is_null[0] = false
if btype == sql_type.TINYINT or
btype == sql_type.SMALLINT or
btype == sql_type.INT or
btype == sql_type.BIGINT
then
self.buffer[0] = value
elseif btype == sql_type.FLOAT or
btype == sql_type.DOUBLE
then
self.buffer[1] = value
elseif btype == sql_type.CHAR or
btype == sql_type.VARCHAR
then
local len = #value
len = self.max_len < len and self.max_len or len
ffi.copy(self.buffer, value, len)
self.data_len[0] = len
else
error("Unsupported argument type: " .. btype, 2)
end
end
function sql_param.set_rand_str(self, fmt)
local sql_type = sysbench.sql.type
local btype = self.type
self.is_null[0] = false
if btype == sql_type.CHAR or
btype == sql_type.VARCHAR
then
local len = #fmt
len = self.max_len < len and self.max_len or len
ffi.C.sb_rand_str(fmt, self.buffer)
self.data_len[0] = len
else
error("Unsupported argument type: " .. btype, 2)
end
end
sql_param.__index = sql_param
sql_param.__tostring = function () return '<sql_param>' end
-- sql_statement methods
local statement_methods = {}
function statement_methods.bind_create(self, btype, max_len)
local sql_type = sysbench.sql.type
local param = setmetatable({}, sql_param)
if btype == sql_type.TINYINT or
btype == sql_type.SMALLINT or
btype == sql_type.INT or
btype == sql_type.BIGINT
then
param.type = sql_type.BIGINT
param.buffer = ffi.new('int64_t[1]')
param.max_len = 8
elseif btype == sql_type.FLOAT or
btype == sql_type.DOUBLE
then
param.type = sql_type.DOUBLE
param.buffer = ffi.new('double[1]')
param.max_len = 8
elseif btype == sql_type.CHAR or
btype == sql_type.VARCHAR
then
param.type = sql_type.VARCHAR
param.buffer = ffi.new('char[?]', max_len)
param.max_len = max_len
else
error("Unsupported argument type: " .. btype, 2)
end
param.data_len = ffi.new('unsigned long[1]')
param.is_null = ffi.new('char[1]')
return param
end
function statement_methods.bind_param(self, ...)
local len = select('#', ...)
if len < 1 then return nil end
local binds = ffi.new("sql_bind[?]", len)
local i, param
for i, param in ipairs({...}) do
binds[i-1].type = param.type
binds[i-1].buffer = param.buffer
binds[i-1].data_len = param.data_len
binds[i-1].max_len = param.max_len
binds[i-1].is_null = param.is_null
end
return ffi.C.db_bind_param(self, binds, len)
end
function statement_methods.execute(self)
local rs = ffi.C.db_execute(self)
return self.connection:check_error(rs, '<prepared statement>')
end
function statement_methods.close(self)
return ffi.C.db_close(self)
end
-- sql_statement metatable
local statement_mt = {
__index = statement_methods,
__tostring = function() return '<sql_statement>' end,
__gc = ffi.C.db_close,
}
ffi.metatype("sql_statement", statement_mt)
local bind_mt = {
__tostring = function() return '<sql_bind>' end,
}
ffi.metatype("sql_bind", bind_mt)
-- sql_result methods
local result_methods = {}
-- Returns the next row of values from a result set, or nil if there are no more
-- rows to fetch. Values are returned as an array, i.e. a table with numeric
-- indexes starting from 1. The total number of values (i.e. fields in a result
-- set) can be obtained from sql_result.nfields.
function result_methods.fetch_row(self)
local res = {}
local row = ffi.C.db_fetch_row(self)
if row == nil then
return nil
end
local i
for i = 0, self.nfields-1 do
if row.values[i].ptr ~= nil then -- not a NULL value
res[i+1] = ffi.string(row.values[i].ptr, tonumber(row.values[i].len))
end
end
return res
end
function result_methods.free(self)
return assert(ffi.C.db_free_results(self) == 0, "db_free_results() failed")
end
-- sql_results metatable
local result_mt = {
__index = result_methods,
__tostring = function() return '<sql_result>' end,
__gc = ffi.C.db_free_results
}
ffi.metatype("sql_result", result_mt)
-- error codes
sysbench.sql.error = {}
sysbench.sql.error.NONE = ffi.C.DB_ERROR_NONE
sysbench.sql.error.IGNORABLE = ffi.C.DB_ERROR_IGNORABLE
sysbench.sql.error.FATAL = ffi.C.DB_ERROR_FATAL

View File

@ -0,0 +1,503 @@
-- Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- -----------------------------------------------------------------------------
-- Common code for OLTP benchmarks.
-- -----------------------------------------------------------------------------
function init()
assert(event ~= nil,
"this script is meant to be included by other OLTP scripts and " ..
"should not be called directly.")
end
if sysbench.cmdline.command == nil then
error("Command is required. Supported commands: prepare, prewarm, run, " ..
"cleanup, help")
end
-- Command line options
sysbench.cmdline.options = {
table_size =
{"Number of rows per table", 10000},
range_size =
{"Range size for range SELECT queries", 100},
tables =
{"Number of tables", 1},
point_selects =
{"Number of point SELECT queries per transaction", 10},
simple_ranges =
{"Number of simple range SELECT queries per transaction", 1},
sum_ranges =
{"Number of SELECT SUM() queries per transaction", 1},
order_ranges =
{"Number of SELECT ORDER BY queries per transaction", 1},
distinct_ranges =
{"Number of SELECT DISTINCT queries per transaction", 1},
index_updates =
{"Number of UPDATE index queries per transaction", 1},
non_index_updates =
{"Number of UPDATE non-index queries per transaction", 1},
delete_inserts =
{"Number of DELETE/INSERT combinations per transaction", 1},
range_selects =
{"Enable/disable all range SELECT queries", true},
auto_inc =
{"Use AUTO_INCREMENT column as Primary Key (for MySQL), " ..
"or its alternatives in other DBMS. When disabled, use " ..
"client-generated IDs", true},
skip_trx =
{"Don't start explicit transactions and execute all queries " ..
"in the AUTOCOMMIT mode", false},
secondary =
{"Use a secondary index in place of the PRIMARY KEY", false},
create_secondary =
{"Create a secondary index in addition to the PRIMARY KEY", true},
mysql_storage_engine =
{"Storage engine, if MySQL is used", "innodb"},
pgsql_variant =
{"Use this PostgreSQL variant when running with the " ..
"PostgreSQL driver. The only currently supported " ..
"variant is 'redshift'. When enabled, " ..
"create_secondary is automatically disabled, and " ..
"delete_inserts is set to 0"}
}
-- Prepare the dataset. This command supports parallel execution, i.e. will
-- benefit from executing with --threads > 1 as long as --tables > 1
function cmd_prepare()
local drv = sysbench.sql.driver()
local con = drv:connect()
for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables,
sysbench.opt.threads do
create_table(drv, con, i)
end
end
-- Preload the dataset into the server cache. This command supports parallel
-- execution, i.e. will benefit from executing with --threads > 1 as long as
-- --tables > 1
--
-- PS. Currently, this command is only meaningful for MySQL/InnoDB benchmarks
function cmd_prewarm()
local drv = sysbench.sql.driver()
local con = drv:connect()
assert(drv:name() == "mysql", "prewarm is currently MySQL only")
-- Do not create on disk tables for subsequent queries
con:query("SET tmp_table_size=2*1024*1024*1024")
con:query("SET max_heap_table_size=2*1024*1024*1024")
for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables,
sysbench.opt.threads do
local t = "sbtest" .. i
print("Prewarming table " .. t)
con:query("ANALYZE TABLE sbtest" .. i)
con:query(string.format(
"SELECT AVG(id) FROM " ..
"(SELECT * FROM %s FORCE KEY (PRIMARY) " ..
"LIMIT %u) t",
t, sysbench.opt.table_size))
con:query(string.format(
"SELECT COUNT(*) FROM " ..
"(SELECT * FROM %s WHERE k LIKE '%%0%%' LIMIT %u) t",
t, sysbench.opt.table_size))
end
end
-- Implement parallel prepare and prewarm commands
sysbench.cmdline.commands = {
prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND},
prewarm = {cmd_prewarm, sysbench.cmdline.PARALLEL_COMMAND}
}
-- Template strings of random digits with 11-digit groups separated by dashes
-- 10 groups, 119 characters
local c_value_template = "###########-###########-###########-" ..
"###########-###########-###########-" ..
"###########-###########-###########-" ..
"###########"
-- 5 groups, 59 characters
local pad_value_template = "###########-###########-###########-" ..
"###########-###########"
function get_c_value()
return sysbench.rand.string(c_value_template)
end
function get_pad_value()
return sysbench.rand.string(pad_value_template)
end
function create_table(drv, con, table_num)
local id_index_def, id_def
local engine_def = ""
local extra_table_options = ""
local query
if sysbench.opt.secondary then
id_index_def = "KEY xid"
else
id_index_def = "PRIMARY KEY"
end
if drv:name() == "mysql" or drv:name() == "attachsql" or
drv:name() == "drizzle"
then
if sysbench.opt.auto_inc then
id_def = "INTEGER NOT NULL AUTO_INCREMENT"
else
id_def = "INTEGER NOT NULL"
end
engine_def = "/*! ENGINE = " .. sysbench.opt.mysql_storage_engine .. " */"
extra_table_options = mysql_table_options or ""
elseif drv:name() == "pgsql"
then
if not sysbench.opt.auto_inc then
id_def = "INTEGER NOT NULL"
elseif pgsql_variant == 'redshift' then
id_def = "INTEGER IDENTITY(1,1)"
else
id_def = "SERIAL"
end
else
error("Unsupported database driver:" .. drv:name())
end
print(string.format("Creating table 'sbtest%d'...", table_num))
query = string.format([[
CREATE TABLE sbtest%d(
id %s,
k INTEGER DEFAULT '0' NOT NULL,
c CHAR(120) DEFAULT '' NOT NULL,
pad CHAR(60) DEFAULT '' NOT NULL,
%s (id)
) %s %s]],
table_num, id_def, id_index_def, engine_def, extra_table_options)
con:query(query)
if (sysbench.opt.table_size > 0) then
print(string.format("Inserting %d records into 'sbtest%d'",
sysbench.opt.table_size, table_num))
end
if sysbench.opt.auto_inc then
query = "INSERT INTO sbtest" .. table_num .. "(k, c, pad) VALUES"
else
query = "INSERT INTO sbtest" .. table_num .. "(id, k, c, pad) VALUES"
end
con:bulk_insert_init(query)
local c_val
local pad_val
for i = 1, sysbench.opt.table_size do
c_val = get_c_value()
pad_val = get_pad_value()
if (sysbench.opt.auto_inc) then
query = string.format("(%d, '%s', '%s')",
sb_rand(1, sysbench.opt.table_size), c_val,
pad_val)
else
query = string.format("(%d, %d, '%s', '%s')",
i, sb_rand(1, sysbench.opt.table_size), c_val,
pad_val)
end
con:bulk_insert_next(query)
end
con:bulk_insert_done()
if sysbench.opt.create_secondary then
print(string.format("Creating a secondary index on 'sbtest%d'...",
table_num))
con:query(string.format("CREATE INDEX k_%d ON sbtest%d(k)",
table_num, table_num))
end
end
local t = sysbench.sql.type
local stmt_defs = {
point_selects = {
"SELECT c FROM sbtest%u WHERE id=?",
t.INT},
simple_ranges = {
"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?",
t.INT, t.INT},
sum_ranges = {
"SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?",
t.INT, t.INT},
order_ranges = {
"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c",
t.INT, t.INT},
distinct_ranges = {
"SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c",
t.INT, t.INT},
index_updates = {
"UPDATE sbtest%u SET k=k+1 WHERE id=?",
t.INT},
non_index_updates = {
"UPDATE sbtest%u SET c=? WHERE id=?",
{t.CHAR, 120}, t.INT},
deletes = {
"DELETE FROM sbtest%u WHERE id=?",
t.INT},
inserts = {
"INSERT INTO sbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)",
t.INT, t.INT, {t.CHAR, 120}, {t.CHAR, 60}},
}
function prepare_begin()
stmt.begin = con:prepare("BEGIN")
end
function prepare_commit()
stmt.commit = con:prepare("COMMIT")
end
function prepare_for_each_table(key)
for t = 1, sysbench.opt.tables do
stmt[t][key] = con:prepare(string.format(stmt_defs[key][1], t))
local nparam = #stmt_defs[key] - 1
if nparam > 0 then
param[t][key] = {}
end
for p = 1, nparam do
local btype = stmt_defs[key][p+1]
local len
if type(btype) == "table" then
len = btype[2]
btype = btype[1]
end
if btype == sysbench.sql.type.VARCHAR or
btype == sysbench.sql.type.CHAR then
param[t][key][p] = stmt[t][key]:bind_create(btype, len)
else
param[t][key][p] = stmt[t][key]:bind_create(btype)
end
end
if nparam > 0 then
stmt[t][key]:bind_param(unpack(param[t][key]))
end
end
end
function prepare_point_selects()
prepare_for_each_table("point_selects")
end
function prepare_simple_ranges()
prepare_for_each_table("simple_ranges")
end
function prepare_sum_ranges()
prepare_for_each_table("sum_ranges")
end
function prepare_order_ranges()
prepare_for_each_table("order_ranges")
end
function prepare_distinct_ranges()
prepare_for_each_table("distinct_ranges")
end
function prepare_index_updates()
prepare_for_each_table("index_updates")
end
function prepare_non_index_updates()
prepare_for_each_table("non_index_updates")
end
function prepare_delete_inserts()
prepare_for_each_table("deletes")
prepare_for_each_table("inserts")
end
function thread_init()
drv = sysbench.sql.driver()
con = drv:connect()
-- Create global nested tables for prepared statements and their
-- parameters. We need a statement and a parameter set for each combination
-- of connection/table/query
stmt = {}
param = {}
for t = 1, sysbench.opt.tables do
stmt[t] = {}
param[t] = {}
end
-- This function is a 'callback' defined by individual benchmark scripts
prepare_statements()
end
-- Close prepared statements
function close_statements()
for t = 1, sysbench.opt.tables do
for k, s in pairs(stmt[t]) do
stmt[t][k]:close()
end
end
if (stmt.begin ~= nil) then
stmt.begin:close()
end
if (stmt.commit ~= nil) then
stmt.commit:close()
end
end
function thread_done()
close_statements()
con:disconnect()
end
function cleanup()
local drv = sysbench.sql.driver()
local con = drv:connect()
for i = 1, sysbench.opt.tables do
print(string.format("Dropping table 'sbtest%d'...", i))
con:query("DROP TABLE IF EXISTS sbtest" .. i )
end
end
local function get_table_num()
return sysbench.rand.uniform(1, sysbench.opt.tables)
end
local function get_id()
return sysbench.rand.default(1, sysbench.opt.table_size)
end
function begin()
stmt.begin:execute()
end
function commit()
stmt.commit:execute()
end
function execute_point_selects()
local tnum = get_table_num()
local i
for i = 1, sysbench.opt.point_selects do
param[tnum].point_selects[1]:set(get_id())
stmt[tnum].point_selects:execute()
end
end
local function execute_range(key)
local tnum = get_table_num()
for i = 1, sysbench.opt[key] do
local id = get_id()
param[tnum][key][1]:set(id)
param[tnum][key][2]:set(id + sysbench.opt.range_size - 1)
stmt[tnum][key]:execute()
end
end
function execute_simple_ranges()
execute_range("simple_ranges")
end
function execute_sum_ranges()
execute_range("sum_ranges")
end
function execute_order_ranges()
execute_range("order_ranges")
end
function execute_distinct_ranges()
execute_range("distinct_ranges")
end
function execute_index_updates()
local tnum = get_table_num()
for i = 1, sysbench.opt.index_updates do
param[tnum].index_updates[1]:set(get_id())
stmt[tnum].index_updates:execute()
end
end
function execute_non_index_updates()
local tnum = get_table_num()
for i = 1, sysbench.opt.non_index_updates do
param[tnum].non_index_updates[1]:set_rand_str(c_value_template)
param[tnum].non_index_updates[2]:set(get_id())
stmt[tnum].non_index_updates:execute()
end
end
function execute_delete_inserts()
local tnum = get_table_num()
for i = 1, sysbench.opt.delete_inserts do
local id = get_id()
local k = get_id()
param[tnum].deletes[1]:set(id)
param[tnum].inserts[1]:set(id)
param[tnum].inserts[2]:set(k)
param[tnum].inserts[3]:set_rand_str(c_value_template)
param[tnum].inserts[4]:set_rand_str(pad_value_template)
stmt[tnum].deletes:execute()
stmt[tnum].inserts:execute()
end
end
-- Re-prepare statements if we have reconnected, which is possible when some of
-- the listed error codes are in the --mysql-ignore-errors list
function sysbench.hooks.before_restart_event(errdesc)
if errdesc.sql_errno == 2013 or -- CR_SERVER_LOST
errdesc.sql_errno == 2055 or -- CR_SERVER_LOST_EXTENDED
errdesc.sql_errno == 2006 or -- CR_SERVER_GONE_ERROR
errdesc.sql_errno == 2011 -- CR_TCP_CONNECTION
then
close_statements()
prepare_statements()
end
end

View File

@ -0,0 +1,34 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Delete-Only OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
prepare_for_each_table("deletes")
end
function event()
local tnum = sysbench.rand.uniform(1, sysbench.opt.tables)
local id = sysbench.rand.default(1, sysbench.opt.table_size)
param[tnum].deletes[1]:set(id)
stmt[tnum].deletes:execute()
end

View File

@ -0,0 +1,65 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Insert-Only OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
sysbench.cmdline.commands.prepare = {
function ()
if (not sysbench.opt.auto_inc) then
-- Create empty tables on prepare when --auto-inc is off, since IDs
-- generated on prepare may collide later with values generated by
-- sysbench.rand.unique()
sysbench.opt.table_size=0
end
cmd_prepare()
end,
sysbench.cmdline.PARALLEL_COMMAND
}
function prepare_statements()
-- We do not use prepared statements here, but oltp_common.sh expects this
-- function to be defined
end
function event()
local table_name = "sbtest" .. sysbench.rand.uniform(1, sysbench.opt.tables)
local k_val = sysbench.rand.default(1, sysbench.opt.table_size)
local c_val = get_c_value()
local pad_val = get_pad_value()
if (drv:name() == "pgsql" and sysbench.opt.auto_inc) then
con:query(string.format("INSERT INTO %s (k, c, pad) VALUES " ..
"(%d, '%s', '%s')",
table_name, k_val, c_val, pad_val))
else
if (sysbench.opt.auto_inc) then
i = 0
else
-- Convert a uint32_t value to SQL INT
i = sysbench.rand.unique() - 2147483648
end
con:query(string.format("INSERT INTO %s (id, k, c, pad) VALUES " ..
"(%d, %d, '%s', '%s')",
table_name, i, k_val, c_val, pad_val))
end
end

View File

@ -0,0 +1,34 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- OLTP Point Select benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
-- use 1 query per event, rather than sysbench.opt.point_selects which
-- defaults to 10 in other OLTP scripts
sysbench.opt.point_selects=1
prepare_point_selects()
end
function event()
execute_point_selects()
end

View File

@ -0,0 +1,57 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Read-Only OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
prepare_point_selects()
if not sysbench.opt.skip_trx then
prepare_begin()
prepare_commit()
end
if sysbench.opt.range_selects then
prepare_simple_ranges()
prepare_sum_ranges()
prepare_order_ranges()
prepare_distinct_ranges()
end
end
function event()
if not sysbench.opt.skip_trx then
begin()
end
execute_point_selects()
if sysbench.opt.range_selects then
execute_simple_ranges()
execute_sum_ranges()
execute_order_ranges()
execute_distinct_ranges()
end
if not sysbench.opt.skip_trx then
commit()
end
end

View File

@ -0,0 +1,65 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Read/Write OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
if not sysbench.opt.skip_trx then
prepare_begin()
prepare_commit()
end
prepare_point_selects()
if sysbench.opt.range_selects then
prepare_simple_ranges()
prepare_sum_ranges()
prepare_order_ranges()
prepare_distinct_ranges()
end
prepare_index_updates()
prepare_non_index_updates()
prepare_delete_inserts()
end
function event()
if not sysbench.opt.skip_trx then
begin()
end
execute_point_selects()
if sysbench.opt.range_selects then
execute_simple_ranges()
execute_sum_ranges()
execute_order_ranges()
execute_distinct_ranges()
end
execute_index_updates()
execute_non_index_updates()
execute_delete_inserts()
if not sysbench.opt.skip_trx then
commit()
end
end

View File

@ -0,0 +1,30 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Update-Index OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
prepare_index_updates()
end
function event()
execute_index_updates(con)
end

View File

@ -0,0 +1,30 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Update-Non-Index OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
prepare_non_index_updates()
end
function event()
execute_non_index_updates()
end

View File

@ -0,0 +1,47 @@
#!/usr/bin/env sysbench
-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- 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
-- ----------------------------------------------------------------------
-- Write-Only OLTP benchmark
-- ----------------------------------------------------------------------
require("oltp_common")
function prepare_statements()
if not sysbench.opt.skip_trx then
prepare_begin()
prepare_commit()
end
prepare_index_updates()
prepare_non_index_updates()
prepare_delete_inserts()
end
function event()
if not sysbench.opt.skip_trx then
begin()
end
execute_index_updates()
execute_non_index_updates()
execute_delete_inserts()
if not sysbench.opt.skip_trx then
commit()
end
end

View File

@ -0,0 +1,72 @@
#!/usr/bin/env sysbench
-- This test is designed for testing MariaDB's key_cache_segments for MyISAM,
-- and should work with other storage engines as well.
--
-- For details about key_cache_segments please refer to:
-- http://kb.askmonty.org/v/segmented-key-cache
--
require("oltp_common")
-- Add random_points to the list of standard OLTP options
sysbench.cmdline.options.random_points =
{"Number of random points in the IN() clause in generated SELECTs", 10}
-- Override standard prepare/cleanup OLTP functions, as this benchmark does not
-- support multiple tables
oltp_prepare = prepare
oltp_cleanup = cleanup
function prepare()
assert(sysbench.opt.tables == 1, "this benchmark does not support " ..
"--tables > 1")
oltp_prepare()
end
function cleanup()
assert(sysbench.opt.tables == 1, "this benchmark does not support " ..
"--tables > 1")
oltp_cleanup()
end
function thread_init()
drv = sysbench.sql.driver()
con = drv:connect()
local points = string.rep("?, ", sysbench.opt.random_points - 1) .. "?"
stmt = con:prepare(string.format([[
SELECT id, k, c, pad
FROM sbtest1
WHERE k IN (%s)
]], points))
params = {}
for j = 1, sysbench.opt.random_points do
params[j] = stmt:bind_create(sysbench.sql.type.INT)
end
stmt:bind_param(unpack(params))
rlen = sysbench.opt.table_size / sysbench.opt.threads
thread_id = sysbench.tid % sysbench.opt.threads
end
function thread_done()
stmt:close()
con:disconnect()
end
function event()
-- To prevent overlapping of our range queries we need to partition the whole
-- table into 'threads' segments and then make each thread work with its
-- own segment.
for i = 1, sysbench.opt.random_points do
local rmin = rlen * thread_id
local rmax = rmin + rlen
params[i]:set(sb_rand(rmin, rmax))
end
stmt:execute()
end

View File

@ -0,0 +1,77 @@
#!/usr/bin/env sysbench
-- This test is designed for testing MariaDB's key_cache_segments for MyISAM,
-- and should work with other storage engines as well.
--
-- For details about key_cache_segments please refer to:
-- http://kb.askmonty.org/v/segmented-key-cache
--
require("oltp_common")
-- Add --number-of-ranges and --delta to the list of standard OLTP options
sysbench.cmdline.options.number_of_ranges =
{"Number of random BETWEEN ranges per SELECT", 10}
sysbench.cmdline.options.delta =
{"Size of BETWEEN ranges", 5}
-- Override standard prepare/cleanup OLTP functions, as this benchmark does not
-- support multiple tables
oltp_prepare = prepare
oltp_cleanup = cleanup
function prepare()
assert(sysbench.opt.tables == 1, "this benchmark does not support " ..
"--tables > 1")
oltp_prepare()
end
function cleanup()
assert(sysbench.opt.tables == 1, "this benchmark does not support " ..
"--tables > 1")
oltp_cleanup()
end
function thread_init()
drv = sysbench.sql.driver()
con = drv:connect()
local ranges = string.rep("k BETWEEN ? AND ? OR ",
sysbench.opt.number_of_ranges - 1) ..
"k BETWEEN ? AND ?"
stmt = con:prepare(string.format([[
SELECT count(k)
FROM sbtest1
WHERE %s]], ranges))
params = {}
for j = 1, sysbench.opt.number_of_ranges*2 do
params[j] = stmt:bind_create(sysbench.sql.type.INT)
end
stmt:bind_param(unpack(params))
rlen = sysbench.opt.table_size / sysbench.opt.threads
thread_id = sysbench.tid % sysbench.opt.threads
end
function thread_done()
stmt:close()
con:disconnect()
end
function event()
-- To prevent overlapping of our range queries we need to partition the whole
-- table into 'threads' segments and then make each thread work with its
-- own segment.
for i = 1, sysbench.opt.number_of_ranges*2, 2 do
local rmin = rlen * thread_id
local rmax = rmin + rlen
local val = sb_rand(rmin, rmax)
params[i]:set(val)
params[i+1]:set(val + sysbench.opt.delta)
end
stmt:execute()
end

View File

@ -0,0 +1,104 @@
/*
Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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);
}

View File

@ -0,0 +1,58 @@
/*
Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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 */

View File

@ -0,0 +1,236 @@
/*
Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
/*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2010 Samy Al Bahra.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
Compatibility wrappers for ConcurrencyKit functions. ConcurrencyKit does not
implement 64-bit atomic primitives on some 32-bit architectures (e.g. x86,
ARMv6) natively. Newer versions support the CK_USE_CC_BUILTINS define which
allows resorting to compiler builtins emulating 64-bit atomics on 32-bit
architectures. However, one might want to build with an old,
distribution-provided CK version where that option is not available. For those
versions, define 64-bit atomics as aliases to GCC builtins. A cleaner solution
would be to define the corresponding sysbench data structures as 32-bit
integers on those architectures, but the amount of extra code to implement and
support is not worth it. Code below has been copied with modifications from
gcc/ck_pr.h from the ConcurrencyKit distribution.
*/
#ifndef SB_CK_H
#define SB_CK_H
#include "ck_pr.h"
#if !defined(CK_F_PR_LOAD_64)
#ifndef __GNUC__
# error Unsupported platform
#endif
#include <ck_cc.h>
#define CK_PR_ACCESS(x) (*(volatile __typeof__(x) *)&(x))
#define CK_PR_LOAD(S, M, T) \
CK_CC_INLINE static T \
ck_pr_md_load_##S(const M *target) \
{ \
T r; \
ck_pr_barrier(); \
r = CK_PR_ACCESS(*(const T *)target); \
ck_pr_barrier(); \
return (r); \
} \
CK_CC_INLINE static void \
ck_pr_md_store_##S(M *target, T v) \
{ \
ck_pr_barrier(); \
CK_PR_ACCESS(*(T *)target) = v; \
ck_pr_barrier(); \
return; \
}
#define CK_PR_LOAD_S(S, T) CK_PR_LOAD(S, T, T)
CK_PR_LOAD_S(64, uint64_t)
#undef CK_PR_LOAD_S
#undef CK_PR_LOAD
#define CK_PR_LOAD_SAFE(SRC, TYPE) ck_pr_md_load_##TYPE((SRC))
#define CK_PR_STORE_SAFE(DST, VAL, TYPE) \
ck_pr_md_store_##TYPE( \
((void)sizeof(*(DST) = (VAL)), (DST)), \
(VAL))
#define ck_pr_load_64(SRC) CK_PR_LOAD_SAFE((SRC), 64)
#define ck_pr_store_64(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 64)
/*
* Atomic compare and swap.
*/
#define CK_PR_CAS(S, M, T) \
CK_CC_INLINE static bool \
ck_pr_cas_##S(M *target, T compare, T set) \
{ \
bool z; \
z = __sync_bool_compare_and_swap((T *)target, compare, set); \
return z; \
}
#define CK_PR_CAS_S(S, T) CK_PR_CAS(S, T, T)
CK_PR_CAS_S(64, uint64_t)
#undef CK_PR_CAS_S
#undef CK_PR_CAS
#define CK_PR_CAS_O(S, T) \
CK_CC_INLINE static bool \
ck_pr_cas_##S##_value(T *target, T compare, T set, T *v) \
{ \
set = __sync_val_compare_and_swap(target, compare, set);\
*v = set; \
return (set == compare); \
}
CK_PR_CAS_O(64, uint64_t)
#undef CK_PR_CAS_O
/*
* Atomic store-only binary operations.
*/
#define CK_PR_BINARY(K, S, M, T) \
CK_CC_INLINE static void \
ck_pr_##K##_##S(M *target, T d) \
{ \
d = __sync_fetch_and_##K((T *)target, d); \
return; \
}
#define CK_PR_BINARY_S(K, S, T) CK_PR_BINARY(K, S, T, T)
#define CK_PR_GENERATE(K) \
CK_PR_BINARY_S(K, 64, uint64_t)
CK_PR_GENERATE(add)
CK_PR_GENERATE(sub)
CK_PR_GENERATE(and)
CK_PR_GENERATE(or)
CK_PR_GENERATE(xor)
#undef CK_PR_GENERATE
#undef CK_PR_BINARY_S
#undef CK_PR_BINARY
#define CK_PR_UNARY(S, M, T) \
CK_CC_INLINE static void \
ck_pr_inc_##S(M *target) \
{ \
ck_pr_add_##S(target, (T)1); \
return; \
} \
CK_CC_INLINE static void \
ck_pr_dec_##S(M *target) \
{ \
ck_pr_sub_##S(target, (T)1); \
return; \
}
#define CK_PR_UNARY_S(S, M) CK_PR_UNARY(S, M, M)
CK_PR_UNARY_S(64, uint64_t)
#undef CK_PR_UNARY_S
#undef CK_PR_UNARY
#define CK_PR_FAA(S, M, T, C) \
CK_CC_INLINE static C \
ck_pr_faa_##S(M *target, T delta) \
{ \
T previous; \
C punt; \
punt = (C)ck_pr_md_load_##S(target); \
previous = (T)punt; \
while (ck_pr_cas_##S##_value(target, \
(C)previous, \
(C)(previous + delta), \
&previous) == false) \
ck_pr_stall(); \
\
return ((C)previous); \
}
#define CK_PR_FAS(S, M, C) \
CK_CC_INLINE static C \
ck_pr_fas_##S(M *target, C update) \
{ \
C previous; \
previous = ck_pr_md_load_##S(target); \
while (ck_pr_cas_##S##_value(target, \
previous, \
update, \
&previous) == false) \
ck_pr_stall(); \
\
return (previous); \
}
#define CK_PR_FAA_S(S, M) CK_PR_FAA(S, M, M, M)
#define CK_PR_FAS_S(S, M) CK_PR_FAS(S, M, M)
CK_PR_FAA_S(64, uint64_t)
CK_PR_FAS_S(64, uint64_t)
#undef CK_PR_FAA_S
#undef CK_PR_FAA
#undef CK_PR_FAS_S
#undef CK_PR_FAS
#endif /* !CK_F_PR_LOAD_64*/
#endif /* SB_CK_H */

View File

@ -0,0 +1,94 @@
/*
Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "sb_counter.h"
#include "sysbench.h"
#include "sb_util.h"
#include "sb_ck_pr.h"
sb_counters_t *sb_counters CK_CC_CACHELINE;
static sb_counters_t last_intermediate_counters;
static sb_counters_t last_cumulative_counters;
/* Initialize per-thread stats */
int sb_counters_init(void)
{
SB_COMPILE_TIME_ASSERT(sizeof(sb_counters_t) % CK_MD_CACHELINE == 0);
sb_counters = sb_alloc_per_thread_array(sizeof(sb_counters_t));
return sb_counters == NULL;
}
void sb_counters_done(void)
{
if (sb_counters != NULL)
{
free(sb_counters);
sb_counters = NULL;
}
}
static void sb_counters_merge(sb_counters_t dst)
{
for (size_t t = 0; t < SB_CNT_MAX; t++)
for (size_t i = 0; i < sb_globals.threads; i++)
dst[t] += sb_counter_val(i, t);
}
static void sb_counters_checkpoint(sb_counters_t dst, sb_counters_t cp)
{
for (size_t i = 0; i < SB_CNT_MAX; i++)
{
uint64_t tmp = cp[i];
cp[i] = dst[i];
dst[i] = dst[i] - tmp;
}
}
/*
Return aggregate counter values since the last intermediate report. This is
not thread-safe as it updates the global last report state, so it must be
called from a single thread.
*/
void sb_counters_agg_intermediate(sb_counters_t val)
{
memset(val, 0, sizeof(sb_counters_t));
sb_counters_merge(val);
sb_counters_checkpoint(val, last_intermediate_counters);
}
/*
Return aggregate counter values since the last cumulative report. This is
not thread-safe as it updates the global last report state, so it must be
called from a single thread.
*/
void sb_counters_agg_cumulative(sb_counters_t val)
{
memset(val, 0, sizeof(sb_counters_t));
sb_counters_merge(val);
sb_counters_checkpoint(val, last_cumulative_counters);
}

View File

@ -0,0 +1,105 @@
/*
Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifndef SB_COUNTER_H
#define SB_COUNTER_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef STDC_HEADERS
# include <inttypes.h>
#endif
#include "sb_util.h"
#include "sb_ck_pr.h"
/* Statistic counter types */
typedef enum {
SB_CNT_OTHER, /* unknown type of queries */
SB_CNT_READ, /* reads */
SB_CNT_WRITE, /* writes */
SB_CNT_EVENT, /* events */
SB_CNT_ERROR, /* errors */
SB_CNT_RECONNECT, /* reconnects */
SB_CNT_MAX
} sb_counter_type_t;
/*
sizeof(sb_counter_t) must be a multiple of CK_MD_CACHELINE to avoid cache
line sharing.
*/
typedef uint64_t
sb_counters_t[SB_ALIGN(SB_CNT_MAX * sizeof(uint64_t), CK_MD_CACHELINE) /
sizeof(uint64_t)];
extern sb_counters_t *sb_counters;
int sb_counters_init(void);
void sb_counters_done(void);
/*
Cannot use C99 inline here, because CK atomic primitives use static inlines
which in turn leads to compiler warnings. So for performance reasons the
following functions are defined 'static inline' too everywhere except sb_lua.c
where they are declared and defined as external linkage functions to be
available from LuaJIT FFI.
*/
#ifndef SB_LUA_EXPORT
# define SB_LUA_INLINE static inline
#else
# define SB_LUA_INLINE
uint64_t sb_counter_val(int thread_id, sb_counter_type_t type);
void sb_counter_inc(int thread_id, sb_counter_type_t type);
#endif
/* Return the current value for a given counter */
SB_LUA_INLINE
uint64_t sb_counter_val(int thread_id, sb_counter_type_t type)
{
return ck_pr_load_64(&sb_counters[thread_id][type]);
}
/* Increment a given stat counter for a given thread */
SB_LUA_INLINE
void sb_counter_inc(int thread_id, sb_counter_type_t type)
{
ck_pr_store_64(&sb_counters[thread_id][type],
sb_counter_val(thread_id, type)+1);
}
#undef SB_LUA_INLINE
/*
Return aggregate counter values since the last intermediate report. This is
not thread-safe as it updates the global last report state, so it must be
called from a single thread.
*/
void sb_counters_agg_intermediate(sb_counters_t val);
/*
Return aggregate counter values since the last cumulative report. This is
not thread-safe as it updates the global last report state, so it must be
called from a single thread.
*/
void sb_counters_agg_cumulative(sb_counters_t val);
#endif

View File

@ -0,0 +1,27 @@
/* Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
/* Global and portability-related macros */
#ifndef SB_GLOBAL_H
#define SB_GLOBAL_H
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#endif /* SB_GLOBAL_H */

View File

@ -0,0 +1,373 @@
/* Copyright (C) 2011-2017 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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#ifdef STDC_HEADERS
# include <stdio.h>
# include <stdlib.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_MATH_H
# include <math.h>
#endif
#include "sysbench.h"
#include "sb_histogram.h"
#include "sb_logger.h"
#include "sb_rand.h"
#include "sb_ck_pr.h"
#include "ck_cc.h"
#include "sb_util.h"
/*
Number of slots for current histogram array. TODO: replace this constant with
some autodetection code based on the number of available cores or some such.
*/
#define SB_HISTOGRAM_NSLOTS 128
/* Global latency histogram */
sb_histogram_t sb_latency_histogram CK_CC_CACHELINE;
int sb_histogram_init(sb_histogram_t *h, size_t size,
double range_min, double range_max)
{
size_t i;
uint64_t *tmp;
/* Allocate memory for cumulative_array + temp_array + all slot arrays */
tmp = (uint64_t *) calloc(size * (SB_HISTOGRAM_NSLOTS + 2), sizeof(uint64_t));
h->interm_slots = (uint64_t **) malloc(SB_HISTOGRAM_NSLOTS *
sizeof(uint64_t *));
if (tmp == NULL || h->interm_slots == NULL)
{
log_text(LOG_FATAL,
"Failed to allocate memory for a histogram object, size = %zd",
size);
return 1;
}
h->cumulative_array = tmp;
tmp += size;
h->temp_array = tmp;
tmp += size;
for (i = 0; i < SB_HISTOGRAM_NSLOTS; i++)
{
h->interm_slots[i] = tmp;
tmp += size;
}
h->range_deduct = log(range_min);
h->range_mult = (size - 1) / (log(range_max) - h->range_deduct);
h->range_min = range_min;
h->range_max = range_max;
h->array_size = size;
pthread_rwlock_init(&h->lock, NULL);
return 0;
}
void sb_histogram_update(sb_histogram_t *h, double value)
{
size_t slot;
ssize_t i;
slot = sb_rand_uniform_uint64() % SB_HISTOGRAM_NSLOTS;
i = floor((log(value) - h->range_deduct) * h->range_mult + 0.5);
if (SB_UNLIKELY(i < 0))
i = 0;
else if (SB_UNLIKELY(i >= (ssize_t) (h->array_size)))
i = h->array_size - 1;
ck_pr_inc_64(&h->interm_slots[slot][i]);
}
double sb_histogram_get_pct_intermediate(sb_histogram_t *h,
double percentile)
{
size_t i, s;
uint64_t nevents, ncur, nmax;
double res;
nevents = 0;
/*
This can be called concurrently with other sb_histogram_get_pct_*()
functions, so use the lock to protect shared structures. This will not block
sb_histogram_update() calls, but we make sure we don't lose any concurrent
increments by atomically fetching each array element and replacing it with
0.
*/
pthread_rwlock_wrlock(&h->lock);
/*
Merge intermediate slots into temp_array.
*/
const size_t size = h->array_size;
uint64_t * const array = h->temp_array;
for (i = 0; i < size; i++)
{
array[i] = ck_pr_fas_64(&h->interm_slots[0][i], 0);
nevents += array[i];
}
for (s = 1; s < SB_HISTOGRAM_NSLOTS; s++)
{
for (i = 0; i < size; i++)
{
uint64_t t;
t = ck_pr_fas_64(&h->interm_slots[s][i], 0);
array[i] += t;
nevents += t;
}
}
/*
Now that we have an aggregate 'snapshot' of current arrays and the total
number of events in it, calculate the current, intermediate percentile value
to return.
*/
nmax = floor(nevents * percentile / 100 + 0.5);
ncur = 0;
for (i = 0; i < size; i++)
{
ncur += array[i];
if (ncur >= nmax)
break;
}
res = exp(i / h->range_mult + h->range_deduct);
/* Finally, add temp_array into accumulated values in cumulative_array. */
for (i = 0; i < size; i++)
{
h->cumulative_array[i] += array[i];
}
h->cumulative_nevents += nevents;
pthread_rwlock_unlock(&h->lock);
return res;
}
/*
Aggregate arrays from intermediate slots into cumulative_array. This should be
called with the histogram lock write-locked.
*/
static void merge_intermediate_into_cumulative(sb_histogram_t *h)
{
size_t i, s;
uint64_t nevents;
nevents = h->cumulative_nevents;
const size_t size = h->array_size;
uint64_t * const array = h->cumulative_array;
for (s = 0; s < SB_HISTOGRAM_NSLOTS; s++)
{
for (i = 0; i < size; i++)
{
uint64_t t = ck_pr_fas_64(&h->interm_slots[s][i], 0);
array[i] += t;
nevents += t;
}
}
h->cumulative_nevents = nevents;
}
/*
Calculate a given percentile from the cumulative array. This should be called
with the histogram lock either read- or write-locked.
*/
static double get_pct_cumulative(sb_histogram_t *h, double percentile)
{
size_t i;
uint64_t ncur, nmax;
nmax = floor(h->cumulative_nevents * percentile / 100 + 0.5);
ncur = 0;
for (i = 0; i < h->array_size; i++)
{
ncur += h->cumulative_array[i];
if (ncur >= nmax)
break;
}
return exp(i / h->range_mult + h->range_deduct);
}
double sb_histogram_get_pct_cumulative(sb_histogram_t *h, double percentile)
{
double res;
/*
This can be called concurrently with other sb_histogram_get_pct_*()
functions, so use the lock to protect shared structures. This will not block
sb_histogram_update() calls, but we make sure we don't lose any concurrent
increments by atomically fetching each array element and replacing it with
0.
*/
pthread_rwlock_wrlock(&h->lock);
merge_intermediate_into_cumulative(h);
res = get_pct_cumulative(h, percentile);
pthread_rwlock_unlock(&h->lock);
return res;
}
double sb_histogram_get_pct_checkpoint(sb_histogram_t *h,
double percentile)
{
double res;
/*
This can be called concurrently with other sb_histogram_get_pct_*()
functions, so use the lock to protect shared structures. This will not block
sb_histogram_update() calls, but we make sure we don't lose any concurrent
increments by atomically fetching each array element and replacing it with
0.
*/
pthread_rwlock_wrlock(&h->lock);
merge_intermediate_into_cumulative(h);
res = get_pct_cumulative(h, percentile);
/* Reset the cumulative array */
memset(h->cumulative_array, 0, h->array_size * sizeof(uint64_t));
h->cumulative_nevents = 0;
pthread_rwlock_unlock(&h->lock);
return res;
}
void sb_histogram_print(sb_histogram_t *h)
{
uint64_t maxcnt;
int width;
size_t i;
pthread_rwlock_wrlock(&h->lock);
merge_intermediate_into_cumulative(h);
uint64_t * const array = h->cumulative_array;
maxcnt = 0;
for (i = 0; i < h->array_size; i++)
{
if (array[i] > maxcnt)
maxcnt = array[i];
}
if (maxcnt == 0)
return;
printf(" value ------------- distribution ------------- count\n");
for (i = 0; i < h->array_size; i++)
{
if (array[i] == 0)
continue;
width = floor(array[i] * (double) 40 / maxcnt + 0.5);
printf("%12.3f |%-40.*s %lu\n",
exp(i / h->range_mult + h->range_deduct), /* value */
width, "****************************************", /* distribution */
(unsigned long) array[i]); /* count */
}
pthread_rwlock_unlock(&h->lock);
}
void sb_histogram_done(sb_histogram_t *h)
{
pthread_rwlock_destroy(&h->lock);
free(h->cumulative_array);
free(h->interm_slots);
}
/*
Allocate a new histogram and initialize it with sb_histogram_init().
*/
sb_histogram_t *sb_histogram_new(size_t size, double range_min,
double range_max)
{
sb_histogram_t *h;
if ((h = malloc(sizeof(*h))) == NULL)
return NULL;
if (sb_histogram_init(h, size, range_min, range_max))
{
free(h);
return NULL;
}
return h;
}
/*
Deallocate a histogram allocated with sb_histogram_new().
*/
void sb_histogram_delete(sb_histogram_t *h)
{
sb_histogram_done(h);
free(h);
}

View File

@ -0,0 +1,119 @@
/* Copyright (C) 2011-2017 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
*/
#ifndef SB_HISTOGRAM_H
#define SB_HISTOGRAM_H
#include <stdint.h>
#ifdef HAVE_PTHREAD_H
# include <pthread.h>
#endif
typedef struct {
/*
Cumulative histogram array. Updated 'on demand' by
sb_histogram_get_pct_intermediate(). Protected by 'lock'.
*/
uint64_t *cumulative_array;
/*
Total number of events in cumulative_array. Updated on demand by
sb_histogram_get_pct_intermediate(). Protected by 'lock'.
*/
uint64_t cumulative_nevents;
/*
Temporary array for intermediate percentile calculations. Protected by
'lock'.
*/
uint64_t *temp_array;
/*
Intermediate histogram values are split into multiple slots and updated
with atomics. Aggregations into cumulative values is performed by
sb_histogram_get_pct_intermediate() function.
*/
uint64_t **interm_slots;
/* Number of elements in each array */
size_t array_size;
/* Lower bound of values to track */
double range_min;
/* Upper bound of values to track */
double range_max;
/* Value to deduct to calculate histogram range based on array element */
double range_deduct;
/* Value to multiply to calculate histogram range based array element */
double range_mult;
/*
rwlock to protect cumulative_array and cumulative_nevents from concurrent
updates.
*/
pthread_rwlock_t lock;
} sb_histogram_t;
/* Global latency histogram */
extern sb_histogram_t sb_latency_histogram;
/*
Allocate a new histogram and initialize it with sb_histogram_init().
*/
sb_histogram_t *sb_histogram_new(size_t size, double range_min,
double range_max);
/*
Deallocate a histogram allocated with sb_histogram_new().
*/
void sb_histogram_delete(sb_histogram_t *h);
/*
Initialize a new histogram object with a given array size and value bounds.
*/
int sb_histogram_init(sb_histogram_t *h, size_t size,
double range_min, double range_max);
/* Update histogram with a given value. */
void sb_histogram_update(sb_histogram_t *h, double value);
/*
Calculate a given percentile value from the intermediate histogram values,
then merge intermediate values into cumulative ones atomically, i.e. in a way
that no concurrent updates are lost and will be accounted in either the
current or later merge of intermediate clues.
*/
double sb_histogram_get_pct_intermediate(sb_histogram_t *h, double percentile);
/*
Merge intermediate histogram values into cumulative ones and calculate a given
percentile value from the cumulative array.
*/
double sb_histogram_get_pct_cumulative(sb_histogram_t *h, double percentile);
/*
Similar to sb_histogram_get_pct_cumulative(), but also resets cumulative
stats right after calculating the returned percentile. The reset happens
atomically so that no conucrrent updates are lost after percentile
calculation. This is currently used only by 'checkpoint' reports.
*/
double sb_histogram_get_pct_checkpoint(sb_histogram_t *h, double percentile);
/*
Print a given histogram to stdout
*/
void sb_histogram_print(sb_histogram_t *h);
/* Destroy a given histogram object */
void sb_histogram_done(sb_histogram_t *h);
#endif

View File

@ -0,0 +1,120 @@
/* Copyright (C) 2004 MySQL AB
Copyright (C) 2004-2014 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifndef SB_LIST_H
#define SB_LIST_H
typedef struct sb_list_item_t
{
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)
#endif
#define SB_LIST_DECLARE(name) \
SB_LIST_T name = { &(name), &(name) }
#define SB_LIST_INIT(head_p) \
do { \
(head_p)->next_p = (head_p); \
(head_p)->prev_p = (head_p); \
} while (0)
#define SB_LIST_ITEM_INIT(item_p) \
SB_LIST_INIT(item_p)
#define SB_LIST_ADD(item_p, head_p) \
do { \
(item_p)->next_p = (head_p)->next_p; \
(item_p)->prev_p = (head_p); \
(head_p)->next_p = (item_p); \
(item_p)->next_p->prev_p = (item_p); \
} while (0)
#define SB_LIST_ADD_TAIL(item_p, head_p) \
do { \
(item_p)->prev_p = (head_p)->prev_p; \
(item_p)->next_p = (head_p); \
(head_p)->prev_p = (item_p); \
(item_p)->prev_p->next_p = (item_p); \
} while (0);
#define SB_LIST_DELETE(old_item_p) \
do { \
(old_item_p)->next_p->prev_p = (old_item_p)->prev_p; \
(old_item_p)->prev_p->next_p = (old_item_p)->next_p; \
} while (0)
#define SB_LIST_REPLACE(item_p, old_item_p) \
do { \
(item_p)->next_p = (old_item_p)->next_p; \
(item_p)->prev_p = (old_item_p)->prev_p; \
(item_p)->next_p->prev_p = (item_p); \
(item_p)->prev_p->next_p = (item_p); \
} while (0)
#define SB_LIST_IS_EMPTY(head_p) \
((head_p)->next_p == (head_p))
#define SB_LIST_ITEM_IN_LIST(item_p) \
((item_p)->next_p != (item_p))
#define SB_LIST_ITEM_FIRST(item_p, head_p) \
((item_p)->prev_p != (head_p))
#define SB_LIST_ITEM_LAST(item_p, head_p) \
((item_p)->next_p == (head_p))
#define SB_LIST_ITEM_NEXT(item_p) \
((item_p)->next_p)
#define SB_LIST_ITEM_PREV(item_p) \
((item_p)->prev_p)
#define SB_LIST_ENTRY(ptr, type, member) \
((type *)(void *)(((char *)(ptr) - offsetof(type, member))))
#define SB_LIST_ONCE(pos_p, head_p) \
pos_p= (head_p)->next_p; if (pos_p != (head_p))
#define SB_LIST_FOR_EACH(pos_p, head_p) \
for (pos_p = (head_p)->next_p; pos_p != (head_p); pos_p = pos_p->next_p)
#define SB_LIST_ENUM_START(head_p) \
(head_p)
#define SB_LIST_ENUM_NEXT(pos_p, head_p) \
((pos_p->next_p != (head_p)) ? (pos_p->next_p) : NULL)
#define SB_LIST_FOR_EACH_SAFE(pos_p, temp_p, head_p) \
for (pos_p = (head_p)->next_p, temp_p = (pos_p)->next_p; pos_p != (head_p); \
pos_p = temp_p, temp_p = (pos_p)->next_p)
#define SB_LIST_FOR_EACH_REV_SAFE(pos_p, temp_p, head_p) \
for (pos_p = (head_p)->prev_p, temp_p = (pos_p)->prev_p; pos_p != (head_p); \
pos_p = temp_p, temp_p = (pos_p)->prev_p)
#endif /* SB_LIST_H */

View File

@ -0,0 +1,517 @@
/* Copyright (C) 2004 MySQL AB
Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
#include "sb_win.h"
#endif
#ifdef STDC_HEADERS
# include <stdio.h>
# include <stdarg.h>
# include <string.h>
#endif
#ifdef HAVE_ERRNO_H
# include <errno.h>
#endif
#ifdef HAVE_MATH_H
# include <math.h>
#endif
#include "sysbench.h"
#include "sb_list.h"
#include "sb_logger.h"
#include "sb_histogram.h"
#include "ck_cc.h"
#define TEXT_BUFFER_SIZE 4096
#define ERROR_BUFFER_SIZE 256
/*
Use 1024-element array for latency histogram tracking values between 0.001
milliseconds and 100 seconds.
*/
#define OPER_LOG_GRANULARITY 1024
#define OPER_LOG_MIN_VALUE 1e-3
#define OPER_LOG_MAX_VALUE 1E5
/* Array of message handlers (one chain per message type) */
static sb_list_t handlers[LOG_MSG_TYPE_MAX];
/* set after logger initialization */
static unsigned char initialized;
static pthread_mutex_t text_mutex;
static unsigned int text_cnt;
static char text_buf[TEXT_BUFFER_SIZE];
static int text_handler_init(void);
static int text_handler_process(log_msg_t *msg);
static int oper_handler_init(void);
static int oper_handler_done(void);
/* Built-in log handlers */
/* Text messages handler */
static sb_arg_t text_handler_args[] =
{
SB_OPT("verbosity", "verbosity level {5 - debug, 0 - only critical messages}",
"3", INT),
SB_OPT_END
};
static log_handler_t text_handler = {
{
&text_handler_init,
&text_handler_process,
NULL,
},
text_handler_args,
{0,0}
};
/* Operation start/stop messages handler */
static sb_arg_t oper_handler_args[] =
{
SB_OPT("percentile", "percentile to calculate in latency statistics (1-100). "
"Use the special value of 0 to disable percentile calculations",
"95", INT),
SB_OPT("histogram", "print latency histogram in report", "off", BOOL),
SB_OPT_END
};
static log_handler_t oper_handler = {
{
oper_handler_init,
NULL,
oper_handler_done,
},
oper_handler_args,
{0,0}
};
/* Register logger and all handlers */
int log_register(void)
{
unsigned int i;
for (i = 0; i < LOG_MSG_TYPE_MAX; i++)
SB_LIST_INIT(handlers + i);
log_add_handler(LOG_MSG_TYPE_TEXT, &text_handler);
log_add_handler(LOG_MSG_TYPE_OPER, &oper_handler);
return 0;
}
/* Display command line options for registered log handlers */
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)
{
handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);
if (handler->args != NULL)
sb_print_options(handler->args);
}
}
}
/* Initialize logger and all handlers */
int log_init(void)
{
unsigned int i;
sb_list_item_t *pos;
log_handler_t *handler;
for (i = 0; i < LOG_MSG_TYPE_MAX; i++)
{
SB_LIST_FOR_EACH(pos, handlers + i)
{
handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);
if (handler->ops.init != NULL && handler->ops.init())
return 1;
}
}
/* required to let log_text() pass messages to handlers */
initialized = 1;
return 0;
}
/* Uninitialize logger and all handlers */
void log_done(void)
{
unsigned int i;
sb_list_item_t *pos;
log_handler_t *handler;
for (i = 0; i < LOG_MSG_TYPE_MAX; i++)
{
SB_LIST_FOR_EACH(pos, handlers + i)
{
handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);
if (handler->ops.done != NULL)
handler->ops.done();
}
}
initialized = 0;
}
/* Add handler for a specified type of messages */
int log_add_handler(log_msg_type_t type, log_handler_t *handler)
{
if (type <= LOG_MSG_TYPE_MIN || type >= LOG_MSG_TYPE_MAX)
return 1;
if (handler->args != NULL)
sb_register_arg_set(handler->args);
SB_LIST_ADD_TAIL(&handler->listitem, handlers + type);
return 0;
}
/* Main function to dispatch log messages */
void log_msg(log_msg_t *msg)
{
sb_list_item_t *pos;
log_handler_t *handler;
SB_LIST_FOR_EACH(pos, handlers + msg->type)
{
handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);
if (handler->ops.process != NULL)
handler->ops.process(msg);
}
}
static const char *get_msg_prefix(log_msg_priority_t priority)
{
const char * prefix;
switch (priority) {
case LOG_FATAL:
prefix = "FATAL: ";
break;
case LOG_ALERT:
prefix = "ALERT: ";
break;
case LOG_WARNING:
prefix = "WARNING: ";
break;
case LOG_DEBUG:
prefix = "DEBUG: ";
break;
default:
prefix = "";
break;
}
return prefix;
}
/* printf-like wrapper to log text messages */
void log_text(log_msg_priority_t priority, const char *fmt, ...)
{
log_msg_t msg;
log_msg_text_t text_msg;
char buf[TEXT_BUFFER_SIZE];
va_list ap;
int n, clen, maxlen;
maxlen = TEXT_BUFFER_SIZE;
clen = 0;
va_start(ap, fmt);
n = vsnprintf(buf + clen, maxlen, fmt, ap);
va_end(ap);
if (n < 0 || n >= maxlen)
n = maxlen;
clen += n;
maxlen -= n;
snprintf(buf + clen, maxlen, "\n");
/*
No race condition here because log_init() is supposed to be called
in a single-threaded stage
*/
if (!initialized)
{
printf("%s%s", get_msg_prefix(priority), buf);
return;
}
msg.type = LOG_MSG_TYPE_TEXT;
msg.data = (void *)&text_msg;
text_msg.priority = priority;
text_msg.text = buf;
text_msg.flags = 0;
log_msg(&msg);
}
/*
variant of log_text() which prepends log lines with the elapsed time of a
specified timer.
*/
void log_timestamp(log_msg_priority_t priority, double seconds,
const char *fmt, ...)
{
log_msg_t msg;
log_msg_text_t text_msg;
char buf[TEXT_BUFFER_SIZE];
va_list ap;
int n, clen, maxlen;
maxlen = TEXT_BUFFER_SIZE;
clen = 0;
n = snprintf(buf, maxlen, "[ %.0fs ] ", seconds);
clen += n;
maxlen -= n;
va_start(ap, fmt);
n = vsnprintf(buf + clen, maxlen, fmt, ap);
va_end(ap);
if (n < 0 || n >= maxlen)
n = maxlen;
clen += n;
maxlen -= n;
snprintf(buf + clen, maxlen, "\n");
/*
No race condition here because log_init() is supposed to be called
in a single-threaded stage
*/
if (!initialized)
{
printf("%s%s", get_msg_prefix(priority), buf);
return;
}
msg.type = LOG_MSG_TYPE_TEXT;
msg.data = (void *)&text_msg;
text_msg.priority = priority;
text_msg.text = buf;
/* Skip duplicate checks */
text_msg.flags = LOG_MSG_TEXT_ALLOW_DUPLICATES;
log_msg(&msg);
}
/* printf-like wrapper to log system error messages */
void log_errno(log_msg_priority_t priority, const char *fmt, ...)
{
char buf[TEXT_BUFFER_SIZE];
char errbuf[ERROR_BUFFER_SIZE];
va_list ap;
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, sizeof(errbuf));
#else
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 /* HAVE_STRERROR_P */
#endif /* WIN32 */
va_start(ap, fmt);
n = vsnprintf(buf, TEXT_BUFFER_SIZE, fmt, ap);
va_end(ap);
if (n < 0 || n == TEXT_BUFFER_SIZE)
return;
snprintf(buf + n, TEXT_BUFFER_SIZE - n, " errno = %d (%s)", old_errno,
tmp);
#ifdef _WIN32
LocalFree(lpMsgBuf);
#endif
log_text(priority, "%s", buf);
}
/* Initialize text handler */
int text_handler_init(void)
{
#ifdef HAVE_SETVBUF
/* Set stdout to unbuffered mode */
setvbuf(stdout, NULL, _IONBF, 0);
#endif
sb_globals.verbosity = sb_get_value_int("verbosity");
if (sb_globals.verbosity > LOG_DEBUG)
{
printf("Invalid value for verbosity: %d\n", sb_globals.verbosity);
return 1;
}
pthread_mutex_init(&text_mutex, NULL);
text_cnt = 0;
text_buf[0] = '\0';
return 0;
}
/* Print text message to the log */
int text_handler_process(log_msg_t *msg)
{
log_msg_text_t *text_msg = (log_msg_text_t *)msg->data;
if (text_msg->priority > sb_globals.verbosity)
return 0;
if (!(text_msg->flags & LOG_MSG_TEXT_ALLOW_DUPLICATES))
{
pthread_mutex_lock(&text_mutex);
if (!strcmp(text_buf, text_msg->text))
{
text_cnt++;
pthread_mutex_unlock(&text_mutex);
return 0;
}
else
{
if (text_cnt > 0)
printf("(last message repeated %u times)\n", text_cnt);
text_cnt = 0;
strncpy(text_buf, text_msg->text, TEXT_BUFFER_SIZE);
}
pthread_mutex_unlock(&text_mutex);
}
printf("%s%s", get_msg_prefix(text_msg->priority), text_msg->text);
return 0;
}
/* Initialize operation messages handler */
int oper_handler_init(void)
{
int tmp;
tmp = sb_get_value_int("percentile");
if (tmp < 0 || tmp > 100)
{
log_text(LOG_FATAL, "Invalid value for --percentile: %d",
tmp);
return 1;
}
sb_globals.percentile = tmp;
sb_globals.histogram = sb_get_value_flag("histogram");
if (sb_globals.percentile == 0 && sb_globals.histogram != 0)
{
log_text(LOG_FATAL, "--histogram cannot be used with --percentile=0");
return 1;
}
if (sb_histogram_init(&sb_latency_histogram, OPER_LOG_GRANULARITY,
OPER_LOG_MIN_VALUE, OPER_LOG_MAX_VALUE))
return 1;
return 0;
}
/* Uninitialize operations messages handler */
int oper_handler_done(void)
{
sb_histogram_done(&sb_latency_histogram);
return 0;
}

View File

@ -0,0 +1,153 @@
/* Copyright (C) 2004 MySQL AB
Copyright (C) 2004-2016 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifndef SB_LOGGER_H
#define SB_LOGGER_H
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_PTHREAD_H
# include <pthread.h>
#endif
#include "sb_util.h"
#include "sb_options.h"
#include "sb_timer.h"
#include "sb_histogram.h"
/* Text message flags (used in the 'flags' field of log_text_msg_t) */
#define LOG_MSG_TEXT_ALLOW_DUPLICATES 1
/* Message types definition */
typedef enum {
LOG_MSG_TYPE_MIN, /* used for internal purposes */
LOG_MSG_TYPE_TEXT, /* arbitrary text messages */
LOG_MSG_TYPE_OPER, /* operation start/stop messages */
LOG_MSG_TYPE_MAX /* used for internal purposes */
} log_msg_type_t;
/* Message priorities definition */
typedef enum {
LOG_FATAL, /* system is unusable */
LOG_ALERT, /* user actions must be taken */
LOG_WARNING, /* warnings */
LOG_NOTICE, /* normal but significant messages */
LOG_INFO, /* informational messages */
LOG_DEBUG, /* debug-level messages */
LOG_MAX /* used for internal purposes */
} log_msg_priority_t;
/* Text message definition */
typedef struct {
log_msg_priority_t priority;
char *text;
unsigned int flags;
} log_msg_text_t;
/* Operation start/stop message definition */
typedef enum {
LOG_MSG_OPER_START,
LOG_MSG_OPER_STOP
} log_msg_oper_action_t;
typedef struct {
log_msg_oper_action_t action;
int thread_id;
} log_msg_oper_t;
/* General log message definition */
typedef struct {
log_msg_type_t type;
void *data;
} log_msg_t;
/* Log handler operations definition */
typedef int log_op_register(void); /* register handler options */
typedef int log_op_init(void); /* initialize log handler */
typedef int log_op_process(log_msg_t *msg); /* process message */
typedef int log_op_done(void); /* uninitialize log handler */
/* Log handler operations structure */
typedef struct {
log_op_init *init;
log_op_process *process;
log_op_done *done;
} log_handler_ops_t;
/* Log handler definition */
typedef struct {
log_handler_ops_t ops; /* handler operations */
sb_arg_t *args; /* handler arguments */
sb_list_item_t listitem; /* can be linked in a list */
} log_handler_t;
/* Register logger */
int log_register(void);
/* Display command line options for all register log handlers */
void log_print_help(void);
/* Initialize logger */
int log_init(void);
/* Add handler for a specified type of messages */
int log_add_handler(log_msg_type_t type, log_handler_t *handler);
/* Main function to dispatch log messages */
void log_msg(log_msg_t *);
/* printf-like wrapper to log text messages */
void log_text(log_msg_priority_t priority, const char *fmt, ...)
SB_ATTRIBUTE_FORMAT(printf, 2, 3);
/*
variant of log_text() which prepends log lines with a elapsed time of the
specified timer.
*/
void log_timestamp(log_msg_priority_t priority, double seconds,
const char *fmt, ...)
SB_ATTRIBUTE_FORMAT(printf, 3, 4);
/* printf-like wrapper to log system error messages */
void log_errno(log_msg_priority_t priority, const char *fmt, ...)
SB_ATTRIBUTE_FORMAT(printf, 2, 3);
/* Uninitialize logger */
void log_done(void);
#endif /* SB_LOGGER_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,42 @@
/* Copyright (C) 2006 MySQL AB
Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
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
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "sysbench.h"
#include "lua.h"
/* Load a specified Lua script */
sb_test_t *sb_load_lua(const char *testname);
void sb_lua_done(void);
int sb_lua_hook_call(lua_State *L, const char *name);
bool sb_lua_custom_command_defined(const char *name);
int sb_lua_call_custom_command(const char *name);
int sb_lua_report_thread_init(void);
void sb_lua_report_thread_done(void *);
bool sb_lua_loaded(void);

Some files were not shown because too many files have changed in this diff Show More