[
  {
    "path": ".github/workflows/ci.yml",
    "content": "name: CI\non: [push, pull_request]\n\njobs:\n  build:\n    strategy:\n      matrix:\n        os: [ ubuntu-22.04, ubuntu-20.04 ]\n    runs-on: ${{ matrix.os }}\n    name: Build on ${{ matrix.os }}\n    steps:\n      - name: Checkout\n        uses: actions/checkout@v3\n      - name: Autogen\n        run: ./autogen.sh\n      - name: Configure\n        run: ./configure --with-mysql --with-pgsql\n      - name: Build\n        run: make\n      - name: MySQL version\n        run: mysql_config --version\n      - name: Sysbench version\n        run: ./src/sysbench --version\n      - name: Test\n        run: make test\n\n  build_mariadb:\n    runs-on: ubuntu-22.04\n    name: Build with MariaDB\n    steps:\n      - name: Setup MariaDB Repo\n        run: |\n          sudo apt-get install software-properties-common\n          sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8\n          sudo add-apt-repository 'deb [arch=amd64] https://ftp.nluug.nl/db/mariadb/repo/11.0/ubuntu jammy main'\n      - name: Setup MariaDB Libs\n        run: sudo apt install libmariadb-dev libmariadb-dev-compat\n      - name: Checkout\n        uses: actions/checkout@v3\n      - name: Autogen\n        run: ./autogen.sh\n      - name: Configure\n        run: ./configure --with-mysql --with-pgsql\n      - name: Build\n        run: make\n      - name: MariaDB version\n        run: mariadb_config --version\n      - name: Sysbench version\n        run: ./src/sysbench --version\n      - name: Test\n        run: make test\n"
  },
  {
    "path": ".gitignore",
    "content": "*.o\n*.a\nMakefile\nMakefile.in\naclocal.m4\nautom4te.cache\n/config/config.h\n/config/ltmain.sh\n/config/stamp-h1\n/doc/manual.html\n/config.log\n/config.status\n/configure\n/libtool\n/doc/xsl/catalog.xml\n/src/.deps\n/src/.libs\n/src/sysbench\n/src/drivers/mysql/.deps\n/src/drivers/oracle/.deps\n/src/drivers/pgsql/.deps\n/src/tests/cpu/.deps\n/src/tests/fileio/.deps\n/src/tests/memory/.deps\n/src/tests/mutex/.deps\n/src/tests/oltp/.deps\n/src/tests/threads/.deps\n/TAGS\n/backup.bzr\n/config/config.guess\n/config/config.h.in\n/config/config.sub\n/src/TAGS\n/src/drivers/TAGS\n/src/drivers/mysql/TAGS\n/src/tests/TAGS\n/src/tests/cpu/TAGS\n/src/tests/fileio/TAGS\n/src/tests/memory/TAGS\n/src/tests/mutex/TAGS\n/src/tests/oltp/TAGS\n/src/tests/threads/TAGS\n/config/compile\n/config/depcomp\n/config/install-sh\n/config/missing\n/m4/libtool.m4\n/m4/ltoptions.m4\n/m4/ltsugar.m4\n/m4/ltversion.m4\n/m4/lt~obsolete.m4\n/src/drivers/drizzle/.deps\n/src/scripting/.deps\n/src/scripting/lua/src/.deps\nGPATH\nGRTAGS\nGTAGS\n/config/ar-lib\n/src/drivers/attachsql/.deps/\n/config/test-driver\n*.DS_Store\n/tests/*.log\n/tests/*.trs\n*.gcda\n*.gcno\n/tests/include/config.sh\n/third_party/concurrency_kit/include/\n/third_party/concurrency_kit/lib/\n/third_party/concurrency_kit/share/\n/third_party/concurrency_kit/tmp/\nthird_party/luajit/bin/\nthird_party/luajit/inc/\nthird_party/luajit/lib/\nthird_party/luajit/share/\nthird_party/luajit/tmp/\nsrc/lua/internal/sysbench.lua.h\nsrc/lua/internal/sysbench.sql.lua.h\n/src/lua/internal/sysbench.rand.lua.h\n/src/lua/internal/sysbench.opt.lua.h\ntests/t/*.err\n/src/lua/internal/sysbench.cmdline.lua.h\n/src/lua/internal/sysbench.compat.lua.h\n/src/lua/internal/sysbench.histogram.lua.h\nparts\nprime\nstage\n*.snap\n/snap/snapcraft.yaml\n"
  },
  {
    "path": ".travis.yml",
    "content": "# vim ft=yaml\n#\n# Travis CI configuration\n\narch:\n  - amd64\n  - arm64\n\ndist: trusty\nsudo: required\n\nservices:\n  - docker\n  - mysql\n  - postgresql\n\ngit:\n  depth: 100500\n\nlanguage: c\n\nos:\n  - linux\n  - osx\n\nosx_image: xcode12.2\n\ncompiler:\n  - gcc\n  - clang\n\nenv:\n    matrix:\n      - TARGET=distcheck\n      - TARGET=test\n      - TARGET=coverage\n      - OS=el DIST=7\n      - OS=el DIST=8\n      - OS=fedora DIST=32\n# Currently unsupported by packagecloud\n#      - OS=fedora DIST=33\n      - OS=ubuntu DIST=xenial\n      - OS=ubuntu DIST=bionic\n      - OS=ubuntu DIST=focal\n      - OS=ubuntu DIST=groovy\n      - OS=debian DIST=stretch\n      - OS=debian DIST=buster\n      - OS=debian DIST=sid\n      - OS=ubuntu DIST=xenial ARCH=i386\n      - OS=ubuntu DIST=bionic ARCH=i386\n      - OS=debian DIST=stretch ARCH=i386\n      - OS=debian DIST=buster ARCH=i386\n      - OS=debian DIST=sid ARCH=i386\n\nmatrix:\n  exclude:\n    - env: OS=el DIST=7\n      compiler: clang\n    - env: OS=el DIST=8\n      compiler: clang\n    - env: OS=fedora DIST=32\n      compiler: clang\n    - env: OS=fedora DIST=33\n      compiler: clang\n    - env: OS=ubuntu DIST=xenial\n      compiler: clang\n    - env: OS=ubuntu DIST=bionic\n      compiler: clang\n    - env: OS=ubuntu DIST=disco\n      compiler: clang\n    - env: OS=ubuntu DIST=focal\n      compiler: clang\n    - env: OS=ubuntu DIST=groovy\n      compiler: clang\n    - env: OS=debian DIST=stretch\n      compiler: clang\n    - env: OS=debian DIST=buster\n      compiler: clang\n    - env: OS=debian DIST=sid\n      compiler: clang\n    - env: OS=ubuntu DIST=xenial ARCH=i386\n      compiler: clang\n    - env: OS=ubuntu DIST=bionic ARCH=i386\n      compiler: clang\n    - env: OS=ubuntu DIST=disco ARCH=i386\n      compiler: clang\n    - env: OS=debian DIST=stretch ARCH=i386\n      compiler: clang\n    - env: OS=debian DIST=buster ARCH=i386\n      compiler: clang\n    - env: OS=debian DIST=sid ARCH=i386\n      compiler: clang\n    - env: OS=ubuntu DIST=xenial ARCH=i386\n      arch: arm64\n    - env: OS=ubuntu DIST=bionic ARCH=i386\n      arch: arm64\n    - env: OS=ubuntu DIST=disco ARCH=i386\n      arch: arm64\n    - env: OS=debian DIST=stretch ARCH=i386\n      arch: arm64\n    - env: OS=debian DIST=buster ARCH=i386\n      arch: arm64\n    - env: OS=debian DIST=sid ARCH=i386\n      arch: arm64\n    - env: OS=el DIST=7\n      os: osx\n    - env: OS=el DIST=8\n      os: osx\n    - env: OS=fedora DIST=32\n      os: osx\n    - env: OS=fedora DIST=33\n      os: osx\n    - env: OS=ubuntu DIST=xenial\n      os: osx\n    - env: OS=ubuntu DIST=bionic\n      os: osx\n    - env: OS=ubuntu DIST=disco\n      os: osx\n    - env: OS=ubuntu DIST=focal\n      os: osx\n    - env: OS=ubuntu DIST=groovy\n      os: osx\n    - env: OS=debian DIST=stretch\n      os: osx\n    - env: OS=debian DIST=buster\n      os: osx\n    - env: OS=debian DIST=sid\n      os: osx\n    - env: TARGET=distcheck\n      compiler: clang\n    - env: TARGET=distcheck\n      os: osx\n    - env: TARGET=distcheck\n      arch: arm64\n    - env: TARGET=coverage\n      os: osx\n    - env: TARGET=coverage\n      compiler: clang\n    - env: TARGET=coverage\n      arch: arm64\n    - os: osx\n      compiler: gcc\n    - os: osx\n      arch: arm64\n    - arch: arm64\n      compiler: clang\n\naddons:\n  apt:\n    packages:\n    - libmysqlclient-dev\n    - libpq-dev\n    - libaio-dev\n    - clang-3.6\n\nbefore_install:\n  # Upload builds corresponding to release tags to the 'sysbench'\n  # repository, push other ones to 'sysbench-prereleases'\n  - git describe --long --always\n  - commits=$(git describe --long --always | sed -n 's/^\\([0-9\\.]*\\)-\\([0-9]*\\)-\\([a-z0-9]*\\)/\\2/p')\n  - >\n    if [ ${commits:-0} = 0 ]; then\n      export VERSION=$(git describe)\n      PACKAGECLOUD_REPO=sysbench\n    else\n      PACKAGECLOUD_REPO=sysbench-prereleases\n    fi\n  - >\n    if [ \"x$TARGET\" = \"xtest\" ]; then\n      case \"${TRAVIS_OS_NAME:-linux}\" in\n      osx)\n        brew update\n        brew install mysql postgresql\n\n        # OS X requires servers to be started explicitly\n        brew services start mysql\n\n        cat /usr/local/var/mysql/*.err\n        lsof -c mysql\n\n        brew postgresql-upgrade-database\n        brew services start postgresql\n\n        echo \"Starting PostgreSQL\"\n        pg_ctl -wD /usr/local/var/postgres start\n        echo \"Creating user postgres\"\n        createuser -s postgres\n        ;;\n      linux)\n        export ASAN_OPTIONS=\"detect_leaks=0\"\n        if [ \"${CC}\" = \"clang\" ]; then\n          CC=clang-3.6\n        fi\n        ;;\n      esac\n    fi\n\ninstall:\n  - >\n    case \"${TRAVIS_OS_NAME:-linux}\" in\n    osx)\n      # OS X requires this for user-local pip packages\n      export PATH=~/Library/Python/2.7/bin:$PATH\n      ;;\n    linux)\n      pip install --user cpp-coveralls\n      ;;\n    esac\n\nbefore_script:\n  - mysql -u root -e 'CREATE DATABASE sbtest'\n  - psql -U postgres -c 'CREATE DATABASE sbtest'\n\nscript:\n  - >\n    if [ -n \"$TARGET\" ]; then\n      case \"$TARGET\" in\n      test)\n        ./autogen.sh && ./configure --with-mysql --with-pgsql\n        make\n        SBTEST_MYSQL_ARGS=\"--mysql-user=root\" SBTEST_PGSQL_ARGS=\"--pgsql-user=postgres\" make test\n        ;;\n      distcheck)\n        ./autogen.sh && ./configure --without-mysql\n        make\n        make distcheck\n        ;;\n      coverage)\n        ./autogen.sh && ./configure --enable-coverage --enable-asan --enable-msan --with-mysql --with-pgsql\n        make -j2\n        SBTEST_MYSQL_ARGS=\"--mysql-user=root\" SBTEST_PGSQL_ARGS=\"--pgsql-user=postgres\" make test\n        ;;\n      esac\n    else\n      # To avoid name conflicts, deploy source packages only for\n      # \"default\", i.e. x86_64 architecture\n      if [[ -z \"$ARCH\" && \"$TRAVIS_CPU_ARCH\" == amd64 ]]; then\n        PACKAGECLOUD_GLOB='build/*.{rpm,deb,dsc}'\n      else\n      # Exclude *.src.rpm and *.dsc\n        PACKAGECLOUD_GLOB='build/*{[^c].rpm,.deb}'\n      fi\n\n      git clone https://github.com/akopytov/packpack.git packpack\n      packpack/packpack\n    fi\n\ndeploy:\n  # Deploy packages to PackageCloud\n  - provider: packagecloud\n    username: \"${PACKAGECLOUD_USER}\"\n    repository: \"${PACKAGECLOUD_REPO}\"\n    token: \"${PACKAGECLOUD_TOKEN}\"\n    dist: \"${OS}/${DIST}\"\n    package_glob: \"${PACKAGECLOUD_GLOB}\"\n    skip_cleanup: true\n    on:\n      all_branches: true\n      condition: -n \"$OS\" && -n \"$DIST\" && -n \"$PACKAGECLOUD_TOKEN\" && \"$DIST\" != \"rawhide\" && \"$DIST\" != \"sid\"\n\nafter_success:\n  - >\n    if [ \"x$TARGET\" = \"xcoverage\" ]; then\n      coveralls --exclude third_party/ --gcov-options '\\-lp'\n    fi\n\n# Local variables:\n# mode: yaml\n# End:\n"
  },
  {
    "path": "COPYING",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "ChangeLog",
    "content": "2020-04-24  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.20\n\t* build/CI/packaging: Add arm64 to Travis CI matrix (#358)\n\t* build/CI/packaging: add Ubuntu Focal\n\t* build/CI/packaging: remove Fedora Rawhide from CI matrix\n\t* build/CI/packaging: fix regression tests to work with MySQL 8.0.19+\n\t* build/CI/packaging: fix macOS builds in Travis\n\t* build/CI/packaging: remove Ubuntu Disco (EOL)\n\n2019-12-08  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.19\n\t* build/CI/packaging: fix Ubuntu packaging for Bionic and later versions\n\t* regression tests: compatibility fix for PostgreSQL 12\n\t* build/CI/packaging: fix macOs builds in Travis\n\t* build/CI/packaging: add Fedora 31.\n\n2019-10-21  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.18\n\t* build/CI/packaging: add Ubuntu Eoan.\n\t* build/CI/packaging: remove Ubuntu Cosmic (EOL).\n\t* build/CI/packaging: add CentOS 8.\n\t* build/CI/packaging: add Ubuntu Disco.\n\t* build/CI/packaging: remove Ubuntu Trusty (EOL).\n\t* build/CI/packaging: remove Fedora 28 (EOL).\n\t* build/CI/packaging: add Fedora 30.\n\t* build/CI/packaging: cherry-pick fix for LuaJIT/LuaJIT#484 to\n\tfix builds on macOS Mojave.\n\t* build/CI/packaging: add Debian Buster\n\n2019-03-15  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.17\n\t* build/CI/packaging: update RPM spec to support RHEL8-beta\n\t(thanks to Alexey Bychko for the patch)\n\t* regression tests: remove unnecessary error leading to opt_rate.t instability.\n\t* --rate mode: return a non-zero exit code on event queue\n\toverflow.\n\t* --rate mode: fix a bogus error about eventgen thread termination\n\n2018-12-16  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.16\n\t* build/CI/packaging: add Ubuntu Cosmic.\n\t* build/CI/packaging: add Fedora 29.\n\t* build/CI/packaging: remove Fedora 27 (EOL).\n\t* SQL API: fix GH-282 (Mysql's fetch_row() is broken)\n\t* --rate mode: fix latency stats skew on low rates\n\t* Lua: Add /usr/share/lua/5.1 to LUA_PATH and /usr/lib/lua/5.1\n\tto LUA_CPATH.\n\t* build/CI/packaging: add -Wvla to default compiler flags.\n\t* build/CI/packaging: fix debian/changelog format\n\t* build/CI/packaging: fix buildpack.sh to not push multiple file\n\ttypes to packagecloud.\n\t* build/CI/packaging: add libaio-dev to Debian/Ubuntu build\n\tdependencies.\n\n2018-07-03  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.15\n\t* CI/build/packaging: add Fedora 28\n\t* CI/build/packaging: add Ubuntu Bionic\n\t* CI/build/packaging: remove Fedora 26 (EOL)\n\t* CI/build/packaging: remove Debian Wheezy (EOL)\n\t* fileio: fix GH-229 (--file-fsync-freq=0 seems to prevent\n\tfsync() at the end of the test)\n\t* command line: improve parsing of boolean command line options\n\t* tests: fix GH-220 (Testsuite api_sql_mysql.t failed ...)\n\t* tests: fix GH-223 (test failure on ppc64)\n\t* tests: fix opt_help.t to pass when the binary is not\n\tconfigured with MySQL support\n\t* MySQL driver: use it by default in DB benchmarks\n\n2018-04-01  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.14\n\t* reports: fix JSON stats reporter to produce valid JSON\n\t(GH-195)\n\t* Lua SQL API: don't crash when query_row() is called with a\n\tSELECT returning empty result set\n\t* Lua SQL API: don't crash when bulk insert API calls are used\n\tout of order\n\t* regression tests: make PostgreSQL tests compatible with the\n\tnew dump format introduced in 10.3\n\t* regression tests: minor stability and coverage improvements\n\n2018-02-17  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.13\n\t* remove Ubuntu Zesty from CI/build/packaging matrices (EOL)\n\t* minor cleanups in build scripts\n\t* improve report formatting for long latency values\n\t* fileio: --file-extra-flags now accepts a list of flags rather\n\tthan just a single value\n\t* OLTP: re-prepare prepared statements after reconnects, i.e. in\n\tcases when a server connection is lost and sysbench is\n\tconfigured to ignore such errors\n\n2018-01-17  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.12\n\t* improve --rate mode precision for high argument values\n\t* add Fedora Rawhide and Debian Sid to CI matrix\n\t* fix compile-time architecture detection for some Broadwell\n\tCPUs which were incorrectly identified as Core 2.\n\t* remove build dependency on xxd (and vim-minimal package)\n\t* fix Lua API to correctly stop the benchmark when event()\n\treturns a value other than nil or false (thanks to caojiafeng\n\tfor the patch)\n\t* fix the fileio benchmark when the specified file size is not a\n\tmultiple of block size\n\t* fix the fileio benchmark to throw a descriptive error when the\n\tspecified file size does not match the size of files created by\n\t'prepare'\n\t* remove Fedora 25 from CI/build/packaging matrices (EOL)\n\t* minor improvements in tests and documentation.\n\n2017-12-09  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.11\n\t* add Debian Stretch to CI/build/packaging matrices\n\t* add Fedora 27 to CI/build/packaging matrices\n\t* make statistic counters usable from Lua scripts\n\t* fix the PostgreSQL driver to be compatible with CockroachDB\n\t(GH-180)\n\t* fix oltp_insert.lua to work correctly when both --tables and\n\t--threads are greater than 1 (GH-178)\n\t* fix FreeBSD builds by adding -rdynamic to the default linker\n\tflags (GH-174)\n\t* minor documentation updates\n\n2017-10-25  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.10\n\t* fixed PK conflicts in oltp_insert.lua by creating empty tables\n\ton 'prepare'\n\t* made sysbench.opt available to init()/done() by exporting it\n\tto the global Lua state\n\t* added Fedora 26 (both x86_64 and AArch64) to the list of\n\tsupported and tested distributions\n\t* fixed GH-172: sysbench 1.0.9 doesn't build with mariadb 10.2.8\n\t* add the /usr/local LuaRocks root directory to default LUA_PATH\n\tand LUA_CPATH\n\t* removed Fedora 24, Ubuntu Precise, Yakkety from default build\n\tmatrices\n\t* added Ubuntu Artful to default build matrices\n\n2017-09-05  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.9\n\t* fixed oltp_delete.lua to not use INSERT statements for\n\tconsistency with other oltp_* benchmarks (GH-168)\n\t* added a workaround for MySQL bug #87337 \"8.0.2 reintroduces\n\tmy_bool to client API\"\n\t* fixed building on on Debian GNU/kFreeBSD (GH-161)\n\t* fixed building against MariaDB 10.2 (thanks to Xavier Bachelot\n\tfor the patch, GH-160)\n\n2017-07-04  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.8\n\t* fixed api_report test for slow machines (thanks to @jcfp)\n\t* fileio: suggest to run prepare step on missing files (thanks\n\tto Heinrich Schuchardt)\n\t* JSON reports: removed an erroneous trailing comma (GH-139)\n\t* added events per second to the CPU benchmark report (GH-140)\n\t* fixed db_connect() in legacy SQL API to use the default value\n\tfor --db-driver (GH-146)\n\t* removed busy-wait in the bounded event generation mode\n\t(--rate) to avoid CPU hogging\n\n2017-05-15  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.7\n\t* Ubuntu Zesty added to package build matrix\n\t* fixed GH-130: Mutex Benchmark Documentation\n\t* fixed latency reports in the --rate mode\n\t* fixed compiler warnings when building against MySQL 8.0 client\n\tlibraries\n\n2017-04-13  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.6\n\t* no functional changes\n\t* many build- and packaging-related improvements\n\t* Linux packages are now automatically built using Travis CI and\n\tpackpack, hosted by packagecloud.io\n\n2017-04-02  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.5\n\t* various build-related documentation updates\n\t* benchmark can now be specified by a module name on the command\n\tline\n\t* memory benchmark: performance and scalability improvements\n\t* fix ARMv6 builds with system ConcurrencyKit\n\t* fix GH-123: Table already exists error on prepare\n\t* fix GH-121: make buildhost cpudetection optional\n\n2017-03-13  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.4\n\t* fixed a number of compilation errors and warnings that were\n\tspecific to 32-bit platforms\n\t* bundle cram (regression tests framework) and use it by default\n\tin 'make test'\n\t* bundled ConcurrencyKit updated to 0.6.0\n\n2017-02-26  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.3\n\t* LuaJIT scalability improvements for non-x86 architectures\n\t* performance optimizations in oltp_read_write.lua to avoid Lua\n\tstring management\n\t* fixed Illumos builds (thanks to Dillon Amburgey)\n\n2017-02-17  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.2\n\t* improved scalability for --report-checkpoints mode\n\t* fix builds on CentoOS 6 and autoconf 2.63\n\t* support for Snap (http://snapcraft.io) packages\n\n2017-02-05  Alexey Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.1\n\t* fix clock_gettime runtime failure built with macOS 10.11 and\n\tXcode 8.x\n\t\n2017-02-04  Aleksei Kopytov  <akopytov@gmail.com>\n\n\t* version 1.0.0\n\t* too much time and too many changes since the previous formal\n\trelease, so briefly:\n\t* Lua scripts instead of hard-coded C tests for database\n\t(\"oltp\") benchmarks + ability to create custom workloads\n\t* much better single-threaded performance\n\t* much better scalability\n\t* improvements and cleanups in command line syntax and options\n\t* latency histograms in cumulative statistic reports\n\t* report hooks to print statistics in custom formats\n\t(CSV/JSON/XML/etc.)\n\t* Dropped Windows support\n\t* Dropped support for Oracle, Drizzle and libattachsql drivers\n\n2006-10-10  Alexey Kopytov <alexeyk@mysql.com>\n\n\t* Removed the debugging code in OLTP test which got into 0.4.7 by mistake\n\t* Handle ER_CHECKREAD in the same way as deadlocks in the MySQL driver\n\t* version 0.4.8\n\t\n2006-05-28  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* count fsync() time as request execution time in file-fsync-all mode\n\n2006-05-24  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added --oltp-reconnect option\n\n2006-05-18  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Allow build with non-gcc compilers\n\t* Fixed random numbers generation on Solaris\n\t* Added --mysql-ssl option\n\t* version 0.4.7\n\t\n2006-04-03  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added a warning for inaccurate gettimeofday() implementations\n\t* version 0.4.6\n\n2006-03-10  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed crash at the end of OLTP test\n\n2006-03-03  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Made auto_increment id column optional\n\t* Use TYPE= or ENGINE= in MySQL driver depending on the version of client libraries\n\n2006-01-17  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* version 0.4.5\n\t* Added several hosts capability to MySQL driver\n\t* Fixed several memory leaks in OLTP test\n\n2005-12-14  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Renamed option 'mysql-table-type' to 'mysql-table-engine'\n\t* It's now possible to pass arbitrary engine names to MySQL driver\n\t* Transactions support must be explicitly specified with \n\t'mysql-engine-trx' option for those engines, which are unknown to SysBench\n\n2005-09-27  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Changed 'thread fairness' calculation from percents to stddev\n\t* Added validation mode to OLTP test (--validate switch)\n\t* Remove auto_increment from the 'id' field before running OLTP tests\n\t* Print separate time for query execution and result fetching in --debug mode\n\t* version 0.4.3\n\n2005-07-25  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Minor cleanups in help messages\n\t* Several FreeBSD-related fixes\n\t* Fixed the Oracle driver\n\t* Version 0.4.1\n\n2005-03-04  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed a lot of small bugs, including portability issues on Mac OS X, \n\t64-bit platforms and old MySQL versions\n\t* Documentation added to the main tree\n\t* New validation mode in fileio test\n\n2005-01-27  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed compilation on Solaris\n\t* Added call to thr_setconcurrency() on Solaris\n\t* Fixed an overflow bug in sb_timer_current()\n\t* Changed the default number of threads to 1\n\t* Added non-transactional mode to the OLTP test\n\t* Fixed bug with excessive number of connections in OLTP test\n\t* Handle ER_LOCK_WAIT_TIMEOUT in the same way as ER_LOCK_DEADLOCK\n\t* Version 0.3.2\n\n2004-07-27  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed MySQL driver to use new PS API in MySQL >= 4.1.2\n\n2004-07-12  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed final fsync in random I/O requests\n\t* Fixed several race conditions\n\n2004-07-09  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Removed --oltp-time-limit option (obsoleted by --max-time)\n\n2004-07-06  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Changed statistics output to more human-readable format\n\n2004-07-04  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added new logger interface to internal API\n\t* Modified all tests to use the new logger interface\n\n2004-06-17  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed table type autodetection with MySQL >= 4.1\n\n2004-06-06  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added preliminary support of prepared statements to DB API\n\n2004-05-31  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added slow-mmap mode for 32-bit boxes in fileio test \n\n2004-05-30  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed compilation with gcc >= 3.3\n\t* Fixed 'prepare' command for sequential write test\n\n2004-05-26  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Changed formatting of file sizes in output\n\t* Fixed type cast warning on SuSE 8.1 \n\n2004-05-21  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added mutex performance benchmark \n\n2004-05-12  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Extended memory benchmark to calculate more useful results\n\n2004-05-10  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Split test file creation, test running and cleaning up into separate \n\tcommands (prepare, run, cleanup) for fileio test\n\n2004-05-05  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Removed limit on maximum block size for fileio test \n\n2004-05-04  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* added --max-time option to limit total test execution time \n\n2004-05-03  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed compilation with --without-mysql option. \n\n2004-04-13  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added mmaped I/O support to fileio test\n\n2004-04-11  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Changed default table size to a lower value in OLTP test\n\n2004-04-07  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added automatic table type detection to MySQL driver\n\t* Changed the default table type for MySQL driver to InnoDB\n\t* Added support for BDB and NDB table types\n\n2004-04-06  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added autoconf macro to handle older (incompatible) version of \n\tlibaio.h\n\n2004-04-05  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed compilation on 64-bit systems\n\t* Replaced Linux AIO calls with more portable equivalents\n\n2004-04-04  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added parameter to specify maximum number of queued operations\n\tin fileio async mode (file-async-backlog)\n\t* Added parameter to specify extra open() flags (file-extra-flags)\n\t* Fixed memory allocation bug in command line parser\n\n2004-04-02  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added Linux asynchronous I/O support to fileio test\n\t* Fixed bug with statistic counters\n\n2004-04-01  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added test file creation to fileio test\n\t* Added read-only mode to OLTP test \n\n2004-03-31  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Close database connections in OLTP test\n\t* Added file-fsync-all mode for fileio test\n\t\n2004-03-30  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Added myisam-max-rows option for MySQL driver\n\t* Fixed configure.ac for cases when no MySQL libraries found\n\n2004-03-10  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Implement proper handling of table locks in OLTP test\n\n2004-03-09  Alexey Kopytov  <alexeyk@mysql.com>\n\n        * Recognize MySQL table type when creating test database\n\t* Fix driver-specific options\n\t* Now it's possible to pass MySQL root directory in --with-mysql option\n\t* Trim trailing '.libs' if user passed it in --with-mysql-libs option\n\tto configure\n\n2004-03-08  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Build drivers and tests as separate libraries (first step to \n\tdynamically loaded modules)\n\t* Display help when required arguments are missing in fileio test\n\t* Changed code formatting to match MySQL coding guidelines\n\n2004-03-04  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Generalized DB-dependent code\n\t* Added 'database capabilities' feature\n\n2004-02-28  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Fixed possible memory leak in sql request generator\n\n2004-03-27  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Split OLTP code into DB-independent part and MySQL driver \n\n2004-02-23  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Use libtool for linking with external libraries\n\t* Statically link external libraries when they are not installed\n\n2004-02-19  Alexey Kopytov  <alexeyk@mysql.com>\n\n\t* Print more info when configure finds no MySQL development files\n\t* Added --with-mysql-includes and --with-mysql-libs to configure\n\t* Fixed compilation error when compiling without MySQL support\n\t* Combine several inserts into one query to speed up database creation\n\t\n\n"
  },
  {
    "path": "Dockerfile",
    "content": "FROM ubuntu:xenial\n\nRUN apt-get update\n\nRUN apt-get -y install make automake libtool pkg-config libaio-dev git\n\n# For MySQL support\nRUN apt-get -y install libmysqlclient-dev libssl-dev\n\n# For PostgreSQL support\nRUN apt-get -y install libpq-dev\n\nRUN git clone https://github.com/akopytov/sysbench.git sysbench\n\nWORKDIR sysbench\nRUN ./autogen.sh\nRUN ./configure --with-mysql --with-pgsql\nRUN make -j\nRUN make install\n\nWORKDIR /root\nRUN rm -rf sysbench\n\nENTRYPOINT sysbench\n"
  },
  {
    "path": "Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nACLOCAL_AMFLAGS = -I m4\nAM_DISTCHECK_CONFIGURE_FLAGS = --without-mysql\n\nif USE_BUNDLED_LUAJIT\n  LUAJIT_DIR = third_party/luajit\nendif\n\nif USE_BUNDLED_CK\n  CK_DIR = third_party/concurrency_kit\nendif\n\nSUBDIRS = $(LUAJIT_DIR) $(CK_DIR) src tests\n\nEXTRA_DIST = autogen.sh README.md ChangeLog \\\n             snap/snapcraft.yaml.in third_party/cram \\\n             debian/changelog debian/compat debian/control debian/copyright \\\n             debian/dirs debian/docs debian/install debian/rules \\\n             debian/source/format \\\n             rpm/sysbench.spec \\\n             scripts/buildpack.sh\n\ndist-hook:\n\t$(MAKE) -C $(distdir)/third_party/cram clean\n\ntest:\n\tcd tests && $(MAKE) test\n\nclean-local:\n\t$(MAKE) -C $(top_srcdir)/third_party/cram clean\n"
  },
  {
    "path": "README.md",
    "content": "[![Latest Release][release-badge]][release-url]\n[![Build Status][action-badge]][action-url]\n[![Debian Packages][deb-badge]][deb-url]\n[![RPM Packages][rpm-badge]][rpm-url]\n[![Coverage Status][coveralls-badge]][coveralls-url]\n[![License][license-badge]][license-url]\n\n<!-- markdown-toc start - Don't edit this section. Run M-x markdown-toc-generate-toc again -->\n**Table of Contents**\n\n- [sysbench](#sysbench)\n    - [Features](#features)\n- [Installing from Binary Packages](#installing-from-binary-packages)\n    - [Linux](#linux)\n    - [macOS](#macos)\n    - [Windows](#windows)\n- [Building and Installing From Source](#building-and-installing-from-source)\n    - [Build Requirements](#build-requirements)\n        - [Windows](#windows)\n        - [Debian/Ubuntu](#debianubuntu)\n        - [RHEL/CentOS](#rhelcentos)\n        - [Fedora](#fedora)\n        - [macOS](#macos)\n    - [Build and Install](#build-and-install)\n- [Usage](#usage)\n    - [General Syntax](#general-syntax)\n    - [General Command Line Options](#general-command-line-options)\n    - [Random Numbers Options](#random-numbers-options)\n- [Versioning](#versioning)\n\n<!-- markdown-toc end -->\n\n# sysbench\n\nsysbench is a scriptable multi-threaded benchmark tool based on\nLuaJIT. It is most frequently used for database benchmarks, but can also\nbe used to create arbitrarily complex workloads that do not involve a\ndatabase server.\n\nsysbench comes with the following bundled benchmarks:\n\n- `oltp_*.lua`: a collection of OLTP-like database benchmarks\n- `fileio`: a filesystem-level benchmark\n- `cpu`: a simple CPU benchmark\n- `memory`: a memory access benchmark\n- `threads`: a thread-based scheduler benchmark\n- `mutex`: a POSIX mutex benchmark\n\n## Features\n\n- extensive statistics about rate and latency is available, including\n  latency percentiles and histograms;\n- low overhead even with thousands of concurrent threads. sysbench is\n  capable of generating and tracking hundreds of millions of events per\n  second;\n- new benchmarks can be easily created by implementing pre-defined hooks\n  in user-provided Lua scripts;\n- can be used as a general-purpose Lua interpreter as well, simply\n  replace `#!/usr/bin/lua` with `#!/usr/bin/sysbench` in your script.\n\n# Installing from Binary Packages\n\n## Linux\n\nThe easiest way to download and install sysbench on Linux is using\nbinary package repositories hosted by\n[packagecloud](https://packagecloud.io). The repositories are\nautomatically updated on each sysbench release. Currently x86_64, i386\nand aarch64 binaries are available.\n\nMultiple methods to download and install sysbench packages are available and\ndescribed at <https://packagecloud.io/akopytov/sysbench/install>.\n\nQuick install instructions:\n\n- Debian/Ubuntu\n  ``` shell\n  curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.deb.sh | sudo bash\n  sudo apt -y install sysbench\n  ```\n\n- RHEL/CentOS:\n  ``` shell\n  curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash\n  sudo yum -y install sysbench\n  ```\n\n- Fedora:\n  ``` shell\n  curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash\t\n  sudo dnf -y install sysbench\n  ```\n\n- Arch Linux:\n  ``` shell\n  sudo pacman -Suy sysbench\n  ```\n\n## macOS\n\nOn macOS, up-to-date sysbench packages are available from Homebrew:\n```shell\n# Add --with-postgresql if you need PostgreSQL support\nbrew install sysbench\n```\n\n## Windows\nAs of sysbench 1.0 support for native Windows builds was dropped. It may\nbe re-introduced in later releases. Currently, the recommended way to\nobtain sysbench on Windows is\nusing\n[Windows Subsystem for Linux available in Windows 10](https://msdn.microsoft.com/en-us/commandline/wsl/about).\n\nAfter installing WSL and getting into he bash prompt on Windows\nfollowing Debian/Ubuntu installation instructions is\nsufficient. Alternatively, one can use WSL to build and install sysbench\nfrom source, or use an older sysbench release to build a native binary.\n\n# Building and Installing From Source\n\nIt is recommended to install sysbench from the official binary\npackages as described in\n[Installing from Binary Packages](#installing-from-binary-packages). Below\nare instruction for cases when you want to use sysbench on an\narchitecture for which no binary packages are available.\n\n## Build Requirements\n\n### Windows\nAs of sysbench 1.0 support for native Windows builds was\ndropped. It may be re-introduced in later versions. Currently, the\nrecommended way to build sysbench on Windows is using\n[Windows Subsystem for Linux available in Windows 10](https://msdn.microsoft.com/en-us/commandline/wsl/about).\n\nAfter installing WSL and getting into bash prompt on Windows, following\nDebian/Ubuntu build instructions is sufficient. Alternatively, one can\nbuild and use an older 0.5 release on Windows.\n\n### Debian/Ubuntu\n``` shell\n    apt -y install make automake libtool pkg-config libaio-dev\n    # For MySQL support\n    apt -y install libmysqlclient-dev libssl-dev\n    # For PostgreSQL support\n    apt -y install libpq-dev\n```\n\n### RHEL/CentOS\n``` shell\n    yum -y install make automake libtool pkgconfig libaio-devel\n    # For MySQL support, replace with mysql-devel on RHEL/CentOS 5\n    yum -y install mariadb-devel openssl-devel\n    # For PostgreSQL support\n    yum -y install postgresql-devel\n```\n\n### Fedora\n``` shell\n    dnf -y install make automake libtool pkgconfig libaio-devel\n    # For MySQL support\n    dnf -y install mariadb-devel openssl-devel\n    # For PostgreSQL support\n    dnf -y install postgresql-devel\n```\n\n### macOS\n\nAssuming you have Xcode (or Xcode Command Line Tools) and Homebrew installed:\n``` shell\n    brew install automake libtool openssl pkg-config\n    # For MySQL support\n    brew install mysql\n    # For PostgreSQL support\n    brew install postgresql\n    # openssl is not linked by Homebrew, this is to avoid \"ld: library not found for -lssl\"\n    export LDFLAGS=-L/usr/local/opt/openssl/lib \n```\n\n## Build and Install\n``` shell\n    ./autogen.sh\n    # Add --with-pgsql to build with PostgreSQL support\n    ./configure\n    make -j\n    make install\n```\n\nThe above will build sysbench with MySQL support by default. If you have\nMySQL headers and libraries in non-standard locations (and no\n`mysql_config` can be found in the `PATH`), you can specify them\nexplicitly with `--with-mysql-includes` and `--with-mysql-libs` options\nto `./configure`.\n\nTo compile sysbench without MySQL support, use `--without-mysql`. If no\ndatabase drivers are available database-related scripts will not work,\nbut other benchmarks will be functional.\n\n# Usage\n\n## General Syntax\n\nThe general command line syntax for sysbench is:\n\n\t\t  sysbench [options]... [testname] [command] \n\n- *testname* is an optional name of a built-in test (e.g. `fileio`,\n  `memory`, `cpu`, etc.), or a name of one of the bundled Lua scripts\n  (e.g. `oltp_read_only`), or a *path* to a custom Lua script. If no\n  test name is specified on the command line (and thus, there is no\n  *command* too, as in that case it would be parsed as a *testname*), or\n  the test name is a dash (\"`-`\"), then sysbench expects a Lua script to\n  execute on its standard input.\n\n- *command* is an optional argument that will be passed by sysbench to\n  the built-in test or script specified with *testname*. *command*\n  defines the *action* that must be performed by the test. The list of\n  available commands depends on a particular test. Some tests also\n  implement their own custom commands.\n\n  Below is a description of typical test commands and their purpose:\n\n\t+ `prepare`: performs preparative actions for those tests which need\n\tthem, e.g. creating the necessary files on disk for the `fileio`\n\ttest, or filling the test database for database benchmarks.\n\t+ `run`: runs the actual test specified with the *testname*\n    argument. This command is provided by all tests.\n\t+ `cleanup`: removes temporary data after the test run in those\n    tests which create one.\n\t+ `help`: displays usage information for the test specified with the\n\t*testname* argument. This includes the full list of commands\n\tprovided by the test, so it should be used to get the available\n\tcommands.\n\n- *options* is a list of zero or more command line options starting with\n\t`'--'`. As with commands, the `sysbench testname help` command\n\tshould be used to describe available options provided by a\n\tparticular test.\n\n\tSee [General command line options](README.md#general-command-line-options)\n\tfor a description of general options provided by sysbench itself.\n\n\nYou can use `sysbench --help` to display the general command line syntax\nand options.\n\n## General Command Line Options\n\nThe table below lists the supported common options, their descriptions and default values:\n\n*Option*              | *Description* | *Default value*\n----------------------|---------------|----------------\n| `--threads`           | The total number of worker threads to create                                                                                                                                                                                                                                                                                                                                                                                                                            | 1               |\n| `--events`            | Limit for total number of requests. 0 (the default) means no limit                                                                                                                                                                                                                                                                                                                                                                                                      | 0               |\n| `--time`              | Limit for total execution time in seconds. 0 means no limit                                                                                                                                                                                                                                                                                                                                                                                                             | 10              |\n| `--warmup-time`       | Execute events for this many seconds with statistics disabled before the actual benchmark run with statistics enabled. This is useful when you want to exclude the initial period of a benchmark run from statistics. In many benchmarks, the initial period is not representative because CPU/database/page and other caches need some time to warm up                                                                                                                                                                                                                                                                                                  | 0               |\n| `--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               |\n| `--thread-init-timeout` | Wait time in seconds for worker threads to initialize                                                                                                                                                                                                                                                                                                                                                                                                                  | 30              |\n| `--thread-stack-size` | Size of stack for each thread                                                                                                                                                                                                                                                                                                                                                                                                                                           | 32K             |\n| `--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               |\n| `--debug`             | Print more debug info                                                                                                                                                                                                                                                                                                                                                                                                                                                   | off             |\n| `--validate`          | Perform validation of test results where possible                                                                                                                                                                                                                                                                                                                                                                                                                       | off             |\n| `--help`              | Print help on general syntax or on a specified test, and exit                                                                                                                                                                                                                                                                                                                                                                                                           | off             |\n| `--verbosity`         | Verbosity level (0 - only critical messages, 5 - debug)                                                                                                                                                                                                                                                                                                                                                                                                                 | 4               |\n| `--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              |\n| `--luajit-cmd`        | perform a LuaJIT control command. This option is equivalent to `luajit -j`. See [LuaJIT documentation](http://luajit.org/running.html#opt_j) for more information                                                                                                                                                                                                                                                                                                       |               |\n\nNote 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).\n\n## Random Numbers Options\n\nsysbench provides a number of algorithms to generate random numbers that are distributed according to a given probability distribution. The table below lists options that can be used to control those algorithms.\n\n*Option*              | *Description* | *Default value*\n----------------------|---------------|----------------\n`--rand-type` | random numbers distribution {uniform, gaussian, special, pareto, zipfian} to use by default. Benchmark scripts may choose to use either the default distribution, or specify it explictly, i.e. override the default. | special\n`--rand-seed` | seed for random number generator. When 0, the current time is used as an RNG seed. | 0\n`--rand-spec-iter` | number of iterations for the special distribution | 12\n`--rand-spec-pct` | percentage of the entire range where 'special' values will fall in the special distribution | 1\n`--rand-spec-res` | percentage of 'special' values to use for the special distribution | 75\n`--rand-pareto-h` | shape parameter for the Pareto distribution | 0.2\n`--rand-zipfian-exp` | shape parameter (theta) for the Zipfian distribution | 0.8\n\n# Versioning\n\nFor 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.\n\nReleases will be numbered with the following format:\n\n`<major>.<minor>.<patch>`\n\nAnd constructed with the following guidelines:\n\n* Breaking backward compatibility bumps the major (and resets the minor and patch)\n* New additions without breaking backward compatibility bumps the minor (and resets the patch)\n* Bug fixes and misc changes bumps the patch\n\nFor more information on SemVer, please visit [http://semver.org/](http://semver.org/).\n\n[coveralls-badge]: https://coveralls.io/repos/github/akopytov/sysbench/badge.svg?branch=master\n[coveralls-url]: https://coveralls.io/github/akopytov/sysbench?branch=master\n[action-url]: https://github.com/akopytov/sysbench/actions/workflows/ci.yml\n[action-badge]: https://github.com/akopytov/sysbench/actions/workflows/ci.yml/badge.svg\n[license-badge]: https://img.shields.io/badge/license-GPLv2-blue.svg\n[license-url]: COPYING\n[release-badge]: https://img.shields.io/github/release/akopytov/sysbench.svg\n[release-url]: https://github.com/akopytov/sysbench/releases/latest\n[deb-badge]: https://img.shields.io/badge/Packages-Debian-red.svg?style=flat\n[deb-url]: https://packagecloud.io/akopytov/sysbench?filter=debs\n[rpm-badge]: https://img.shields.io/badge/Packages-RPM-blue.svg?style=flat\n[rpm-url]: https://packagecloud.io/akopytov/sysbench?filter=rpms\n"
  },
  {
    "path": "autogen.sh",
    "content": "#!/bin/sh\n\nautoreconf -vi\n"
  },
  {
    "path": "config/config.rpath",
    "content": "#! /bin/sh\n# Output a system dependent set of variables, describing how to set the\n# run time search path of shared libraries in an executable.\n#\n#   Copyright 1996-2007 Free Software Foundation, Inc.\n#   Taken from GNU libtool, 2001\n#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996\n#\n#   This file is free software; the Free Software Foundation gives\n#   unlimited permission to copy and/or distribute it, with or without\n#   modifications, as long as this notice is preserved.\n#\n# The first argument passed to this file is the canonical host specification,\n#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM\n# or\n#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM\n# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld\n# should be set by the caller.\n#\n# The set of defined variables is at the end of this script.\n\n# Known limitations:\n# - On IRIX 6.5 with CC=\"cc\", the run time search patch must not be longer\n#   than 256 bytes, otherwise the compiler driver will dump core. The only\n#   known workaround is to choose shorter directory names for the build\n#   directory and/or the installation directory.\n\n# All known linkers require a `.a' archive for static linking (except MSVC,\n# which needs '.lib').\nlibext=a\nshrext=.so\n\nhost=\"$1\"\nhost_cpu=`echo \"$host\" | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\1/'`\nhost_vendor=`echo \"$host\" | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\2/'`\nhost_os=`echo \"$host\" | sed 's/^\\([^-]*\\)-\\([^-]*\\)-\\(.*\\)$/\\3/'`\n\n# Code taken from libtool.m4's _LT_CC_BASENAME.\n\nfor cc_temp in $CC\"\"; do\n  case $cc_temp in\n    compile | *[\\\\/]compile | ccache | *[\\\\/]ccache ) ;;\n    distcc | *[\\\\/]distcc | purify | *[\\\\/]purify ) ;;\n    \\-*) ;;\n    *) break;;\n  esac\ndone\ncc_basename=`echo \"$cc_temp\" | sed -e 's%^.*/%%'`\n\n# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.\n\nwl=\nif test \"$GCC\" = yes; then\n  wl='-Wl,'\nelse\n  case \"$host_os\" in\n    aix*)\n      wl='-Wl,'\n      ;;\n    darwin*)\n      case $cc_basename in\n        xlc*)\n          wl='-Wl,'\n          ;;\n      esac\n      ;;\n    mingw* | cygwin* | pw32* | os2*)\n      ;;\n    hpux9* | hpux10* | hpux11*)\n      wl='-Wl,'\n      ;;\n    irix5* | irix6* | nonstopux*)\n      wl='-Wl,'\n      ;;\n    newsos6)\n      ;;\n    linux* | k*bsd*-gnu)\n      case $cc_basename in\n        icc* | ecc*)\n          wl='-Wl,'\n          ;;\n        pgcc | pgf77 | pgf90)\n          wl='-Wl,'\n          ;;\n        ccc*)\n          wl='-Wl,'\n          ;;\n        como)\n          wl='-lopt='\n          ;;\n        *)\n          case `$CC -V 2>&1 | sed 5q` in\n            *Sun\\ C*)\n              wl='-Wl,'\n              ;;\n          esac\n          ;;\n      esac\n      ;;\n    osf3* | osf4* | osf5*)\n      wl='-Wl,'\n      ;;\n    rdos*)\n      ;;\n    solaris*)\n      wl='-Wl,'\n      ;;\n    sunos4*)\n      wl='-Qoption ld '\n      ;;\n    sysv4 | sysv4.2uw2* | sysv4.3*)\n      wl='-Wl,'\n      ;;\n    sysv4*MP*)\n      ;;\n    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)\n      wl='-Wl,'\n      ;;\n    unicos*)\n      wl='-Wl,'\n      ;;\n    uts4*)\n      ;;\n  esac\nfi\n\n# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.\n\nhardcode_libdir_flag_spec=\nhardcode_libdir_separator=\nhardcode_direct=no\nhardcode_minus_L=no\n\ncase \"$host_os\" in\n  cygwin* | mingw* | pw32*)\n    # FIXME: the MSVC++ port hasn't been tested in a loooong time\n    # When not using gcc, we currently assume that we are using\n    # Microsoft Visual C++.\n    if test \"$GCC\" != yes; then\n      with_gnu_ld=no\n    fi\n    ;;\n  interix*)\n    # we just hope/assume this is gcc and not c89 (= MSVC++)\n    with_gnu_ld=yes\n    ;;\n  openbsd*)\n    with_gnu_ld=no\n    ;;\nesac\n\nld_shlibs=yes\nif test \"$with_gnu_ld\" = yes; then\n  # Set some defaults for GNU ld with shared library support. These\n  # are reset later if shared libraries are not supported. Putting them\n  # here allows them to be overridden if necessary.\n  # Unlike libtool, we use -rpath here, not --rpath, since the documented\n  # option of GNU ld is called -rpath, not --rpath.\n  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n  case \"$host_os\" in\n    aix3* | aix4* | aix5*)\n      # On AIX/PPC, the GNU linker is very broken\n      if test \"$host_cpu\" != ia64; then\n        ld_shlibs=no\n      fi\n      ;;\n    amigaos*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_minus_L=yes\n      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports\n      # that the semantics of dynamic libraries on AmigaOS, at least up\n      # to version 4, is to share data among multiple programs linked\n      # with the same dynamic library.  Since this doesn't match the\n      # behavior of shared libraries on other platforms, we cannot use\n      # them.\n      ld_shlibs=no\n      ;;\n    beos*)\n      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then\n        :\n      else\n        ld_shlibs=no\n      fi\n      ;;\n    cygwin* | mingw* | pw32*)\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      hardcode_libdir_flag_spec='-L$libdir'\n      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then\n        :\n      else\n        ld_shlibs=no\n      fi\n      ;;\n    interix[3-9]*)\n      hardcode_direct=no\n      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n      ;;\n    gnu* | linux* | k*bsd*-gnu)\n      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then\n        :\n      else\n        ld_shlibs=no\n      fi\n      ;;\n    netbsd*)\n      ;;\n    solaris*)\n      if $LD -v 2>&1 | grep 'BFD 2\\.8' > /dev/null; then\n        ld_shlibs=no\n      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then\n        :\n      else\n        ld_shlibs=no\n      fi\n      ;;\n    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)\n      case `$LD -v 2>&1` in\n        *\\ [01].* | *\\ 2.[0-9].* | *\\ 2.1[0-5].*)\n          ld_shlibs=no\n          ;;\n        *)\n          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then\n            hardcode_libdir_flag_spec='`test -z \"$SCOABSPATH\" && echo ${wl}-rpath,$libdir`'\n          else\n            ld_shlibs=no\n          fi\n          ;;\n      esac\n      ;;\n    sunos4*)\n      hardcode_direct=yes\n      ;;\n    *)\n      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then\n        :\n      else\n        ld_shlibs=no\n      fi\n      ;;\n  esac\n  if test \"$ld_shlibs\" = no; then\n    hardcode_libdir_flag_spec=\n  fi\nelse\n  case \"$host_os\" in\n    aix3*)\n      # Note: this linker hardcodes the directories in LIBPATH if there\n      # are no directories specified by -L.\n      hardcode_minus_L=yes\n      if test \"$GCC\" = yes; then\n        # Neither direct hardcoding nor static linking is supported with a\n        # broken collect2.\n        hardcode_direct=unsupported\n      fi\n      ;;\n    aix4* | aix5*)\n      if test \"$host_cpu\" = ia64; then\n        # On IA64, the linker does run time linking by default, so we don't\n        # have to do anything special.\n        aix_use_runtimelinking=no\n      else\n        aix_use_runtimelinking=no\n        # Test if we are trying to use run time linking or normal\n        # AIX style linking. If -brtl is somewhere in LDFLAGS, we\n        # need to do runtime linking.\n        case $host_os in aix4.[23]|aix4.[23].*|aix5*)\n          for ld_flag in $LDFLAGS; do\n            if (test $ld_flag = \"-brtl\" || test $ld_flag = \"-Wl,-brtl\"); then\n              aix_use_runtimelinking=yes\n              break\n            fi\n          done\n          ;;\n        esac\n      fi\n      hardcode_direct=yes\n      hardcode_libdir_separator=':'\n      if test \"$GCC\" = yes; then\n        case $host_os in aix4.[012]|aix4.[012].*)\n          collect2name=`${CC} -print-prog-name=collect2`\n          if test -f \"$collect2name\" && \\\n            strings \"$collect2name\" | grep resolve_lib_name >/dev/null\n          then\n            # We have reworked collect2\n            :\n          else\n            # We have old collect2\n            hardcode_direct=unsupported\n            hardcode_minus_L=yes\n            hardcode_libdir_flag_spec='-L$libdir'\n            hardcode_libdir_separator=\n          fi\n          ;;\n        esac\n      fi\n      # Begin _LT_AC_SYS_LIBPATH_AIX.\n      echo 'int main () { return 0; }' > conftest.c\n      ${CC} ${LDFLAGS} conftest.c -o conftest\n      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\\(.*\\)$/\\1/; p; }\n}'`\n      if test -z \"$aix_libpath\"; then\n        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\\(.*\\)$/\\1/; p; }\n}'`\n      fi\n      if test -z \"$aix_libpath\"; then\n        aix_libpath=\"/usr/lib:/lib\"\n      fi\n      rm -f conftest.c conftest\n      # End _LT_AC_SYS_LIBPATH_AIX.\n      if test \"$aix_use_runtimelinking\" = yes; then\n        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n      else\n        if test \"$host_cpu\" = ia64; then\n          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'\n        else\n          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'\"$aix_libpath\"\n        fi\n      fi\n      ;;\n    amigaos*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_minus_L=yes\n      # see comment about different semantics on the GNU ld section\n      ld_shlibs=no\n      ;;\n    bsdi[45]*)\n      ;;\n    cygwin* | mingw* | pw32*)\n      # When not using gcc, we currently assume that we are using\n      # Microsoft Visual C++.\n      # hardcode_libdir_flag_spec is actually meaningless, as there is\n      # no search path for DLLs.\n      hardcode_libdir_flag_spec=' '\n      libext=lib\n      ;;\n    darwin* | rhapsody*)\n      hardcode_direct=no\n      if test \"$GCC\" = yes ; then\n        :\n      else\n        case $cc_basename in\n          xlc*)\n            ;;\n          *)\n            ld_shlibs=no\n            ;;\n        esac\n      fi\n      ;;\n    dgux*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      ;;\n    freebsd1*)\n      ld_shlibs=no\n      ;;\n    freebsd2.2*)\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      ;;\n    freebsd2*)\n      hardcode_direct=yes\n      hardcode_minus_L=yes\n      ;;\n    freebsd* | dragonfly*)\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      ;;\n    hpux9*)\n      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n      hardcode_libdir_separator=:\n      hardcode_direct=yes\n      # hardcode_minus_L: Not really in the search PATH,\n      # but as the default location of the library.\n      hardcode_minus_L=yes\n      ;;\n    hpux10*)\n      if test \"$with_gnu_ld\" = no; then\n        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n        hardcode_libdir_separator=:\n        hardcode_direct=yes\n        # hardcode_minus_L: Not really in the search PATH,\n        # but as the default location of the library.\n        hardcode_minus_L=yes\n      fi\n      ;;\n    hpux11*)\n      if test \"$with_gnu_ld\" = no; then\n        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'\n        hardcode_libdir_separator=:\n        case $host_cpu in\n          hppa*64*|ia64*)\n            hardcode_direct=no\n            ;;\n          *)\n            hardcode_direct=yes\n            # hardcode_minus_L: Not really in the search PATH,\n            # but as the default location of the library.\n            hardcode_minus_L=yes\n            ;;\n        esac\n      fi\n      ;;\n    irix5* | irix6* | nonstopux*)\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      ;;\n    netbsd*)\n      hardcode_libdir_flag_spec='-R$libdir'\n      hardcode_direct=yes\n      ;;\n    newsos6)\n      hardcode_direct=yes\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      ;;\n    openbsd*)\n      if test -f /usr/libexec/ld.so; then\n        hardcode_direct=yes\n        if test -z \"`echo __ELF__ | $CC -E - | grep __ELF__`\" || test \"$host_os-$host_cpu\" = \"openbsd2.8-powerpc\"; then\n          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n        else\n          case \"$host_os\" in\n            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)\n              hardcode_libdir_flag_spec='-R$libdir'\n              ;;\n            *)\n              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'\n              ;;\n          esac\n        fi\n      else\n        ld_shlibs=no\n      fi\n      ;;\n    os2*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_minus_L=yes\n      ;;\n    osf3*)\n      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      hardcode_libdir_separator=:\n      ;;\n    osf4* | osf5*)\n      if test \"$GCC\" = yes; then\n        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'\n      else\n        # Both cc and cxx compiler support -rpath directly\n        hardcode_libdir_flag_spec='-rpath $libdir'\n      fi\n      hardcode_libdir_separator=:\n      ;;\n    solaris*)\n      hardcode_libdir_flag_spec='-R$libdir'\n      ;;\n    sunos4*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      hardcode_direct=yes\n      hardcode_minus_L=yes\n      ;;\n    sysv4)\n      case $host_vendor in\n        sni)\n          hardcode_direct=yes # is this really true???\n          ;;\n        siemens)\n          hardcode_direct=no\n          ;;\n        motorola)\n          hardcode_direct=no #Motorola manual says yes, but my tests say they lie\n          ;;\n      esac\n      ;;\n    sysv4.3*)\n      ;;\n    sysv4*MP*)\n      if test -d /usr/nec; then\n        ld_shlibs=yes\n      fi\n      ;;\n    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)\n      ;;\n    sysv5* | sco3.2v5* | sco5v6*)\n      hardcode_libdir_flag_spec='`test -z \"$SCOABSPATH\" && echo ${wl}-R,$libdir`'\n      hardcode_libdir_separator=':'\n      ;;\n    uts4*)\n      hardcode_libdir_flag_spec='-L$libdir'\n      ;;\n    *)\n      ld_shlibs=no\n      ;;\n  esac\nfi\n\n# Check dynamic linker characteristics\n# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.\n# Unlike libtool.m4, here we don't care about _all_ names of the library, but\n# only about the one the linker finds when passed -lNAME. This is the last\n# element of library_names_spec in libtool.m4, or possibly two of them if the\n# linker has special search rules.\nlibrary_names_spec=      # the last element of library_names_spec in libtool.m4\nlibname_spec='lib$name'\ncase \"$host_os\" in\n  aix3*)\n    library_names_spec='$libname.a'\n    ;;\n  aix4* | aix5*)\n    library_names_spec='$libname$shrext'\n    ;;\n  amigaos*)\n    library_names_spec='$libname.a'\n    ;;\n  beos*)\n    library_names_spec='$libname$shrext'\n    ;;\n  bsdi[45]*)\n    library_names_spec='$libname$shrext'\n    ;;\n  cygwin* | mingw* | pw32*)\n    shrext=.dll\n    library_names_spec='$libname.dll.a $libname.lib'\n    ;;\n  darwin* | rhapsody*)\n    shrext=.dylib\n    library_names_spec='$libname$shrext'\n    ;;\n  dgux*)\n    library_names_spec='$libname$shrext'\n    ;;\n  freebsd1*)\n    ;;\n  freebsd* | dragonfly*)\n    case \"$host_os\" in\n      freebsd[123]*)\n        library_names_spec='$libname$shrext$versuffix' ;;\n      *)\n        library_names_spec='$libname$shrext' ;;\n    esac\n    ;;\n  gnu*)\n    library_names_spec='$libname$shrext'\n    ;;\n  hpux9* | hpux10* | hpux11*)\n    case $host_cpu in\n      ia64*)\n        shrext=.so\n        ;;\n      hppa*64*)\n        shrext=.sl\n        ;;\n      *)\n        shrext=.sl\n        ;;\n    esac\n    library_names_spec='$libname$shrext'\n    ;;\n  interix[3-9]*)\n    library_names_spec='$libname$shrext'\n    ;;\n  irix5* | irix6* | nonstopux*)\n    library_names_spec='$libname$shrext'\n    case \"$host_os\" in\n      irix5* | nonstopux*)\n        libsuff= shlibsuff=\n        ;;\n      *)\n        case $LD in\n          *-32|*\"-32 \"|*-melf32bsmip|*\"-melf32bsmip \") libsuff= shlibsuff= ;;\n          *-n32|*\"-n32 \"|*-melf32bmipn32|*\"-melf32bmipn32 \") libsuff=32 shlibsuff=N32 ;;\n          *-64|*\"-64 \"|*-melf64bmip|*\"-melf64bmip \") libsuff=64 shlibsuff=64 ;;\n          *) libsuff= shlibsuff= ;;\n        esac\n        ;;\n    esac\n    ;;\n  linux*oldld* | linux*aout* | linux*coff*)\n    ;;\n  linux* | k*bsd*-gnu)\n    library_names_spec='$libname$shrext'\n    ;;\n  knetbsd*-gnu)\n    library_names_spec='$libname$shrext'\n    ;;\n  netbsd*)\n    library_names_spec='$libname$shrext'\n    ;;\n  newsos6)\n    library_names_spec='$libname$shrext'\n    ;;\n  nto-qnx*)\n    library_names_spec='$libname$shrext'\n    ;;\n  openbsd*)\n    library_names_spec='$libname$shrext$versuffix'\n    ;;\n  os2*)\n    libname_spec='$name'\n    shrext=.dll\n    library_names_spec='$libname.a'\n    ;;\n  osf3* | osf4* | osf5*)\n    library_names_spec='$libname$shrext'\n    ;;\n  rdos*)\n    ;;\n  solaris*)\n    library_names_spec='$libname$shrext'\n    ;;\n  sunos4*)\n    library_names_spec='$libname$shrext$versuffix'\n    ;;\n  sysv4 | sysv4.3*)\n    library_names_spec='$libname$shrext'\n    ;;\n  sysv4*MP*)\n    library_names_spec='$libname$shrext'\n    ;;\n  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)\n    library_names_spec='$libname$shrext'\n    ;;\n  uts4*)\n    library_names_spec='$libname$shrext'\n    ;;\nesac\n\nsed_quote_subst='s/\\([\"`$\\\\]\\)/\\\\\\1/g'\nescaped_wl=`echo \"X$wl\" | sed -e 's/^X//' -e \"$sed_quote_subst\"`\nshlibext=`echo \"$shrext\" | sed -e 's,^\\.,,'`\nescaped_libname_spec=`echo \"X$libname_spec\" | sed -e 's/^X//' -e \"$sed_quote_subst\"`\nescaped_library_names_spec=`echo \"X$library_names_spec\" | sed -e 's/^X//' -e \"$sed_quote_subst\"`\nescaped_hardcode_libdir_flag_spec=`echo \"X$hardcode_libdir_flag_spec\" | sed -e 's/^X//' -e \"$sed_quote_subst\"`\n\nLC_ALL=C sed -e 's/^\\([a-zA-Z0-9_]*\\)=/acl_cv_\\1=/' <<EOF\n\n# How to pass a linker flag through the compiler.\nwl=\"$escaped_wl\"\n\n# Static library suffix (normally \"a\").\nlibext=\"$libext\"\n\n# Shared library suffix (normally \"so\").\nshlibext=\"$shlibext\"\n\n# Format of library name prefix.\nlibname_spec=\"$escaped_libname_spec\"\n\n# Library names that the linker finds when passed -lNAME.\nlibrary_names_spec=\"$escaped_library_names_spec\"\n\n# Flag to hardcode \\$libdir into a binary during linking.\n# This must work even if \\$libdir does not exist.\nhardcode_libdir_flag_spec=\"$escaped_hardcode_libdir_flag_spec\"\n\n# Whether we need a single -rpath flag with a separated argument.\nhardcode_libdir_separator=\"$hardcode_libdir_separator\"\n\n# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the\n# resulting binary.\nhardcode_direct=\"$hardcode_direct\"\n\n# Set to yes if using the -LDIR flag during linking hardcodes DIR into the\n# resulting binary.\nhardcode_minus_L=\"$hardcode_minus_L\"\n\nEOF\n"
  },
  {
    "path": "configure.ac",
    "content": "# Process this file with autoconf to produce a configure script.\n\nAC_PREREQ([2.63])\nAC_INIT([sysbench],[1.1.0],[https://github.com/akopytov/sysbench/issues],[sysbench],[https://github.com/akopytov/sysbench])\nAC_CONFIG_AUX_DIR([config])\n\n# Define m4_ifblank and m4_ifnblank macros from introduced in\n#  autotools 2.64 m4sugar.m4 if using an earlier autotools.\nm4_ifdef([m4_ifblank], [], [\nm4_define([m4_ifblank],\n[m4_if(m4_translit([[$1]],  [ ][\t][\n]), [], [$2], [$3])])\n])\n\nm4_ifdef([m4_ifnblank], [], [\nm4_define([m4_ifnblank],\n[m4_if(m4_translit([[$1]],  [ ][\t][\n]), [], [$3], [$2])])\n])\n\n# Setting CFLAGS here prevents AC_CANONICAL_TARGET from injecting them\nSAVE_CFLAGS=${CFLAGS}\nSAVE_CXXFLAGS=${CXXFLAGS}\nCFLAGS=\nCXXFLAGS=\nAC_CANONICAL_TARGET\n\nCFLAGS=${SAVE_CFLAGS}\nCXXFLAGS=${SAVE_CXXFLAGS}\n \nAM_INIT_AUTOMAKE([-Wall -Werror foreign])\nAC_CONFIG_SRCDIR([src/sysbench.c])\nAC_CONFIG_HEADERS([config/config.h])\nAC_CONFIG_MACRO_DIR([m4])\n\nm4_pattern_forbid([^PKG_[A-Z_]+$],\n        [pkg-config has to be installed to build sysbench])\n\nACX_USE_SYSTEM_EXTENSIONS\n\nAC_PROG_CC\nAC_PROG_CPP\nAM_PROG_CC_C_O\n\nif test x\"$ac_cv_prog_cc_c99\" = xno; then\n   AC_MSG_ERROR([a C99 compiler is required to build sysbench])\nfi\n\n# Try to guess the most optimal compiler architecture flag, unless it's already\n# been specified by the user via CFLAGS (or --without-gcc-arch is passed to\n# configure)\nAS_CASE([$CFLAGS],\n  [*-march=*],,\n  [AX_GCC_ARCHFLAG([no])]\n)\n\nm4_ifdef([AM_PROG_AR], [AM_PROG_AR])\n\nLT_INIT\n\nAC_CHECK_PROG(sb_have_pkg_config, pkg-config, yes, no)\nif test x\"$sb_have_pkg_config\" = xno; then\n  AC_MSG_ERROR([the pkg-config package is required to build sysbench])\nfi\n\nAX_COMPILER_VENDOR\n\n# Checks for user arguments\n\nAC_LIB_PREFIX()\n\nCPPFLAGS=\"-D_GNU_SOURCE ${CPPFLAGS}\"\n\nAM_CONDITIONAL([IS_MACOS], [test \"$host_os\" = \"darwin\"])\n\nif test \"$host_os\" = \"darwin\"; then\n   # MacOS requires _DARWIN_C_SOURCE for valloc(3) to be visible\n\tCPPFLAGS=\"-D_DARWIN_C_SOURCE ${CPPFLAGS}\"\n  # LuaJIT also requires MACOSX_DEPLOYMENT_TARGET to be set on MacOS\n  if test -z \"$MACOSX_DEPLOYMENT_TARGET\"; then\n     MACOSX_DEPLOYMENT_TARGET=\"$(sw_vers -productVersion)\"\n  fi\n  AC_SUBST(MACOSX_DEPLOYMENT_TARGET, $MACOSX_DEPLOYMENT_TARGET)\nfi\n\n# Build optimized or debug version ?\n# First check for gcc and g++\nif test \"$GCC\" = \"yes\"\nthen\n  CFLAGS=\"-ggdb3 ${CFLAGS}\"\n  DEBUG_CFLAGS=\"-O0\"\n  OPTIMIZE_CFLAGS=\"-O3 -funroll-loops\"\n  GCOV_CFLAGS=\"-O0 --coverage\"\n  GCOV_LDFLAGS=\"-coverage\"\n  ASAN_CFLAGS=\"-fsanitize=address\"\n  ASAN_LDFLAGS=\"${ASAN_CFLAGS}\"\n  MSAN_CFLAGS=\"-fsanitize=memory\"\n  MSAN_LDFLAGS=\"${MSAN_LDFLAGS}\"\nfi\nif test \"$ax_cv_c_compiler_vendor\" = \"sun\"\nthen\n  isainfo_k=`isainfo -k`\n  if test \"$target_cpu\" = \"sparc\"\n  then\n    MEMALIGN_FLAGS=\"-xmemalign=8s\"\n    IS_64=\"-m64\"\n    LDFLAGS=\"${LDFLAGS} -L/usr/lib/${isainfo_k} -L/usr/local/lib/${isainfo_k}\"\n  else\n    if test \"$isainfo_k\" = \"amd64\"\n    then\n      IS_64=\"-m64\"\n      LDFLAGS=\"${LDFLAGS} -L/usr/lib/${isainfo_k} -L/usr/local/lib/${isainfo_k}\"\n    fi\n  fi\n  CPPFLAGS=\"${CPPFLAGS} -I/usr/local/include\"\n\n  CFLAGS=\"-g -mt ${IS_64} ${MEMALIGN_FLAGS} ${CFLAGS}\"\n  DEBUG_CFLAGS=\"-xO0\"\n  OPTIMIZE_CFLAGS=\"-xO2 -xlibmil -xdepend -Xa -mt -xstrconst\"\n# TODO: Set flags for Gcov-enabled builds, if supported by Sun Studio\nfi\n\n\n# Check if we should compile with MySQL support\nAC_ARG_WITH([mysql],\n            AS_HELP_STRING([--with-mysql],\n                           [compile with MySQL support (default is enabled)]),\n            [], [with_mysql=yes])\nAC_MSG_CHECKING([whether to compile with MySQL support])\nAS_IF([test \"x$with_mysql\" != \"xno\"],\n   [mysql_support=yes],\n   [mysql_support=no])\nAC_MSG_RESULT([$mysql_support])\n\n# Check if we should compile with PostgreSQL support\nAC_ARG_WITH([pgsql],\n            AS_HELP_STRING([--with-pgsql],\n                           [compile with PostgreSQL support (default is disabled)]),\n            [], [with_pgsql=no])\nAC_MSG_CHECKING([whether to compile with PostgreSQL support])\nAS_IF([test \"x$with_pgsql\" != \"xno\"],\n   [pgsql_support=yes],\n   [pgsql_support=no])\nAC_MSG_RESULT([$pgsql_support])\n\n# Set LuaJIT flags\nSB_LUAJIT\n\n# Set Concurrency Kit flags\nSB_CONCURRENCY_KIT\n\n# Check if we should enable large files support\nAC_ARG_ENABLE(largefile,\n    AS_HELP_STRING([--enable-largefile],[enable large files support (default is enabled)]), ,\n    enable_largefile=yes\n)\n\n# For SHM_HUGETLB on Linux\nAC_CHECK_DECLS(SHM_HUGETLB, \n    AC_DEFINE([HAVE_LARGE_PAGES], [1], \n              [Define if you have large pages support])\n    AC_DEFINE([HUGETLB_USE_PROC_MEMINFO], [1],\n              [Define if /proc/meminfo shows the huge page size (Linux only)])\n    , ,\n    [\n#include <sys/shm.h>\n    ]\n)\n\n# Check if we should enable Linux AIO support\nAC_ARG_ENABLE(aio,\n   AS_HELP_STRING([--enable-aio],[enable Linux asynchronous I/O support (default is enabled)]), ,\n   enable_aio=yes\n)\n\nAC_CHECK_DECLS(O_SYNC, ,\n   AC_DEFINE([O_SYNC], [O_FSYNC],\n             [Define to the appropriate value for O_SYNC on your platform]),\n   [\n#include <fcntl.h>\n   ]\n)\n\n\n# Checks for libraries.\n\nACX_PTHREAD\n\nAC_CHECK_LIB(m, sqrt)\n\nSB_CHECK_MYSQL\n\nAS_IF([test x$with_pgsql != xno], [\n    AC_CHECK_PGSQL([$with_pgsql])\n    USE_PGSQL=1\n    AC_DEFINE(USE_PGSQL,1,[Define to 1 if you want to compile with PostgreSQL support])\n    AC_SUBST([PGSQL_LIBS])\n    AC_SUBST([PGSQL_CFLAGS])\n])\nAM_CONDITIONAL(USE_PGSQL, test x$with_pgsql != xno)\nAC_SUBST([USE_PGSQL])\n\n# Check for libaio\nAC_CHECK_AIO\nAM_CONDITIONAL(USE_AIO, test x$enable_aio = xyes)\n\nAC_CHECK_HEADERS([ \\\nerrno.h \\\nfcntl.h \\\nmath.h \\\npthread.h \\\nsched.h \\\nsignal.h \\\nstdlib.h \\\nstring.h \\\nsys/aio.h \\\nsys/ipc.h \\\nsys/time.h \\\nsys/mman.h \\\nsys/shm.h \\\nthread.h \\\nunistd.h \\\nlimits.h \\\nlibgen.h \\\n])\n\n\n# Checks for typedefs, structures, and compiler characteristics.\nAC_TYPE_OFF_T\n\nAX_TLS([],\n  AC_MSG_ERROR([thread-local storage is not suppored by the target platform!])\n)\n\n# Define HAVE_FUNC_ATTRIBUTE_FORMAT if compiler supports the\n# __attribute__((format...)) function attribute\nAX_GCC_FUNC_ATTRIBUTE(format)\n\n# Define HAVE_FUNC_ATTRIBUTE_UNUSED if compiler supports the\n# __attribute__((unused)) function attribute\nAX_GCC_FUNC_ATTRIBUTE(unused)\n\nif test \"$enable_largefile\" = yes; then\n    AC_SYS_LARGEFILE\nfi\n\nAC_CHECK_SIZEOF(size_t)\nAC_CHECK_SIZEOF(bool,,\n  [\n    #include <stdbool.h>\n  ])\n\n# Checks for library functions.\nAC_FUNC_MMAP\nAC_FUNC_STRERROR_R\n\nAC_SEARCH_LIBS([clock_gettime], [rt]) \n\nsave_CFLAGS=\"$CFLAGS\"\nCFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\nsave_LIBS=\"$LIBS\"\nLIBS=\"$PTHREAD_LIBS $LIBS\"\n\nAC_CHECK_FUNCS([ \\\nalarm \\\nclock_gettime \\\ndirectio \\\nfdatasync \\\ngettimeofday \\\nisatty \\\nmemalign \\\nmemset \\\nposix_memalign \\\npthread_cancel \\\npthread_yield \\\nsetvbuf \\\nsqrt \\\nstrdup \\\nthr_setconcurrency \\\nvalloc \\\n])\n\nAC_CHECK_FUNC(pthread_once, , \n              AC_MSG_ERROR([*** pthread_once() is not available on this platform ***])\n)\n\nLIBS=\"$save_LIBS\"\nCFLAGS=\"$save_CFLAGS\"\n\nAC_ARG_WITH([debug],\n    [AS_HELP_STRING([--with-debug],\n       [Add debug code/turns off optimizations (yes|no) @<:@default=no@:>@])],\n    [with_debug=$withval],\n    [with_debug=no])\n\nAC_ARG_ENABLE([coverage],\n    [AS_HELP_STRING([--enable-coverage],\n       [Toggle coverage @<:@default=no@:>@])],\n    [ac_coverage=\"$enableval\"],\n    [ac_coverage=\"no\"])\n\nAC_ARG_ENABLE([asan],\n  [AS_HELP_STRING([--enable-asan],\n    [Enable AddressSanitizer @<:@default=no@:>@])],\n  [ac_asan=\"$enableval\"],\n  [ac_asan=\"no\"])\n\nAC_ARG_ENABLE([msan],\n  [AS_HELP_STRING([--enable-msan],\n    [Enable MemorySanitizer @<:@default=no@:>@])],\n  [ac_msan=\"$enableval\"],\n  [ac_msan=\"no\"])\n\nAC_ARG_ENABLE([fail],\n    [AS_HELP_STRING([--disable-fail],\n       [Turn warnings into failures @<:@default=no@:>@])],\n    [ac_warn_fail=\"$enableval\"],\n    [ac_warn_fail=\"no\"])\n\nif test \"$with_debug\" = \"yes\"\nthen\n  # Debugging. No optimization.\n  CFLAGS=\"${DEBUG_CFLAGS} -DDEBUG ${CFLAGS}\"\nelif test \"$ac_coverage\" = \"yes\"\nthen\n  # Gcov-enabled build. No optimization.\n  CFLAGS=\"${GCOV_CFLAGS} ${CFLAGS}\"\n  LDFLAGS=\"${GCOV_LDFLAGS} ${LDFLAGS}\"\nelse\n  # Optimized version. No debug\n  CFLAGS=\"${OPTIMIZE_CFLAGS} ${CFLAGS}\"\nfi\n\nif test \"$ac_asan\" = \"yes\"\nthen\n  # Add -fsanitize=address to CFLAGS/LDFLAGS if supported by the compiler\n  AX_CHECK_COMPILE_FLAG([-fsanitize=address],\n  [\n    CFLAGS=\"${ASAN_CFLAGS} ${CFLAGS}\"\n    LDFLAGS=\"${ASAN_LDFLAGS} ${LDFLAGS}\"\n  ])\nfi\n\nif test \"$ac_msan\" = \"yes\"\nthen\n  # Add -fsanitize=memory to CFLAGS/LDFLAGS if supported by the compiler\n  AX_CHECK_COMPILE_FLAG([-fsanitize=memory],\n  [\n    CFLAGS=\"${MSAN_CFLAGS} ${CFLAGS}\"\n    LDFLAGS=\"${MSAN_CFLAGS} ${LDFLAGS}\"\n  ])\nfi\n\nif test \"$GCC\" = \"yes\"\nthen\n  if test \"$ac_warn_fail\" = \"yes\"\n  then\n    W_FAIL=\"-Werror\"\n  fi\n\n  CC_WARNINGS=\"-Wall -Wextra -Wpointer-arith -Wbad-function-cast \\\n-Wstrict-prototypes -Wnested-externs -Wno-format-zero-length \\\n-Wundef -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations \\\n-Wredundant-decls -Wcast-align -Wvla ${W_FAIL}\"\nfi\n\nif test \"$ax_cv_c_compiler_vendor\" = \"sun\"\nthen\n  CC_WARNINGS=\"-v -errtags=yes -errwarn=%all -erroff=E_INTEGER_OVERFLOW_DETECTED -erroff=E_STATEMENT_NOT_REACHED\"\nfi\n\nAM_CFLAGS=\"${CC_WARNINGS} ${AM_CFLAGS} ${PTHREAD_CFLAGS}\"\n\nAM_CPPFLAGS=\"${AM_CPPFLAGS} -I\\$(top_srcdir)/src ${LUAJIT_CFLAGS} ${CK_CFLAGS}\"\n\nAM_LDFLAGS=\"$PTHREAD_LIBS\"\n\nAC_SUBST(AM_CFLAGS)\nAC_SUBST(AM_CPPFLAGS)\nAC_SUBST(AM_LDFLAGS)\n\n# Define SB_GIT_SHA\ngit=$(which git)\nif test -n \"$git\"\nthen\n        SB_GIT_SHA=$(git rev-parse --short HEAD 2>/dev/null)\n        if test -n \"$SB_GIT_SHA\"\n        then\n          SB_GIT_SHA=\"-$SB_GIT_SHA\"\n        fi\nfi\nAC_DEFINE_UNQUOTED([SB_GIT_SHA], [\"$SB_GIT_SHA\"], [Git commit hash, if available.])\nAC_SUBST([SB_GIT_SHA])\n\nAC_CONFIG_FILES([\nMakefile\nthird_party/luajit/Makefile\nthird_party/concurrency_kit/Makefile\nsrc/Makefile\nsrc/drivers/Makefile\nsrc/drivers/mysql/Makefile\nsrc/drivers/pgsql/Makefile\nsrc/tests/Makefile\nsrc/tests/cpu/Makefile\nsrc/tests/fileio/Makefile\nsrc/tests/memory/Makefile\nsrc/tests/threads/Makefile\nsrc/tests/mutex/Makefile\nsrc/lua/Makefile\nsrc/lua/internal/Makefile\ntests/Makefile\ntests/include/config.sh\nsnap/snapcraft.yaml\n])\nAC_OUTPUT\n\nAC_MSG_RESULT([===============================================================================])\nAC_MSG_RESULT([sysbench version   : ${PACKAGE_VERSION}${SB_GIT_SHA}])\nAC_MSG_RESULT([CC                 : ${CC}])\nAC_MSG_RESULT([CFLAGS             : ${CFLAGS} ${AM_CFLAGS}])\nAC_MSG_RESULT([CPPFLAGS           : ${CPPFLAGS} ${AM_CPPFLAGS}])\nAC_MSG_RESULT([LDFLAGS            : ${LDFLAGS} ${AM_LDFLAGS}])\nAC_MSG_RESULT([LIBS               : ${LIBS}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([prefix             : $(eval echo ${prefix})])\nAC_MSG_RESULT([bindir             : $(eval echo ${bindir})])\nAC_MSG_RESULT([libexecdir         : $(eval echo ${libexecdir})])\nAC_MSG_RESULT([mandir             : $(eval echo ${mandir})])\nAC_MSG_RESULT([datadir            : $(eval echo ${datadir})])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([MySQL support      : ${mysql_support}])\nAC_MSG_RESULT([PostgreSQL support : ${pgsql_support}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([LuaJIT             : ${sb_use_luajit}])\nAC_MSG_RESULT([LUAJIT_CFLAGS      : ${LUAJIT_CFLAGS}])\nAC_MSG_RESULT([LUAJIT_LIBS        : ${LUAJIT_LIBS}])\nAC_MSG_RESULT([LUAJIT_LDFLAGS     : ${LUAJIT_LDFLAGS}])\nAC_MSG_RESULT([])\nAC_MSG_RESULT([Concurrency Kit    : ${sb_use_ck}])\nif test \"$sb_use_ck\" = bundled; then\n  AC_MSG_RESULT([CK_CFLAGS          : ${CK_CFLAGS}])\n  AC_MSG_RESULT([CK_LIBS            : ${CK_LIBS}])\n  AC_MSG_RESULT([configure flags    : ${CK_CONFIGURE_FLAGS}])\nfi\nAC_MSG_RESULT([===============================================================================])\n"
  },
  {
    "path": "debian/changelog",
    "content": "sysbench (1.0.21-1) unstable; urgency=low\n\n  * add libzstd-dev to build dependencies\n\n -- Alexey Kopytov <akopytov@gmail.com>  Sun, 24 Jan 2021 13:16:04 +0300\n\nsysbench (1.0.18-1) unstable; urgency=low\n\n  * add libssl-dev to build dependencies\n\n -- Alexey Kopytov <akopytov@gmail.com>  Sun, 08 Dec 2019 14:02:01 +0300\n\nsysbench (1.0.15-2) unstable; urgency=low\n\n  * add libaio-dev to build dependencies\n\n -- Alexey Kopytov <akopytov@gmail.com>  Sat, 09 Jul 2018 09:24:42 +0300\n\nsysbench (1.0.12-1) unstable; urgency=low\n\n  * remove vim-common from build dependencies\n\n -- Alexey Kopytov <akopytov@gmail.com>  Sat, 06 Jan 2018 10:59:42 +0300\n\nsysbench (1.0.11-1) unstable; urgency=low\n\n  * add Debian Stretch support by adding optional build dependency on\n    default-libmysqlclient-dev and replacing python-minimal with python\n    (as minimal does not provide the shlex module required by cram)\n\n -- Alexey Kopytov <akopytov@gmail.com>  Sat, 09 Dec 2017 19:52:23 +0300\n\nsysbench (1.0.6-1) unstable; urgency=low\n\n  * Add pkg-config, vim-common and python-minimal and libpq-dev to build dependencies.\n  * Fix 'clean' target in rules.\n  * Add ChangeLog and COPYING to docs.\n  * Remove tests/db/*.lua from install.\n  * Pass --without-gcc-arch to configure to not override compiler flags\n    passed by the build system\n\n -- Alexey Kopytov <akopytov@gmail.com>  Thu, 13 Apr 2017 23:04:34 +0300\n\nsysbench (1.0-1) unstable; urgency=low\n\n  * Initial release\n\n -- Alexey Kopytov <akopytov@gmail.com>  Wed, 10 Aug 2016 18:04:53 +0300\n\n"
  },
  {
    "path": "debian/compat",
    "content": "7\n"
  },
  {
    "path": "debian/control",
    "content": "Source: sysbench\nSection: misc\nPriority: extra\nMaintainer: Alexey Kopytov <akopytov@gmail.com>\nBuild-Depends: debhelper, autoconf, automake, libaio-dev, libtool, libmysqlclient-dev | default-libmysqlclient-dev, libpq-dev, pkg-config, python, libssl-dev, libzstd-dev\nStandards-Version: 3.9.5\nHomepage: https://github.com/akopytov/sysbench\n\nPackage: sysbench\nArchitecture: any\nDepends: ${shlibs:Depends}, ${misc:Depends}\nDescription: Scriptable database and system performance benchmark\n sysbench is a scriptable multi-threaded benchmark tool based on\n LuaJIT. It is most frequently used for database benchmarks, but can also\n be used to create arbitrarily complex workloads that do not involve a\n database server.\n .\n sysbench comes with the following bundled benchmarks:\n .\n - oltp_*.lua: a collection of OLTP-like database benchmarks\n - fileio: a filesystem-level benchmark\n - cpu: a simple CPU benchmark\n - memory: a memory access benchmark\n - threads: a thread-based scheduler benchmark\n - mutex: a POSIX mutex benchmark\n"
  },
  {
    "path": "debian/copyright",
    "content": "Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat\nUpstream-Name: sysbench\nUpstream-Maintainer: Alexey Kopytov <akopytov@gmail.com>\nUpstream-Source: https://github.com/akopytov/sysbench\n\nFiles: *\nCopyright: 2016 Alexey Kopytov\nLicense: GPL-2\n This package is free software; you can redistribute it and/or modify\n it under the terms of the GNU General Public License version 2 as\n published by the Free Software Foundation.\n .\n On Debian systems, the complete text of the GNU General\n Public License can be found in `/usr/share/common-licenses/GPL-2'.\n\n"
  },
  {
    "path": "debian/dirs",
    "content": "usr/bin\n"
  },
  {
    "path": "debian/docs",
    "content": "README.md\nChangeLog\nCOPYING\n"
  },
  {
    "path": "debian/install",
    "content": ""
  },
  {
    "path": "debian/rules",
    "content": "#!/usr/bin/make -f\n\n%:\n\tdh $@\n\noverride_dh_auto_configure:\n\tdh_testdir\n\tautoreconf -vif\n\tdh_auto_configure -- --with-mysql --with-pgsql --without-gcc-arch\n\noverride_dh_compress:\n\tdh_compress -X.lua\n"
  },
  {
    "path": "debian/source/format",
    "content": "3.0 (quilt)\n"
  },
  {
    "path": "install-sh",
    "content": "#!/bin/sh\n#\n# install - install a program, script, or datafile\n#\n# This originates from X11R5 (mit/util/scripts/install.sh), which was\n# later released in X11R6 (xc/config/util/install.sh) with the\n# following copyright and license.\n#\n# Copyright (C) 1994 X Consortium\n#\n# Permission is hereby granted, free of charge, to any person obtaining a copy\n# of this software and associated documentation files (the \"Software\"), to\n# deal in the Software without restriction, including without limitation the\n# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n# sell copies of the Software, and to permit persons to whom the Software is\n# furnished to do so, subject to the following conditions:\n#\n# The above copyright notice and this permission notice shall be included in\n# all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\n# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\n# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-\n# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n#\n# Except as contained in this notice, the name of the X Consortium shall not\n# be used in advertising or otherwise to promote the sale, use or other deal-\n# ings in this Software without prior written authorization from the X Consor-\n# tium.\n#\n#\n# FSF changes to this file are in the public domain.\n#\n# Calling this script install-sh is preferred over install.sh, to prevent\n# `make' implicit rules from creating a file called install from it\n# when there is no Makefile.\n#\n# This script is compatible with the BSD install script, but was written\n# from scratch.  It can only install one file at a time, a restriction\n# shared with many OS's install programs.\n\n\n# set DOITPROG to echo to test this script\n\n# Don't use :- since 4.3BSD and earlier shells don't like it.\ndoit=\"${DOITPROG-}\"\n\n\n# put in absolute paths if you don't have them in your path; or use env. vars.\n\nmvprog=\"${MVPROG-mv}\"\ncpprog=\"${CPPROG-cp}\"\nchmodprog=\"${CHMODPROG-chmod}\"\nchownprog=\"${CHOWNPROG-chown}\"\nchgrpprog=\"${CHGRPPROG-chgrp}\"\nstripprog=\"${STRIPPROG-strip}\"\nrmprog=\"${RMPROG-rm}\"\nmkdirprog=\"${MKDIRPROG-mkdir}\"\n\ntransformbasename=\"\"\ntransform_arg=\"\"\ninstcmd=\"$mvprog\"\nchmodcmd=\"$chmodprog 0755\"\nchowncmd=\"\"\nchgrpcmd=\"\"\nstripcmd=\"\"\nrmcmd=\"$rmprog -f\"\nmvcmd=\"$mvprog\"\nsrc=\"\"\ndst=\"\"\ndir_arg=\"\"\n\nwhile [ x\"$1\" != x ]; do\n    case $1 in\n\t-c) instcmd=$cpprog\n\t    shift\n\t    continue;;\n\n\t-d) dir_arg=true\n\t    shift\n\t    continue;;\n\n\t-m) chmodcmd=\"$chmodprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-o) chowncmd=\"$chownprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-g) chgrpcmd=\"$chgrpprog $2\"\n\t    shift\n\t    shift\n\t    continue;;\n\n\t-s) stripcmd=$stripprog\n\t    shift\n\t    continue;;\n\n\t-t=*) transformarg=`echo $1 | sed 's/-t=//'`\n\t    shift\n\t    continue;;\n\n\t-b=*) transformbasename=`echo $1 | sed 's/-b=//'`\n\t    shift\n\t    continue;;\n\n\t*)  if [ x\"$src\" = x ]\n\t    then\n\t\tsrc=$1\n\t    else\n\t\t# this colon is to work around a 386BSD /bin/sh bug\n\t\t:\n\t\tdst=$1\n\t    fi\n\t    shift\n\t    continue;;\n    esac\ndone\n\nif [ x\"$src\" = x ]\nthen\n\techo \"$0: no input file specified\" >&2\n\texit 1\nelse\n\t:\nfi\n\nif [ x\"$dir_arg\" != x ]; then\n\tdst=$src\n\tsrc=\"\"\n\n\tif [ -d \"$dst\" ]; then\n\t\tinstcmd=:\n\t\tchmodcmd=\"\"\n\telse\n\t\tinstcmd=$mkdirprog\n\tfi\nelse\n\n# Waiting for this to be detected by the \"$instcmd $src $dsttmp\" command\n# might cause directories to be created, which would be especially bad\n# if $src (and thus $dsttmp) contains '*'.\n\n\tif [ -f \"$src\" ] || [ -d \"$src\" ]\n\tthen\n\t\t:\n\telse\n\t\techo \"$0: $src does not exist\" >&2\n\t\texit 1\n\tfi\n\n\tif [ x\"$dst\" = x ]\n\tthen\n\t\techo \"$0: no destination specified\" >&2\n\t\texit 1\n\telse\n\t\t:\n\tfi\n\n# If destination is a directory, append the input filename; if your system\n# does not like double slashes in filenames, you may need to add some logic\n\n\tif [ -d \"$dst\" ]\n\tthen\n\t\tdst=$dst/`basename \"$src\"`\n\telse\n\t\t:\n\tfi\nfi\n\n## this sed command emulates the dirname command\ndstdir=`echo \"$dst\" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`\n\n# Make sure that the destination directory exists.\n#  this part is taken from Noah Friedman's mkinstalldirs script\n\n# Skip lots of stat calls in the usual case.\nif [ ! -d \"$dstdir\" ]; then\ndefaultIFS='\n\t'\nIFS=\"${IFS-$defaultIFS}\"\n\noIFS=$IFS\n# Some sh's can't handle IFS=/ for some reason.\nIFS='%'\nset - `echo \"$dstdir\" | sed -e 's@/@%@g' -e 's@^%@/@'`\nIFS=$oIFS\n\npathcomp=''\n\nwhile [ $# -ne 0 ] ; do\n\tpathcomp=$pathcomp$1\n\tshift\n\n\tif [ ! -d \"$pathcomp\" ] ;\n        then\n\t\t$mkdirprog \"$pathcomp\"\n\telse\n\t\t:\n\tfi\n\n\tpathcomp=$pathcomp/\ndone\nfi\n\nif [ x\"$dir_arg\" != x ]\nthen\n\t$doit $instcmd \"$dst\" &&\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd \"$dst\"; else : ; fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd \"$dst\"; else : ; fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd \"$dst\"; else : ; fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd \"$dst\"; else : ; fi\nelse\n\n# If we're going to rename the final executable, determine the name now.\n\n\tif [ x\"$transformarg\" = x ]\n\tthen\n\t\tdstfile=`basename \"$dst\"`\n\telse\n\t\tdstfile=`basename \"$dst\" $transformbasename |\n\t\t\tsed $transformarg`$transformbasename\n\tfi\n\n# don't allow the sed command to completely eliminate the filename\n\n\tif [ x\"$dstfile\" = x ]\n\tthen\n\t\tdstfile=`basename \"$dst\"`\n\telse\n\t\t:\n\tfi\n\n# Make a couple of temp file names in the proper directory.\n\n\tdsttmp=$dstdir/_inst.$$_\n\trmtmp=$dstdir/_rm.$$_\n\n# Trap to clean up temp files at exit.\n\n\ttrap 'status=$?; rm -f \"$dsttmp\" \"$rmtmp\" && exit $status' 0\n\ttrap '(exit $?); exit' 1 2 13 15\n\n# Move or copy the file name to the temp name\n\n\t$doit $instcmd \"$src\" \"$dsttmp\" &&\n\n# and set any options; do chmod last to preserve setuid bits\n\n# If any of these fail, we abort the whole thing.  If we want to\n# ignore errors from any of these, just make sure not to ignore\n# errors from the above \"$doit $instcmd $src $dsttmp\" command.\n\n\tif [ x\"$chowncmd\" != x ]; then $doit $chowncmd \"$dsttmp\"; else :;fi &&\n\tif [ x\"$chgrpcmd\" != x ]; then $doit $chgrpcmd \"$dsttmp\"; else :;fi &&\n\tif [ x\"$stripcmd\" != x ]; then $doit $stripcmd \"$dsttmp\"; else :;fi &&\n\tif [ x\"$chmodcmd\" != x ]; then $doit $chmodcmd \"$dsttmp\"; else :;fi &&\n\n# Now remove or move aside any old file at destination location.  We try this\n# two ways since rm can't unlink itself on some systems and the destination\n# file might be busy for other reasons.  In this case, the final cleanup\n# might fail but the new file should still install successfully.\n\n{\n\tif [ -f \"$dstdir/$dstfile\" ]\n\tthen\n\t\t$doit $rmcmd -f \"$dstdir/$dstfile\" 2>/dev/null ||\n\t\t$doit $mvcmd -f \"$dstdir/$dstfile\" \"$rmtmp\" 2>/dev/null ||\n\t\t{\n\t\t  echo \"$0: cannot unlink or rename $dstdir/$dstfile\" >&2\n\t\t  (exit 1); exit\n\t\t}\n\telse\n\t\t:\n\tfi\n} &&\n\n# Now rename the file to the real destination.\n\n\t$doit $mvcmd \"$dsttmp\" \"$dstdir/$dstfile\"\n\nfi &&\n\n# The final little trick to \"correctly\" pass the exit status to the exit trap.\n\n{\n\t(exit 0); exit\n}\n"
  },
  {
    "path": "m4/ac_check_aio.m4",
    "content": "dnl ---------------------------------------------------------------------------\ndnl Macro: AC_CHECK_AIO\ndnl Check for Linux AIO availability on the target system\ndnl Also, check the version of libaio library (at the moment, there are two\ndnl versions with incompatible interfaces).\ndnl ---------------------------------------------------------------------------\n\nAC_DEFUN([AC_CHECK_AIO],[\nif test x$enable_aio = xyes; then\n    AC_CHECK_HEADER([libaio.h], \n                    [AC_DEFINE(HAVE_LIBAIO_H,1,[Define to 1 if your system has <libaio.h> header file])],\n                    [enable_aio=no])\nfi\nif test x$enable_aio = xyes; then \n    AC_CHECK_LIB([aio], [io_queue_init], , [enable_aio=no])\nfi\nif test x$enable_aio = xyes; then\n    AC_MSG_CHECKING(if io_getevents() has an old interface)\n    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n                       [[\n#ifdef HAVE_LIBAIO_H\n# include <libaio.h>\n#endif\nstruct io_event event; \nio_context_t ctxt;\n                       ]],\n                       [[\n(void)io_getevents(ctxt, 1, &event, NULL);\n                       ]] )\n    ], [\n        AC_DEFINE([HAVE_OLD_GETEVENTS], 1, [Define to 1 if libaio has older getevents() interface])\n        AC_MSG_RESULT(yes)\n       ],\n    [AC_MSG_RESULT(no)]\n    )\nfi\n])\n\n"
  },
  {
    "path": "m4/ac_check_pgsql.m4",
    "content": "dnl ---------------------------------------------------------------------------\ndnl Macro: AC_CHECK_PGSQL\ndnl First check for custom PostgreSQL paths in --with-pgsql-* options.\ndnl If some paths are missing,  check if pg_config exists. \ndnl ---------------------------------------------------------------------------\n\nAC_DEFUN([AC_CHECK_PGSQL],[\n\n# Check for custom includes path\nif test [ -z \"$ac_cv_pgsql_includes\" ] \nthen \n    AC_ARG_WITH([pgsql-includes], \n                AS_HELP_STRING([--with-pgsql-includes], [path to PostgreSQL header files]),\n                [ac_cv_pgsql_includes=$withval])\nfi\nif test [ -n \"$ac_cv_pgsql_includes\" ]\nthen\n    AC_CACHE_CHECK([PostgreSQL includes], [ac_cv_pgsql_includes], [ac_cv_pgsql_includes=\"\"])\n    PGSQL_CFLAGS=\"-I$ac_cv_pgsql_includes\"\nfi\n\n# Check for custom library path\n\nif test [ -z \"$ac_cv_pgsql_libs\" ]\nthen\n    AC_ARG_WITH([pgsql-libs], \n                AS_HELP_STRING([--with-pgsql-libs], [path to PostgreSQL libraries]),\n                [ac_cv_pgsql_libs=$withval])\nfi\n\nif test [ -n \"$ac_cv_pgsql_libs\" ]\nthen\n     AC_CACHE_CHECK([PostgreSQL libraries], [ac_cv_pgsql_libs], [ac_cv_pgsql_libs=\"\"])\n     PGSQL_LIBS=\"-L$ac_cv_pgsql_libs -lpq\"\nfi\n\n# If some path is missing, try to autodetermine with pgsql_config\nif test [ -z \"$ac_cv_pgsql_includes\" -o -z \"$ac_cv_pgsql_libs\" ]\nthen\n    if test [ -z \"$pgconfig\" ]\n    then \n        AC_PATH_PROG(pgconfig,pg_config)\n    fi\n    if test [ -z \"$pgconfig\" ]\n    then\n        AC_MSG_ERROR([pg_config executable not found\n********************************************************************************\nERROR: cannot find PostgreSQL libraries. If you want to compile with PosgregSQL support,\n       you must either specify file locations explicitly using \n       --with-pgsql-includes and --with-pgsql-libs options, or make sure path to \n       pg_config is listed in your PATH environment variable. If you want to \n       disable PostgreSQL support, use --without-pgsql option.\n********************************************************************************\n])\n    else\n        if test [ -z \"$ac_cv_pgsql_includes\" ]\n        then\n            AC_MSG_CHECKING(PostgreSQL C flags)\n            PGSQL_CFLAGS=\"-I`${pgconfig} --includedir`\"\n            AC_MSG_RESULT($PGSQL_CFLAGS)\n        fi\n        if test [ -z \"$ac_cv_pgsql_libs\" ]\n        then\n            AC_MSG_CHECKING(PostgreSQL linker flags)\n            PGSQL_LIBS=\"-L`${pgconfig} --libdir` -lpq\"\n            AC_MSG_RESULT($PGSQL_LIBS)\n        fi\n    fi\nfi\n])\n\n"
  },
  {
    "path": "m4/acx_pthread.m4",
    "content": "##### http://autoconf-archive.cryp.to/acx_pthread.html\n#\n# SYNOPSIS\n#\n#   ACX_PTHREAD([ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]])\n#\n# DESCRIPTION\n#\n#   This macro figures out how to build C programs using POSIX threads.\n#   It sets the PTHREAD_LIBS output variable to the threads library and\n#   linker flags, and the PTHREAD_CFLAGS output variable to any special\n#   C compiler flags that are needed. (The user can also force certain\n#   compiler flags/libs to be tested by setting these environment\n#   variables.)\n#\n#   Also sets PTHREAD_CC to any special C compiler that is needed for\n#   multi-threaded programs (defaults to the value of CC otherwise).\n#   (This is necessary on AIX to use the special cc_r compiler alias.)\n#\n#   NOTE: You are assumed to not only compile your program with these\n#   flags, but also link it with them as well. e.g. you should link\n#   with $PTHREAD_CC $CFLAGS $PTHREAD_CFLAGS $LDFLAGS ... $PTHREAD_LIBS\n#   $LIBS\n#\n#   If you are only building threads programs, you may wish to use\n#   these variables in your default LIBS, CFLAGS, and CC:\n#\n#          LIBS=\"$PTHREAD_LIBS $LIBS\"\n#          CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n#          CC=\"$PTHREAD_CC\"\n#\n#   In addition, if the PTHREAD_CREATE_JOINABLE thread-attribute\n#   constant has a nonstandard name, defines PTHREAD_CREATE_JOINABLE to\n#   that name (e.g. PTHREAD_CREATE_UNDETACHED on AIX).\n#\n#   ACTION-IF-FOUND is a list of shell commands to run if a threads\n#   library is found, and ACTION-IF-NOT-FOUND is a list of commands to\n#   run it if it is not found. If ACTION-IF-FOUND is not specified, the\n#   default action will define HAVE_PTHREAD.\n#\n#   Please let the authors know if this macro fails on any platform, or\n#   if you have any other suggestions or comments. This macro was based\n#   on work by SGJ on autoconf scripts for FFTW (http://www.fftw.org/)\n#   (with help from M. Frigo), as well as ac_pthread and hb_pthread\n#   macros posted by Alejandro Forero Cuervo to the autoconf macro\n#   repository. We are also grateful for the helpful feedback of\n#   numerous users.\n#\n# LAST MODIFICATION\n#\n#   2006-05-29\n#\n# COPYLEFT\n#\n#   Copyright (c) 2006 Steven G. Johnson <stevenj@alum.mit.edu>\n#\n#   This program is free software; you can redistribute it and/or\n#   modify it under the terms of the GNU General Public License as\n#   published by the Free Software Foundation; either version 2 of the\n#   License, or (at your option) any later version.\n#\n#   This program is distributed in the hope that it will be useful, but\n#   WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n#   General Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License\n#   along with this program; if not, write to the Free Software\n#   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n#   02111-1307, USA.\n#\n#   As a special exception, the respective Autoconf Macro's copyright\n#   owner gives unlimited permission to copy, distribute and modify the\n#   configure scripts that are the output of Autoconf when processing\n#   the Macro. You need not follow the terms of the GNU General Public\n#   License when using or distributing such scripts, even though\n#   portions of the text of the Macro appear in them. The GNU General\n#   Public License (GPL) does govern all other use of the material that\n#   constitutes the Autoconf Macro.\n#\n#   This special exception to the GPL applies to versions of the\n#   Autoconf Macro released by the Autoconf Macro Archive. When you\n#   make and distribute a modified version of the Autoconf Macro, you\n#   may extend this special exception to the GPL to apply to your\n#   modified version as well.\n\nAC_DEFUN([ACX_PTHREAD], [\nAC_REQUIRE([AC_CANONICAL_HOST])\nAC_LANG_PUSH([C])\nacx_pthread_ok=no\n\n# We used to check for pthread.h first, but this fails if pthread.h\n# requires special compiler flags (e.g. on True64 or Sequent).\n# It gets checked for in the link test anyway.\n\n# First of all, check if the user has set any of the PTHREAD_LIBS,\n# etcetera environment variables, and if threads linking works using\n# them:\nif test x\"$PTHREAD_LIBS$PTHREAD_CFLAGS\" != x; then\n        save_CFLAGS=\"$CFLAGS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n        save_LIBS=\"$LIBS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])\n        AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)\n        AC_MSG_RESULT($acx_pthread_ok)\n        if test x\"$acx_pthread_ok\" = xno; then\n                PTHREAD_LIBS=\"\"\n                PTHREAD_CFLAGS=\"\"\n        fi\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\nfi\n\n# We must check for the threads library under a number of different\n# names; the ordering is very important because some systems\n# (e.g. DEC) have both -lpthread and -lpthreads, where one of the\n# libraries is broken (non-POSIX).\n\n# Create a list of thread flags to try.  Items starting with a \"-\" are\n# C compiler flags, and other items are library names, except for \"none\"\n# which indicates that we try without any flags at all, and \"pthread-config\"\n# which is a program returning the flags for the Pth emulation library.\n\nacx_pthread_flags=\"pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config\"\n\n# The ordering *is* (sometimes) important.  Some notes on the\n# individual items follow:\n\n# pthreads: AIX (must check this before -lpthread)\n# none: in case threads are in libc; should be tried before -Kthread and\n#       other compiler flags to prevent continual compiler warnings\n# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)\n# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)\n# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)\n# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)\n# -pthreads: Solaris/gcc\n# -mthreads: Mingw32/gcc, Lynx/gcc\n# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it\n#      doesn't hurt to check since this sometimes defines pthreads too;\n#      also defines -D_REENTRANT)\n#      ... -mt is also the pthreads flag for HP/aCC\n# pthread: Linux, etcetera\n# --thread-safe: KAI C++\n# pthread-config: use pthread-config program (for GNU Pth library)\n\ncase \"${host_cpu}-${host_os}\" in\n        *solaris*)\n\n        # On Solaris (at least, for some versions), libc contains stubbed\n        # (non-functional) versions of the pthreads routines, so link-based\n        # tests will erroneously succeed.  (We need to link with -pthreads/-mt/\n        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather\n        # a function called by this macro, so we could check for that, but\n        # who knows whether they'll stub that too in a future libc.)  So,\n        # we'll just look for -pthreads and -lpthread first:\n\n        acx_pthread_flags=\"-pthreads pthread -mt -pthread $acx_pthread_flags\"\n        ;;\nesac\n\nif test x\"$acx_pthread_ok\" = xno; then\nfor flag in $acx_pthread_flags; do\n\n        case $flag in\n                none)\n                AC_MSG_CHECKING([whether pthreads work without any flags])\n                ;;\n\n                -*)\n                AC_MSG_CHECKING([whether pthreads work with $flag])\n                PTHREAD_CFLAGS=\"$flag\"\n                ;;\n\n\t\tpthread-config)\n\t\tAC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)\n\t\tif test x\"$acx_pthread_config\" = xno; then continue; fi\n\t\tPTHREAD_CFLAGS=\"`pthread-config --cflags`\"\n\t\tPTHREAD_LIBS=\"`pthread-config --ldflags` `pthread-config --libs`\"\n\t\t;;\n\n                *)\n                AC_MSG_CHECKING([for the pthreads library -l$flag])\n                PTHREAD_LIBS=\"-l$flag\"\n                ;;\n        esac\n\n        save_LIBS=\"$LIBS\"\n        save_CFLAGS=\"$CFLAGS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n\n        # Check for various functions.  We must include pthread.h,\n        # since some functions may be macros.  (On the Sequent, we\n        # need a special flag -Kthread to make this header compile.)\n        # We check for pthread_join because it is in -lpthread on IRIX\n        # while pthread_create is in libc.  We check for pthread_attr_init\n        # due to DEC craziness with -lpthreads.  We check for\n        # pthread_cleanup_push because it is one of the few pthread\n        # functions on Solaris that doesn't have a non-functional libc stub.\n        # We try pthread_create on general principles.\n        AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[pthread_t th; pthread_join(th, 0);\n                     pthread_attr_init(0); pthread_cleanup_push(0, 0);\n                     pthread_create(0,0,0,0); pthread_cleanup_pop(0); ]])],[acx_pthread_ok=yes],[])\n\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\n\n        AC_MSG_RESULT($acx_pthread_ok)\n        if test \"x$acx_pthread_ok\" = xyes; then\n                break;\n        fi\n\n        PTHREAD_LIBS=\"\"\n        PTHREAD_CFLAGS=\"\"\ndone\nfi\n\n# Various other checks:\nif test \"x$acx_pthread_ok\" = xyes; then\n        save_LIBS=\"$LIBS\"\n        LIBS=\"$PTHREAD_LIBS $LIBS\"\n        save_CFLAGS=\"$CFLAGS\"\n        CFLAGS=\"$CFLAGS $PTHREAD_CFLAGS\"\n\n        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.\n\tAC_MSG_CHECKING([for joinable pthread attribute])\n\tattr_name=unknown\n\tfor attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do\n\t    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <pthread.h>]], [[int attr=$attr; return attr;]])],[attr_name=$attr; break],[])\n\tdone\n        AC_MSG_RESULT($attr_name)\n        if test \"$attr_name\" != PTHREAD_CREATE_JOINABLE; then\n            AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,\n                               [Define to necessary symbol if this constant\n                                uses a non-standard name on your system.])\n        fi\n\n        AC_MSG_CHECKING([if more special flags are required for pthreads])\n        flag=no\n        case \"${host_cpu}-${host_os}\" in\n            *-aix* | *-freebsd* | *-darwin*) flag=\"-D_THREAD_SAFE\";;\n            *solaris* | *-osf* | *-hpux*) flag=\"-D_REENTRANT\";;\n        esac\n        AC_MSG_RESULT(${flag})\n        if test \"x$flag\" != xno; then\n            PTHREAD_CFLAGS=\"$flag $PTHREAD_CFLAGS\"\n        fi\n\n        LIBS=\"$save_LIBS\"\n        CFLAGS=\"$save_CFLAGS\"\n\n        # More AIX lossage: must compile with xlc_r or cc_r\n\tif test x\"$GCC\" != xyes; then\n          AC_CHECK_PROGS(PTHREAD_CC, xlc_r cc_r, ${CC})\n        else\n          PTHREAD_CC=$CC\n\tfi\nelse\n        PTHREAD_CC=\"$CC\"\nfi\n\nAC_SUBST(PTHREAD_LIBS)\nAC_SUBST(PTHREAD_CFLAGS)\nAC_SUBST(PTHREAD_CC)\n\n# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:\nif test x\"$acx_pthread_ok\" = xyes; then\n        ifelse([$1],,AC_DEFINE(HAVE_PTHREAD,1,[Define if you have POSIX threads libraries and header files.]),[$1])\n        :\nelse\n        acx_pthread_ok=no\n        $2\nfi\nAC_LANG_POP([])\n])dnl ACX_PTHREAD\n"
  },
  {
    "path": "m4/ax_check_compile_flag.m4",
    "content": "# ===========================================================================\n#  https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT])\n#\n# DESCRIPTION\n#\n#   Check whether the given FLAG works with the current language's compiler\n#   or gives an error.  (Warnings, however, are ignored)\n#\n#   ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on\n#   success/failure.\n#\n#   If EXTRA-FLAGS is defined, it is added to the current language's default\n#   flags (e.g. CFLAGS) when the check is done.  The check is thus made with\n#   the flags: \"CFLAGS EXTRA-FLAGS FLAG\".  This can for example be used to\n#   force the compiler to issue an error when a bad flag is given.\n#\n#   INPUT gives an alternative input source to AC_COMPILE_IFELSE.\n#\n#   NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this\n#   macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG.\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Guido U. Draheim <guidod@gmx.de>\n#   Copyright (c) 2011 Maarten Bosmans <mkbosmans@gmail.com>\n#\n#   This program is free software: you can redistribute it and/or modify it\n#   under the terms of the GNU General Public License as published by the\n#   Free Software Foundation, either version 3 of the License, or (at your\n#   option) any later version.\n#\n#   This program is distributed in the hope that it will be useful, but\n#   WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\n#   Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License along\n#   with this program. If not, see <https://www.gnu.org/licenses/>.\n#\n#   As a special exception, the respective Autoconf Macro's copyright owner\n#   gives unlimited permission to copy, distribute and modify the configure\n#   scripts that are the output of Autoconf when processing the Macro. You\n#   need not follow the terms of the GNU General Public License when using\n#   or distributing such scripts, even though portions of the text of the\n#   Macro appear in them. The GNU General Public License (GPL) does govern\n#   all other use of the material that constitutes the Autoconf Macro.\n#\n#   This special exception to the GPL applies to versions of the Autoconf\n#   Macro released by the Autoconf Archive. When you make and distribute a\n#   modified version of the Autoconf Macro, you may extend this special\n#   exception to the GPL to apply to your modified version as well.\n\n#serial 5\n\nAC_DEFUN([AX_CHECK_COMPILE_FLAG],\n[\nAS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl\nAC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [\n  ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS\n  _AC_LANG_PREFIX[]FLAGS=\"$[]_AC_LANG_PREFIX[]FLAGS $4 $1\"\n  AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])],\n    [AS_VAR_SET(CACHEVAR,[yes])],\n    [AS_VAR_SET(CACHEVAR,[no])])\n  _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags])\nAS_VAR_IF(CACHEVAR,yes,\n  [m4_default([$2], :)],\n  [m4_default([$3], :)])\nAS_VAR_POPDEF([CACHEVAR])dnl\n])dnl AX_CHECK_COMPILE_FLAGS\n"
  },
  {
    "path": "m4/ax_compiler_vendor.m4",
    "content": "# ===========================================================================\n#    https://www.gnu.org/software/autoconf-archive/ax_compiler_vendor.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_COMPILER_VENDOR\n#\n# DESCRIPTION\n#\n#   Determine the vendor of the C/C++ compiler, e.g., gnu, intel, ibm, sun,\n#   hp, borland, comeau, dec, cray, kai, lcc, metrowerks, sgi, microsoft,\n#   watcom, etc. The vendor is returned in the cache variable\n#   $ax_cv_c_compiler_vendor for C and $ax_cv_cxx_compiler_vendor for C++.\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>\n#   Copyright (c) 2008 Matteo Frigo\n#\n#   This program is free software: you can redistribute it and/or modify it\n#   under the terms of the GNU General Public License as published by the\n#   Free Software Foundation, either version 3 of the License, or (at your\n#   option) any later version.\n#\n#   This program is distributed in the hope that it will be useful, but\n#   WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\n#   Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License along\n#   with this program. If not, see <https://www.gnu.org/licenses/>.\n#\n#   As a special exception, the respective Autoconf Macro's copyright owner\n#   gives unlimited permission to copy, distribute and modify the configure\n#   scripts that are the output of Autoconf when processing the Macro. You\n#   need not follow the terms of the GNU General Public License when using\n#   or distributing such scripts, even though portions of the text of the\n#   Macro appear in them. The GNU General Public License (GPL) does govern\n#   all other use of the material that constitutes the Autoconf Macro.\n#\n#   This special exception to the GPL applies to versions of the Autoconf\n#   Macro released by the Autoconf Archive. When you make and distribute a\n#   modified version of the Autoconf Macro, you may extend this special\n#   exception to the GPL to apply to your modified version as well.\n\n#serial 16\n\nAC_DEFUN([AX_COMPILER_VENDOR],\n[AC_CACHE_CHECK([for _AC_LANG compiler vendor], ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor,\n  dnl Please add if possible support to ax_compiler_version.m4\n  [# note: don't check for gcc first since some other compilers define __GNUC__\n  vendors=\"intel:     __ICC,__ECC,__INTEL_COMPILER\n           ibm:       __xlc__,__xlC__,__IBMC__,__IBMCPP__\n           pathscale: __PATHCC__,__PATHSCALE__\n           clang:     __clang__\n           cray:      _CRAYC\n           fujitsu:   __FUJITSU\n           gnu:       __GNUC__\n           sun:       __SUNPRO_C,__SUNPRO_CC\n           hp:        __HP_cc,__HP_aCC\n           dec:       __DECC,__DECCXX,__DECC_VER,__DECCXX_VER\n           borland:   __BORLANDC__,__CODEGEARC__,__TURBOC__\n           comeau:    __COMO__\n           kai:       __KCC\n           lcc:       __LCC__\n           sgi:       __sgi,sgi\n           microsoft: _MSC_VER\n           metrowerks: __MWERKS__\n           watcom:    __WATCOMC__\n           portland:  __PGI\n\t   tcc:       __TINYC__\n           unknown:   UNKNOWN\"\n  for ventest in $vendors; do\n    case $ventest in\n      *:) vendor=$ventest; continue ;;\n      *)  vencpp=\"defined(\"`echo $ventest | sed 's/,/) || defined(/g'`\")\" ;;\n    esac\n    AC_COMPILE_IFELSE([AC_LANG_PROGRAM(,[\n      #if !($vencpp)\n        thisisanerror;\n      #endif\n    ])], [break])\n  done\n  ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor=`echo $vendor | cut -d: -f1`\n ])\n])\n"
  },
  {
    "path": "m4/ax_gcc_archflag.m4",
    "content": "# ===========================================================================\n#     https://www.gnu.org/software/autoconf-archive/ax_gcc_archflag.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_GCC_ARCHFLAG([PORTABLE?], [ACTION-SUCCESS], [ACTION-FAILURE])\n#\n# DESCRIPTION\n#\n#   This macro tries to guess the \"native\" arch corresponding to the target\n#   architecture for use with gcc's -march=arch or -mtune=arch flags. If\n#   found, the cache variable $ax_cv_gcc_archflag is set to this flag and\n#   ACTION-SUCCESS is executed; otherwise $ax_cv_gcc_archflag is set to\n#   \"unknown\" and ACTION-FAILURE is executed. The default ACTION-SUCCESS is\n#   to add $ax_cv_gcc_archflag to the end of $CFLAGS.\n#\n#   PORTABLE? should be either [yes] (default) or [no]. In the former case,\n#   the flag is set to -mtune (or equivalent) so that the architecture is\n#   only used for tuning, but the instruction set used is still portable. In\n#   the latter case, the flag is set to -march (or equivalent) so that\n#   architecture-specific instructions are enabled.\n#\n#   The user can specify --with-gcc-arch=<arch> in order to override the\n#   macro's choice of architecture, or --without-gcc-arch to disable this.\n#\n#   When cross-compiling, or if $CC is not gcc, then ACTION-FAILURE is\n#   called unless the user specified --with-gcc-arch manually.\n#\n#   Requires macros: AX_CHECK_COMPILE_FLAG, AX_GCC_X86_CPUID\n#\n#   (The main emphasis here is on recent CPUs, on the principle that doing\n#   high-performance computing on old hardware is uncommon.)\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>\n#   Copyright (c) 2008 Matteo Frigo\n#   Copyright (c) 2014 Tsukasa Oi\n#   Copyright (c) 2017-2018 Alexey Kopytov\n#\n#   This program is free software: you can redistribute it and/or modify it\n#   under the terms of the GNU General Public License as published by the\n#   Free Software Foundation, either version 3 of the License, or (at your\n#   option) any later version.\n#\n#   This program is distributed in the hope that it will be useful, but\n#   WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\n#   Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License along\n#   with this program. If not, see <https://www.gnu.org/licenses/>.\n#\n#   As a special exception, the respective Autoconf Macro's copyright owner\n#   gives unlimited permission to copy, distribute and modify the configure\n#   scripts that are the output of Autoconf when processing the Macro. You\n#   need not follow the terms of the GNU General Public License when using\n#   or distributing such scripts, even though portions of the text of the\n#   Macro appear in them. The GNU General Public License (GPL) does govern\n#   all other use of the material that constitutes the Autoconf Macro.\n#\n#   This special exception to the GPL applies to versions of the Autoconf\n#   Macro released by the Autoconf Archive. When you make and distribute a\n#   modified version of the Autoconf Macro, you may extend this special\n#   exception to the GPL to apply to your modified version as well.\n\n#serial 21\n\nAC_DEFUN([AX_GCC_ARCHFLAG],\n[AC_REQUIRE([AC_PROG_CC])\nAC_REQUIRE([AC_CANONICAL_HOST])\nAC_REQUIRE([AC_PROG_SED])\nAC_REQUIRE([AX_COMPILER_VENDOR])\n\nAC_ARG_WITH(gcc-arch, [AS_HELP_STRING([--with-gcc-arch=<arch>], [use architecture <arch> for gcc -march/-mtune, instead of guessing])],\n\tax_gcc_arch=$withval, ax_gcc_arch=yes)\n\nAC_MSG_CHECKING([for gcc architecture flag])\nAC_MSG_RESULT([])\nAC_CACHE_VAL(ax_cv_gcc_archflag,\n[\nax_cv_gcc_archflag=\"unknown\"\n\nif test \"$GCC\" = yes; then\n\nif test \"x$ax_gcc_arch\" = xyes; then\nax_gcc_arch=\"\"\nif test \"$cross_compiling\" = no; then\ncase $host_cpu in\n  i[[3456]]86*|x86_64*|amd64*) # use cpuid codes\n     AX_GCC_X86_CPUID(0)\n     AX_GCC_X86_CPUID(1)\n     case $ax_cv_gcc_x86_cpuid_0 in\n       *:756e6547:6c65746e:49656e69) # Intel\n          case $ax_cv_gcc_x86_cpuid_1 in\n\t    *5[[4578]]?:*:*:*) ax_gcc_arch=\"pentium-mmx pentium\" ;;\n\t    *5[[123]]?:*:*:*) ax_gcc_arch=pentium ;;\n\t    *0?61?:*:*:*|?61?:*:*:*|61?:*:*:*) ax_gcc_arch=pentiumpro ;;\n\t    *0?6[[356]]?:*:*:*|?6[[356]]?:*:*:*|6[[356]]?:*:*:*) ax_gcc_arch=\"pentium2 pentiumpro\" ;;\n\t    *0?6[[78ab]]?:*:*:*|?6[[78ab]]?:*:*:*|6[[78ab]]?:*:*:*) ax_gcc_arch=\"pentium3 pentiumpro\" ;;\n\t    *0?6[[9d]]?:*:*:*|?6[[9d]]?:*:*:*|6[[9d]]?:*:*:*|*1?65?:*:*:*) ax_gcc_arch=\"pentium-m pentium3 pentiumpro\" ;;\n\t    *0?6e?:*:*:*|?6e?:*:*:*|6e?:*:*:*) ax_gcc_arch=\"yonah pentium-m pentium3 pentiumpro\" ;;\n\t    *0?6f?:*:*:*|?6f?:*:*:*|6f?:*:*:*|*1?66?:*:*:*) ax_gcc_arch=\"core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *1?6[[7d]]?:*:*:*) ax_gcc_arch=\"penryn core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *1?6[[aef]]?:*:*:*|*2?6e?:*:*:*) ax_gcc_arch=\"nehalem corei7 core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *2?6[[5cf]]?:*:*:*) ax_gcc_arch=\"westmere corei7 core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *2?6[[ad]]?:*:*:*) ax_gcc_arch=\"sandybridge corei7-avx corei7 core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *3?6[[ae]]?:*:*:*) ax_gcc_arch=\"ivybridge core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *3?6[[cf]]?:*:*:*|*4?6[[56]]?:*:*:*) ax_gcc_arch=\"haswell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *3?6d?:*:*:*|*4?6[[7f]]?:*:*:*|*5?66?:*:*:*) ax_gcc_arch=\"broadwell core-avx2 core-avx-i corei7-avx corei7 core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *1?6c?:*:*:*|*2?6[[67]]?:*:*:*|*3?6[[56]]?:*:*:*) ax_gcc_arch=\"bonnell atom core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *3?67?:*:*:*|*[[45]]?6[[ad]]?:*:*:*) ax_gcc_arch=\"silvermont atom core2 pentium-m pentium3 pentiumpro\" ;;\n\t    *000?f[[012]]?:*:*:*|?f[[012]]?:*:*:*|f[[012]]?:*:*:*) ax_gcc_arch=\"pentium4 pentiumpro\" ;;\n\t    *000?f[[346]]?:*:*:*|?f[[346]]?:*:*:*|f[[346]]?:*:*:*) ax_gcc_arch=\"nocona prescott pentium4 pentiumpro\" ;;\n\t    # fallback\n\t    *5??:*:*:*) ax_gcc_arch=pentium ;;\n\t    *??6??:*:*:*) ax_gcc_arch=\"core2 pentiumpro\" ;;\n\t    *6??:*:*:*) ax_gcc_arch=pentiumpro ;;\n\t    *00??f??:*:*:*|??f??:*:*:*|?f??:*:*:*|f??:*:*:*) ax_gcc_arch=\"pentium4 pentiumpro\" ;;\n          esac ;;\n       *:68747541:444d4163:69746e65) # AMD\n          case $ax_cv_gcc_x86_cpuid_1 in\n\t    *5[[67]]?:*:*:*) ax_gcc_arch=k6 ;;\n\t    *5[[8]]?:*:*:*) ax_gcc_arch=\"k6-2 k6\" ;;\n\t    *5[[9d]]?:*:*:*) ax_gcc_arch=\"k6-3 k6\" ;;\n\t    *6[[12]]?:*:*:*) ax_gcc_arch=\"athlon k7\" ;;\n\t    *6[[34]]?:*:*:*) ax_gcc_arch=\"athlon-tbird k7\" ;;\n\t    *6[[678a]]?:*:*:*) ax_gcc_arch=\"athlon-xp athlon-4 athlon k7\" ;;\n\t    *000?f[[4578bcef]]?:*:*:*|?f[[4578bcef]]?:*:*:*|f[[4578bcef]]?:*:*:*|*001?f[[4578bcf]]?:*:*:*|1?f[[4578bcf]]?:*:*:*) ax_gcc_arch=\"athlon64 k8\" ;;\n\t    *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\" ;;\n\t    *010?f[[245689a]]?:*:*:*|10?f[[245689a]]?:*:*:*|*030?f1?:*:*:*|30?f1?:*:*:*) ax_gcc_arch=\"barcelona amdfam10 k8\" ;;\n\t    *050?f[[12]]?:*:*:*|50?f[[12]]?:*:*:*) ax_gcc_arch=\"btver1 amdfam10 k8\" ;;\n\t    *060?f1?:*:*:*|60?f1?:*:*:*) ax_gcc_arch=\"bdver1 amdfam10 k8\" ;;\n\t    *060?f2?:*:*:*|60?f2?:*:*:*|*061?f[[03]]?:*:*:*|61?f[[03]]?:*:*:*) ax_gcc_arch=\"bdver2 bdver1 amdfam10 k8\" ;;\n\t    *063?f0?:*:*:*|63?f0?:*:*:*) ax_gcc_arch=\"bdver3 bdver2 bdver1 amdfam10 k8\" ;;\n\t    *07[[03]]?f0?:*:*:*|7[[03]]?f0?:*:*:*) ax_gcc_arch=\"btver2 btver1 amdfam10 k8\" ;;\n\t    # fallback\n\t    *0[[13]]??f??:*:*:*|[[13]]??f??:*:*:*) ax_gcc_arch=\"barcelona amdfam10 k8\" ;;\n\t    *020?f??:*:*:*|20?f??:*:*:*) ax_gcc_arch=\"athlon64-sse3 k8-sse3 athlon64 k8\" ;;\n\t    *05??f??:*:*:*|5??f??:*:*:*) ax_gcc_arch=\"btver1 amdfam10 k8\" ;;\n\t    *060?f??:*:*:*|60?f??:*:*:*) ax_gcc_arch=\"bdver1 amdfam10 k8\" ;;\n\t    *061?f??:*:*:*|61?f??:*:*:*) ax_gcc_arch=\"bdver2 bdver1 amdfam10 k8\" ;;\n\t    *06??f??:*:*:*|6??f??:*:*:*) ax_gcc_arch=\"bdver3 bdver2 bdver1 amdfam10 k8\" ;;\n\t    *070?f??:*:*:*|70?f??:*:*:*) ax_gcc_arch=\"btver2 btver1 amdfam10 k8\" ;;\n\t    *???f??:*:*:*) ax_gcc_arch=\"amdfam10 k8\" ;;\n          esac ;;\n\t*:746e6543:736c7561:48727561) # IDT / VIA (Centaur)\n\t   case $ax_cv_gcc_x86_cpuid_1 in\n\t     *54?:*:*:*) ax_gcc_arch=winchip-c6 ;;\n\t     *5[[89]]?:*:*:*) ax_gcc_arch=winchip2 ;;\n\t     *66?:*:*:*) ax_gcc_arch=winchip2 ;;\n\t     *6[[78]]?:*:*:*) ax_gcc_arch=c3 ;;\n\t     *6[[9adf]]?:*:*:*) ax_gcc_arch=\"c3-2 c3\" ;;\n\t   esac ;;\n     esac\n     if test x\"$ax_gcc_arch\" = x; then # fallback\n\tcase $host_cpu in\n\t  i586*) ax_gcc_arch=pentium ;;\n\t  i686*) ax_gcc_arch=pentiumpro ;;\n        esac\n     fi\n     ;;\n\n  sparc*)\n     AC_PATH_PROG([PRTDIAG], [prtdiag], [prtdiag], [$PATH:/usr/platform/`uname -i`/sbin/:/usr/platform/`uname -m`/sbin/])\n     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`\n     cputype=`echo \"$cputype\" | tr -d ' -' | $SED 's/SPARCIIi/SPARCII/' |tr $as_cr_LETTERS $as_cr_letters`\n     case $cputype in\n         *ultrasparciv*) ax_gcc_arch=\"ultrasparc4 ultrasparc3 ultrasparc v9\" ;;\n         *ultrasparciii*) ax_gcc_arch=\"ultrasparc3 ultrasparc v9\" ;;\n         *ultrasparc*) ax_gcc_arch=\"ultrasparc v9\" ;;\n         *supersparc*|*tms390z5[[05]]*) ax_gcc_arch=\"supersparc v8\" ;;\n         *hypersparc*|*rt62[[056]]*) ax_gcc_arch=\"hypersparc v8\" ;;\n         *cypress*) ax_gcc_arch=cypress ;;\n     esac ;;\n\n  alphaev5) ax_gcc_arch=ev5 ;;\n  alphaev56) ax_gcc_arch=ev56 ;;\n  alphapca56) ax_gcc_arch=\"pca56 ev56\" ;;\n  alphapca57) ax_gcc_arch=\"pca57 pca56 ev56\" ;;\n  alphaev6) ax_gcc_arch=ev6 ;;\n  alphaev67) ax_gcc_arch=ev67 ;;\n  alphaev68) ax_gcc_arch=\"ev68 ev67\" ;;\n  alphaev69) ax_gcc_arch=\"ev69 ev68 ev67\" ;;\n  alphaev7) ax_gcc_arch=\"ev7 ev69 ev68 ev67\" ;;\n  alphaev79) ax_gcc_arch=\"ev79 ev7 ev69 ev68 ev67\" ;;\n\n  powerpc*)\n     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`\n     cputype=`echo $cputype | $SED -e 's/ppc//g;s/ *//g'`\n     case $cputype in\n       *750*) ax_gcc_arch=\"750 G3\" ;;\n       *740[[0-9]]*) ax_gcc_arch=\"$cputype 7400 G4\" ;;\n       *74[[4-5]][[0-9]]*) ax_gcc_arch=\"$cputype 7450 G4\" ;;\n       *74[[0-9]][[0-9]]*) ax_gcc_arch=\"$cputype G4\" ;;\n       *970*) ax_gcc_arch=\"970 G5 power4\";;\n       *POWER4*|*power4*|*gq*) ax_gcc_arch=\"power4 970\";;\n       *POWER5*|*power5*|*gr*|*gs*) ax_gcc_arch=\"power5 power4 970\";;\n       603ev|8240) ax_gcc_arch=\"$cputype 603e 603\";;\n       *) ax_gcc_arch=$cputype ;;\n     esac\n     ax_gcc_arch=\"$ax_gcc_arch powerpc\"\n     ;;\n  aarch64)\n     cpuimpl=`grep 'CPU implementer' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d \" \" | head -n 1`\n     cpuarch=`grep 'CPU architecture' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d \" \" | head -n 1`\n     cpuvar=`grep 'CPU variant' /proc/cpuinfo 2> /dev/null | cut -d: -f2 | tr -d \" \" | head -n 1`\n     case $cpuimpl in\n       0x42) case $cpuarch in\n               8) case $cpuvar in\n                    0x0) ax_gcc_arch=\"thunderx2t99 vulcan armv8.1-a armv8-a+lse armv8-a native\" ;;\n                  esac\n                  ;;\n             esac\n             ;;\n       0x43) case $cpuarch in\n               8) case $cpuvar in\n                    0x0) ax_gcc_arch=\"thunderx armv8-a native\" ;;\n                    0x1) ax_gcc_arch=\"thunderx+lse armv8.1-a armv8-a+lse armv8-a native\" ;;\n                  esac\n                  ;;\n             esac\n             ;;\n      esac\n      ;;\nesac\nfi # not cross-compiling\nfi # guess arch\n\nif test \"x$ax_gcc_arch\" != x -a \"x$ax_gcc_arch\" != xno; then\nif test \"x[]m4_default([$1],yes)\" = xyes; then # if we require portable code\n  flag_prefixes=\"-mtune=\"\n  if test \"x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor\" = xclang; then flag_prefixes=\"-march=\"; fi\n  # -mcpu=$arch and m$arch generate nonportable code on every arch except\n  # x86.  And some other arches (e.g. Alpha) don't accept -mtune.  Grrr.\n  case $host_cpu in i*86|x86_64*|amd64*) flag_prefixes=\"$flag_prefixes -mcpu= -m\";; esac\nelse\n  flag_prefixes=\"-march= -mcpu= -m\"\nfi\nfor flag_prefix in $flag_prefixes; do\n  for arch in $ax_gcc_arch; do\n    flag=\"$flag_prefix$arch\"\n    AX_CHECK_COMPILE_FLAG($flag, [if test \"x$ax_cv_[]_AC_LANG_ABBREV[]_compiler_vendor\" = xclang; then\n      if test \"x[]m4_default([$1],yes)\" = xyes; then\n\tif test \"x$flag\" = \"x-march=$arch\"; then flag=-mtune=$arch; fi\n      fi\n    fi; ax_cv_gcc_archflag=$flag; break])\n  done\n  test \"x$ax_cv_gcc_archflag\" = xunknown || break\ndone\nfi\n\nfi # $GCC=yes\n])\nAC_MSG_CHECKING([for gcc architecture flag])\nAC_MSG_RESULT($ax_cv_gcc_archflag)\nif test \"x$ax_cv_gcc_archflag\" = xunknown; then\n  m4_default([$3],:)\nelse\n  m4_default([$2], [CFLAGS=\"$CFLAGS $ax_cv_gcc_archflag\"])\nfi\n])\n"
  },
  {
    "path": "m4/ax_gcc_func_attribute.m4",
    "content": "# ===========================================================================\n#  https://www.gnu.org/software/autoconf-archive/ax_gcc_func_attribute.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_GCC_FUNC_ATTRIBUTE(ATTRIBUTE)\n#\n# DESCRIPTION\n#\n#   This macro checks if the compiler supports one of GCC's function\n#   attributes; many other compilers also provide function attributes with\n#   the same syntax. Compiler warnings are used to detect supported\n#   attributes as unsupported ones are ignored by default so quieting\n#   warnings when using this macro will yield false positives.\n#\n#   The ATTRIBUTE parameter holds the name of the attribute to be checked.\n#\n#   If ATTRIBUTE is supported define HAVE_FUNC_ATTRIBUTE_<ATTRIBUTE>.\n#\n#   The macro caches its result in the ax_cv_have_func_attribute_<attribute>\n#   variable.\n#\n#   The macro currently supports the following function attributes:\n#\n#    alias\n#    aligned\n#    alloc_size\n#    always_inline\n#    artificial\n#    cold\n#    const\n#    constructor\n#    constructor_priority for constructor attribute with priority\n#    deprecated\n#    destructor\n#    dllexport\n#    dllimport\n#    error\n#    externally_visible\n#    fallthrough\n#    flatten\n#    format\n#    format_arg\n#    gnu_inline\n#    hot\n#    ifunc\n#    leaf\n#    malloc\n#    noclone\n#    noinline\n#    nonnull\n#    noreturn\n#    nothrow\n#    optimize\n#    pure\n#    sentinel\n#    sentinel_position\n#    unused\n#    used\n#    visibility\n#    warning\n#    warn_unused_result\n#    weak\n#    weakref\n#\n#   Unsupported function attributes will be tested with a prototype\n#   returning an int and not accepting any arguments and the result of the\n#   check might be wrong or meaningless so use with care.\n#\n# LICENSE\n#\n#   Copyright (c) 2013 Gabriele Svelto <gabriele.svelto@gmail.com>\n#\n#   Copying and distribution of this file, with or without modification, are\n#   permitted in any medium without royalty provided the copyright notice\n#   and this notice are preserved.  This file is offered as-is, without any\n#   warranty.\n\n#serial 9\n\nAC_DEFUN([AX_GCC_FUNC_ATTRIBUTE], [\n    AS_VAR_PUSHDEF([ac_var], [ax_cv_have_func_attribute_$1])\n\n    AC_CACHE_CHECK([for __attribute__(($1))], [ac_var], [\n        AC_LINK_IFELSE([AC_LANG_PROGRAM([\n            m4_case([$1],\n                [alias], [\n                    int foo( void ) { return 0; }\n                    int bar( void ) __attribute__(($1(\"foo\")));\n                ],\n                [aligned], [\n                    int foo( void ) __attribute__(($1(32)));\n                ],\n                [alloc_size], [\n                    void *foo(int a) __attribute__(($1(1)));\n                ],\n                [always_inline], [\n                    inline __attribute__(($1)) int foo( void ) { return 0; }\n                ],\n                [artificial], [\n                    inline __attribute__(($1)) int foo( void ) { return 0; }\n                ],\n                [cold], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [const], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [constructor_priority], [\n                    int foo( void ) __attribute__((__constructor__(65535/2)));\n                ],\n                [constructor], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [deprecated], [\n                    int foo( void ) __attribute__(($1(\"\")));\n                ],\n                [destructor], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [dllexport], [\n                    __attribute__(($1)) int foo( void ) { return 0; }\n                ],\n                [dllimport], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [error], [\n                    int foo( void ) __attribute__(($1(\"\")));\n                ],\n                [externally_visible], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [fallthrough], [\n                    int foo( void ) {switch (0) { case 1: __attribute__(($1)); case 2: break ; }};\n                ],\n                [flatten], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [format], [\n                    int foo(const char *p, ...) __attribute__(($1(printf, 1, 2)));\n                ],\n                [format_arg], [\n                    char *foo(const char *p) __attribute__(($1(1)));\n                ],\n                [gnu_inline], [\n                    inline __attribute__(($1)) int foo( void ) { return 0; }\n                ],\n                [hot], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [ifunc], [\n                    int my_foo( void ) { return 0; }\n                    static int (*resolve_foo(void))(void) { return my_foo; }\n                    int foo( void ) __attribute__(($1(\"resolve_foo\")));\n                ],\n                [leaf], [\n                    __attribute__(($1)) int foo( void ) { return 0; }\n                ],\n                [malloc], [\n                    void *foo( void ) __attribute__(($1));\n                ],\n                [noclone], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [noinline], [\n                    __attribute__(($1)) int foo( void ) { return 0; }\n                ],\n                [nonnull], [\n                    int foo(char *p) __attribute__(($1(1)));\n                ],\n                [noreturn], [\n                    void foo( void ) __attribute__(($1));\n                ],\n                [nothrow], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [optimize], [\n                    __attribute__(($1(3))) int foo( void ) { return 0; }\n                ],\n                [pure], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [sentinel], [\n                    int foo(void *p, ...) __attribute__(($1));\n                ],\n                [sentinel_position], [\n                    int foo(void *p, ...) __attribute__(($1(1)));\n                ],\n                [returns_nonnull], [\n                    void *foo( void ) __attribute__(($1));\n                ],\n                [unused], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [used], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [visibility], [\n                    int foo_def( void ) __attribute__(($1(\"default\")));\n                    int foo_hid( void ) __attribute__(($1(\"hidden\")));\n                    int foo_int( void ) __attribute__(($1(\"internal\")));\n                    int foo_pro( void ) __attribute__(($1(\"protected\")));\n                ],\n                [warning], [\n                    int foo( void ) __attribute__(($1(\"\")));\n                ],\n                [warn_unused_result], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [weak], [\n                    int foo( void ) __attribute__(($1));\n                ],\n                [weakref], [\n                    static int foo( void ) { return 0; }\n                    static int bar( void ) __attribute__(($1(\"foo\")));\n                ],\n                [\n                 m4_warn([syntax], [Unsupported attribute $1, the test may fail])\n                 int foo( void ) __attribute__(($1));\n                ]\n            )], [])\n            ],\n            dnl GCC doesn't exit with an error if an unknown attribute is\n            dnl provided but only outputs a warning, so accept the attribute\n            dnl only if no warning were issued.\n            [AS_IF([test -s conftest.err],\n                [AS_VAR_SET([ac_var], [no])],\n                [AS_VAR_SET([ac_var], [yes])])],\n            [AS_VAR_SET([ac_var], [no])])\n    ])\n\n    AS_IF([test yes = AS_VAR_GET([ac_var])],\n        [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_FUNC_ATTRIBUTE_$1), 1,\n            [Define to 1 if the system has the `$1' function attribute])], [])\n\n    AS_VAR_POPDEF([ac_var])\n])\n"
  },
  {
    "path": "m4/ax_gcc_x86_cpuid.m4",
    "content": "# ===========================================================================\n#     https://www.gnu.org/software/autoconf-archive/ax_gcc_x86_cpuid.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_GCC_X86_CPUID(OP)\n#   AX_GCC_X86_CPUID_COUNT(OP, COUNT)\n#\n# DESCRIPTION\n#\n#   On Pentium and later x86 processors, with gcc or a compiler that has a\n#   compatible syntax for inline assembly instructions, run a small program\n#   that executes the cpuid instruction with input OP. This can be used to\n#   detect the CPU type. AX_GCC_X86_CPUID_COUNT takes an additional COUNT\n#   parameter that gets passed into register ECX before calling cpuid.\n#\n#   On output, the values of the eax, ebx, ecx, and edx registers are stored\n#   as hexadecimal strings as \"eax:ebx:ecx:edx\" in the cache variable\n#   ax_cv_gcc_x86_cpuid_OP.\n#\n#   If the cpuid instruction fails (because you are running a\n#   cross-compiler, or because you are not using gcc, or because you are on\n#   a processor that doesn't have this instruction), ax_cv_gcc_x86_cpuid_OP\n#   is set to the string \"unknown\".\n#\n#   This macro mainly exists to be used in AX_GCC_ARCHFLAG.\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Steven G. Johnson <stevenj@alum.mit.edu>\n#   Copyright (c) 2008 Matteo Frigo\n#   Copyright (c) 2015 Michael Petch <mpetch@capp-sysware.com>\n#\n#   This program is free software: you can redistribute it and/or modify it\n#   under the terms of the GNU General Public License as published by the\n#   Free Software Foundation, either version 3 of the License, or (at your\n#   option) any later version.\n#\n#   This program is distributed in the hope that it will be useful, but\n#   WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\n#   Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License along\n#   with this program. If not, see <https://www.gnu.org/licenses/>.\n#\n#   As a special exception, the respective Autoconf Macro's copyright owner\n#   gives unlimited permission to copy, distribute and modify the configure\n#   scripts that are the output of Autoconf when processing the Macro. You\n#   need not follow the terms of the GNU General Public License when using\n#   or distributing such scripts, even though portions of the text of the\n#   Macro appear in them. The GNU General Public License (GPL) does govern\n#   all other use of the material that constitutes the Autoconf Macro.\n#\n#   This special exception to the GPL applies to versions of the Autoconf\n#   Macro released by the Autoconf Archive. When you make and distribute a\n#   modified version of the Autoconf Macro, you may extend this special\n#   exception to the GPL to apply to your modified version as well.\n\n#serial 10\n\nAC_DEFUN([AX_GCC_X86_CPUID],\n[AX_GCC_X86_CPUID_COUNT($1, 0)\n])\n\nAC_DEFUN([AX_GCC_X86_CPUID_COUNT],\n[AC_REQUIRE([AC_PROG_CC])\nAC_LANG_PUSH([C])\nAC_CACHE_CHECK(for x86 cpuid $1 output, ax_cv_gcc_x86_cpuid_$1,\n [AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdio.h>], [\n     int op = $1, level = $2, eax, ebx, ecx, edx;\n     FILE *f;\n      __asm__ __volatile__ (\"xchg %%ebx, %1\\n\"\n        \"cpuid\\n\"\n        \"xchg %%ebx, %1\\n\"\n        : \"=a\" (eax), \"=r\" (ebx), \"=c\" (ecx), \"=d\" (edx)\n        : \"a\" (op), \"2\" (level));\n\n     f = fopen(\"conftest_cpuid\", \"w\"); if (!f) return 1;\n     fprintf(f, \"%x:%x:%x:%x\\n\", eax, ebx, ecx, edx);\n     fclose(f);\n     return 0;\n])],\n     [ax_cv_gcc_x86_cpuid_$1=`cat conftest_cpuid`; rm -f conftest_cpuid],\n     [ax_cv_gcc_x86_cpuid_$1=unknown; rm -f conftest_cpuid],\n     [ax_cv_gcc_x86_cpuid_$1=unknown])])\nAC_LANG_POP([C])\n])\n"
  },
  {
    "path": "m4/ax_tls.m4",
    "content": "# ===========================================================================\n#          https://www.gnu.org/software/autoconf-archive/ax_tls.html\n# ===========================================================================\n#\n# SYNOPSIS\n#\n#   AX_TLS([action-if-found], [action-if-not-found])\n#\n# DESCRIPTION\n#\n#   Provides a test for the compiler support of thread local storage (TLS)\n#   extensions. Defines TLS if it is found. Currently knows about C++11,\n#   GCC/ICC, and MSVC. I think SunPro uses the same as GCC, and Borland\n#   apparently supports either.\n#\n# LICENSE\n#\n#   Copyright (c) 2008 Alan Woodland <ajw05@aber.ac.uk>\n#   Copyright (c) 2010 Diego Elio Petteno` <flameeyes@gmail.com>\n#\n#   This program is free software: you can redistribute it and/or modify it\n#   under the terms of the GNU General Public License as published by the\n#   Free Software Foundation, either version 3 of the License, or (at your\n#   option) any later version.\n#\n#   This program is distributed in the hope that it will be useful, but\n#   WITHOUT ANY WARRANTY; without even the implied warranty of\n#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General\n#   Public License for more details.\n#\n#   You should have received a copy of the GNU General Public License along\n#   with this program. If not, see <https://www.gnu.org/licenses/>.\n#\n#   As a special exception, the respective Autoconf Macro's copyright owner\n#   gives unlimited permission to copy, distribute and modify the configure\n#   scripts that are the output of Autoconf when processing the Macro. You\n#   need not follow the terms of the GNU General Public License when using\n#   or distributing such scripts, even though portions of the text of the\n#   Macro appear in them. The GNU General Public License (GPL) does govern\n#   all other use of the material that constitutes the Autoconf Macro.\n#\n#   This special exception to the GPL applies to versions of the Autoconf\n#   Macro released by the Autoconf Archive. When you make and distribute a\n#   modified version of the Autoconf Macro, you may extend this special\n#   exception to the GPL to apply to your modified version as well.\n\n#serial 15\n\nAC_DEFUN([AX_TLS], [\n  AC_MSG_CHECKING([for thread local storage (TLS) class])\n  AC_CACHE_VAL([ac_cv_tls],\n   [for ax_tls_keyword in thread_local _Thread_local __thread '__declspec(thread)' none; do\n       AS_CASE([$ax_tls_keyword],\n          [none], [ac_cv_tls=none ; break],\n          [AC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n              [#include <stdlib.h>],\n              [static  $ax_tls_keyword  int bar;]\n            )],\n            [ac_cv_tls=$ax_tls_keyword ; break],\n            [ac_cv_tls=none]\n          )]\n        )\n    done ]\n  )\n  AC_MSG_RESULT([$ac_cv_tls])\n\n  AS_IF([test \"$ac_cv_tls\" != \"none\"],\n    [AC_DEFINE_UNQUOTED([TLS],[$ac_cv_tls],[If the compiler supports a TLS storage class, define it to that here])\n     m4_ifnblank([$1],[$1],[[:]])],\n    [m4_ifnblank([$2],[$2],[[:]])])\n])\n"
  },
  {
    "path": "m4/extensions.m4",
    "content": "dnl Provide AC_USE_SYSTEM_EXTENSIONS for old autoconf machines.\nAC_DEFUN([ACX_USE_SYSTEM_EXTENSIONS],[\n  ifdef([AC_USE_SYSTEM_EXTENSIONS],[\n    AC_USE_SYSTEM_EXTENSIONS\n  ],[\n    AC_BEFORE([$0], [AC_COMPILE_IFELSE])\n    AC_BEFORE([$0], [AC_RUN_IFELSE])\n\n    AC_REQUIRE([AC_GNU_SOURCE])\n    AC_REQUIRE([AC_AIX])\n    AC_REQUIRE([AC_MINIX])\n\n    AH_VERBATIM([__EXTENSIONS__],\n[/* Enable extensions on Solaris.  */\n#ifndef __EXTENSIONS__\n# undef __EXTENSIONS__\n#endif\n#ifndef _POSIX_PTHREAD_SEMANTICS\n# undef _POSIX_PTHREAD_SEMANTICS\n#endif\n#ifndef _TANDEM_SOURCE\n# undef _TANDEM_SOURCE\n#endif])\n    AC_CACHE_CHECK([whether it is safe to define __EXTENSIONS__],\n      [ac_cv_safe_to_define___extensions__],\n      [AC_COMPILE_IFELSE(\n         [AC_LANG_PROGRAM([\n#           define __EXTENSIONS__ 1\n            AC_INCLUDES_DEFAULT])],\n         [ac_cv_safe_to_define___extensions__=yes],\n         [ac_cv_safe_to_define___extensions__=no])])\n    test $ac_cv_safe_to_define___extensions__ = yes &&\n      AC_DEFINE([__EXTENSIONS__])\n    AC_DEFINE([_POSIX_PTHREAD_SEMANTICS])\n    AC_DEFINE([_TANDEM_SOURCE])\n  ])\n])\n"
  },
  {
    "path": "m4/host-cpu-c-abi.m4",
    "content": "# host-cpu-c-abi.m4\n# serial 18\ndnl Copyright (C) 2002-2024 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\ndnl This file is offered as-is, without any warranty.\n\ndnl From Bruno Haible and Sam Steingold.\n\ndnl Sets the HOST_CPU variable to the canonical name of the CPU.\ndnl Sets the HOST_CPU_C_ABI variable to the canonical name of the CPU with its\ndnl C language ABI (application binary interface).\ndnl Also defines __${HOST_CPU}__ and __${HOST_CPU_C_ABI}__ as C macros in\ndnl config.h.\ndnl\ndnl This canonical name can be used to select a particular assembly language\ndnl source file that will interoperate with C code on the given host.\ndnl\ndnl For example:\ndnl * 'i386' and 'sparc' are different canonical names, because code for i386\ndnl   will not run on SPARC CPUs and vice versa. They have different\ndnl   instruction sets.\ndnl * 'sparc' and 'sparc64' are different canonical names, because code for\ndnl   'sparc' and code for 'sparc64' cannot be linked together: 'sparc' code\ndnl   contains 32-bit instructions, whereas 'sparc64' code contains 64-bit\ndnl   instructions. A process on a SPARC CPU can be in 32-bit mode or in 64-bit\ndnl   mode, but not both.\ndnl * 'mips' and 'mipsn32' are different canonical names, because they use\ndnl   different argument passing and return conventions for C functions, and\ndnl   although the instruction set of 'mips' is a large subset of the\ndnl   instruction set of 'mipsn32'.\ndnl * 'mipsn32' and 'mips64' are different canonical names, because they use\ndnl   different sizes for the C types like 'int' and 'void *', and although\ndnl   the instruction sets of 'mipsn32' and 'mips64' are the same.\ndnl * The same canonical name is used for different endiannesses. You can\ndnl   determine the endianness through preprocessor symbols:\ndnl   - 'arm': test __ARMEL__.\ndnl   - 'mips', 'mipsn32', 'mips64': test _MIPSEB vs. _MIPSEL.\ndnl   - 'powerpc64': test __BIG_ENDIAN__ vs. __LITTLE_ENDIAN__.\ndnl * The same name 'i386' is used for CPUs of type i386, i486, i586\ndnl   (Pentium), AMD K7, Pentium II, Pentium IV, etc., because\ndnl   - Instructions that do not exist on all of these CPUs (cmpxchg,\ndnl     MMX, SSE, SSE2, 3DNow! etc.) are not frequently used. If your\ndnl     assembly language source files use such instructions, you will\ndnl     need to make the distinction.\ndnl   - Speed of execution of the common instruction set is reasonable across\ndnl     the entire family of CPUs. If you have assembly language source files\ndnl     that are optimized for particular CPU types (like GNU gmp has), you\ndnl     will need to make the distinction.\ndnl   See <https://en.wikipedia.org/wiki/X86_instruction_listings>.\nAC_DEFUN([gl_HOST_CPU_C_ABI],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([gl_C_ASM])\n  AC_CACHE_CHECK([host CPU and C ABI], [gl_cv_host_cpu_c_abi],\n    [case \"$host_cpu\" in\n\nchangequote(,)dnl\n       i[34567]86 )\nchangequote([,])dnl\n         gl_cv_host_cpu_c_abi=i386\n         ;;\n\n       x86_64 )\n         # On x86_64 systems, the C compiler may be generating code in one of\n         # these ABIs:\n         # - 64-bit instruction set, 64-bit pointers, 64-bit 'long': x86_64.\n         # - 64-bit instruction set, 64-bit pointers, 32-bit 'long': x86_64\n         #   with native Windows (mingw, MSVC).\n         # - 64-bit instruction set, 32-bit pointers, 32-bit 'long': x86_64-x32.\n         # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': i386.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if (defined __x86_64__ || defined __amd64__ \\\n                     || defined _M_X64 || defined _M_AMD64)\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [AC_COMPILE_IFELSE(\n              [AC_LANG_SOURCE(\n                 [[#if defined __ILP32__ || defined _ILP32\n                    int ok;\n                   #else\n                    error fail\n                   #endif\n                 ]])],\n              [gl_cv_host_cpu_c_abi=x86_64-x32],\n              [gl_cv_host_cpu_c_abi=x86_64])],\n           [gl_cv_host_cpu_c_abi=i386])\n         ;;\n\nchangequote(,)dnl\n       alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] )\nchangequote([,])dnl\n         gl_cv_host_cpu_c_abi=alpha\n         ;;\n\n       arm* | aarch64 )\n         # Assume arm with EABI.\n         # On arm64 systems, the C compiler may be generating code in one of\n         # these ABIs:\n         # - aarch64 instruction set, 64-bit pointers, 64-bit 'long': arm64.\n         # - aarch64 instruction set, 32-bit pointers, 32-bit 'long': arm64-ilp32.\n         # - 32-bit instruction set, 32-bit pointers, 32-bit 'long': arm or armhf.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#ifdef __aarch64__\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [AC_COMPILE_IFELSE(\n              [AC_LANG_SOURCE(\n                [[#if defined __ILP32__ || defined _ILP32\n                   int ok;\n                  #else\n                   error fail\n                  #endif\n                ]])],\n              [gl_cv_host_cpu_c_abi=arm64-ilp32],\n              [gl_cv_host_cpu_c_abi=arm64])],\n           [# Don't distinguish little-endian and big-endian arm, since they\n            # don't require different machine code for simple operations and\n            # since the user can distinguish them through the preprocessor\n            # defines __ARMEL__ vs. __ARMEB__.\n            # But distinguish arm which passes floating-point arguments and\n            # return values in integer registers (r0, r1, ...) - this is\n            # gcc -mfloat-abi=soft or gcc -mfloat-abi=softfp - from arm which\n            # passes them in float registers (s0, s1, ...) and double registers\n            # (d0, d1, ...) - this is gcc -mfloat-abi=hard. GCC 4.6 or newer\n            # sets the preprocessor defines __ARM_PCS (for the first case) and\n            # __ARM_PCS_VFP (for the second case), but older GCC does not.\n            echo 'double ddd; void func (double dd) { ddd = dd; }' > conftest.c\n            # Look for a reference to the register d0 in the .s file.\n            AC_TRY_COMMAND(${CC-cc} $CFLAGS $CPPFLAGS $gl_c_asm_opt conftest.c) >/dev/null 2>&1\n            if LC_ALL=C grep 'd0,' conftest.$gl_asmext >/dev/null; then\n              gl_cv_host_cpu_c_abi=armhf\n            else\n              gl_cv_host_cpu_c_abi=arm\n            fi\n            rm -f conftest*\n           ])\n         ;;\n\n       hppa1.0 | hppa1.1 | hppa2.0* | hppa64 )\n         # On hppa, the C compiler may be generating 32-bit code or 64-bit\n         # code. In the latter case, it defines _LP64 and __LP64__.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#ifdef __LP64__\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [gl_cv_host_cpu_c_abi=hppa64],\n           [gl_cv_host_cpu_c_abi=hppa])\n         ;;\n\n       ia64* )\n         # On ia64 on HP-UX, the C compiler may be generating 64-bit code or\n         # 32-bit code. In the latter case, it defines _ILP32.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#ifdef _ILP32\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [gl_cv_host_cpu_c_abi=ia64-ilp32],\n           [gl_cv_host_cpu_c_abi=ia64])\n         ;;\n\n       mips* )\n         # We should also check for (_MIPS_SZPTR == 64), but gcc keeps this\n         # at 32.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if defined _MIPS_SZLONG && (_MIPS_SZLONG == 64)\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [gl_cv_host_cpu_c_abi=mips64],\n           [# In the n32 ABI, _ABIN32 is defined, _ABIO32 is not defined (but\n            # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIN32.\n            # In the 32 ABI, _ABIO32 is defined, _ABIN32 is not defined (but\n            # may later get defined by <sgidefs.h>), and _MIPS_SIM == _ABIO32.\n            AC_COMPILE_IFELSE(\n              [AC_LANG_SOURCE(\n                 [[#if (_MIPS_SIM == _ABIN32)\n                    int ok;\n                   #else\n                    error fail\n                   #endif\n                 ]])],\n              [gl_cv_host_cpu_c_abi=mipsn32],\n              [gl_cv_host_cpu_c_abi=mips])])\n         ;;\n\n       powerpc* )\n         # Different ABIs are in use on AIX vs. Mac OS X vs. Linux,*BSD.\n         # No need to distinguish them here; the caller may distinguish\n         # them based on the OS.\n         # On powerpc64 systems, the C compiler may still be generating\n         # 32-bit code. And on powerpc-ibm-aix systems, the C compiler may\n         # be generating 64-bit code.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if defined __powerpc64__ || defined __LP64__\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [# On powerpc64, there are two ABIs on Linux: The AIX compatible\n            # one and the ELFv2 one. The latter defines _CALL_ELF=2.\n            AC_COMPILE_IFELSE(\n              [AC_LANG_SOURCE(\n                 [[#if defined _CALL_ELF && _CALL_ELF == 2\n                    int ok;\n                   #else\n                    error fail\n                   #endif\n                 ]])],\n              [gl_cv_host_cpu_c_abi=powerpc64-elfv2],\n              [gl_cv_host_cpu_c_abi=powerpc64])\n           ],\n           [gl_cv_host_cpu_c_abi=powerpc])\n         ;;\n\n       rs6000 )\n         gl_cv_host_cpu_c_abi=powerpc\n         ;;\n\n       riscv32 | riscv64 )\n         # There are 2 architectures (with variants): rv32* and rv64*.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if __riscv_xlen == 64\n                  int ok;\n                #else\n                  error fail\n                #endif\n              ]])],\n           [cpu=riscv64],\n           [cpu=riscv32])\n         # There are 6 ABIs: ilp32, ilp32f, ilp32d, lp64, lp64f, lp64d.\n         # Size of 'long' and 'void *':\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if defined __LP64__\n                  int ok;\n                #else\n                  error fail\n                #endif\n              ]])],\n           [main_abi=lp64],\n           [main_abi=ilp32])\n         # Float ABIs:\n         # __riscv_float_abi_double:\n         #   'float' and 'double' are passed in floating-point registers.\n         # __riscv_float_abi_single:\n         #   'float' are passed in floating-point registers.\n         # __riscv_float_abi_soft:\n         #   No values are passed in floating-point registers.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if defined __riscv_float_abi_double\n                  int ok;\n                #else\n                  error fail\n                #endif\n              ]])],\n           [float_abi=d],\n           [AC_COMPILE_IFELSE(\n              [AC_LANG_SOURCE(\n                 [[#if defined __riscv_float_abi_single\n                     int ok;\n                   #else\n                     error fail\n                   #endif\n                 ]])],\n              [float_abi=f],\n              [float_abi=''])\n           ])\n         gl_cv_host_cpu_c_abi=\"${cpu}-${main_abi}${float_abi}\"\n         ;;\n\n       s390* )\n         # On s390x, the C compiler may be generating 64-bit (= s390x) code\n         # or 31-bit (= s390) code.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if defined __LP64__ || defined __s390x__\n                  int ok;\n                #else\n                  error fail\n                #endif\n              ]])],\n           [gl_cv_host_cpu_c_abi=s390x],\n           [gl_cv_host_cpu_c_abi=s390])\n         ;;\n\n       sparc | sparc64 )\n         # UltraSPARCs running Linux have `uname -m` = \"sparc64\", but the\n         # C compiler still generates 32-bit code.\n         AC_COMPILE_IFELSE(\n           [AC_LANG_SOURCE(\n              [[#if defined __sparcv9 || defined __arch64__\n                 int ok;\n                #else\n                 error fail\n                #endif\n              ]])],\n           [gl_cv_host_cpu_c_abi=sparc64],\n           [gl_cv_host_cpu_c_abi=sparc])\n         ;;\n\n       *)\n         gl_cv_host_cpu_c_abi=\"$host_cpu\"\n         ;;\n     esac\n    ])\n\n  dnl In most cases, $HOST_CPU and $HOST_CPU_C_ABI are the same.\n  HOST_CPU=`echo \"$gl_cv_host_cpu_c_abi\" | sed -e 's/-.*//'`\n  HOST_CPU_C_ABI=\"$gl_cv_host_cpu_c_abi\"\n  AC_SUBST([HOST_CPU])\n  AC_SUBST([HOST_CPU_C_ABI])\n\n  # This was\n  #   AC_DEFINE_UNQUOTED([__${HOST_CPU}__])\n  #   AC_DEFINE_UNQUOTED([__${HOST_CPU_C_ABI}__])\n  # earlier, but KAI C++ 3.2d doesn't like this.\n  sed -e 's/-/_/g' >> confdefs.h <<EOF\n#ifndef __${HOST_CPU}__\n#define __${HOST_CPU}__ 1\n#endif\n#ifndef __${HOST_CPU_C_ABI}__\n#define __${HOST_CPU_C_ABI}__ 1\n#endif\nEOF\n  AH_TOP([/* CPU and C ABI indicator */\n#ifndef __i386__\n#undef __i386__\n#endif\n#ifndef __x86_64_x32__\n#undef __x86_64_x32__\n#endif\n#ifndef __x86_64__\n#undef __x86_64__\n#endif\n#ifndef __alpha__\n#undef __alpha__\n#endif\n#ifndef __arm__\n#undef __arm__\n#endif\n#ifndef __armhf__\n#undef __armhf__\n#endif\n#ifndef __arm64_ilp32__\n#undef __arm64_ilp32__\n#endif\n#ifndef __arm64__\n#undef __arm64__\n#endif\n#ifndef __hppa__\n#undef __hppa__\n#endif\n#ifndef __hppa64__\n#undef __hppa64__\n#endif\n#ifndef __ia64_ilp32__\n#undef __ia64_ilp32__\n#endif\n#ifndef __ia64__\n#undef __ia64__\n#endif\n#ifndef __loongarch64__\n#undef __loongarch64__\n#endif\n#ifndef __m68k__\n#undef __m68k__\n#endif\n#ifndef __mips__\n#undef __mips__\n#endif\n#ifndef __mipsn32__\n#undef __mipsn32__\n#endif\n#ifndef __mips64__\n#undef __mips64__\n#endif\n#ifndef __powerpc__\n#undef __powerpc__\n#endif\n#ifndef __powerpc64__\n#undef __powerpc64__\n#endif\n#ifndef __powerpc64_elfv2__\n#undef __powerpc64_elfv2__\n#endif\n#ifndef __riscv32__\n#undef __riscv32__\n#endif\n#ifndef __riscv64__\n#undef __riscv64__\n#endif\n#ifndef __riscv32_ilp32__\n#undef __riscv32_ilp32__\n#endif\n#ifndef __riscv32_ilp32f__\n#undef __riscv32_ilp32f__\n#endif\n#ifndef __riscv32_ilp32d__\n#undef __riscv32_ilp32d__\n#endif\n#ifndef __riscv64_ilp32__\n#undef __riscv64_ilp32__\n#endif\n#ifndef __riscv64_ilp32f__\n#undef __riscv64_ilp32f__\n#endif\n#ifndef __riscv64_ilp32d__\n#undef __riscv64_ilp32d__\n#endif\n#ifndef __riscv64_lp64__\n#undef __riscv64_lp64__\n#endif\n#ifndef __riscv64_lp64f__\n#undef __riscv64_lp64f__\n#endif\n#ifndef __riscv64_lp64d__\n#undef __riscv64_lp64d__\n#endif\n#ifndef __s390__\n#undef __s390__\n#endif\n#ifndef __s390x__\n#undef __s390x__\n#endif\n#ifndef __sh__\n#undef __sh__\n#endif\n#ifndef __sparc__\n#undef __sparc__\n#endif\n#ifndef __sparc64__\n#undef __sparc64__\n#endif\n])\n\n])\n\n\ndnl Sets the HOST_CPU_C_ABI_32BIT variable to 'yes' if the C language ABI\ndnl (application binary interface) is a 32-bit one, to 'no' if it is a 64-bit\ndnl one.\ndnl This is a simplified variant of gl_HOST_CPU_C_ABI.\nAC_DEFUN([gl_HOST_CPU_C_ABI_32BIT],\n[\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_CACHE_CHECK([32-bit host C ABI], [gl_cv_host_cpu_c_abi_32bit],\n    [case \"$host_cpu\" in\n\n       # CPUs that only support a 32-bit ABI.\n       arc \\\n       | bfin \\\n       | cris* \\\n       | csky \\\n       | epiphany \\\n       | ft32 \\\n       | h8300 \\\n       | m68k \\\n       | microblaze | microblazeel \\\n       | nds32 | nds32le | nds32be \\\n       | nios2 | nios2eb | nios2el \\\n       | or1k* \\\n       | or32 \\\n       | sh | sh[1234] | sh[1234]e[lb] \\\n       | tic6x \\\n       | xtensa* )\n         gl_cv_host_cpu_c_abi_32bit=yes\n         ;;\n\n       # CPUs that only support a 64-bit ABI.\nchangequote(,)dnl\n       alpha | alphaev[4-8] | alphaev56 | alphapca5[67] | alphaev6[78] \\\n       | mmix )\nchangequote([,])dnl\n         gl_cv_host_cpu_c_abi_32bit=no\n         ;;\n\n       *)\n         if test -n \"$gl_cv_host_cpu_c_abi\"; then\n           dnl gl_HOST_CPU_C_ABI has already been run. Use its result.\n           case \"$gl_cv_host_cpu_c_abi\" in\n             i386 | x86_64-x32 | arm | armhf | arm64-ilp32 | hppa | ia64-ilp32 | mips | mipsn32 | powerpc | riscv*-ilp32* | s390 | sparc)\n               gl_cv_host_cpu_c_abi_32bit=yes ;;\n             x86_64 | alpha | arm64 | aarch64c | hppa64 | ia64 | mips64 | powerpc64 | powerpc64-elfv2 | riscv*-lp64* | s390x | sparc64 )\n               gl_cv_host_cpu_c_abi_32bit=no ;;\n             *)\n               gl_cv_host_cpu_c_abi_32bit=unknown ;;\n           esac\n         else\n           gl_cv_host_cpu_c_abi_32bit=unknown\n         fi\n         if test $gl_cv_host_cpu_c_abi_32bit = unknown; then\n           AC_COMPILE_IFELSE(\n             [AC_LANG_SOURCE(\n                [[int test_pointer_size[sizeof (void *) - 5];\n                ]])],\n             [gl_cv_host_cpu_c_abi_32bit=no],\n             [gl_cv_host_cpu_c_abi_32bit=yes])\n         fi\n         ;;\n     esac\n    ])\n\n  HOST_CPU_C_ABI_32BIT=\"$gl_cv_host_cpu_c_abi_32bit\"\n])\n"
  },
  {
    "path": "m4/lib-ld.m4",
    "content": "# lib-ld.m4 serial 3 (gettext-0.13)\ndnl Copyright (C) 1996-2003 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl Subroutines of libtool.m4,\ndnl with replacements s/AC_/AC_LIB/ and s/lt_cv/acl_cv/ to avoid collision\ndnl with libtool.m4.\n\ndnl From libtool-1.4. Sets the variable with_gnu_ld to yes or no.\nAC_DEFUN([AC_LIB_PROG_LD_GNU],\n[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], acl_cv_prog_gnu_ld,\n[# I'd rather use --version here, but apparently some GNU ld's only accept -v.\ncase `$LD -v 2>&1 </dev/null` in\n*GNU* | *'with BFD'*)\n  acl_cv_prog_gnu_ld=yes ;;\n*)\n  acl_cv_prog_gnu_ld=no ;;\nesac])\nwith_gnu_ld=$acl_cv_prog_gnu_ld\n])\n\ndnl From libtool-1.4. Sets the variable LD.\nAC_DEFUN([AC_LIB_PROG_LD],\n[AC_ARG_WITH(gnu-ld,\n[  --with-gnu-ld           assume the C compiler uses GNU ld [default=no]],\ntest \"$withval\" = no || with_gnu_ld=yes, with_gnu_ld=no)\nAC_REQUIRE([AC_PROG_CC])dnl\nAC_REQUIRE([AC_CANONICAL_HOST])dnl\n# Prepare PATH_SEPARATOR.\n# The user is always right.\nif test \"${PATH_SEPARATOR+set}\" != set; then\n  echo \"#! /bin/sh\" >conf$$.sh\n  echo  \"exit 0\"   >>conf$$.sh\n  chmod +x conf$$.sh\n  if (PATH=\"/nonexistent;.\"; conf$$.sh) >/dev/null 2>&1; then\n    PATH_SEPARATOR=';'\n  else\n    PATH_SEPARATOR=:\n  fi\n  rm -f conf$$.sh\nfi\nac_prog=ld\nif test \"$GCC\" = yes; then\n  # Check if gcc -print-prog-name=ld gives a path.\n  AC_MSG_CHECKING([for ld used by GCC])\n  case $host in\n  *-*-mingw*)\n    # gcc leaves a trailing carriage return which upsets mingw\n    ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\\015'` ;;\n  *)\n    ac_prog=`($CC -print-prog-name=ld) 2>&5` ;;\n  esac\n  case $ac_prog in\n    # Accept absolute paths.\n    [[\\\\/]* | [A-Za-z]:[\\\\/]*)]\n      [re_direlt='/[^/][^/]*/\\.\\./']\n      # Canonicalize the path of ld\n      ac_prog=`echo $ac_prog| sed 's%\\\\\\\\%/%g'`\n      while echo $ac_prog | grep \"$re_direlt\" > /dev/null 2>&1; do\n\tac_prog=`echo $ac_prog| sed \"s%$re_direlt%/%\"`\n      done\n      test -z \"$LD\" && LD=\"$ac_prog\"\n      ;;\n  \"\")\n    # If it fails, then pretend we aren't using GCC.\n    ac_prog=ld\n    ;;\n  *)\n    # If it is relative, then search for the first ld in PATH.\n    with_gnu_ld=unknown\n    ;;\n  esac\nelif test \"$with_gnu_ld\" = yes; then\n  AC_MSG_CHECKING([for GNU ld])\nelse\n  AC_MSG_CHECKING([for non-GNU ld])\nfi\nAC_CACHE_VAL(acl_cv_path_LD,\n[if test -z \"$LD\"; then\n  IFS=\"${IFS= \t}\"; ac_save_ifs=\"$IFS\"; IFS=\"${IFS}${PATH_SEPARATOR-:}\"\n  for ac_dir in $PATH; do\n    test -z \"$ac_dir\" && ac_dir=.\n    if test -f \"$ac_dir/$ac_prog\" || test -f \"$ac_dir/$ac_prog$ac_exeext\"; then\n      acl_cv_path_LD=\"$ac_dir/$ac_prog\"\n      # Check to see if the program is GNU ld.  I'd rather use --version,\n      # but apparently some GNU ld's only accept -v.\n      # Break only if it was the GNU/non-GNU ld that we prefer.\n      case `\"$acl_cv_path_LD\" -v 2>&1 < /dev/null` in\n      *GNU* | *'with BFD'*)\n\ttest \"$with_gnu_ld\" != no && break ;;\n      *)\n\ttest \"$with_gnu_ld\" != yes && break ;;\n      esac\n    fi\n  done\n  IFS=\"$ac_save_ifs\"\nelse\n  acl_cv_path_LD=\"$LD\" # Let the user override the test with a path.\nfi])\nLD=\"$acl_cv_path_LD\"\nif test -n \"$LD\"; then\n  AC_MSG_RESULT($LD)\nelse\n  AC_MSG_RESULT(no)\nfi\ntest -z \"$LD\" && AC_MSG_ERROR([no acceptable ld found in \\$PATH])\nAC_LIB_PROG_LD_GNU\n])\n"
  },
  {
    "path": "m4/lib-link.m4",
    "content": "# lib-link.m4 serial 13 (gettext-0.17)\ndnl Copyright (C) 2001-2007 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\n\ndnl From Bruno Haible.\n\nAC_PREREQ(2.54)\n\ndnl AC_LIB_LINKFLAGS(name [, dependencies]) searches for libname and\ndnl the libraries corresponding to explicit and implicit dependencies.\ndnl Sets and AC_SUBSTs the LIB${NAME} and LTLIB${NAME} variables and\ndnl augments the CPPFLAGS variable.\ndnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname\ndnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.\nAC_DEFUN([AC_LIB_LINKFLAGS],\n[\n  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])\n  AC_REQUIRE([AC_LIB_RPATH])\n  define([Name],[translit([$1],[./-], [___])])\n  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],\n                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])\n  AC_CACHE_CHECK([how to link with lib[]$1], [ac_cv_lib[]Name[]_libs], [\n    AC_LIB_LINKFLAGS_BODY([$1], [$2])\n    ac_cv_lib[]Name[]_libs=\"$LIB[]NAME\"\n    ac_cv_lib[]Name[]_ltlibs=\"$LTLIB[]NAME\"\n    ac_cv_lib[]Name[]_cppflags=\"$INC[]NAME\"\n    ac_cv_lib[]Name[]_prefix=\"$LIB[]NAME[]_PREFIX\"\n  ])\n  LIB[]NAME=\"$ac_cv_lib[]Name[]_libs\"\n  LTLIB[]NAME=\"$ac_cv_lib[]Name[]_ltlibs\"\n  INC[]NAME=\"$ac_cv_lib[]Name[]_cppflags\"\n  LIB[]NAME[]_PREFIX=\"$ac_cv_lib[]Name[]_prefix\"\n  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)\n  AC_SUBST([LIB]NAME)\n  AC_SUBST([LTLIB]NAME)\n  AC_SUBST([LIB]NAME[_PREFIX])\n  dnl Also set HAVE_LIB[]NAME so that AC_LIB_HAVE_LINKFLAGS can reuse the\n  dnl results of this search when this library appears as a dependency.\n  HAVE_LIB[]NAME=yes\n  undefine([Name])\n  undefine([NAME])\n])\n\ndnl AC_LIB_HAVE_LINKFLAGS(name, dependencies, includes, testcode)\ndnl searches for libname and the libraries corresponding to explicit and\ndnl implicit dependencies, together with the specified include files and\ndnl the ability to compile and link the specified testcode. If found, it\ndnl sets and AC_SUBSTs HAVE_LIB${NAME}=yes and the LIB${NAME} and\ndnl LTLIB${NAME} variables and augments the CPPFLAGS variable, and\ndnl #defines HAVE_LIB${NAME} to 1. Otherwise, it sets and AC_SUBSTs\ndnl HAVE_LIB${NAME}=no and LIB${NAME} and LTLIB${NAME} to empty.\ndnl Sets and AC_SUBSTs the LIB${NAME}_PREFIX variable to nonempty if libname\ndnl was found in ${LIB${NAME}_PREFIX}/$acl_libdirstem.\nAC_DEFUN([AC_LIB_HAVE_LINKFLAGS],\n[\n  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])\n  AC_REQUIRE([AC_LIB_RPATH])\n  define([Name],[translit([$1],[./-], [___])])\n  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],\n                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])\n\n  dnl Search for lib[]Name and define LIB[]NAME, LTLIB[]NAME and INC[]NAME\n  dnl accordingly.\n  AC_LIB_LINKFLAGS_BODY([$1], [$2])\n\n  dnl Add $INC[]NAME to CPPFLAGS before performing the following checks,\n  dnl because if the user has installed lib[]Name and not disabled its use\n  dnl via --without-lib[]Name-prefix, he wants to use it.\n  ac_save_CPPFLAGS=\"$CPPFLAGS\"\n  AC_LIB_APPENDTOVAR([CPPFLAGS], [$INC]NAME)\n\n  AC_CACHE_CHECK([for lib[]$1], [ac_cv_lib[]Name], [\n    ac_save_LIBS=\"$LIBS\"\n    LIBS=\"$LIBS $LIB[]NAME\"\n    AC_TRY_LINK([$3], [$4], [ac_cv_lib[]Name=yes], [ac_cv_lib[]Name=no])\n    LIBS=\"$ac_save_LIBS\"\n  ])\n  if test \"$ac_cv_lib[]Name\" = yes; then\n    HAVE_LIB[]NAME=yes\n    AC_DEFINE([HAVE_LIB]NAME, 1, [Define if you have the $1 library.])\n    AC_MSG_CHECKING([how to link with lib[]$1])\n    AC_MSG_RESULT([$LIB[]NAME])\n  else\n    HAVE_LIB[]NAME=no\n    dnl If $LIB[]NAME didn't lead to a usable library, we don't need\n    dnl $INC[]NAME either.\n    CPPFLAGS=\"$ac_save_CPPFLAGS\"\n    LIB[]NAME=\n    LTLIB[]NAME=\n    LIB[]NAME[]_PREFIX=\n  fi\n  AC_SUBST([HAVE_LIB]NAME)\n  AC_SUBST([LIB]NAME)\n  AC_SUBST([LTLIB]NAME)\n  AC_SUBST([LIB]NAME[_PREFIX])\n  undefine([Name])\n  undefine([NAME])\n])\n\ndnl Determine the platform dependent parameters needed to use rpath:\ndnl   acl_libext,\ndnl   acl_shlibext,\ndnl   acl_hardcode_libdir_flag_spec,\ndnl   acl_hardcode_libdir_separator,\ndnl   acl_hardcode_direct,\ndnl   acl_hardcode_minus_L.\nAC_DEFUN([AC_LIB_RPATH],\n[\n  dnl Tell automake >= 1.10 to complain if config.rpath is missing.\n  m4_ifdef([AC_REQUIRE_AUX_FILE], [AC_REQUIRE_AUX_FILE([config.rpath])])\n  AC_REQUIRE([AC_PROG_CC])                dnl we use $CC, $GCC, $LDFLAGS\n  AC_REQUIRE([AC_LIB_PROG_LD])            dnl we use $LD, $with_gnu_ld\n  AC_REQUIRE([AC_CANONICAL_HOST])         dnl we use $host\n  AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT]) dnl we use $ac_aux_dir\n  AC_CACHE_CHECK([for shared library run path origin], acl_cv_rpath, [\n    CC=\"$CC\" GCC=\"$GCC\" LDFLAGS=\"$LDFLAGS\" LD=\"$LD\" with_gnu_ld=\"$with_gnu_ld\" \\\n    ${CONFIG_SHELL-/bin/sh} \"$ac_aux_dir/config.rpath\" \"$host\" > conftest.sh\n    . ./conftest.sh\n    rm -f ./conftest.sh\n    acl_cv_rpath=done\n  ])\n  wl=\"$acl_cv_wl\"\n  acl_libext=\"$acl_cv_libext\"\n  acl_shlibext=\"$acl_cv_shlibext\"\n  acl_libname_spec=\"$acl_cv_libname_spec\"\n  acl_library_names_spec=\"$acl_cv_library_names_spec\"\n  acl_hardcode_libdir_flag_spec=\"$acl_cv_hardcode_libdir_flag_spec\"\n  acl_hardcode_libdir_separator=\"$acl_cv_hardcode_libdir_separator\"\n  acl_hardcode_direct=\"$acl_cv_hardcode_direct\"\n  acl_hardcode_minus_L=\"$acl_cv_hardcode_minus_L\"\n  dnl Determine whether the user wants rpath handling at all.\n  AC_ARG_ENABLE(rpath,\n    [  --disable-rpath         do not hardcode runtime library paths],\n    :, enable_rpath=yes)\n])\n\ndnl AC_LIB_LINKFLAGS_BODY(name [, dependencies]) searches for libname and\ndnl the libraries corresponding to explicit and implicit dependencies.\ndnl Sets the LIB${NAME}, LTLIB${NAME} and INC${NAME} variables.\ndnl Also, sets the LIB${NAME}_PREFIX variable to nonempty if libname was found\ndnl in ${LIB${NAME}_PREFIX}/$acl_libdirstem.\nAC_DEFUN([AC_LIB_LINKFLAGS_BODY],\n[\n  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])\n  define([NAME],[translit([$1],[abcdefghijklmnopqrstuvwxyz./-],\n                               [ABCDEFGHIJKLMNOPQRSTUVWXYZ___])])\n  dnl Autoconf >= 2.61 supports dots in --with options.\n  define([N_A_M_E],[m4_if(m4_version_compare(m4_defn([m4_PACKAGE_VERSION]),[2.61]),[-1],[translit([$1],[.],[_])],[$1])])\n  dnl By default, look in $includedir and $libdir.\n  use_additional=yes\n  AC_LIB_WITH_FINAL_PREFIX([\n    eval additional_includedir=\\\"$includedir\\\"\n    eval additional_libdir=\\\"$libdir\\\"\n  ])\n  AC_LIB_ARG_WITH([lib]N_A_M_E[-prefix],\n[  --with-lib]N_A_M_E[-prefix[=DIR]  search for lib$1 in DIR/include and DIR/lib\n  --without-lib]N_A_M_E[-prefix     don't search for lib$1 in includedir and libdir],\n[\n    if test \"X$withval\" = \"Xno\"; then\n      use_additional=no\n    else\n      if test \"X$withval\" = \"X\"; then\n        AC_LIB_WITH_FINAL_PREFIX([\n          eval additional_includedir=\\\"$includedir\\\"\n          eval additional_libdir=\\\"$libdir\\\"\n        ])\n      else\n        additional_includedir=\"$withval/include\"\n        additional_libdir=\"$withval/$acl_libdirstem\"\n      fi\n    fi\n])\n  dnl Search the library and its dependencies in $additional_libdir and\n  dnl $LDFLAGS. Using breadth-first-seach.\n  LIB[]NAME=\n  LTLIB[]NAME=\n  INC[]NAME=\n  LIB[]NAME[]_PREFIX=\n  rpathdirs=\n  ltrpathdirs=\n  names_already_handled=\n  names_next_round='$1 $2'\n  while test -n \"$names_next_round\"; do\n    names_this_round=\"$names_next_round\"\n    names_next_round=\n    for name in $names_this_round; do\n      already_handled=\n      for n in $names_already_handled; do\n        if test \"$n\" = \"$name\"; then\n          already_handled=yes\n          break\n        fi\n      done\n      if test -z \"$already_handled\"; then\n        names_already_handled=\"$names_already_handled $name\"\n        dnl See if it was already located by an earlier AC_LIB_LINKFLAGS\n        dnl or AC_LIB_HAVE_LINKFLAGS call.\n        uppername=`echo \"$name\" | sed -e 'y|abcdefghijklmnopqrstuvwxyz./-|ABCDEFGHIJKLMNOPQRSTUVWXYZ___|'`\n        eval value=\\\"\\$HAVE_LIB$uppername\\\"\n        if test -n \"$value\"; then\n          if test \"$value\" = yes; then\n            eval value=\\\"\\$LIB$uppername\\\"\n            test -z \"$value\" || LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$value\"\n            eval value=\\\"\\$LTLIB$uppername\\\"\n            test -z \"$value\" || LTLIB[]NAME=\"${LTLIB[]NAME}${LTLIB[]NAME:+ }$value\"\n          else\n            dnl An earlier call to AC_LIB_HAVE_LINKFLAGS has determined\n            dnl that this library doesn't exist. So just drop it.\n            :\n          fi\n        else\n          dnl Search the library lib$name in $additional_libdir and $LDFLAGS\n          dnl and the already constructed $LIBNAME/$LTLIBNAME.\n          found_dir=\n          found_la=\n          found_so=\n          found_a=\n          eval libname=\\\"$acl_libname_spec\\\"    # typically: libname=lib$name\n          if test -n \"$acl_shlibext\"; then\n            shrext=\".$acl_shlibext\"             # typically: shrext=.so\n          else\n            shrext=\n          fi\n          if test $use_additional = yes; then\n            dir=\"$additional_libdir\"\n            dnl The same code as in the loop below:\n            dnl First look for a shared library.\n            if test -n \"$acl_shlibext\"; then\n              if test -f \"$dir/$libname$shrext\"; then\n                found_dir=\"$dir\"\n                found_so=\"$dir/$libname$shrext\"\n              else\n                if test \"$acl_library_names_spec\" = '$libname$shrext$versuffix'; then\n                  ver=`(cd \"$dir\" && \\\n                        for f in \"$libname$shrext\".*; do echo \"$f\"; done \\\n                        | sed -e \"s,^$libname$shrext\\\\\\\\.,,\" \\\n                        | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \\\n                        | sed 1q ) 2>/dev/null`\n                  if test -n \"$ver\" && test -f \"$dir/$libname$shrext.$ver\"; then\n                    found_dir=\"$dir\"\n                    found_so=\"$dir/$libname$shrext.$ver\"\n                  fi\n                else\n                  eval library_names=\\\"$acl_library_names_spec\\\"\n                  for f in $library_names; do\n                    if test -f \"$dir/$f\"; then\n                      found_dir=\"$dir\"\n                      found_so=\"$dir/$f\"\n                      break\n                    fi\n                  done\n                fi\n              fi\n            fi\n            dnl Then look for a static library.\n            if test \"X$found_dir\" = \"X\"; then\n              if test -f \"$dir/$libname.$acl_libext\"; then\n                found_dir=\"$dir\"\n                found_a=\"$dir/$libname.$acl_libext\"\n              fi\n            fi\n            if test \"X$found_dir\" != \"X\"; then\n              if test -f \"$dir/$libname.la\"; then\n                found_la=\"$dir/$libname.la\"\n              fi\n            fi\n          fi\n          if test \"X$found_dir\" = \"X\"; then\n            for x in $LDFLAGS $LTLIB[]NAME; do\n              AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n              case \"$x\" in\n                -L*)\n                  dir=`echo \"X$x\" | sed -e 's/^X-L//'`\n                  dnl First look for a shared library.\n                  if test -n \"$acl_shlibext\"; then\n                    if test -f \"$dir/$libname$shrext\"; then\n                      found_dir=\"$dir\"\n                      found_so=\"$dir/$libname$shrext\"\n                    else\n                      if test \"$acl_library_names_spec\" = '$libname$shrext$versuffix'; then\n                        ver=`(cd \"$dir\" && \\\n                              for f in \"$libname$shrext\".*; do echo \"$f\"; done \\\n                              | sed -e \"s,^$libname$shrext\\\\\\\\.,,\" \\\n                              | sort -t '.' -n -r -k1,1 -k2,2 -k3,3 -k4,4 -k5,5 \\\n                              | sed 1q ) 2>/dev/null`\n                        if test -n \"$ver\" && test -f \"$dir/$libname$shrext.$ver\"; then\n                          found_dir=\"$dir\"\n                          found_so=\"$dir/$libname$shrext.$ver\"\n                        fi\n                      else\n                        eval library_names=\\\"$acl_library_names_spec\\\"\n                        for f in $library_names; do\n                          if test -f \"$dir/$f\"; then\n                            found_dir=\"$dir\"\n                            found_so=\"$dir/$f\"\n                            break\n                          fi\n                        done\n                      fi\n                    fi\n                  fi\n                  dnl Then look for a static library.\n                  if test \"X$found_dir\" = \"X\"; then\n                    if test -f \"$dir/$libname.$acl_libext\"; then\n                      found_dir=\"$dir\"\n                      found_a=\"$dir/$libname.$acl_libext\"\n                    fi\n                  fi\n                  if test \"X$found_dir\" != \"X\"; then\n                    if test -f \"$dir/$libname.la\"; then\n                      found_la=\"$dir/$libname.la\"\n                    fi\n                  fi\n                  ;;\n              esac\n              if test \"X$found_dir\" != \"X\"; then\n                break\n              fi\n            done\n          fi\n          if test \"X$found_dir\" != \"X\"; then\n            dnl Found the library.\n            LTLIB[]NAME=\"${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$found_dir -l$name\"\n            if test \"X$found_so\" != \"X\"; then\n              dnl Linking with a shared library. We attempt to hardcode its\n              dnl directory into the executable's runpath, unless it's the\n              dnl standard /usr/lib.\n              if test \"$enable_rpath\" = no || test \"X$found_dir\" = \"X/usr/$acl_libdirstem\"; then\n                dnl No hardcoding is needed.\n                LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$found_so\"\n              else\n                dnl Use an explicit option to hardcode DIR into the resulting\n                dnl binary.\n                dnl Potentially add DIR to ltrpathdirs.\n                dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.\n                haveit=\n                for x in $ltrpathdirs; do\n                  if test \"X$x\" = \"X$found_dir\"; then\n                    haveit=yes\n                    break\n                  fi\n                done\n                if test -z \"$haveit\"; then\n                  ltrpathdirs=\"$ltrpathdirs $found_dir\"\n                fi\n                dnl The hardcoding into $LIBNAME is system dependent.\n                if test \"$acl_hardcode_direct\" = yes; then\n                  dnl Using DIR/libNAME.so during linking hardcodes DIR into the\n                  dnl resulting binary.\n                  LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$found_so\"\n                else\n                  if test -n \"$acl_hardcode_libdir_flag_spec\" && test \"$acl_hardcode_minus_L\" = no; then\n                    dnl Use an explicit option to hardcode DIR into the resulting\n                    dnl binary.\n                    LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$found_so\"\n                    dnl Potentially add DIR to rpathdirs.\n                    dnl The rpathdirs will be appended to $LIBNAME at the end.\n                    haveit=\n                    for x in $rpathdirs; do\n                      if test \"X$x\" = \"X$found_dir\"; then\n                        haveit=yes\n                        break\n                      fi\n                    done\n                    if test -z \"$haveit\"; then\n                      rpathdirs=\"$rpathdirs $found_dir\"\n                    fi\n                  else\n                    dnl Rely on \"-L$found_dir\".\n                    dnl But don't add it if it's already contained in the LDFLAGS\n                    dnl or the already constructed $LIBNAME\n                    haveit=\n                    for x in $LDFLAGS $LIB[]NAME; do\n                      AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n                      if test \"X$x\" = \"X-L$found_dir\"; then\n                        haveit=yes\n                        break\n                      fi\n                    done\n                    if test -z \"$haveit\"; then\n                      LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir\"\n                    fi\n                    if test \"$acl_hardcode_minus_L\" != no; then\n                      dnl FIXME: Not sure whether we should use\n                      dnl \"-L$found_dir -l$name\" or \"-L$found_dir $found_so\"\n                      dnl here.\n                      LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$found_so\"\n                    else\n                      dnl We cannot use $acl_hardcode_runpath_var and LD_RUN_PATH\n                      dnl here, because this doesn't fit in flags passed to the\n                      dnl compiler. So give up. No hardcoding. This affects only\n                      dnl very old systems.\n                      dnl FIXME: Not sure whether we should use\n                      dnl \"-L$found_dir -l$name\" or \"-L$found_dir $found_so\"\n                      dnl here.\n                      LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }-l$name\"\n                    fi\n                  fi\n                fi\n              fi\n            else\n              if test \"X$found_a\" != \"X\"; then\n                dnl Linking with a static library.\n                LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$found_a\"\n              else\n                dnl We shouldn't come here, but anyway it's good to have a\n                dnl fallback.\n                LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }-L$found_dir -l$name\"\n              fi\n            fi\n            dnl Assume the include files are nearby.\n            additional_includedir=\n            case \"$found_dir\" in\n              */$acl_libdirstem | */$acl_libdirstem/)\n                basedir=`echo \"X$found_dir\" | sed -e 's,^X,,' -e \"s,/$acl_libdirstem/\"'*$,,'`\n                LIB[]NAME[]_PREFIX=\"$basedir\"\n                additional_includedir=\"$basedir/include\"\n                ;;\n            esac\n            if test \"X$additional_includedir\" != \"X\"; then\n              dnl Potentially add $additional_includedir to $INCNAME.\n              dnl But don't add it\n              dnl   1. if it's the standard /usr/include,\n              dnl   2. if it's /usr/local/include and we are using GCC on Linux,\n              dnl   3. if it's already present in $CPPFLAGS or the already\n              dnl      constructed $INCNAME,\n              dnl   4. if it doesn't exist as a directory.\n              if test \"X$additional_includedir\" != \"X/usr/include\"; then\n                haveit=\n                if test \"X$additional_includedir\" = \"X/usr/local/include\"; then\n                  if test -n \"$GCC\"; then\n                    case $host_os in\n                      linux* | gnu* | k*bsd*-gnu) haveit=yes;;\n                    esac\n                  fi\n                fi\n                if test -z \"$haveit\"; then\n                  for x in $CPPFLAGS $INC[]NAME; do\n                    AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n                    if test \"X$x\" = \"X-I$additional_includedir\"; then\n                      haveit=yes\n                      break\n                    fi\n                  done\n                  if test -z \"$haveit\"; then\n                    if test -d \"$additional_includedir\"; then\n                      dnl Really add $additional_includedir to $INCNAME.\n                      INC[]NAME=\"${INC[]NAME}${INC[]NAME:+ }-I$additional_includedir\"\n                    fi\n                  fi\n                fi\n              fi\n            fi\n            dnl Look for dependencies.\n            if test -n \"$found_la\"; then\n              dnl Read the .la file. It defines the variables\n              dnl dlname, library_names, old_library, dependency_libs, current,\n              dnl age, revision, installed, dlopen, dlpreopen, libdir.\n              save_libdir=\"$libdir\"\n              case \"$found_la\" in\n                */* | *\\\\*) . \"$found_la\" ;;\n                *) . \"./$found_la\" ;;\n              esac\n              libdir=\"$save_libdir\"\n              dnl We use only dependency_libs.\n              for dep in $dependency_libs; do\n                case \"$dep\" in\n                  -L*)\n                    additional_libdir=`echo \"X$dep\" | sed -e 's/^X-L//'`\n                    dnl Potentially add $additional_libdir to $LIBNAME and $LTLIBNAME.\n                    dnl But don't add it\n                    dnl   1. if it's the standard /usr/lib,\n                    dnl   2. if it's /usr/local/lib and we are using GCC on Linux,\n                    dnl   3. if it's already present in $LDFLAGS or the already\n                    dnl      constructed $LIBNAME,\n                    dnl   4. if it doesn't exist as a directory.\n                    if test \"X$additional_libdir\" != \"X/usr/$acl_libdirstem\"; then\n                      haveit=\n                      if test \"X$additional_libdir\" = \"X/usr/local/$acl_libdirstem\"; then\n                        if test -n \"$GCC\"; then\n                          case $host_os in\n                            linux* | gnu* | k*bsd*-gnu) haveit=yes;;\n                          esac\n                        fi\n                      fi\n                      if test -z \"$haveit\"; then\n                        haveit=\n                        for x in $LDFLAGS $LIB[]NAME; do\n                          AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n                          if test \"X$x\" = \"X-L$additional_libdir\"; then\n                            haveit=yes\n                            break\n                          fi\n                        done\n                        if test -z \"$haveit\"; then\n                          if test -d \"$additional_libdir\"; then\n                            dnl Really add $additional_libdir to $LIBNAME.\n                            LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }-L$additional_libdir\"\n                          fi\n                        fi\n                        haveit=\n                        for x in $LDFLAGS $LTLIB[]NAME; do\n                          AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n                          if test \"X$x\" = \"X-L$additional_libdir\"; then\n                            haveit=yes\n                            break\n                          fi\n                        done\n                        if test -z \"$haveit\"; then\n                          if test -d \"$additional_libdir\"; then\n                            dnl Really add $additional_libdir to $LTLIBNAME.\n                            LTLIB[]NAME=\"${LTLIB[]NAME}${LTLIB[]NAME:+ }-L$additional_libdir\"\n                          fi\n                        fi\n                      fi\n                    fi\n                    ;;\n                  -R*)\n                    dir=`echo \"X$dep\" | sed -e 's/^X-R//'`\n                    if test \"$enable_rpath\" != no; then\n                      dnl Potentially add DIR to rpathdirs.\n                      dnl The rpathdirs will be appended to $LIBNAME at the end.\n                      haveit=\n                      for x in $rpathdirs; do\n                        if test \"X$x\" = \"X$dir\"; then\n                          haveit=yes\n                          break\n                        fi\n                      done\n                      if test -z \"$haveit\"; then\n                        rpathdirs=\"$rpathdirs $dir\"\n                      fi\n                      dnl Potentially add DIR to ltrpathdirs.\n                      dnl The ltrpathdirs will be appended to $LTLIBNAME at the end.\n                      haveit=\n                      for x in $ltrpathdirs; do\n                        if test \"X$x\" = \"X$dir\"; then\n                          haveit=yes\n                          break\n                        fi\n                      done\n                      if test -z \"$haveit\"; then\n                        ltrpathdirs=\"$ltrpathdirs $dir\"\n                      fi\n                    fi\n                    ;;\n                  -l*)\n                    dnl Handle this in the next round.\n                    names_next_round=\"$names_next_round \"`echo \"X$dep\" | sed -e 's/^X-l//'`\n                    ;;\n                  *.la)\n                    dnl Handle this in the next round. Throw away the .la's\n                    dnl directory; it is already contained in a preceding -L\n                    dnl option.\n                    names_next_round=\"$names_next_round \"`echo \"X$dep\" | sed -e 's,^X.*/,,' -e 's,^lib,,' -e 's,\\.la$,,'`\n                    ;;\n                  *)\n                    dnl Most likely an immediate library name.\n                    LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$dep\"\n                    LTLIB[]NAME=\"${LTLIB[]NAME}${LTLIB[]NAME:+ }$dep\"\n                    ;;\n                esac\n              done\n            fi\n          else\n            dnl Didn't find the library; assume it is in the system directories\n            dnl known to the linker and runtime loader. (All the system\n            dnl directories known to the linker should also be known to the\n            dnl runtime loader, otherwise the system is severely misconfigured.)\n            LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }-l$name\"\n            LTLIB[]NAME=\"${LTLIB[]NAME}${LTLIB[]NAME:+ }-l$name\"\n          fi\n        fi\n      fi\n    done\n  done\n  if test \"X$rpathdirs\" != \"X\"; then\n    if test -n \"$acl_hardcode_libdir_separator\"; then\n      dnl Weird platform: only the last -rpath option counts, the user must\n      dnl pass all path elements in one option. We can arrange that for a\n      dnl single library, but not when more than one $LIBNAMEs are used.\n      alldirs=\n      for found_dir in $rpathdirs; do\n        alldirs=\"${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$found_dir\"\n      done\n      dnl Note: acl_hardcode_libdir_flag_spec uses $libdir and $wl.\n      acl_save_libdir=\"$libdir\"\n      libdir=\"$alldirs\"\n      eval flag=\\\"$acl_hardcode_libdir_flag_spec\\\"\n      libdir=\"$acl_save_libdir\"\n      LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$flag\"\n    else\n      dnl The -rpath options are cumulative.\n      for found_dir in $rpathdirs; do\n        acl_save_libdir=\"$libdir\"\n        libdir=\"$found_dir\"\n        eval flag=\\\"$acl_hardcode_libdir_flag_spec\\\"\n        libdir=\"$acl_save_libdir\"\n        LIB[]NAME=\"${LIB[]NAME}${LIB[]NAME:+ }$flag\"\n      done\n    fi\n  fi\n  if test \"X$ltrpathdirs\" != \"X\"; then\n    dnl When using libtool, the option that works for both libraries and\n    dnl executables is -R. The -R options are cumulative.\n    for found_dir in $ltrpathdirs; do\n      LTLIB[]NAME=\"${LTLIB[]NAME}${LTLIB[]NAME:+ }-R$found_dir\"\n    done\n  fi\n])\n\ndnl AC_LIB_APPENDTOVAR(VAR, CONTENTS) appends the elements of CONTENTS to VAR,\ndnl unless already present in VAR.\ndnl Works only for CPPFLAGS, not for LIB* variables because that sometimes\ndnl contains two or three consecutive elements that belong together.\nAC_DEFUN([AC_LIB_APPENDTOVAR],\n[\n  for element in [$2]; do\n    haveit=\n    for x in $[$1]; do\n      AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n      if test \"X$x\" = \"X$element\"; then\n        haveit=yes\n        break\n      fi\n    done\n    if test -z \"$haveit\"; then\n      [$1]=\"${[$1]}${[$1]:+ }$element\"\n    fi\n  done\n])\n\ndnl For those cases where a variable contains several -L and -l options\ndnl referring to unknown libraries and directories, this macro determines the\ndnl necessary additional linker options for the runtime path.\ndnl AC_LIB_LINKFLAGS_FROM_LIBS([LDADDVAR], [LIBSVALUE], [USE-LIBTOOL])\ndnl sets LDADDVAR to linker options needed together with LIBSVALUE.\ndnl If USE-LIBTOOL evaluates to non-empty, linking with libtool is assumed,\ndnl otherwise linking without libtool is assumed.\nAC_DEFUN([AC_LIB_LINKFLAGS_FROM_LIBS],\n[\n  AC_REQUIRE([AC_LIB_RPATH])\n  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])\n  $1=\n  if test \"$enable_rpath\" != no; then\n    if test -n \"$acl_hardcode_libdir_flag_spec\" && test \"$acl_hardcode_minus_L\" = no; then\n      dnl Use an explicit option to hardcode directories into the resulting\n      dnl binary.\n      rpathdirs=\n      next=\n      for opt in $2; do\n        if test -n \"$next\"; then\n          dir=\"$next\"\n          dnl No need to hardcode the standard /usr/lib.\n          if test \"X$dir\" != \"X/usr/$acl_libdirstem\"; then\n            rpathdirs=\"$rpathdirs $dir\"\n          fi\n          next=\n        else\n          case $opt in\n            -L) next=yes ;;\n            -L*) dir=`echo \"X$opt\" | sed -e 's,^X-L,,'`\n                 dnl No need to hardcode the standard /usr/lib.\n                 if test \"X$dir\" != \"X/usr/$acl_libdirstem\"; then\n                   rpathdirs=\"$rpathdirs $dir\"\n                 fi\n                 next= ;;\n            *) next= ;;\n          esac\n        fi\n      done\n      if test \"X$rpathdirs\" != \"X\"; then\n        if test -n \"\"$3\"\"; then\n          dnl libtool is used for linking. Use -R options.\n          for dir in $rpathdirs; do\n            $1=\"${$1}${$1:+ }-R$dir\"\n          done\n        else\n          dnl The linker is used for linking directly.\n          if test -n \"$acl_hardcode_libdir_separator\"; then\n            dnl Weird platform: only the last -rpath option counts, the user\n            dnl must pass all path elements in one option.\n            alldirs=\n            for dir in $rpathdirs; do\n              alldirs=\"${alldirs}${alldirs:+$acl_hardcode_libdir_separator}$dir\"\n            done\n            acl_save_libdir=\"$libdir\"\n            libdir=\"$alldirs\"\n            eval flag=\\\"$acl_hardcode_libdir_flag_spec\\\"\n            libdir=\"$acl_save_libdir\"\n            $1=\"$flag\"\n          else\n            dnl The -rpath options are cumulative.\n            for dir in $rpathdirs; do\n              acl_save_libdir=\"$libdir\"\n              libdir=\"$dir\"\n              eval flag=\\\"$acl_hardcode_libdir_flag_spec\\\"\n              libdir=\"$acl_save_libdir\"\n              $1=\"${$1}${$1:+ }$flag\"\n            done\n          fi\n        fi\n      fi\n    fi\n  fi\n  AC_SUBST([$1])\n])\n"
  },
  {
    "path": "m4/lib-prefix.m4",
    "content": "# lib-prefix.m4\n# serial 23\ndnl Copyright (C) 2001-2005, 2008-2024 Free Software Foundation, Inc.\ndnl This file is free software; the Free Software Foundation\ndnl gives unlimited permission to copy and/or distribute it,\ndnl with or without modifications, as long as this notice is preserved.\ndnl This file is offered as-is, without any warranty.\n\ndnl From Bruno Haible.\n\ndnl AC_LIB_PREFIX adds to the CPPFLAGS and LDFLAGS the flags that are needed\ndnl to access previously installed libraries. The basic assumption is that\ndnl a user will want packages to use other packages he previously installed\ndnl with the same --prefix option.\ndnl This macro is not needed if only AC_LIB_LINKFLAGS is used to locate\ndnl libraries, but is otherwise very convenient.\nAC_DEFUN([AC_LIB_PREFIX],\n[\n  AC_BEFORE([$0], [AC_LIB_LINKFLAGS])\n  AC_REQUIRE([AC_PROG_CC])\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([AC_LIB_PREPARE_MULTILIB])\n  AC_REQUIRE([AC_LIB_PREPARE_PREFIX])\n  dnl By default, look in $includedir and $libdir.\n  use_additional=yes\n  AC_LIB_WITH_FINAL_PREFIX([\n    eval additional_includedir=\\\"$includedir\\\"\n    eval additional_libdir=\\\"$libdir\\\"\n  ])\n  AC_ARG_WITH([lib-prefix],\n[[  --with-lib-prefix[=DIR] search for libraries in DIR/include and DIR/lib\n  --without-lib-prefix    don't search for libraries in includedir and libdir]],\n[\n    if test \"X$withval\" = \"Xno\"; then\n      use_additional=no\n    else\n      if test \"X$withval\" = \"X\"; then\n        AC_LIB_WITH_FINAL_PREFIX([\n          eval additional_includedir=\\\"$includedir\\\"\n          eval additional_libdir=\\\"$libdir\\\"\n        ])\n      else\n        additional_includedir=\"$withval/include\"\n        additional_libdir=\"$withval/$acl_libdirstem\"\n      fi\n    fi\n])\n  if test $use_additional = yes; then\n    dnl Potentially add $additional_includedir to $CPPFLAGS.\n    dnl But don't add it\n    dnl   1. if it's the standard /usr/include,\n    dnl   2. if it's already present in $CPPFLAGS,\n    dnl   3. if it's /usr/local/include and we are using GCC on Linux,\n    dnl   4. if it doesn't exist as a directory.\n    if test \"X$additional_includedir\" != \"X/usr/include\"; then\n      haveit=\n      for x in $CPPFLAGS; do\n        AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n        if test \"X$x\" = \"X-I$additional_includedir\"; then\n          haveit=yes\n          break\n        fi\n      done\n      if test -z \"$haveit\"; then\n        if test \"X$additional_includedir\" = \"X/usr/local/include\"; then\n          if test -n \"$GCC\"; then\n            case $host_os in\n              linux* | gnu* | k*bsd*-gnu) haveit=yes;;\n            esac\n          fi\n        fi\n        if test -z \"$haveit\"; then\n          if test -d \"$additional_includedir\"; then\n            dnl Really add $additional_includedir to $CPPFLAGS.\n            CPPFLAGS=\"${CPPFLAGS}${CPPFLAGS:+ }-I$additional_includedir\"\n          fi\n        fi\n      fi\n    fi\n    dnl Potentially add $additional_libdir to $LDFLAGS.\n    dnl But don't add it\n    dnl   1. if it's the standard /usr/lib,\n    dnl   2. if it's already present in $LDFLAGS,\n    dnl   3. if it's /usr/local/lib and we are using GCC on Linux,\n    dnl   4. if it doesn't exist as a directory.\n    if test \"X$additional_libdir\" != \"X/usr/$acl_libdirstem\"; then\n      haveit=\n      for x in $LDFLAGS; do\n        AC_LIB_WITH_FINAL_PREFIX([eval x=\\\"$x\\\"])\n        if test \"X$x\" = \"X-L$additional_libdir\"; then\n          haveit=yes\n          break\n        fi\n      done\n      if test -z \"$haveit\"; then\n        if test \"X$additional_libdir\" = \"X/usr/local/$acl_libdirstem\"; then\n          if test -n \"$GCC\"; then\n            case $host_os in\n              linux*) haveit=yes;;\n            esac\n          fi\n        fi\n        if test -z \"$haveit\"; then\n          if test -d \"$additional_libdir\"; then\n            dnl Really add $additional_libdir to $LDFLAGS.\n            LDFLAGS=\"${LDFLAGS}${LDFLAGS:+ }-L$additional_libdir\"\n          fi\n        fi\n      fi\n    fi\n  fi\n])\n\ndnl AC_LIB_PREPARE_PREFIX creates variables acl_final_prefix,\ndnl acl_final_exec_prefix, containing the values to which $prefix and\ndnl $exec_prefix will expand at the end of the configure script.\nAC_DEFUN([AC_LIB_PREPARE_PREFIX],\n[\n  dnl Unfortunately, prefix and exec_prefix get only finally determined\n  dnl at the end of configure.\n  if test \"X$prefix\" = \"XNONE\"; then\n    acl_final_prefix=\"$ac_default_prefix\"\n  else\n    acl_final_prefix=\"$prefix\"\n  fi\n  if test \"X$exec_prefix\" = \"XNONE\"; then\n    acl_final_exec_prefix='${prefix}'\n  else\n    acl_final_exec_prefix=\"$exec_prefix\"\n  fi\n  acl_saved_prefix=\"$prefix\"\n  prefix=\"$acl_final_prefix\"\n  eval acl_final_exec_prefix=\\\"$acl_final_exec_prefix\\\"\n  prefix=\"$acl_saved_prefix\"\n])\n\ndnl AC_LIB_WITH_FINAL_PREFIX([statement]) evaluates statement, with the\ndnl variables prefix and exec_prefix bound to the values they will have\ndnl at the end of the configure script.\nAC_DEFUN([AC_LIB_WITH_FINAL_PREFIX],\n[\n  acl_saved_prefix=\"$prefix\"\n  prefix=\"$acl_final_prefix\"\n  acl_saved_exec_prefix=\"$exec_prefix\"\n  exec_prefix=\"$acl_final_exec_prefix\"\n  $1\n  exec_prefix=\"$acl_saved_exec_prefix\"\n  prefix=\"$acl_saved_prefix\"\n])\n\ndnl AC_LIB_PREPARE_MULTILIB creates\ndnl - a function acl_is_expected_elfclass, that tests whether standard input\ndn;   has a 32-bit or 64-bit ELF header, depending on the host CPU ABI,\ndnl - 3 variables acl_libdirstem, acl_libdirstem2, acl_libdirstem3, containing\ndnl   the basename of the libdir to try in turn, either \"lib\" or \"lib64\" or\ndnl   \"lib/64\" or \"lib32\" or \"lib/sparcv9\" or \"lib/amd64\" or similar.\nAC_DEFUN([AC_LIB_PREPARE_MULTILIB],\n[\n  dnl There is no formal standard regarding lib, lib32, and lib64.\n  dnl On most glibc systems, the current practice is that on a system supporting\n  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under\n  dnl $prefix/lib64 and 32-bit libraries go under $prefix/lib. However, on\n  dnl Arch Linux based distributions, it's the opposite: 32-bit libraries go\n  dnl under $prefix/lib32 and 64-bit libraries go under $prefix/lib.\n  dnl We determine the compiler's default mode by looking at the compiler's\n  dnl library search path. If at least one of its elements ends in /lib64 or\n  dnl points to a directory whose absolute pathname ends in /lib64, we use that\n  dnl for 64-bit ABIs. Similarly for 32-bit ABIs. Otherwise we use the default,\n  dnl namely \"lib\".\n  dnl On Solaris systems, the current practice is that on a system supporting\n  dnl 32-bit and 64-bit instruction sets or ABIs, 64-bit libraries go under\n  dnl $prefix/lib/64 (which is a symlink to either $prefix/lib/sparcv9 or\n  dnl $prefix/lib/amd64) and 32-bit libraries go under $prefix/lib.\n  AC_REQUIRE([AC_CANONICAL_HOST])\n  AC_REQUIRE([gl_HOST_CPU_C_ABI_32BIT])\n\n  AC_CACHE_CHECK([for ELF binary format], [gl_cv_elf],\n    [AC_EGREP_CPP([Extensible Linking Format],\n       [#if defined __ELF__ || (defined __linux__ && (defined __EDG__ || defined __SUNPRO_C))\n        Extensible Linking Format\n        #endif\n       ],\n       [gl_cv_elf=yes],\n       [gl_cv_elf=no])\n    ])\n  if test $gl_cv_elf = yes; then\n    # Extract the ELF class of a file (5th byte) in decimal.\n    # Cf. https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header\n    if od -A x < /dev/null >/dev/null 2>/dev/null; then\n      # Use POSIX od.\n      func_elfclass ()\n      {\n        od -A n -t d1 -j 4 -N 1\n      }\n    else\n      # Use BSD hexdump.\n      func_elfclass ()\n      {\n        dd bs=1 count=1 skip=4 2>/dev/null | hexdump -e '1/1 \"%3d \"'\n        echo\n      }\n    fi\n    # Use 'expr', not 'test', to compare the values of func_elfclass, because on\n    # Solaris 11 OpenIndiana and Solaris 11 OmniOS, the result is 001 or 002,\n    # not 1 or 2.\nchangequote(,)dnl\n    case $HOST_CPU_C_ABI_32BIT in\n      yes)\n        # 32-bit ABI.\n        acl_is_expected_elfclass ()\n        {\n          expr \"`func_elfclass | sed -e 's/[ \t]//g'`\" = 1 > /dev/null\n        }\n        ;;\n      no)\n        # 64-bit ABI.\n        acl_is_expected_elfclass ()\n        {\n          expr \"`func_elfclass | sed -e 's/[ \t]//g'`\" = 2 > /dev/null\n        }\n        ;;\n      *)\n        # Unknown.\n        acl_is_expected_elfclass ()\n        {\n          :\n        }\n        ;;\n    esac\nchangequote([,])dnl\n  else\n    acl_is_expected_elfclass ()\n    {\n      :\n    }\n  fi\n\n  dnl Allow the user to override the result by setting acl_cv_libdirstems.\n  AC_CACHE_CHECK([for the common suffixes of directories in the library search path],\n    [acl_cv_libdirstems],\n    [dnl Try 'lib' first, because that's the default for libdir in GNU, see\n     dnl <https://www.gnu.org/prep/standards/html_node/Directory-Variables.html>.\n     acl_libdirstem=lib\n     acl_libdirstem2=\n     acl_libdirstem3=\n     case \"$host_os\" in\n       solaris*)\n         dnl See Solaris 10 Software Developer Collection > Solaris 64-bit Developer's Guide > The Development Environment\n         dnl <https://docs.oracle.com/cd/E19253-01/816-5138/dev-env/index.html>.\n         dnl \"Portable Makefiles should refer to any library directories using the 64 symbolic link.\"\n         dnl But we want to recognize the sparcv9 or amd64 subdirectory also if the\n         dnl symlink is missing, so we set acl_libdirstem2 too.\n         if test $HOST_CPU_C_ABI_32BIT = no; then\n           acl_libdirstem2=lib/64\n           case \"$host_cpu\" in\n             sparc*)        acl_libdirstem3=lib/sparcv9 ;;\n             i*86 | x86_64) acl_libdirstem3=lib/amd64 ;;\n           esac\n         fi\n         ;;\n       netbsd*)\n         dnl On NetBSD/sparc64, there is a 'sparc' subdirectory that contains\n         dnl 32-bit libraries.\n         if test $HOST_CPU_C_ABI_32BIT != no; then\n           case \"$host_cpu\" in\n             sparc*) acl_libdirstem2=lib/sparc ;;\n           esac\n         fi\n         ;;\n       *)\n         dnl If $CC generates code for a 32-bit ABI, the libraries are\n         dnl surely under $prefix/lib or $prefix/lib32, not $prefix/lib64.\n         dnl Similarly, if $CC generates code for a 64-bit ABI, the libraries\n         dnl are surely under $prefix/lib or $prefix/lib64, not $prefix/lib32.\n         dnl Find the compiler's search path. However, non-system compilers\n         dnl sometimes have odd library search paths. But we can't simply invoke\n         dnl '/usr/bin/gcc -print-search-dirs' because that would not take into\n         dnl account the -m32/-m31 or -m64 options from the $CC or $CFLAGS.\n         searchpath=`(LC_ALL=C $CC $CPPFLAGS $CFLAGS -print-search-dirs) 2>/dev/null \\\n                     | sed -n -e 's,^libraries: ,,p' | sed -e 's,^=,,'`\n         if test $HOST_CPU_C_ABI_32BIT != no; then\n           # 32-bit or unknown ABI.\n           if test -d /usr/lib32; then\n             acl_libdirstem2=lib32\n           fi\n         fi\n         if test $HOST_CPU_C_ABI_32BIT != yes; then\n           # 64-bit or unknown ABI.\n           if test -d /usr/lib64; then\n             acl_libdirstem3=lib64\n           fi\n         fi\n         if test -n \"$searchpath\"; then\n           acl_saved_IFS=\"${IFS= \t}\"; IFS=\":\"\n           for searchdir in $searchpath; do\n             if test -d \"$searchdir\"; then\n               case \"$searchdir\" in\n                 */lib32/ | */lib32 ) acl_libdirstem2=lib32 ;;\n                 */lib64/ | */lib64 ) acl_libdirstem3=lib64 ;;\n                 */../ | */.. )\n                   # Better ignore directories of this form. They are misleading.\n                   ;;\n                 *) searchdir=`cd \"$searchdir\" && pwd`\n                    case \"$searchdir\" in\n                      */lib32 ) acl_libdirstem2=lib32 ;;\n                      */lib64 ) acl_libdirstem3=lib64 ;;\n                    esac ;;\n               esac\n             fi\n           done\n           IFS=\"$acl_saved_IFS\"\n           if test $HOST_CPU_C_ABI_32BIT = yes; then\n             # 32-bit ABI.\n             acl_libdirstem3=\n           fi\n           if test $HOST_CPU_C_ABI_32BIT = no; then\n             # 64-bit ABI.\n             acl_libdirstem2=\n           fi\n         fi\n         ;;\n     esac\n     test -n \"$acl_libdirstem2\" || acl_libdirstem2=\"$acl_libdirstem\"\n     test -n \"$acl_libdirstem3\" || acl_libdirstem3=\"$acl_libdirstem\"\n     acl_cv_libdirstems=\"$acl_libdirstem,$acl_libdirstem2,$acl_libdirstem3\"\n    ])\n  dnl Decompose acl_cv_libdirstems into acl_libdirstem, acl_libdirstem2, and\n  dnl acl_libdirstem3.\nchangequote(,)dnl\n  acl_libdirstem=`echo \"$acl_cv_libdirstems\" | sed -e 's/,.*//'`\n  acl_libdirstem2=`echo \"$acl_cv_libdirstems\" | sed -e 's/^[^,]*,//' -e 's/,.*//'`\n  acl_libdirstem3=`echo \"$acl_cv_libdirstems\" | sed -e 's/^[^,]*,[^,]*,//' -e 's/,.*//'`\nchangequote([,])dnl\n])\n"
  },
  {
    "path": "m4/pkg.m4",
    "content": "# pkg.m4 - Macros to locate and use pkg-config.   -*- Autoconf -*-\n# serial 12 (pkg-config-0.29.2)\n\ndnl Copyright © 2004 Scott James Remnant <scott@netsplit.com>.\ndnl Copyright © 2012-2015 Dan Nicholson <dbn.lists@gmail.com>\ndnl\ndnl This program is free software; you can redistribute it and/or modify\ndnl it under the terms of the GNU General Public License as published by\ndnl the Free Software Foundation; either version 2 of the License, or\ndnl (at your option) any later version.\ndnl\ndnl This program is distributed in the hope that it will be useful, but\ndnl WITHOUT ANY WARRANTY; without even the implied warranty of\ndnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\ndnl General Public License for more details.\ndnl\ndnl You should have received a copy of the GNU General Public License\ndnl along with this program; if not, write to the Free Software\ndnl Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\ndnl 02111-1307, USA.\ndnl\ndnl As a special exception to the GNU General Public License, if you\ndnl distribute this file as part of a program that contains a\ndnl configuration script generated by Autoconf, you may include it under\ndnl the same distribution terms that you use for the rest of that\ndnl program.\n\ndnl PKG_PREREQ(MIN-VERSION)\ndnl -----------------------\ndnl Since: 0.29\ndnl\ndnl Verify that the version of the pkg-config macros are at least\ndnl MIN-VERSION. Unlike PKG_PROG_PKG_CONFIG, which checks the user's\ndnl installed version of pkg-config, this checks the developer's version\ndnl of pkg.m4 when generating configure.\ndnl\ndnl To ensure that this macro is defined, also add:\ndnl m4_ifndef([PKG_PREREQ],\ndnl     [m4_fatal([must install pkg-config 0.29 or later before running autoconf/autogen])])\ndnl\ndnl See the \"Since\" comment for each macro you use to see what version\ndnl of the macros you require.\nm4_defun([PKG_PREREQ],\n[m4_define([PKG_MACROS_VERSION], [0.29.2])\nm4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1,\n    [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])])\n])dnl PKG_PREREQ\n\ndnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND])\ndnl ---------------------------------------------------------\ndnl Since: 0.16\ndnl\ndnl Search for the pkg-config tool and set the PKG_CONFIG variable to\ndnl first found in the path. Checks that the version of pkg-config found\ndnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is\ndnl used since that's the first version where most current features of\ndnl pkg-config existed.\ndnl\ndnl If pkg-config is not found or older than specified, it will result\ndnl in an empty PKG_CONFIG variable. To avoid widespread issues with\ndnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting.\ndnl You can specify [PKG_CONFIG=false] as an action instead, which would\ndnl result in pkg-config tests failing, but no bogus error messages.\nAC_DEFUN([PKG_PROG_PKG_CONFIG],\n[m4_pattern_forbid([^_?PKG_[A-Z_]+$])\nm4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])\nm4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])\nAC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])\nAC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])\nAC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])\n\nif test \"x$ac_cv_env_PKG_CONFIG_set\" != \"xset\"; then\n\tAC_PATH_TOOL([PKG_CONFIG], [pkg-config])\nfi\nif test -n \"$PKG_CONFIG\"; then\n\t_pkg_min_version=m4_default([$1], [0.9.0])\n\tAC_MSG_CHECKING([pkg-config is at least version $_pkg_min_version])\n\tif $PKG_CONFIG --atleast-pkgconfig-version $_pkg_min_version; then\n\t\tAC_MSG_RESULT([yes])\n\telse\n\t\tAC_MSG_RESULT([no])\n\t\tPKG_CONFIG=\"\"\n\tfi\nfi\nif test -z \"$PKG_CONFIG\"; then\n\tm4_default([$2], [AC_MSG_ERROR([pkg-config not found])])\nfi[]dnl\n])dnl PKG_PROG_PKG_CONFIG\n\ndnl PKG_CHECK_EXISTS(MODULES, [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])\ndnl -------------------------------------------------------------------\ndnl Since: 0.18\ndnl\ndnl Check to see whether a particular set of modules exists. Similar to\ndnl PKG_CHECK_MODULES(), but does not set variables or print errors.\ndnl\ndnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG])\ndnl only at the first occurrence in configure.ac, so if the first place\ndnl it's called might be skipped (such as if it is within an \"if\", you\ndnl have to call PKG_CHECK_EXISTS manually\nAC_DEFUN([PKG_CHECK_EXISTS],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl\nif test -n \"$PKG_CONFIG\" && \\\n    AC_RUN_LOG([$PKG_CONFIG --exists --print-errors \"$1\"]); then\n  m4_default([$2], [:])\nm4_ifvaln([$3], [else\n  $3])dnl\nfi])\n\ndnl _PKG_CONFIG([VARIABLE], [COMMAND], [MODULES])\ndnl ---------------------------------------------\ndnl Internal wrapper calling pkg-config via PKG_CONFIG and setting\ndnl pkg_failed based on the result.\nm4_define([_PKG_CONFIG],\n[if test -n \"$$1\"; then\n    pkg_cv_[]$1=\"$$1\"\n elif test -n \"$PKG_CONFIG\"; then\n    PKG_CHECK_EXISTS([$3],\n                     [pkg_cv_[]$1=`$PKG_CONFIG --[]$2 \"$3\" 2>/dev/null`\n\t\t      test \"x$?\" != \"x0\" && pkg_failed=yes ],\n\t\t     [pkg_failed=yes])\n else\n    pkg_failed=untried\nfi[]dnl\n])dnl _PKG_CONFIG\n\ndnl _PKG_SHORT_ERRORS_SUPPORTED\ndnl ---------------------------\ndnl Internal check to see if pkg-config supports short errors.\nAC_DEFUN([_PKG_SHORT_ERRORS_SUPPORTED],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])\nif $PKG_CONFIG --atleast-pkgconfig-version 0.20; then\n        _pkg_short_errors_supported=yes\nelse\n        _pkg_short_errors_supported=no\nfi[]dnl\n])dnl _PKG_SHORT_ERRORS_SUPPORTED\n\n\ndnl PKG_CHECK_MODULES(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],\ndnl   [ACTION-IF-NOT-FOUND])\ndnl --------------------------------------------------------------\ndnl Since: 0.4.0\ndnl\ndnl Note that if there is a possibility the first call to\ndnl PKG_CHECK_MODULES might not happen, you should be sure to include an\ndnl explicit call to PKG_PROG_PKG_CONFIG in your configure.ac\nAC_DEFUN([PKG_CHECK_MODULES],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl\nAC_ARG_VAR([$1][_CFLAGS], [C compiler flags for $1, overriding pkg-config])dnl\nAC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl\n\npkg_failed=no\nAC_MSG_CHECKING([for $2])\n\n_PKG_CONFIG([$1][_CFLAGS], [cflags], [$2])\n_PKG_CONFIG([$1][_LIBS], [libs], [$2])\n\nm4_define([_PKG_TEXT], [Alternatively, you may set the environment variables $1[]_CFLAGS\nand $1[]_LIBS to avoid the need to call pkg-config.\nSee the pkg-config man page for more details.])\n\nif test $pkg_failed = yes; then\n        AC_MSG_RESULT([no])\n        _PKG_SHORT_ERRORS_SUPPORTED\n        if test $_pkg_short_errors_supported = yes; then\n                $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs \"$2\" 2>&1`\n        else\n                $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs \"$2\" 2>&1`\n        fi\n        # Put the nasty error message in config.log where it belongs\n        echo \"$$1[]_PKG_ERRORS\" >&AS_MESSAGE_LOG_FD\n\n        m4_default([$4], [AC_MSG_ERROR(\n[Package requirements ($2) were not met:\n\n$$1_PKG_ERRORS\n\nConsider adjusting the PKG_CONFIG_PATH environment variable if you\ninstalled software in a non-standard prefix.\n\n_PKG_TEXT])[]dnl\n        ])\nelif test $pkg_failed = untried; then\n        AC_MSG_RESULT([no])\n        m4_default([$4], [AC_MSG_FAILURE(\n[The pkg-config script could not be found or is too old.  Make sure it\nis in your PATH or set the PKG_CONFIG environment variable to the full\npath to pkg-config.\n\n_PKG_TEXT\n\nTo get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl\n        ])\nelse\n        $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS\n        $1[]_LIBS=$pkg_cv_[]$1[]_LIBS\n        AC_MSG_RESULT([yes])\n        $3\nfi[]dnl\n])dnl PKG_CHECK_MODULES\n\n\ndnl PKG_CHECK_MODULES_STATIC(VARIABLE-PREFIX, MODULES, [ACTION-IF-FOUND],\ndnl   [ACTION-IF-NOT-FOUND])\ndnl ---------------------------------------------------------------------\ndnl Since: 0.29\ndnl\ndnl Checks for existence of MODULES and gathers its build flags with\ndnl static libraries enabled. Sets VARIABLE-PREFIX_CFLAGS from --cflags\ndnl and VARIABLE-PREFIX_LIBS from --libs.\ndnl\ndnl Note that if there is a possibility the first call to\ndnl PKG_CHECK_MODULES_STATIC might not happen, you should be sure to\ndnl include an explicit call to PKG_PROG_PKG_CONFIG in your\ndnl configure.ac.\nAC_DEFUN([PKG_CHECK_MODULES_STATIC],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl\n_save_PKG_CONFIG=$PKG_CONFIG\nPKG_CONFIG=\"$PKG_CONFIG --static\"\nPKG_CHECK_MODULES($@)\nPKG_CONFIG=$_save_PKG_CONFIG[]dnl\n])dnl PKG_CHECK_MODULES_STATIC\n\n\ndnl PKG_INSTALLDIR([DIRECTORY])\ndnl -------------------------\ndnl Since: 0.27\ndnl\ndnl Substitutes the variable pkgconfigdir as the location where a module\ndnl should install pkg-config .pc files. By default the directory is\ndnl $libdir/pkgconfig, but the default can be changed by passing\ndnl DIRECTORY. The user can override through the --with-pkgconfigdir\ndnl parameter.\nAC_DEFUN([PKG_INSTALLDIR],\n[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])\nm4_pushdef([pkg_description],\n    [pkg-config installation directory @<:@]pkg_default[@:>@])\nAC_ARG_WITH([pkgconfigdir],\n    [AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,\n    [with_pkgconfigdir=]pkg_default)\nAC_SUBST([pkgconfigdir], [$with_pkgconfigdir])\nm4_popdef([pkg_default])\nm4_popdef([pkg_description])\n])dnl PKG_INSTALLDIR\n\n\ndnl PKG_NOARCH_INSTALLDIR([DIRECTORY])\ndnl --------------------------------\ndnl Since: 0.27\ndnl\ndnl Substitutes the variable noarch_pkgconfigdir as the location where a\ndnl module should install arch-independent pkg-config .pc files. By\ndnl default the directory is $datadir/pkgconfig, but the default can be\ndnl changed by passing DIRECTORY. The user can override through the\ndnl --with-noarch-pkgconfigdir parameter.\nAC_DEFUN([PKG_NOARCH_INSTALLDIR],\n[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])\nm4_pushdef([pkg_description],\n    [pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])\nAC_ARG_WITH([noarch-pkgconfigdir],\n    [AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,\n    [with_noarch_pkgconfigdir=]pkg_default)\nAC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])\nm4_popdef([pkg_default])\nm4_popdef([pkg_description])\n])dnl PKG_NOARCH_INSTALLDIR\n\n\ndnl PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,\ndnl [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])\ndnl -------------------------------------------\ndnl Since: 0.28\ndnl\ndnl Retrieves the value of the pkg-config variable for the given module.\nAC_DEFUN([PKG_CHECK_VAR],\n[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl\nAC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl\n\n_PKG_CONFIG([$1], [variable=\"][$3][\"], [$2])\nAS_VAR_COPY([$1], [pkg_cv_][$1])\n\nAS_VAR_IF([$1], [\"\"], [$5], [$4])dnl\n])dnl PKG_CHECK_VAR\n\ndnl PKG_WITH_MODULES(VARIABLE-PREFIX, MODULES,\ndnl   [ACTION-IF-FOUND],[ACTION-IF-NOT-FOUND],\ndnl   [DESCRIPTION], [DEFAULT])\ndnl ------------------------------------------\ndnl\ndnl Prepare a \"--with-\" configure option using the lowercase\ndnl [VARIABLE-PREFIX] name, merging the behaviour of AC_ARG_WITH and\ndnl PKG_CHECK_MODULES in a single macro.\nAC_DEFUN([PKG_WITH_MODULES],\n[\nm4_pushdef([with_arg], m4_tolower([$1]))\n\nm4_pushdef([description],\n           [m4_default([$5], [build with ]with_arg[ support])])\n\nm4_pushdef([def_arg], [m4_default([$6], [auto])])\nm4_pushdef([def_action_if_found], [AS_TR_SH([with_]with_arg)=yes])\nm4_pushdef([def_action_if_not_found], [AS_TR_SH([with_]with_arg)=no])\n\nm4_case(def_arg,\n            [yes],[m4_pushdef([with_without], [--without-]with_arg)],\n            [m4_pushdef([with_without],[--with-]with_arg)])\n\nAC_ARG_WITH(with_arg,\n     AS_HELP_STRING(with_without, description[ @<:@default=]def_arg[@:>@]),,\n    [AS_TR_SH([with_]with_arg)=def_arg])\n\nAS_CASE([$AS_TR_SH([with_]with_arg)],\n            [yes],[PKG_CHECK_MODULES([$1],[$2],$3,$4)],\n            [auto],[PKG_CHECK_MODULES([$1],[$2],\n                                        [m4_n([def_action_if_found]) $3],\n                                        [m4_n([def_action_if_not_found]) $4])])\n\nm4_popdef([with_arg])\nm4_popdef([description])\nm4_popdef([def_arg])\n\n])dnl PKG_WITH_MODULES\n\ndnl PKG_HAVE_WITH_MODULES(VARIABLE-PREFIX, MODULES,\ndnl   [DESCRIPTION], [DEFAULT])\ndnl -----------------------------------------------\ndnl\ndnl Convenience macro to trigger AM_CONDITIONAL after PKG_WITH_MODULES\ndnl check._[VARIABLE-PREFIX] is exported as make variable.\nAC_DEFUN([PKG_HAVE_WITH_MODULES],\n[\nPKG_WITH_MODULES([$1],[$2],,,[$3],[$4])\n\nAM_CONDITIONAL([HAVE_][$1],\n               [test \"$AS_TR_SH([with_]m4_tolower([$1]))\" = \"yes\"])\n])dnl PKG_HAVE_WITH_MODULES\n\ndnl PKG_HAVE_DEFINE_WITH_MODULES(VARIABLE-PREFIX, MODULES,\ndnl   [DESCRIPTION], [DEFAULT])\ndnl ------------------------------------------------------\ndnl\ndnl Convenience macro to run AM_CONDITIONAL and AC_DEFINE after\ndnl PKG_WITH_MODULES check. HAVE_[VARIABLE-PREFIX] is exported as make\ndnl and preprocessor variable.\nAC_DEFUN([PKG_HAVE_DEFINE_WITH_MODULES],\n[\nPKG_HAVE_WITH_MODULES([$1],[$2],[$3],[$4])\n\nAS_IF([test \"$AS_TR_SH([with_]m4_tolower([$1]))\" = \"yes\"],\n        [AC_DEFINE([HAVE_][$1], 1, [Enable ]m4_tolower([$1])[ support])])\n])dnl PKG_HAVE_DEFINE_WITH_MODULES\n"
  },
  {
    "path": "m4/sb_autoconf_compat.m4",
    "content": "# ---------------------------------------------------------------------------\n# Provide various compatibility macros for older Autoconf machines\n# Definitions were copied from the Autoconf source code.\n# ---------------------------------------------------------------------------\nm4_ifdef([AS_VAR_IF],,m4_define([AS_VAR_IF],\n[AS_LITERAL_WORD_IF([$1],\n  [AS_IF(m4_ifval([$2], [[test \"x$$1\" = x[]$2]], [[${$1:+false} :]])],\n  [AS_VAR_COPY([as_val], [$1])\n   AS_IF(m4_ifval([$2], [[test \"x$as_val\" = x[]$2]], [[${as_val:+false} :]])],\n  [AS_IF(m4_ifval([$2],\n    [[eval test \\\"x\\$\"$1\"\\\" = x\"_AS_ESCAPE([$2], [`], [\\\"$])\"]],\n    [[eval \\${$1:+false} :]])]),\n[$3], [$4])]))dnl\n"
  },
  {
    "path": "m4/sb_check_mysql.m4",
    "content": "dnl ---------------------------------------------------------------------------\ndnl Macro: SB_CHECK_MYSQL\ndnl First check if the MySQL root directory is specified with --with-mysql.\ndnl Otherwise check for custom MySQL paths in --with-mysql-includes and\ndnl --with-mysql-libs. If some paths are not specified explicitly, try to get\ndnl them from mysql_config.\ndnl ---------------------------------------------------------------------------\n\nAC_DEFUN([SB_CHECK_MYSQL],[\n\nAS_IF([test \"x$with_mysql\" != xno], [\n\n# Check for custom MySQL root directory\nif test [ \"x$with_mysql\" != xyes -a \"x$with_mysql\" != xno ] \nthen\n    ac_cv_mysql_root=`echo \"$with_mysql\" | sed -e 's+/$++'`\n    if test [ -d \"$ac_cv_mysql_root/include\" -a \\\n              -d \"$ac_cv_mysql_root/libmysql_r\" ]\n    then\n        ac_cv_mysql_includes=\"$ac_cv_mysql_root/include\"\n        ac_cv_mysql_libs=\"$ac_cv_mysql_root/libmysql_r\"\n    elif test [ -x \"$ac_cv_mysql_root/bin/mysql_config\" ]\n    then\n        mysqlconfig=\"$ac_cv_mysql_root/bin/mysql_config\"\n    else \n        AC_MSG_ERROR([invalid MySQL root directory: $ac_cv_mysql_root])\n    fi\nfi\n\n# Check for custom includes path\nif test [ -z \"$ac_cv_mysql_includes\" ] \nthen \n    AC_ARG_WITH([mysql-includes], \n                AS_HELP_STRING([--with-mysql-includes], [path to MySQL header files]),\n                [ac_cv_mysql_includes=$withval])\nfi\nif test [ -n \"$ac_cv_mysql_includes\" ]\nthen\n    AC_CACHE_CHECK([MySQL includes], [ac_cv_mysql_includes], [ac_cv_mysql_includes=\"\"])\n    MYSQL_CFLAGS=\"-I$ac_cv_mysql_includes\"\nfi\n\n# Check for custom library path\n\nif test [ -z \"$ac_cv_mysql_libs\" ]\nthen\n    AC_ARG_WITH([mysql-libs], \n                AS_HELP_STRING([--with-mysql-libs], [path to MySQL libraries]),\n                [ac_cv_mysql_libs=$withval])\nfi\nif test [ -n \"$ac_cv_mysql_libs\" ]\nthen\n    # Trim trailing '.libs' if user passed it in --with-mysql-libs option\n    ac_cv_mysql_libs=`echo ${ac_cv_mysql_libs} | sed -e 's/.libs$//' \\\n                      -e 's+.libs/$++'`\n    AC_CACHE_CHECK([MySQL libraries], [ac_cv_mysql_libs], [ac_cv_mysql_libs=\"\"])\n    save_LDFLAGS=\"$LDFLAGS\"\n    save_LIBS=\"$LIBS\"\n    LDFLAGS=\"-L$ac_cv_mysql_libs\"\n    LIBS=\"\"\n\n    # libmysqlclient_r has been removed in MySQL 5.7\n    AC_SEARCH_LIBS([mysql_real_connect],\n      [mysqlclient_r mysqlclient],\n      [],\n      AC_MSG_ERROR([cannot find MySQL client libraries in $ac_cv_mysql_libs]))\n\n    MYSQL_LIBS=\"$LDFLAGS $LIBS\"\n    LIBS=\"$save_LIBS\"\n    LDFLAGS=\"$save_LDFLAGS\"\nfi\n\n# If some path is missing, try to autodetermine with mysql_config\nif test [ -z \"$ac_cv_mysql_includes\" -o -z \"$ac_cv_mysql_libs\" ]\nthen\n    if test [ -z \"$mysqlconfig\" ]\n    then \n        AC_PATH_PROG(mysqlconfig,mysql_config)\n    fi\n    if test [ -z \"$mysqlconfig\" ]\n    then\n        AC_MSG_ERROR([mysql_config executable not found\n********************************************************************************\nERROR: cannot find MySQL libraries. If you want to compile with MySQL support,\n       please install the package containing MySQL client libraries and headers.\n       On Debian-based systems the package name is libmysqlclient-dev.\n       On RedHat-based systems, it is mysql-devel.\n       If you have those libraries installed in non-standard locations,\n       you must either specify file locations explicitly using\n       --with-mysql-includes and --with-mysql-libs options, or make sure path to\n       mysql_config is listed in your PATH environment variable. If you want to\n       disable MySQL support, use --without-mysql option.\n********************************************************************************\n])\n    else\n        if test [ -z \"$ac_cv_mysql_includes\" ]\n        then\n            AC_MSG_CHECKING(MySQL C flags)\n            MYSQL_CFLAGS=`${mysqlconfig} --cflags`\n            AC_MSG_RESULT($MYSQL_CFLAGS)\n        fi\n        if test [ -z \"$ac_cv_mysql_libs\" ]\n        then\n            AC_MSG_CHECKING(MySQL linker flags)\n            MYSQL_LIBS=`${mysqlconfig} --libs_r`\n            AC_MSG_RESULT($MYSQL_LIBS)\n        fi\n    fi\nfi\n\nAC_DEFINE([USE_MYSQL], 1,\n          [Define to 1 if you want to compile with MySQL support])\n\nUSE_MYSQL=1\nAC_SUBST([MYSQL_LIBS])\nAC_SUBST([MYSQL_CFLAGS])\n\nAC_MSG_CHECKING([if mysql.h defines MYSQL_OPT_SSL_MODE])\n\nSAVE_CFLAGS=\"${CFLAGS}\"\nCFLAGS=\"${CFLAGS} ${MYSQL_CFLAGS}\"\nAC_COMPILE_IFELSE([AC_LANG_PROGRAM(\n        [[\n#include <mysql.h>\n\nenum mysql_option opt = MYSQL_OPT_SSL_MODE;\n        ]])], [\n          AC_DEFINE([HAVE_MYSQL_OPT_SSL_MODE], 1,\n                    [Define to 1 if mysql.h defines MYSQL_OPT_SSL_MODE])\n          AC_MSG_RESULT([yes])\n          ], [AC_MSG_RESULT([no])])\n])\nCFLAGS=\"${SAVE_CFLAGS}\"\n\n\nAM_CONDITIONAL([USE_MYSQL], test \"x$with_mysql\" != xno)\nAC_SUBST([USE_MYSQL])\n])\n"
  },
  {
    "path": "m4/sb_concurrency_kit.m4",
    "content": "# Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n# ---------------------------------------------------------------------------\n# Macro: SB_CONCURRENCY_KIT\n# ---------------------------------------------------------------------------\nAC_DEFUN([SB_CONCURRENCY_KIT], [\n\nAC_ARG_WITH([system-ck],\n  AS_HELP_STRING([--with-system-ck],\n  [Use system-provided Concurrency Kit headers and library (requires pkg-config)]),\n  [sb_use_ck=\"system\"],\n  [sb_use_ck=\"bundled\"])\n\nAC_CACHE_CHECK([whether to build with system or bundled Concurrency Kit],\n  [sb_cv_lib_ck], [\n    AS_IF([test \"x$sb_use_ck\" = \"xsystem\"],\n    [\n      sb_cv_lib_ck=[system]\n    ], [\n      sb_cv_lib_ck=[bundled]\n    ])\n  ])\n\nAS_IF([test \"x$sb_cv_lib_ck\" = \"xsystem\"],\n  # let PKG_CHECK_MODULES set CK_CFLAGS and CK_LIBS for system libck\n  [PKG_CHECK_MODULES([CK], [ck])],\n  # Set CK_CFLAGS and CK_LIBS manually for bundled libck\n  [\n    CK_CFLAGS=\"-I\\$(abs_top_builddir)/third_party/concurrency_kit/include\"\n    CK_LIBS=\"\\$(abs_top_builddir)/third_party/concurrency_kit/lib/libck.a\"\n\n    case $target_cpu in\n      powerpc*|aarch64)\n        # Assume 128-byte cache line on AArch64 and PowerPC\n        CPPFLAGS=\"${CPPFLAGS} -DCK_MD_CACHELINE=128\"\n        ;;\n        # Force --platform=i*86 for CK, otherwise its configure script\n        # autodetects target based on 'uname -m' which doesn't work for\n        # cross-compiliation\n      i486*|i586*)\n        CK_CONFIGURE_FLAGS=\"--platform=i586\"\n        ;;\n      i686*)\n        CK_CONFIGURE_FLAGS=\"--platform=i686\"\n        ;;\n      mips64*)\n        CK_CONFIGURE_FLAGS=\"--use-cc-builtins\"\n        ;;\n    esac\n    # Add --enable-lse to CK build flags, if LSE instructions are supported by\n    # the target architecture\n    if test \"$cross_compiling\" = no -a \"$host_cpu\" = aarch64; then\n      AC_MSG_CHECKING([whether LSE instructions are supported])\n      AC_COMPILE_IFELSE(\n        [AC_LANG_PROGRAM(,\n        [[\n          unsigned long long d = 1, a = 1;\n          unsigned long long *t = &a;\n\n          __asm__ __volatile__(\n                               \"stadd %0, [%1];\"\n                                  : \"+&r\" (d)\n                                  : \"r\"   (t)\n                                  : \"memory\");\n        ]])],\n        [\n          CK_CONFIGURE_FLAGS=\"--enable-lse\"\n          AC_MSG_RESULT([yes])\n        ],\n        [\n          CK_CONFIGURE_FLAGS=\"\"\n          AC_MSG_RESULT([no])\n        ]\n      )\n\n      AC_SUBST([CK_CONFIGURE_FLAGS])\n    fi\n  ]\n)\n\nAC_DEFINE_UNQUOTED([SB_WITH_CK], [\"$sb_use_ck\"],\n  [Whether system or bundled Concurrency Kit is used])\n\nAM_CONDITIONAL([USE_BUNDLED_CK], [test \"x$sb_use_ck\" = xbundled])\n])\n"
  },
  {
    "path": "m4/sb_luajit.m4",
    "content": "# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n# ---------------------------------------------------------------------------\n# Macro: SB_LUAJIT\n# ---------------------------------------------------------------------------\nAC_DEFUN([SB_LUAJIT], [\n\nAC_ARG_WITH([system-luajit],\n  AS_HELP_STRING([--with-system-luajit],\n  [Use system-provided LuaJIT headers and library (requires pkg-config)]),\n  [sb_use_luajit=\"system\"],\n  [sb_use_luajit=\"bundled\"])\n\nAC_CACHE_CHECK([whether to build with system or bundled LuaJIT],\n  [sb_cv_lib_luajit], [\n    AS_IF([test \"x$sb_use_luajit\" = \"xsystem\"],\n    [\n      sb_cv_lib_luajit=[system]\n    ], [\n      sb_cv_lib_luajit=[bundled]\n    ])\n  ])\n\nAS_IF([test \"x$sb_cv_lib_luajit\" = \"xsystem\"],\n  # let PKG_CHECK_MODULES set LUAJIT_CFLAGS and LUAJIT_LIBS for system libluajit\n  [PKG_CHECK_MODULES([LUAJIT], [luajit])],\n  # Set LUAJIT_CFLAGS and LUAJIT_LIBS manually for bundled libluajit\n  [\n    LUAJIT_CFLAGS=\"-I\\$(abs_top_builddir)/third_party/luajit/inc\"\n    LUAJIT_LIBS=\"\\$(abs_top_builddir)/third_party/luajit/lib/libluajit-5.1.a\"\n  ]\n)\n\nAC_DEFINE_UNQUOTED([SB_WITH_LUAJIT], [\"$sb_use_luajit\"],\n  [Whether system or bundled LuaJIT is used])\n\nAM_CONDITIONAL([USE_BUNDLED_LUAJIT], [test \"x$sb_use_luajit\" = xbundled])\n\nAS_CASE([$host_os:$host_cpu],\n        # Add extra flags when building a 64-bit application on OS X,\n        # http://luajit.org/install.html\n        [*darwin*:x86_64],\n          [LUAJIT_LDFLAGS=\"-pagezero_size 10000 -image_base 100000000\"],\n        # -ldl and -rdynamic are required on Linux\n        [*linux*:*],\n          [\n            LUAJIT_LIBS=\"$LUAJIT_LIBS -ldl\"\n            LUAJIT_LDFLAGS=\"-rdynamic\"\n          ],\n        # -rdynamic is required on FreeBSD\n        [*freebsd*:*],\n          [\n            LUAJIT_LDFLAGS=\"-rdynamic\"\n          ]\n)\n\nAC_SUBST([LUAJIT_LDFLAGS])\n])\n"
  },
  {
    "path": "missing",
    "content": "#! /bin/sh\n# Common stub for a few missing GNU programs while installing.\n# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.\n# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.\n\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2, or (at your option)\n# any later version.\n\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n# 02111-1307, USA.\n\n# As a special exception to the GNU General Public License, if you\n# distribute this file as part of a program that contains a\n# configuration script generated by Autoconf, you may include it under\n# the same distribution terms that you use for the rest of that program.\n\nif test $# -eq 0; then\n  echo 1>&2 \"Try \\`$0 --help' for more information\"\n  exit 1\nfi\n\nrun=:\n\n# In the cases where this matters, `missing' is being run in the\n# srcdir already.\nif test -f configure.ac; then\n  configure_ac=configure.ac\nelse\n  configure_ac=configure.in\nfi\n\ncase \"$1\" in\n--run)\n  # Try to run requested program, and just exit if it succeeds.\n  run=\n  shift\n  \"$@\" && exit 0\n  ;;\nesac\n\n# If it does not exist, or fails to run (possibly an outdated version),\n# try to emulate it.\ncase \"$1\" in\n\n  -h|--h|--he|--hel|--help)\n    echo \"\\\n$0 [OPTION]... PROGRAM [ARGUMENT]...\n\nHandle \\`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an\nerror status if there is no known handling for PROGRAM.\n\nOptions:\n  -h, --help      display this help and exit\n  -v, --version   output version information and exit\n  --run           try to run the given command, and emulate it if it fails\n\nSupported PROGRAM values:\n  aclocal      touch file \\`aclocal.m4'\n  autoconf     touch file \\`configure'\n  autoheader   touch file \\`config.h.in'\n  automake     touch all \\`Makefile.in' files\n  bison        create \\`y.tab.[ch]', if possible, from existing .[ch]\n  flex         create \\`lex.yy.c', if possible, from existing .c\n  help2man     touch the output file\n  lex          create \\`lex.yy.c', if possible, from existing .c\n  makeinfo     touch the output file\n  tar          try tar, gnutar, gtar, then tar without non-portable flags\n  yacc         create \\`y.tab.[ch]', if possible, from existing .[ch]\"\n    ;;\n\n  -v|--v|--ve|--ver|--vers|--versi|--versio|--version)\n    echo \"missing 0.4 - GNU automake\"\n    ;;\n\n  -*)\n    echo 1>&2 \"$0: Unknown \\`$1' option\"\n    echo 1>&2 \"Try \\`$0 --help' for more information\"\n    exit 1\n    ;;\n\n  aclocal*)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified \\`acinclude.m4' or \\`${configure_ac}'.  You might want\n         to install the \\`Automake' and \\`Perl' packages.  Grab them from\n         any GNU archive site.\"\n    touch aclocal.m4\n    ;;\n\n  autoconf)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified \\`${configure_ac}'.  You might want to install the\n         \\`Autoconf' and \\`GNU m4' packages.  Grab them from any GNU\n         archive site.\"\n    touch configure\n    ;;\n\n  autoheader)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified \\`acconfig.h' or \\`${configure_ac}'.  You might want\n         to install the \\`Autoconf' and \\`GNU m4' packages.  Grab them\n         from any GNU archive site.\"\n    files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\\([^)]*\\)).*/\\1/p' ${configure_ac}`\n    test -z \"$files\" && files=\"config.h\"\n    touch_files=\n    for f in $files; do\n      case \"$f\" in\n      *:*) touch_files=\"$touch_files \"`echo \"$f\" |\n\t\t\t\t       sed -e 's/^[^:]*://' -e 's/:.*//'`;;\n      *) touch_files=\"$touch_files $f.in\";;\n      esac\n    done\n    touch $touch_files\n    ;;\n\n  automake*)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified \\`Makefile.am', \\`acinclude.m4' or \\`${configure_ac}'.\n         You might want to install the \\`Automake' and \\`Perl' packages.\n         Grab them from any GNU archive site.\"\n    find . -type f -name Makefile.am -print |\n\t   sed 's/\\.am$/.in/' |\n\t   while read f; do touch \"$f\"; done\n    ;;\n\n  autom4te)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is needed, and you do not seem to have it handy on your\n         system.  You might have modified some files without having the\n         proper tools for further handling them.\n         You can get \\`$1' as part of \\`Autoconf' from any GNU\n         archive site.\"\n\n    file=`echo \"$*\" | sed -n 's/.*--output[ =]*\\([^ ]*\\).*/\\1/p'`\n    test -z \"$file\" && file=`echo \"$*\" | sed -n 's/.*-o[ ]*\\([^ ]*\\).*/\\1/p'`\n    if test -f \"$file\"; then\n\ttouch $file\n    else\n\ttest -z \"$file\" || exec >$file\n\techo \"#! /bin/sh\"\n\techo \"# Created by GNU Automake missing as a replacement of\"\n\techo \"#  $ $@\"\n\techo \"exit 0\"\n\tchmod +x $file\n\texit 1\n    fi\n    ;;\n\n  bison|yacc)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified a \\`.y' file.  You may need the \\`Bison' package\n         in order for those modifications to take effect.  You can get\n         \\`Bison' from any GNU archive site.\"\n    rm -f y.tab.c y.tab.h\n    if [ $# -ne 1 ]; then\n        eval LASTARG=\"\\${$#}\"\n\tcase \"$LASTARG\" in\n\t*.y)\n\t    SRCFILE=`echo \"$LASTARG\" | sed 's/y$/c/'`\n\t    if [ -f \"$SRCFILE\" ]; then\n\t         cp \"$SRCFILE\" y.tab.c\n\t    fi\n\t    SRCFILE=`echo \"$LASTARG\" | sed 's/y$/h/'`\n\t    if [ -f \"$SRCFILE\" ]; then\n\t         cp \"$SRCFILE\" y.tab.h\n\t    fi\n\t  ;;\n\tesac\n    fi\n    if [ ! -f y.tab.h ]; then\n\techo >y.tab.h\n    fi\n    if [ ! -f y.tab.c ]; then\n\techo 'main() { return 0; }' >y.tab.c\n    fi\n    ;;\n\n  lex|flex)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified a \\`.l' file.  You may need the \\`Flex' package\n         in order for those modifications to take effect.  You can get\n         \\`Flex' from any GNU archive site.\"\n    rm -f lex.yy.c\n    if [ $# -ne 1 ]; then\n        eval LASTARG=\"\\${$#}\"\n\tcase \"$LASTARG\" in\n\t*.l)\n\t    SRCFILE=`echo \"$LASTARG\" | sed 's/l$/c/'`\n\t    if [ -f \"$SRCFILE\" ]; then\n\t         cp \"$SRCFILE\" lex.yy.c\n\t    fi\n\t  ;;\n\tesac\n    fi\n    if [ ! -f lex.yy.c ]; then\n\techo 'main() { return 0; }' >lex.yy.c\n    fi\n    ;;\n\n  help2man)\n    if test -z \"$run\" && ($1 --version) > /dev/null 2>&1; then\n       # We have it, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n\t you modified a dependency of a manual page.  You may need the\n\t \\`Help2man' package in order for those modifications to take\n\t effect.  You can get \\`Help2man' from any GNU archive site.\"\n\n    file=`echo \"$*\" | sed -n 's/.*-o \\([^ ]*\\).*/\\1/p'`\n    if test -z \"$file\"; then\n\tfile=`echo \"$*\" | sed -n 's/.*--output=\\([^ ]*\\).*/\\1/p'`\n    fi\n    if [ -f \"$file\" ]; then\n\ttouch $file\n    else\n\ttest -z \"$file\" || exec >$file\n\techo \".ab help2man is required to generate this page\"\n\texit 1\n    fi\n    ;;\n\n  makeinfo)\n    if test -z \"$run\" && (makeinfo --version) > /dev/null 2>&1; then\n       # We have makeinfo, but it failed.\n       exit 1\n    fi\n\n    echo 1>&2 \"\\\nWARNING: \\`$1' is missing on your system.  You should only need it if\n         you modified a \\`.texi' or \\`.texinfo' file, or any other file\n         indirectly affecting the aspect of the manual.  The spurious\n         call might also be the consequence of using a buggy \\`make' (AIX,\n         DU, IRIX).  You might want to install the \\`Texinfo' package or\n         the \\`GNU make' package.  Grab either from any GNU archive site.\"\n    file=`echo \"$*\" | sed -n 's/.*-o \\([^ ]*\\).*/\\1/p'`\n    if test -z \"$file\"; then\n      file=`echo \"$*\" | sed 's/.* \\([^ ]*\\) *$/\\1/'`\n      file=`sed -n '/^@setfilename/ { s/.* \\([^ ]*\\) *$/\\1/; p; q; }' $file`\n    fi\n    touch $file\n    ;;\n\n  tar)\n    shift\n    if test -n \"$run\"; then\n      echo 1>&2 \"ERROR: \\`tar' requires --run\"\n      exit 1\n    fi\n\n    # We have already tried tar in the generic part.\n    # Look for gnutar/gtar before invocation to avoid ugly error\n    # messages.\n    if (gnutar --version > /dev/null 2>&1); then\n       gnutar \"$@\" && exit 0\n    fi\n    if (gtar --version > /dev/null 2>&1); then\n       gtar \"$@\" && exit 0\n    fi\n    firstarg=\"$1\"\n    if shift; then\n\tcase \"$firstarg\" in\n\t*o*)\n\t    firstarg=`echo \"$firstarg\" | sed s/o//`\n\t    tar \"$firstarg\" \"$@\" && exit 0\n\t    ;;\n\tesac\n\tcase \"$firstarg\" in\n\t*h*)\n\t    firstarg=`echo \"$firstarg\" | sed s/h//`\n\t    tar \"$firstarg\" \"$@\" && exit 0\n\t    ;;\n\tesac\n    fi\n\n    echo 1>&2 \"\\\nWARNING: I can't seem to be able to run \\`tar' with the given arguments.\n         You may want to install GNU tar or Free paxutils, or check the\n         command line arguments.\"\n    exit 1\n    ;;\n\n  *)\n    echo 1>&2 \"\\\nWARNING: \\`$1' is needed, and you do not seem to have it handy on your\n         system.  You might have modified some files without having the\n         proper tools for further handling them.  Check the \\`README' file,\n         it often tells you about the needed prerequisites for installing\n         this package.  You may also peek at any GNU archive site, in case\n         some other package would contain this missing \\`$1' program.\"\n    exit 1\n    ;;\nesac\n\nexit 0\n"
  },
  {
    "path": "mkinstalldirs",
    "content": "#! /bin/sh\n# mkinstalldirs --- make directory hierarchy\n# Author: Noah Friedman <friedman@prep.ai.mit.edu>\n# Created: 1993-05-16\n# Public domain\n\nerrstatus=0\ndirmode=\"\"\n\nusage=\"\\\nUsage: mkinstalldirs [-h] [--help] [-m mode] dir ...\"\n\n# process command line arguments\nwhile test $# -gt 0 ; do\n  case $1 in\n    -h | --help | --h*)         # -h for help\n      echo \"$usage\" 1>&2\n      exit 0\n      ;;\n    -m)                         # -m PERM arg\n      shift\n      test $# -eq 0 && { echo \"$usage\" 1>&2; exit 1; }\n      dirmode=$1\n      shift\n      ;;\n    --)                         # stop option processing\n      shift\n      break\n      ;;\n    -*)                         # unknown option\n      echo \"$usage\" 1>&2\n      exit 1\n      ;;\n    *)                          # first non-opt arg\n      break\n      ;;\n  esac\ndone\n\nfor file\ndo\n  if test -d \"$file\"; then\n    shift\n  else\n    break\n  fi\ndone\n\ncase $# in\n  0) exit 0 ;;\nesac\n\ncase $dirmode in\n  '')\n    if mkdir -p -- . 2>/dev/null; then\n      echo \"mkdir -p -- $*\"\n      exec mkdir -p -- \"$@\"\n    fi\n    ;;\n  *)\n    if mkdir -m \"$dirmode\" -p -- . 2>/dev/null; then\n      echo \"mkdir -m $dirmode -p -- $*\"\n      exec mkdir -m \"$dirmode\" -p -- \"$@\"\n    fi\n    ;;\nesac\n\nfor file\ndo\n  set fnord `echo \":$file\" | sed -ne 's/^:\\//#/;s/^://;s/\\// /g;s/^#/\\//;p'`\n  shift\n\n  pathcomp=\n  for d\n  do\n    pathcomp=\"$pathcomp$d\"\n    case $pathcomp in\n      -*) pathcomp=./$pathcomp ;;\n    esac\n\n    if test ! -d \"$pathcomp\"; then\n      echo \"mkdir $pathcomp\"\n\n      mkdir \"$pathcomp\" || lasterr=$?\n\n      if test ! -d \"$pathcomp\"; then\n  \terrstatus=$lasterr\n      else\n  \tif test ! -z \"$dirmode\"; then\n\t  echo \"chmod $dirmode $pathcomp\"\n    \t  lasterr=\"\"\n  \t  chmod \"$dirmode\" \"$pathcomp\" || lasterr=$?\n\n  \t  if test ! -z \"$lasterr\"; then\n  \t    errstatus=$lasterr\n  \t  fi\n  \tfi\n      fi\n    fi\n\n    pathcomp=\"$pathcomp/\"\n  done\ndone\n\nexit $errstatus\n\n# Local Variables:\n# mode: shell-script\n# sh-indentation: 2\n# End:\n# mkinstalldirs ends here\n"
  },
  {
    "path": "rpm/sysbench.spec",
    "content": "Summary:       Scriptable database and system performance benchmark\nName:          sysbench\n# Version will be replaced by packpack\nVersion:       x.y.z\nRelease:       1%{?dist}\nLicense:       GPLv2+\nGroup:         Applications/System\nSource0:       https://github.com/akopytov/%{name}/archive/%{version}/%{name}-%{version}.tar.gz\nURL:           https://github.com/akopytov/sysbench/\n\n%if 0%{?rhel} < 7\nBuildRequires: mysql-devel\n%else\nBuildRequires: mariadb-devel\n%endif\nBuildRequires: postgresql-devel\nBuildRequires: make\nBuildRequires: automake\nBuildRequires: libtool\nBuildRequires: pkgconfig\nBuildRequires: libaio-devel\n# Use bundled cram for tests\n%if 0%{?rhel} > 7\nBuildRequires: python2\n%else\nBuildRequires: python\n%endif\n\nExclusiveArch: %{arm} %{ix86} x86_64 %{mips} aarch64\n\n\n%description\nsysbench is a scriptable multi-threaded benchmark tool based on\nLuaJIT. It is most frequently used for database benchmarks, but can also\nbe used to create arbitrarily complex workloads that do not involve a\ndatabase server.\n\nsysbench comes with the following bundled benchmarks:\n\n- oltp_*.lua: a collection of OLTP-like database benchmarks\n- fileio: a filesystem-level benchmark\n- cpu: a simple CPU benchmark\n- memory: a memory access benchmark\n- threads: a thread-based scheduler benchmark\n- mutex: a POSIX mutex benchmark\n\n%prep\n%setup -q\n\n%build\nexport CFLAGS=\"%{optflags}\"\nautoreconf -vif\n%configure --with-mysql \\\n           --with-pgsql \\\n\t   --without-gcc-arch\n\n%if 0%{?el6}\nmake -j2\n%else\n%make_build\n%endif\n\n%install\n%make_install\nrm -f %{buildroot}%{_docdir}/sysbench/manual.html\n\n%check\nmake test\n\n%files\n%doc ChangeLog COPYING README.md\n%if 0%{?el6}\n%else\n%license COPYING\n%endif\n%{_bindir}/*\n%{_datadir}/%{name}\n\n\n%changelog\n* Fri Mar 15 2019 Alexey Bychko <abychko@gmail.com> - 1.0.16-1\n- Updated build dependencies for RHEL8-Beta.\n\n* Sat Jan  6 2018 Alexey Kopytov <akopytov@gmail.com> - 1.0.12-1\n- Remove vim-common from build dependencies.\n\n* Sun Apr 09 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1\n- Add --without-gcc-arch to configure flags\n\n* Sat Apr 08 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1\n- Workarounds for make_build and license macros which are not available on EL 6.\n\n* Fri Apr 07 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1\n- Depend on mysql-devel rather than mariadb-devel on EL 6.\n- Use bundled cram for tests, because it's not available on EL 6.\n\n* Thu Apr 06 2017 Alexey Kopytov <akopytov@gmail.com> - 1.0.5-1\n- Reuse downstream Fedora spec with modifications (prefer bundled libraries)\n\n* Mon Mar 13 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.4-2\n- Don't build aarch64 on el7.\n\n* Mon Mar 13 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.4-1\n- Fix build for i686.\n- Drop bundled cram.\n\n* Wed Mar 08 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.3-1\n- Update to 1.0.3 (RHBZ#1424670).\n- Restrict arches to the same ones as luajit.\n- Add --with-gcc-arch=native to configure for %%{arm} and aarch64.\n- Ignore test suite results for aarch64, it segfaults in koji.\n\n* Sat Feb 25 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.2-2\n- Run test suite.\n\n* Sat Feb 25 2017 Xavier Bachelot <xavier@bachelot.org> 1.0.2-1\n- Update to 1.0.2 (RHBZ#1424670).\n\n* Sun Feb 12 2017 Honza Horak <hhorak@redhat.com> - 1.0.0-1\n- Update to the first proper release 1.0.0\n\n* Sat Feb 11 2017 Fedora Release Engineering <releng@fedoraproject.org> - 0.4.12-15\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild\n\n* Fri Feb 05 2016 Fedora Release Engineering <releng@fedoraproject.org> - 0.4.12-14\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild\n\n* Fri Jun 19 2015 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-13\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild\n\n* Thu Sep 04 2014 Xavier Bachelot <xavier@bachelot.org> 0.4.12-12\n- Modernize specfile.\n\n* Mon Aug 18 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-11\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild\n\n* Sun Jun 08 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-10\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild\n\n* Sun Aug 04 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-9\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_20_Mass_Rebuild\n\n* Fri Feb 15 2013 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-8\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild\n\n* Sat Jul 21 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-7\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild\n\n* Sat Jan 14 2012 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-6\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild\n\n* Tue Sep 06 2011 Xavier Bachelot <xavier@bachelot.org> 0.4.12-5\n- Add BR: libaio-devel (rhbz#735882).\n\n* Wed Mar 23 2011 Dan Horák <dan@danny.cz> - 0.4.12-4\n- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)\n\n* Wed Feb 09 2011 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.12-3\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild\n\n* Fri Dec 24 2010 Xavier Bachelot <xavier@bachelot.org> 0.4.12-2\n- Rebuild against new mysql.\n\n* Wed Jul 07 2010 Xavier Bachelot <xavier@bachelot.org> 0.4.12-1\n- Update to 0.4.12.\n\n* Fri Aug 21 2009 Tomas Mraz <tmraz@redhat.com> - 0.4.10-5\n- rebuilt with new openssl\n\n* Sun Jul 26 2009 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.4.10-4\n- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild\n\n* Wed Mar 18 2009 Xavier Bachelot <xavier@bachelot.org> 0.4.10-3\n- License is GPLv2+, not GPLv2.\n\n* Sat Mar 14 2009 Xavier Bachelot <xavier@bachelot.org> 0.4.10-2\n- Make postgres support optional, the version in rhel4 is too old.\n- Drop TODO and manual.html from %%doc, they are empty.\n\n* Thu Mar 05 2009 Xavier Bachelot <xavier@bachelot.org> 0.4.10-1\n- Adapt original spec file taken from PLD.\n"
  },
  {
    "path": "scripts/buildpack.sh",
    "content": "#!/usr/bin/env bash\n#\n# Copyright (C) 2017-2019 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n# Build packages for a specified architecture and upload them to packagecloud.io\n# Expects the following environment variables to be defined:\n#\n#   ARCH - architecture. 'aarch64', 'x86_64 and 'i386' are currently supported\n#          values. If not set, the script behaves as if it was sequentially\n#          called with 'x86_64' and 'i386' values\n#\n#   OS/DIST - distribution specification for packpack. When empty (the default)\n#             use all disitributions available for ARCH\n#\n#   PACKAGECLOUD_TOKEN - packagecloud.io API token\n#\n#   PACKAGECLOUD_USER - packagecloud.io user name, defaults to 'akopytov'\n#\n#   PACKAGECLOUD_REPO - packagecloud.io repository. The default is 'sysbench'\n#                       for releases (i.e. if git HEAD corresponds to a tag),\n#                       and 'sysbench-prereleases' otherwise.\n#\n#   PACKAGECLOUD_EXTRA_ARGS - extra arguments to pass to the package_cloud\n#                             utility. Empty by default. Can be used to pass the\n#                             --skip-errors flag to ignore deploy errors.\n#\n#   PACKPACK_REPO - packpack repository to use. Defaults to akopytov/packpack.\n\nset -eu\n\nPACKAGECLOUD_USER=${PACKAGECLOUD_USER:-\"akopytov\"}\nPACKAGECLOUD_EXTRA_ARGS=${PACKAGECLOUD_EXTRA_ARGS:-}\nPACKPACK_REPO=${PACKPACK_REPO:-akopytov/packpack}\n\ndistros_x86_64=(\n    \"el 7 x86_64\"\n    \"el 8 x86_64\"\n    \"fedora 32 x86_64\"\n    \"fedora 33 x86_64\"\n    \"ubuntu xenial x86_64\"\n    \"ubuntu bionic x86_64\"\n    \"ubuntu focal x86_64\"\n    \"ubuntu groovy x86_64\"\n    \"debian stretch x86_64\"\n    \"debian buster x86_64\"\n)\n\ndistros_i386=(\n    \"ubuntu xenial i386\"\n    \"ubuntu bionic i386\"\n    \"debian stretch i386\"\n    \"debian buster i386\"\n)\n\ndistros_aarch64=(\n    \"el 7 aarch64\"\n    \"fedora 32 aarch64\"\n    \"fedora 33 aarch64\"\n    \"ubuntu bionic aarch64\"\n    \"ubuntu focal aarch64\"\n    \"ubuntu groovy aarch64\"\n    \"ubuntu xenial aarch64\"\n    \"debian stretch aarch64\"\n    \"debian buster aarch64\"\n)\n\nmain()\n{\n    if [ ! -r configure.ac ]; then\n        echo \"This script should be executed from the source root directory.\"\n        exit 1\n    fi\n\n    if [ -z \"${PACKAGECLOUD_TOKEN+x}\" ]; then\n        echo \"This script expects PACKAGECLOUD_TOKEN to be defined.\"\n        exit 1\n    fi\n\n    if ! which package_cloud >/dev/null 2>&1 ; then\n        echo \"This script requires package_cloud. You can install it by running:\"\n        echo \"  gem install package_cloud\"\n        exit 1\n    fi\n\n    if [ ! -d packpack ]; then\n        git clone https://github.com/${PACKPACK_REPO} packpack\n    fi\n\n    if [ -z \"${PACKAGECLOUD_REPO+x}\" ]; then\n        # Upload builds corresponding to release tags to the 'sysbench'\n        # repository, push other ones to 'sysbench-prereleases'\n        if ! git describe --long --always >/dev/null 2>&1 ; then\n            echo \"Either run this script from a git repository, or specify \"\n            echo \"the packagecloud repository explicitly with PACKAGECLOUD_REPO\"\n            exit 1\n        fi\n        local commits=$(git describe --long --always |\n                            sed -n 's/^\\([0-9\\.]*\\)-\\([0-9]*\\)-\\([a-z0-9]*\\)/\\2/p')\n        if [ ${commits:-0} = 0 ]; then\n            export PACKAGECLOUD_REPO=sysbench\n            # Use short version numbers for release builds\n            export VERSION=$(git describe)\n        else\n            export PACKAGECLOUD_REPO=sysbench-prereleases\n        fi\n    fi\n\n    declare -a distros\n\n    OS=${OS:-}\n    DIST=${DIST:-}\n\n    if [ -n \"${OS}\" -a -n \"${DIST}\" ]; then\n        distros=( \"${OS} ${DIST} ${ARCH:-x86_64}\" )\n    elif [ -z \"${ARCH+x}\" ]; then\n        distros=(\"${distros_x86_64[@]}\" \"${distros_i386[@]}\")\n    else\n        case \"$ARCH\" in\n            x86_64)\n                distros=( \"${distros_x86_64[@]}\" )\n                ;;\n            i386)\n                distros=( \"${distros_i386[@]}\" )\n                ;;\n            aarch64)\n                distros=( \"${distros_aarch64[@]}\" )\n                ;;\n            *)\n                echo \"Invalid ARCH value: $ARCH\"\n                exit 1\n                ;;\n        esac\n    fi\n\n    export PRODUCT=sysbench\n    export CHANGELOG_NAME=sysbench\n    export CHANGELOG_EMAIL=akopytov@gmail.com\n\n    for d in \"${distros[@]}\"; do\n        echo \"*** Building package for $d ***\"\n        local t=( $d )\n        export OS=${t[0]}\n        export DIST=${t[1]}\n        export ARCH=${t[2]}\n\n        # Replace \"el\" with \"centos\" for packpack, as there is no \"el-*\" docker\n        # images for some architectures\n        local PPOS=${OS/#el/centos}\n        OS=\"$PPOS\" packpack/packpack\n\n        # To avoid name conflicts, deploy source packages only for\n        # \"default\", i.e. x86_64 architecture\n        if [ \"${ARCH}\" = \"x86_64\" ]; then\n            files=\"$(ls build/*.{rpm,deb,dsc} 2>/dev/null || :)\"\n        else\n            files=\"$(ls build/*{[^c].rpm,.deb} 2>/dev/null || :)\"\n        fi\n\n        if [ -z \"$files\" ]; then\n            echo \"No package files to push\"\n            exit 1\n        fi\n\n        echo \"Pushing packages to ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO}\"\n\n        for f in $files ; do\n            echo $f\n            package_cloud push ${PACKAGECLOUD_EXTRA_ARGS} \\\n                          ${PACKAGECLOUD_USER}/${PACKAGECLOUD_REPO}/${OS}/${DIST} \\\n                          $f\n        done\n\n        OS=${PPOS} packpack/packpack clean\n    done\n}\n\nmain\n"
  },
  {
    "path": "snap/snapcraft.yaml.in",
    "content": "name: sysbench\nversion: @PACKAGE_VERSION@\nsummary: Scriptable database and system performance benchmark\ndescription: |\n sysbench is a scriptable multi-threaded benchmark tool based on\n LuaJIT. It is most frequently used for database benchmarks, but can also\n be used to create arbitrarily complex workloads that do not involve a\n database server.\n \n sysbench comes with the following bundled benchmarks:\n\n - oltp_*.lua: a collection of OLTP-like database benchmarks\n - fileio: a filesystem-level benchmark\n - cpu: a simple CPU benchmark\n - memory: a memory access benchmark\n - threads: a thread-based scheduler benchmark\n - mutex: a POSIX mutex benchmark\n\ngrade: stable\nconfinement: classic\n\napps:\n  sysbench:\n    command: sysbench\n    plugs:\n      - network\n\nparts:\n  sysbench:\n    source: .\n    plugin: autotools\n    build-packages:\n      - libmysqlclient-dev\n    stage-packages:\n      - libmysqlclient20\n      - libaio1\n"
  },
  {
    "path": "src/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nSUBDIRS = drivers tests lua .\n\nAM_CPPFLAGS += -DDATADIR=\\\"$(pkgdatadir)\\\" -DLIBDIR=\\\"$(pkglibdir)\\\"\n\nbin_PROGRAMS = sysbench\n\n# The following check will be extended as new database drivers will be added\nif USE_MYSQL\nmysql_ldadd = drivers/mysql/libsbmysql.a $(MYSQL_LIBS)\nendif\n\nif USE_PGSQL\npgsql_ldadd = drivers/pgsql/libsbpgsql.a $(PGSQL_LIBS)\nendif\n\nsysbench_SOURCES = sysbench.c sysbench.h sb_timer.c sb_timer.h \\\nsb_options.c sb_options.h sb_logger.c sb_logger.h sb_list.h db_driver.h \\\ndb_driver.c sb_histogram.c sb_histogram.h sb_rand.c sb_rand.h \\\nsb_thread.c sb_thread.h sb_barrier.c sb_barrier.h sb_lua.c \\\nsb_ck_pr.h \\\nsb_lua.h sb_util.h sb_util.c sb_counter.h sb_counter.c \\\nlua/internal/sysbench.lua.h lua/internal/sysbench.sql.lua.h \\\nlua/internal/sysbench.rand.lua.h lua/internal/sysbench.cmdline.lua.h  \\\nlua/internal/sysbench.histogram.lua.h \\\nxoroshiro128plus.h\n\nsysbench_LDADD = tests/fileio/libsbfileio.a tests/threads/libsbthreads.a \\\n    tests/memory/libsbmemory.a tests/cpu/libsbcpu.a \\\n    tests/mutex/libsbmutex.a \\\n    $(mysql_ldadd) $(pgsql_ldadd) \\\n    $(LUAJIT_LIBS) $(CK_LIBS)\n\nsysbench_LDFLAGS = $(mysql_ldflags) \\\n    $(pgsql_ldflags) $(LUAJIT_LDFLAGS)\n"
  },
  {
    "path": "src/db_driver.c",
    "content": "/*\n   Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n#ifdef STDC_HEADERS\n# include <ctype.h>\n# include <inttypes.h>\n# include <stdbool.h>\n#endif\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n\n#include <pthread.h>\n\n#include \"db_driver.h\"\n#include \"sb_list.h\"\n#include \"sb_histogram.h\"\n#include \"sb_ck_pr.h\"\n\n/* Query length limit for bulk insert queries */\n#define BULK_PACKET_SIZE (512*1024)\n\n/* How many rows to insert before COMMITs (used in bulk insert) */\n#define ROWS_BEFORE_COMMIT 1000\n\n/* Global variables */\ndb_globals_t db_globals CK_CC_CACHELINE;\n\nstatic sb_list_t        drivers;          /* list of available DB drivers */\n\nstatic uint8_t stats_enabled;\n\nstatic bool db_global_initialized;\nstatic pthread_once_t db_global_once = PTHREAD_ONCE_INIT;\n\n/* Timers used in debug mode */\nstatic sb_timer_t *exec_timers;\nstatic sb_timer_t *fetch_timers;\n\n/* Static functions */\n\nstatic int db_parse_arguments(void);\n#if 0\nstatic void db_free_row(db_row_t *);\n#endif\nstatic int db_bulk_do_insert(db_conn_t *, int);\nstatic void db_reset_stats(void);\nstatic int db_free_results_int(db_conn_t *con);\n\n/* DB layer arguments */\n\nstatic sb_arg_t db_args[] =\n{\n  SB_OPT(\"db-driver\", \"specifies database driver to use \"\n         \"('help' to get list of available drivers)\",\n#ifdef USE_MYSQL\n         \"mysql\",\n#else\n         NULL,\n#endif\n         STRING),\n  SB_OPT(\"db-ps-mode\", \"prepared statements usage mode {auto, disable}\", \"auto\",\n         STRING),\n  SB_OPT(\"db-debug\", \"print database-specific debug information\", \"off\", BOOL),\n\n  SB_OPT_END\n};\n\n/* Register available database drivers and command line arguments */\n\nint db_register(void)\n{\n  sb_list_item_t *pos;\n  db_driver_t    *drv;\n\n  /* Register database drivers */\n  SB_LIST_INIT(&drivers);\n#ifdef USE_MYSQL\n  register_driver_mysql(&drivers);\n#endif\n#ifdef USE_PGSQL\n  register_driver_pgsql(&drivers);\n#endif\n\n  /* Register command line options for each driver */\n  SB_LIST_FOR_EACH(pos, &drivers)\n  {\n    drv = SB_LIST_ENTRY(pos, db_driver_t, listitem);\n    if (drv->args != NULL)\n      sb_register_arg_set(drv->args);\n    drv->initialized = false;\n    pthread_mutex_init(&drv->mutex, NULL);\n  }\n  /* Register general command line arguments for DB API */\n  sb_register_arg_set(db_args);\n\n  return 0;\n}\n\n\n/* Print list of available drivers and their options */\n\n\nvoid db_print_help(void)\n{\n  sb_list_item_t *pos;\n  db_driver_t    *drv;\n\n  log_text(LOG_NOTICE, \"General database options:\\n\");\n  sb_print_options(db_args);\n  log_text(LOG_NOTICE, \"\");\n  \n  log_text(LOG_NOTICE, \"Compiled-in database drivers:\");\n  SB_LIST_FOR_EACH(pos, &drivers)\n  {\n    drv = SB_LIST_ENTRY(pos, db_driver_t, listitem);\n    log_text(LOG_NOTICE, \"  %s - %s\", drv->sname, drv->lname);\n  }\n  log_text(LOG_NOTICE, \"\");\n  SB_LIST_FOR_EACH(pos, &drivers)\n  {\n    drv = SB_LIST_ENTRY(pos, db_driver_t, listitem);\n    log_text(LOG_NOTICE, \"%s options:\", drv->sname);\n    sb_print_options(drv->args);\n  }\n}\n\n\nstatic void enable_print_stats(void)\n{\n  ck_pr_fence_store();\n  ck_pr_store_8(&stats_enabled, 1);\n}\n\nstatic void disable_print_stats(void)\n{\n  ck_pr_store_8(&stats_enabled, 0);\n  ck_pr_fence_store();\n}\n\n\nstatic bool check_print_stats(void)\n{\n  bool rc = ck_pr_load_8(&stats_enabled) == 1;\n  ck_pr_fence_load();\n\n  return rc;\n}\n\nstatic void db_init(void)\n{\n  if (SB_LIST_IS_EMPTY(&drivers))\n  {\n    log_text(LOG_FATAL, \"No DB drivers available\");\n    return;\n  }\n\n  if (db_parse_arguments())\n    return;\n\n  /* Initialize timers if in debug mode */\n  if (db_globals.debug)\n  {\n    exec_timers = sb_alloc_per_thread_array(sizeof(sb_timer_t));\n    fetch_timers = sb_alloc_per_thread_array(sizeof(sb_timer_t));\n  }\n\n  db_reset_stats();\n\n  enable_print_stats();\n\n  db_global_initialized = true;\n}\n\n/*\n  Initialize a driver specified by 'name' and return a handle to it\n  If NULL is passed as a name, then use the driver passed in --db-driver\n  command line option\n*/\n\ndb_driver_t *db_create(const char *name)\n{\n  db_driver_t    *drv = NULL;\n  db_driver_t    *tmp;\n  sb_list_item_t *pos;\n\n  pthread_once(&db_global_once, db_init);\n\n  if (!db_global_initialized)\n    goto err;\n\n  if (name == NULL && db_globals.driver == NULL)\n  {\n    drv = SB_LIST_ENTRY(SB_LIST_ITEM_NEXT(&drivers), db_driver_t, listitem);\n    /* Is it the only driver available? */\n    if (SB_LIST_ITEM_NEXT(&(drv->listitem)) ==\n        SB_LIST_ITEM_PREV(&(drv->listitem)))\n      log_text(LOG_INFO, \"No DB drivers specified, using %s\", drv->sname);\n    else\n    {\n      log_text(LOG_FATAL, \"Multiple DB drivers are available. \"\n               \"Use --db-driver=name to specify which one to use\");\n      goto err;\n    }\n  }\n  else\n  {\n    if (name == NULL)\n      name = db_globals.driver;\n\n    SB_LIST_FOR_EACH(pos, &drivers)\n    {\n      tmp = SB_LIST_ENTRY(pos, db_driver_t, listitem);\n      if (!strcmp(tmp->sname, name))\n      {\n        drv = tmp;\n        break;\n      }\n    }\n  }\n\n  if (drv == NULL)\n  {\n    log_text(LOG_FATAL, \"invalid database driver name: '%s'\", name);\n    goto err;\n  }\n\n  /* Initialize database driver only once */\n  pthread_mutex_lock(&drv->mutex);\n  if (!drv->initialized)\n  {\n    if (drv->ops.init())\n    {\n      pthread_mutex_unlock(&drv->mutex);\n      goto err;\n    }\n    drv->initialized = true;\n  }\n  pthread_mutex_unlock(&drv->mutex);\n\n  if (drv->ops.thread_init != NULL && drv->ops.thread_init(sb_tls_thread_id))\n  {\n    log_text(LOG_FATAL, \"thread-local driver initialization failed.\");\n    return NULL;\n  }\n\n  return drv;\n\nerr:\n  return NULL;\n}\n\n/* Deinitialize a driver object */\n\nint db_destroy(db_driver_t *drv)\n{\n  if (drv->ops.thread_done != NULL)\n    return drv->ops.thread_done(sb_tls_thread_id);\n\n  return 0;\n}\n\n/* Describe database capabilities */\n\nint db_describe(db_driver_t *drv, drv_caps_t *caps)\n{\n  if (drv->ops.describe == NULL)\n    return 1;\n\n  return drv->ops.describe(caps);\n}\n\n\n/* Connect to database */\n\n\ndb_conn_t *db_connection_create(db_driver_t *drv)\n{\n  db_conn_t *con;\n\n  SB_COMPILE_TIME_ASSERT(sizeof(db_conn_t) % CK_MD_CACHELINE == 0);\n\n  con = (db_conn_t *)calloc(1, sizeof(db_conn_t));\n  if (con == NULL)\n    return NULL;\n\n  con->driver = drv;\n  con->state = DB_CONN_READY;\n\n  con->thread_id =  sb_tls_thread_id;\n\n  if (drv->ops.connect(con))\n  {\n    free(con);\n    return NULL;\n  }\n\n  return con;\n}\n\n\n/* Disconnect from database */\n\n\nint db_connection_close(db_conn_t *con)\n{\n  int         rc;\n  db_driver_t *drv = con->driver;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to close an already closed connection\");\n    return 0;\n  }\n  else if (con->state == DB_CONN_RESULT_SET)\n  {\n    db_free_results_int(con);\n  }\n\n  rc = drv->ops.disconnect(con);\n\n  con->state = DB_CONN_INVALID;\n\n  return rc;\n}\n\n/* Reconnect with the same connection parameters */\n\nint db_connection_reconnect(db_conn_t *con)\n{\n  int         rc;\n  db_driver_t *drv = con->driver;\n\n  if (drv->ops.reconnect == NULL)\n  {\n    log_text(LOG_ALERT, \"reconnect is not supported by the current driver\");\n    return 0;\n  }\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to close an already closed connection\");\n    return 0;\n  }\n  else if (con->state == DB_CONN_RESULT_SET)\n  {\n    db_free_results_int(con);\n  }\n\n  rc = drv->ops.reconnect(con);\n\n  if (rc == DB_ERROR_FATAL)\n  {\n    con->state = DB_CONN_INVALID;\n    sb_counter_inc(con->thread_id, SB_CNT_ERROR);\n  }\n  else\n  {\n    con->state = DB_CONN_READY;\n    sb_counter_inc(con->thread_id, SB_CNT_RECONNECT);\n\n    /* Clear DB_ERROR_IGNORABLE */\n    rc = DB_ERROR_NONE;\n  }\n\n  return rc;\n}\n\n/* Disconnect and release memory allocated by a connection object */\n\nvoid db_connection_free(db_conn_t *con)\n{\n  if (con->state != DB_CONN_INVALID)\n    db_connection_close(con);\n\n  free(con);\n}\n\n\n/* Prepare statement */\n\n\ndb_stmt_t *db_prepare(db_conn_t *con, const char *query, size_t len)\n{\n  db_stmt_t *stmt;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return NULL;\n  }\n\n  stmt = (db_stmt_t *)calloc(1, sizeof(db_stmt_t));\n  if (stmt == NULL)\n    return NULL;\n\n  stmt->connection = con;\n\n  if (con->driver->ops.prepare(stmt, query, len))\n  {\n    con->error = DB_ERROR_FATAL;\n    free(stmt);\n    return NULL;\n  }\n\n  return stmt;\n}\n\n\n/* Bind parameters for prepared statement */\n\n\nint db_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len)\n{\n  db_conn_t *con = stmt->connection;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 1;\n  }\n\n  return con->driver->ops.bind_param(stmt, params, len);\n}\n\n\n/* Bind results for prepared statement */\n\n\nint db_bind_result(db_stmt_t *stmt, db_bind_t *results, size_t len)\n{\n  db_conn_t *con = stmt->connection;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 1;\n  }\n\n  return con->driver->ops.bind_result(stmt, results, len);\n}\n\n\n/* Execute prepared statement */\n\n\ndb_result_t *db_execute(db_stmt_t *stmt)\n{\n  db_conn_t       *con = stmt->connection;\n  db_result_t     *rs = &con->rs;\n  int             rc;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return NULL;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    return NULL;\n  }\n\n  rs->statement = stmt;\n\n  con->error = con->driver->ops.execute(stmt, rs);\n\n  sb_counter_inc(con->thread_id, rs->counter);\n\n  if (SB_LIKELY(con->error == DB_ERROR_NONE))\n  {\n    if (rs->counter == SB_CNT_READ)\n    {\n      con->state = DB_CONN_RESULT_SET;\n      return rs;\n    }\n    con->state = DB_CONN_READY;\n\n    return NULL;\n  }\n\n  return NULL;\n}\n\n/* Retrieve the next result of a prepared statement */\n\ndb_result_t *db_stmt_next_result(db_stmt_t *stmt)\n{\n  db_conn_t       *con = stmt->connection;\n  db_result_t     *rs = &con->rs;\n  int             rc;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return NULL;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    return NULL;\n  }\n\n  rs->statement = stmt;\n\n  if (con->driver->ops.stmt_next_result == NULL)\n  {\n    con->error = DB_ERROR_NONE;\n    return NULL;\n  }\n\n  con->error = con->driver->ops.stmt_next_result(stmt, rs);\n\n  sb_counter_inc(con->thread_id, rs->counter);\n\n  if (SB_LIKELY(con->error == DB_ERROR_NONE))\n  {\n    if (rs->counter == SB_CNT_READ)\n    {\n      con->state = DB_CONN_RESULT_SET;\n      return rs;\n    }\n    con->state = DB_CONN_READY;\n\n    return NULL;\n  }\n\n  return NULL;\n}\n\n\n/* Fetch row from result set of a query */\n\n\ndb_row_t *db_fetch_row(db_result_t *rs)\n{\n  db_conn_t *con = SB_CONTAINER_OF(rs, db_conn_t, rs);\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return NULL;\n  }\n  else if (con->state != DB_CONN_RESULT_SET)\n  {\n    log_text(LOG_ALERT, \"attempt to fetch row from an invalid result set\");\n    return NULL;\n  }\n\n  if (con->driver->ops.fetch_row == NULL)\n  {\n    log_text(LOG_ALERT, \"fetching rows is not supported by the driver\");\n  }\n\n  if (rs->nrows == 0 || rs->nfields == 0)\n  {\n    log_text(LOG_ALERT, \"attempt to fetch row from an empty result set\");\n    return NULL;\n  }\n\n  if (rs->row.values == NULL)\n  {\n    rs->row.values = malloc(rs->nfields * sizeof(db_value_t));\n  }\n\n  if (con->driver->ops.fetch_row(rs, &rs->row))\n  {\n    return NULL;\n  }\n\n  return &rs->row;\n}\n\n\n/* Execute non-prepared statement */\n\n\ndb_result_t *db_query(db_conn_t *con, const char *query, size_t len)\n{\n  db_result_t *rs = &con->rs;\n  int         rc;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    con->error = DB_ERROR_FATAL;\n    return NULL;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    con->error = DB_ERROR_FATAL;\n    return NULL;\n  }\n\n  con->error = con->driver->ops.query(con, query, len, rs);\n\n  sb_counter_inc(con->thread_id, rs->counter);\n\n  if (SB_LIKELY(con->error == DB_ERROR_NONE))\n  {\n    if (rs->counter == SB_CNT_READ)\n    {\n      con->state = DB_CONN_RESULT_SET;\n      return rs;\n    }\n    con->state = DB_CONN_READY;\n\n    return NULL;\n  }\n\n  return NULL;\n}\n\n/* Check if more result sets are available */\n\nbool db_more_results(db_conn_t *con)\n{\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return false;\n  }\n\n  if (con->state != DB_CONN_RESULT_SET ||\n      con->driver->ops.more_results == NULL ||\n      con->driver->ops.more_results(con) == false)\n    return false;\n\n  return true;\n}\n\n/* Retrieve the next result set */\n\ndb_result_t *db_next_result(db_conn_t *con)\n{\n  db_result_t *rs = &con->rs;\n  int         rc;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    con->error = DB_ERROR_FATAL;\n    return NULL;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    con->error = DB_ERROR_FATAL;\n    return NULL;\n  }\n\n  if (con->driver->ops.next_result == NULL)\n  {\n    con->error = DB_ERROR_NONE;\n    return NULL;\n  }\n\n  con->error = con->driver->ops.next_result(con, rs);\n\n  sb_counter_inc(con->thread_id, rs->counter);\n\n  if (SB_LIKELY(con->error == DB_ERROR_NONE))\n  {\n    if (rs->counter == SB_CNT_READ)\n    {\n      con->state = DB_CONN_RESULT_SET;\n      return rs;\n    }\n    con->state = DB_CONN_READY;\n  }\n\n  return NULL;\n}\n\n/* Free result set */\n\n\nstatic int db_free_results_int(db_conn_t *con)\n{\n  int       rc;\n\n  rc = con->driver->ops.free_results(&con->rs);\n\n  if (con->rs.row.values != NULL)\n  {\n    free(con->rs.row.values);\n    con->rs.row.values = NULL;\n  }\n\n  con->rs.nrows = 0;\n  con->rs.nfields = 0;\n\n  con->rs.statement = NULL;\n\n  con->state = DB_CONN_READY;\n\n  return rc;\n}\n\nint db_free_results(db_result_t *rs)\n{\n  db_conn_t * const con = SB_CONTAINER_OF(rs, db_conn_t, rs);\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 1;\n  }\n  else if (con->state != DB_CONN_RESULT_SET)\n  {\n    log_text(LOG_ALERT, \"attempt to free an invalid result set\");\n    return 1;\n  }\n\n  return db_free_results_int(con);\n}\n\n/* Close prepared statement */\n\n\nint db_close(db_stmt_t *stmt)\n{\n  int       rc;\n  db_conn_t *con = stmt->connection;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 0;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    return DB_ERROR_FATAL;\n  }\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 0;\n  }\n  else if (con->state == DB_CONN_RESULT_SET && con->rs.statement == stmt &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    return 0;\n  }\n\n  rc = con->driver->ops.close(stmt);\n\n  if (stmt->query != NULL)\n  {\n    free(stmt->query);\n    stmt->query = NULL;\n  }\n  if (stmt->bound_param != NULL)\n  {\n    free(stmt->bound_param);\n    stmt->bound_param = NULL;\n  }\n  free(stmt);\n\n  return rc;\n}\n\n/* Uninitialize DB API */\n\nvoid db_done(void)\n{\n  sb_list_item_t *pos;\n  db_driver_t    *drv;\n\n  if (!db_global_initialized)\n    return;\n\n  disable_print_stats();\n\n  if (db_globals.debug)\n  {\n    free(exec_timers);\n    free(fetch_timers);\n\n    exec_timers = fetch_timers = NULL;\n  }\n\n  SB_LIST_FOR_EACH(pos, &drivers)\n  {\n    drv = SB_LIST_ENTRY(pos, db_driver_t, listitem);\n    if (drv->initialized)\n    {\n      drv->ops.done();\n      pthread_mutex_destroy(&drv->mutex);\n    }\n  }\n\n  return;\n}\n\n\n/* Parse command line arguments */\n\n\nint db_parse_arguments(void)\n{\n  char *s;\n\n  s = sb_get_value_string(\"db-ps-mode\");\n\n  if (!strcmp(s, \"auto\"))\n    db_globals.ps_mode = DB_PS_MODE_AUTO;\n  else if (!strcmp(s, \"disable\"))\n    db_globals.ps_mode = DB_PS_MODE_DISABLE;\n  else\n  {\n    log_text(LOG_FATAL, \"Invalid value for db-ps-mode: %s\", s);\n    return 1;\n  }\n\n  db_globals.driver = sb_get_value_string(\"db-driver\");\n\n  db_globals.debug = sb_get_value_flag(\"db-debug\");\n  \n  return 0;\n}\n\n\n/* Produce character representation of a 'bind' variable */\n\n\nint db_print_value(db_bind_t *var, char *buf, int buflen)\n{\n  int       n;\n  db_time_t *tm;\n\n  if (var->is_null != NULL && *var->is_null)\n  {\n    n = snprintf(buf, buflen, \"NULL\");\n    return (n < buflen) ? n : -1;\n  }\n  \n  switch (var->type) {\n    case DB_TYPE_TINYINT:\n      n = snprintf(buf, buflen, \"%hhd\", *(char *)var->buffer);\n      break;\n    case DB_TYPE_SMALLINT:\n      n = snprintf(buf, buflen, \"%hd\", *(short *)var->buffer);\n      break;\n    case DB_TYPE_INT:\n      n = snprintf(buf, buflen, \"%d\", *(int *)var->buffer);\n      break;\n    case DB_TYPE_BIGINT:\n      n = snprintf(buf, buflen, \"%lld\", *(long long *)var->buffer);\n      break;\n    case DB_TYPE_FLOAT:\n      n = snprintf(buf, buflen, \"%f\", *(float *)var->buffer);\n      break;\n    case DB_TYPE_DOUBLE:\n      n = snprintf(buf, buflen, \"%f\", *(double *)var->buffer);\n      break;\n    case DB_TYPE_CHAR:\n    case DB_TYPE_VARCHAR:\n      n = snprintf(buf, buflen, \"'%s'\", (char *)var->buffer);\n      break;\n    case DB_TYPE_DATE:\n      tm = (db_time_t *)var->buffer;\n      n = snprintf(buf, buflen, \"'%d-%d-%d'\", tm->year, tm->month, tm->day);\n      break;\n    case DB_TYPE_TIME:\n      tm = (db_time_t *)var->buffer;\n      n = snprintf(buf, buflen, \"'%d:%d:%d'\", tm->hour, tm->minute,\n                   tm->second);\n      break;\n    case DB_TYPE_DATETIME:\n    case DB_TYPE_TIMESTAMP:\n      tm = (db_time_t *)var->buffer;\n      n = snprintf(buf, buflen, \"'%d-%d-%d %d:%d:%d'\", tm->year, tm->month,\n                   tm->day, tm->hour, tm->minute, tm->second);\n      break;\n    default:\n      n = 0;\n      break;\n  }\n\n  return (n < buflen) ? n : -1;\n}\n\n\n#if 0\n/* Free row fetched by db_fetch_row() */\n\n\nvoid db_free_row(db_row_t *row)\n{\n  free(row);\n}\n#endif\n\n/* Initialize multi-row insert operation */\n\n\nint db_bulk_insert_init(db_conn_t *con, const char *query, size_t query_len)\n{\n  drv_caps_t driver_caps;\n  int        rc;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 0;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    return 0;\n  }\n\n  /* Get database capabilites */\n  if (db_describe(con->driver, &driver_caps))\n  {\n    log_text(LOG_FATAL, \"failed to get database capabilities!\");\n    return 1;\n  }\n\n  /* Allocate query buffer */\n  if (query_len + 1 > BULK_PACKET_SIZE)\n  {\n    log_text(LOG_FATAL,\n             \"Query length exceeds the maximum value (%u), aborting\",\n             BULK_PACKET_SIZE);\n    return 1;\n  }\n  con->bulk_buflen = BULK_PACKET_SIZE;\n  con->bulk_buffer = (char *)malloc(con->bulk_buflen);\n  if (con->bulk_buffer == NULL)\n    return 1;\n  \n  con->bulk_commit_max = driver_caps.needs_commit ? ROWS_BEFORE_COMMIT : 0;\n  con->bulk_commit_cnt = 0;\n  strcpy(con->bulk_buffer, query);\n  con->bulk_ptr = query_len;\n  con->bulk_values = query_len;\n  con->bulk_cnt = 0;\n\n  return 0;\n}\n\n/* Add row to multi-row insert operation */\n\nint db_bulk_insert_next(db_conn_t *con, const char *query, size_t query_len)\n{\n  int rc;\n\n  if (con->state == DB_CONN_INVALID)\n  {\n    log_text(LOG_ALERT, \"attempt to use an already closed connection\");\n    return 0;\n  }\n  else if (con->state == DB_CONN_RESULT_SET &&\n           (rc = db_free_results_int(con)) != 0)\n  {\n    return 0;\n  }\n\n  if (con->bulk_buffer == NULL)\n  {\n    log_text(LOG_ALERT, \"attempt to call bulk_insert_next() before bulk_insert_init()\");\n    return 1;\n  }\n\n  /*\n    Reserve space for '\\0' and ',' (if not the first chunk in\n    a bulk insert\n  */\n  if (con->bulk_ptr + query_len + 1 + (con->bulk_cnt>0) > con->bulk_buflen)\n  {\n    /* Is this a first row? */\n    if (!con->bulk_cnt)\n    {\n      log_text(LOG_FATAL,\n               \"Query length exceeds the maximum value (%u), aborting\",\n               con->bulk_buflen);\n      return 1;\n    }\n    if (db_bulk_do_insert(con, 0))\n      return 1;\n  }\n\n  if (con->bulk_cnt > 0)\n  {\n    con->bulk_buffer[con->bulk_ptr] = ',';\n    strcpy(con->bulk_buffer + con->bulk_ptr + 1, query);\n  }\n  else\n    strcpy(con->bulk_buffer + con->bulk_ptr, query);\n  con->bulk_ptr += query_len + (con->bulk_cnt > 0);\n\n  con->bulk_cnt++;\n\n  return 0;\n}\n\n/* Do the actual INSERT (and COMMIT, if necessary) */\n\nstatic int db_bulk_do_insert(db_conn_t *con, int is_last)\n{\n  if (!con->bulk_cnt)\n    return 0;\n\n  if (db_query(con, con->bulk_buffer, con->bulk_ptr) == NULL &&\n      con->error != DB_ERROR_NONE)\n    return 1;\n\n\n  if (con->bulk_commit_max != 0)\n  {\n    con->bulk_commit_cnt += con->bulk_cnt;\n\n    if (is_last || con->bulk_commit_cnt >= con->bulk_commit_max)\n    {\n      if (db_query(con, \"COMMIT\", 6) == NULL &&\n          con->error != DB_ERROR_NONE)\n        return 1;\n      con->bulk_commit_cnt = 0;\n    }\n  }\n\n  con->bulk_ptr = con->bulk_values;\n  con->bulk_cnt = 0;\n\n  return 0;\n}\n\n/* Finish multi-row insert operation */\n\nint db_bulk_insert_done(db_conn_t *con)\n{\n  /* Flush remaining data in buffer, if any */\n  if (db_bulk_do_insert(con, 1))\n    return 1;\n\n  if (con->bulk_buffer != NULL)\n  {\n    free(con->bulk_buffer);\n    con->bulk_buffer = NULL;\n  }\n\n  return 0;\n}\n\nvoid db_report_intermediate(sb_stat_t *stat)\n{\n  /* Use default stats handler if no drivers are used */\n  if (!check_print_stats())\n  {\n    sb_report_intermediate(stat);\n    return;\n  }\n\n  const double seconds = stat->time_interval;\n\n  log_timestamp(LOG_NOTICE, stat->time_total,\n                \"thds: %u tps: %4.2f \"\n                \"qps: %4.2f (r/w/o: %4.2f/%4.2f/%4.2f) \"\n                \"lat (ms,%u%%): %4.2f err/s: %4.2f \"\n                \"reconn/s: %4.2f\",\n                stat->threads_running,\n                stat->events / seconds,\n                (stat->reads + stat->writes + stat->other) / seconds,\n                stat->reads / seconds,\n                stat->writes / seconds,\n                stat->other / seconds,\n                sb_globals.percentile,\n                SEC2MS(stat->latency_pct),\n                stat->errors / seconds,\n                stat->reconnects / seconds);\n\n  if (sb_globals.tx_rate > 0)\n  {\n    log_timestamp(LOG_NOTICE, stat->time_total,\n                  \"queue length: %\" PRIu64\", concurrency: %\" PRIu64,\n                  stat->queue_length, stat->concurrency);\n  }\n}\n\n\nvoid db_report_cumulative(sb_stat_t *stat)\n{\n  sb_timer_t    exec_timer;\n  sb_timer_t    fetch_timer;\n\n  /* Use default stats handler if no drivers are used */\n  if (!check_print_stats())\n  {\n    sb_report_cumulative(stat);\n    return;\n  }\n\n  const double seconds = stat->time_interval;\n  const uint64_t queries = stat->reads + stat->writes + stat->other;\n\n  log_text(LOG_NOTICE, \"SQL statistics:\");\n  log_text(LOG_NOTICE, \"    queries performed:\");\n  log_text(LOG_NOTICE, \"        read:                            %\" PRIu64,\n           stat->reads);\n  log_text(LOG_NOTICE, \"        write:                           %\" PRIu64,\n           stat->writes);\n  log_text(LOG_NOTICE, \"        other:                           %\" PRIu64,\n           stat->other);\n  log_text(LOG_NOTICE, \"        total:                           %\" PRIu64,\n           queries);\n  log_text(LOG_NOTICE, \"    transactions:                        %-6\" PRIu64\n           \" (%.2f per sec.)\", stat->events, stat->events / seconds);\n  log_text(LOG_NOTICE, \"    queries:                             %-6\" PRIu64\n           \" (%.2f per sec.)\", queries,\n           queries / seconds);\n  log_text(LOG_NOTICE, \"    ignored errors:                      %-6\" PRIu64\n           \" (%.2f per sec.)\", stat->errors, stat->errors / seconds);\n  log_text(LOG_NOTICE, \"    reconnects:                          %-6\" PRIu64\n           \" (%.2f per sec.)\", stat->reconnects, stat->reconnects / seconds);\n\n  if (db_globals.debug)\n  {\n    sb_timer_init(&exec_timer);\n    sb_timer_init(&fetch_timer);\n\n    for (unsigned i = 0; i < sb_globals.threads; i++)\n    {\n      exec_timer = sb_timer_merge(&exec_timer, exec_timers + i);\n      fetch_timer = sb_timer_merge(&fetch_timer, fetch_timers + i);\n    }\n\n    log_text(LOG_DEBUG, \"\");\n    log_text(LOG_DEBUG, \"Query execution statistics:\");\n    log_text(LOG_DEBUG, \"    min:                                %.4fs\",\n             NS2SEC(sb_timer_min(&exec_timer)));\n    log_text(LOG_DEBUG, \"    avg:                                %.4fs\",\n             NS2SEC(sb_timer_avg(&exec_timer)));\n    log_text(LOG_DEBUG, \"    max:                                %.4fs\",\n             NS2SEC(sb_timer_max(&exec_timer)));\n    log_text(LOG_DEBUG, \"  total:                                %.4fs\",\n             NS2SEC(sb_timer_sum(&exec_timer)));\n\n    log_text(LOG_DEBUG, \"Results fetching statistics:\");\n    log_text(LOG_DEBUG, \"    min:                                %.4fs\",\n             NS2SEC(sb_timer_min(&fetch_timer)));\n    log_text(LOG_DEBUG, \"    avg:                                %.4fs\",\n             NS2SEC(sb_timer_avg(&fetch_timer)));\n    log_text(LOG_DEBUG, \"    max:                                %.4fs\",\n             NS2SEC(sb_timer_max(&fetch_timer)));\n    log_text(LOG_DEBUG, \"  total:                                %.4fs\",\n             NS2SEC(sb_timer_sum(&fetch_timer)));\n  }\n\n  /* Report sysbench general stats */\n  sb_report_cumulative(stat);\n}\n\n\nstatic void db_reset_stats(void)\n{\n  unsigned int i;\n\n  /*\n    So that intermediate stats are calculated from the current moment\n    rather than from the previous intermediate report\n  */\n  sb_timer_current(&sb_intermediate_timer);\n\n  if (db_globals.debug)\n  {\n    for (i = 0; i < sb_globals.threads; i++)\n    {\n      sb_timer_init(exec_timers + i);\n      sb_timer_init(fetch_timers + i);\n    }\n  }\n}\n"
  },
  {
    "path": "src/db_driver.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef DB_DRIVER_H\n#define DB_DRIVER_H\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#include \"sysbench.h\"\n#include \"sb_list.h\"\n#include \"sb_histogram.h\"\n#include \"sb_counter.h\"\n\n/* Prepared statements usage modes */\n\ntypedef enum\n{\n  DB_PS_MODE_AUTO,\n  DB_PS_MODE_DISABLE,\n} db_ps_mode_t;\n\n/* Global DB API options */\n\ntypedef struct\n{\n  db_ps_mode_t  ps_mode;   /* Requested prepared statements usage mode */\n  char          *driver;   /* Requested database driver */\n  unsigned char debug;     /* debug flag */\n} db_globals_t;\n\n/* Driver capabilities definition */\n\ntypedef struct\n{\n  char     multi_rows_insert;   /* 1 if database supports multi-row inserts */\n  char     prepared_statements; /* 1 if database supports prepared statements */\n  char     auto_increment;      /* 1 if database supports AUTO_INCREMENT clause */\n  char     needs_commit;        /* 1 if database needs explicit commit after INSERTs */\n  char     serial;              /* 1 if database supports SERIAL clause */\n  char     unsigned_int;        /* 1 if database supports UNSIGNED INTEGER types */\n} drv_caps_t;\n\n/* Database errors definition */\n\ntypedef enum\n{\n  DB_ERROR_NONE,                /* no error(s) */\n  DB_ERROR_IGNORABLE,           /* error should be ignored as defined by command\n                                line arguments or a custom error handler */\n  DB_ERROR_FATAL                /* non-ignorable error */\n} db_error_t;\n\n\n/* Available buffer types (for parameters binding) */\n\ntypedef enum\n{\n  DB_TYPE_NONE,\n  DB_TYPE_TINYINT,\n  DB_TYPE_SMALLINT,\n  DB_TYPE_INT,\n  DB_TYPE_BIGINT,\n  DB_TYPE_FLOAT,\n  DB_TYPE_DOUBLE,\n  DB_TYPE_TIME,\n  DB_TYPE_DATE,\n  DB_TYPE_DATETIME,\n  DB_TYPE_TIMESTAMP,\n  DB_TYPE_CHAR,\n  DB_TYPE_VARCHAR\n} db_bind_type_t;\n\n\n/* Structure used to represent DATE, TIME, DATETIME and TIMESTAMP values */\n\ntypedef struct\n{\n  unsigned int year;\n  unsigned int month;\n  unsigned int day;\n  unsigned int hour;\n  unsigned int minute;\n  unsigned int second;\n} db_time_t;\n\n\n/* Structure used to bind data for prepared statements */\n\ntypedef struct\n{\n  db_bind_type_t   type;\n  void             *buffer;\n  unsigned long    *data_len;\n  unsigned long    max_len;\n  char             *is_null;\n} db_bind_t;\n\n/* Forward declarations */\n\nstruct db_conn;\nstruct db_stmt;\nstruct db_result;\nstruct db_row;\n\n/* Driver operations definition */\n\ntypedef int drv_op_init(void);\ntypedef int drv_op_thread_init(int);\ntypedef int drv_op_describe(drv_caps_t *);\ntypedef int drv_op_connect(struct db_conn *);\ntypedef int drv_op_reconnect(struct db_conn *);\ntypedef int drv_op_disconnect(struct db_conn *);\ntypedef int drv_op_prepare(struct db_stmt *, const char *, size_t);\ntypedef int drv_op_bind_param(struct db_stmt *, db_bind_t *, size_t);\ntypedef int drv_op_bind_result(struct db_stmt *, db_bind_t *, size_t);\ntypedef db_error_t drv_op_execute(struct db_stmt *, struct db_result *);\ntypedef db_error_t drv_op_stmt_next_result(struct db_stmt *,\n                                           struct db_result *);\ntypedef int drv_op_fetch(struct db_result *);\ntypedef int drv_op_fetch_row(struct db_result *, struct db_row *);\ntypedef db_error_t drv_op_query(struct db_conn *, const char *, size_t,\n                                struct db_result *);\ntypedef bool drv_op_more_results(struct db_conn *);\ntypedef db_error_t drv_op_next_result(struct db_conn *, struct db_result *);\ntypedef int drv_op_free_results(struct db_result *);\ntypedef int drv_op_close(struct db_stmt *);\ntypedef int drv_op_thread_done(int);\ntypedef int drv_op_done(void);\n\ntypedef struct\n{\n  drv_op_init            *init;           /* initializate driver */\n  drv_op_thread_init     *thread_init;    /* thread-local driver initialization */\n  drv_op_describe        *describe;       /* describe database capabilities */\n  drv_op_connect         *connect;        /* connect to database */\n  drv_op_disconnect      *disconnect;     /* disconnect from database */\n  drv_op_reconnect       *reconnect;      /* reconnect with the same parameters */\n  drv_op_prepare         *prepare;        /* prepare statement */\n  drv_op_bind_param      *bind_param;     /* bind params for prepared statement */\n  drv_op_bind_result     *bind_result;    /* bind results for prepared statement */\n  drv_op_execute         *execute;        /* execute prepared statement */\n  /* retrieve the next result of a prepared statement */\n  drv_op_stmt_next_result *stmt_next_result;\n  drv_op_fetch           *fetch;          /* fetch row for prepared statement */\n  drv_op_fetch_row       *fetch_row;      /* fetch row for queries */\n  drv_op_free_results    *free_results;   /* free result set */\n  drv_op_more_results    *more_results;   /* check if more result sets are\n                                             available */\n  drv_op_next_result     *next_result;    /* retrieve the next result set */\n  drv_op_close           *close;          /* close prepared statement */\n  drv_op_query           *query;          /* execute non-prepared statement */\n  drv_op_thread_done     *thread_done;    /* thread-local driver deinitialization */\n  drv_op_done            *done;           /* uninitialize driver */\n} drv_ops_t;\n\n/* Database driver definition */\n\ntypedef struct\n{\n  const char      *sname;   /* short name */\n  const char      *lname;   /* long name */\n  sb_arg_t        *args;    /* driver command line arguments */\n  drv_ops_t       ops;      /* driver operations */\n\n  sb_list_item_t  listitem; /* can be linked in a list */\n  bool            initialized;\n  pthread_mutex_t mutex;\n} db_driver_t;\n\n/* Row value definition */\n\ntypedef struct {\n  uint32_t        len;         /* Value length */\n  const char      *ptr;        /* Value string */\n} db_value_t;\n\n/* Result set row definition */\n\ntypedef struct db_row\n{\n  void            *ptr;        /* Driver-specific row data */\n  db_value_t      *values;     /* Array of column values */\n} db_row_t;\n\n/* Result set definition */\n\ntypedef struct db_result\n{\n  sb_counter_type_t counter;     /* Statistical counter type */\n  uint32_t       nrows;         /* Number of affected rows */\n  uint32_t       nfields;       /* Number of fields */\n  struct db_stmt *statement;    /* Pointer to prepared statement (if used) */\n  void           *ptr;          /* Pointer to driver-specific data */\n  db_row_t       row;           /* Last fetched row */\n} db_result_t;\n\ntypedef enum {\n  DB_CONN_READY,\n  DB_CONN_RESULT_SET,\n  DB_CONN_INVALID\n} db_conn_state_t;\n\n/* Database connection structure */\n\ntypedef struct db_conn\n{\n  db_error_t      error;             /* Database-independent error code */\n  int             sql_errno;         /* Database-specific error code */\n  const char      *sql_state;        /* Database-specific SQL state */\n  const char      *sql_errmsg;       /* Database-specific error message */\n  db_driver_t     *driver;           /* DB driver for this connection */\n  void            *ptr;              /* Driver-specific data */\n  db_result_t     rs;                /* Result set */\n  db_conn_state_t state;             /* Connection state */\n  int             thread_id;         /* Thread this connection belongs to */\n\n  unsigned int    bulk_cnt;          /* Current number of rows in bulk insert buffer */\n  unsigned int    bulk_buflen;       /* Current length of bulk_buffer */\n  char            *bulk_buffer;      /* Bulk insert query buffer */\n  unsigned int    bulk_ptr;          /* Current position in bulk_buffer */\n  unsigned int    bulk_values;       /* Save value of bulk_ptr */\n  unsigned int    bulk_commit_cnt;   /* Current value of uncommitted rows */\n  unsigned int    bulk_commit_max;   /* Maximum value of uncommitted rows */\n\n  char            pad[SB_CACHELINE_PAD(sizeof(db_error_t) +\n                                       sizeof(int) +\n                                       sizeof(void *) +\n                                       sizeof(void *) +\n                                       sizeof(void *) +\n                                       sizeof(void *) +\n                                       sizeof(db_result_t) +\n                                       sizeof(db_conn_state_t) +\n                                       sizeof(int) +\n                                       sizeof(int) * 2 +\n                                       sizeof(void *) +\n                                       sizeof(int) * 4\n                                       )];\n} db_conn_t;\n\n/* Prepared statement definition */\n\ntypedef struct db_stmt\n{\n  db_conn_t       *connection;     /* Connection which this statement belongs to */\n  char            *query;          /* Query string for emulated PS */\n  db_bind_t       *bound_param;    /* Array of bound parameters for emulated PS */\n  unsigned int    bound_param_len; /* Length of the bound_param array */\n  db_bind_t       *bound_res;      /* Array of bound results for emulated PS */ \n  db_bind_t       *bound_res_len;  /* Length of the bound_res array */\n  char            emulated;        /* Should this statement be emulated? */\n  void            *ptr;            /* Pointer to driver-specific data structure */\n} db_stmt_t;\n\nextern db_globals_t db_globals;\n\n/* Database abstraction layer calls */\n\nint db_register(void);\n\nvoid db_print_help(void);\n\ndb_driver_t *db_create(const char *);\n\nint db_destroy(db_driver_t *);\n\nint db_describe(db_driver_t *, drv_caps_t *);\n\ndb_conn_t *db_connection_create(db_driver_t *);\n\nint db_connection_close(db_conn_t *);\n\nint db_connection_reconnect(db_conn_t *con);\n\nvoid db_connection_free(db_conn_t *con);\n\ndb_stmt_t *db_prepare(db_conn_t *, const char *, size_t);\n\nint db_bind_param(db_stmt_t *, db_bind_t *, size_t);\n\nint db_bind_result(db_stmt_t *, db_bind_t *, size_t);\n\ndb_result_t *db_execute(db_stmt_t *);\n\ndb_result_t *db_stmt_next_result(db_stmt_t *);\n\ndb_row_t *db_fetch_row(db_result_t *);\n\ndb_result_t *db_query(db_conn_t *, const char *, size_t len);\n\nint db_free_results(db_result_t *);\n\nbool db_more_results(db_conn_t *);\n\ndb_result_t *db_next_result(db_conn_t *);\n\nint db_store_results(db_result_t *);\n\nint db_close(db_stmt_t *);\n\nvoid db_done(void);\n\nint db_print_value(db_bind_t *, char *, int);\n\n/* Initialize multi-row insert operation */\nint db_bulk_insert_init(db_conn_t *, const char *, size_t);\n\n/* Add row to multi-row insert operation */\nint db_bulk_insert_next(db_conn_t *, const char *, size_t);\n\n/* Finish multi-row insert operation */\nint db_bulk_insert_done(db_conn_t *);\n\n/* Print database-specific test stats */\nvoid db_report_intermediate(sb_stat_t *);\nvoid db_report_cumulative(sb_stat_t *);\n\n/* DB drivers registrars */\n\n#ifdef USE_MYSQL\nint register_driver_mysql(sb_list_t *);\n#endif\n\n#ifdef USE_PGSQL\nint register_driver_pgsql(sb_list_t *);\n#endif\n\n#endif /* DB_DRIVER_H */\n"
  },
  {
    "path": "src/drivers/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nif USE_MYSQL\nMYSQL_DIR = mysql\nendif\n\nif USE_PGSQL\nPGSQL_DIR = pgsql\nendif\n\nSUBDIRS = $(MYSQL_DIR) $(PGSQL_DIR)\n"
  },
  {
    "path": "src/drivers/mysql/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbmysql.a\n\nlibsbmysql_a_SOURCES = drv_mysql.c\nlibsbmysql_a_CPPFLAGS = $(MYSQL_CFLAGS) $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/drivers/mysql/drv_mysql.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n#endif\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#include <stdio.h>\n\n#include <mysql.h>\n#include <mysqld_error.h>\n#include <errmsg.h>\n\n#include \"sb_options.h\"\n#include \"db_driver.h\"\n\n#define DEBUG(format, ...)                      \\\n  do {                                          \\\n    if (SB_UNLIKELY(args.debug != 0))           \\\n      log_text(LOG_DEBUG, format, __VA_ARGS__); \\\n  } while (0)\n\nstatic inline const char *SAFESTR(const char *s)\n{\n  return s ? s : \"(null)\";\n}\n\n#if !defined(MARIADB_BASE_VERSION) && !defined(MARIADB_VERSION_ID) && \\\n  MYSQL_VERSION_ID >= 80001 && MYSQL_VERSION_ID != 80002 /* see https://bugs.mysql.com/?id=87337 */\ntypedef bool my_bool;\n#endif\n\n/* MySQL driver arguments */\n\nstatic sb_arg_t mysql_drv_args[] =\n{\n  SB_OPT(\"mysql-host\", \"MySQL server host\", \"localhost\", LIST),\n  SB_OPT(\"mysql-port\", \"MySQL server port\", \"3306\", LIST),\n  SB_OPT(\"mysql-socket\", \"MySQL socket\", NULL, LIST),\n  SB_OPT(\"mysql-user\", \"MySQL user\", \"sbtest\", STRING),\n  SB_OPT(\"mysql-password\", \"MySQL password\", \"\", STRING),\n  SB_OPT(\"mysql-db\", \"MySQL database name\", \"sbtest\", STRING),\n#ifdef HAVE_MYSQL_OPT_SSL_MODE\n  SB_OPT(\"mysql-ssl\", \"SSL mode. This accepts the same values as the \"\n         \"--ssl-mode option in the MySQL client utilities. Disabled by default\",\n         \"disabled\", STRING),\n#else\n  SB_OPT(\"mysql-ssl\", \"use SSL connections, if available in the client \"\n         \"library\", \"off\", BOOL),\n#endif\n  SB_OPT(\"mysql-ssl-key\", \"path name of the client private key file\", NULL,\n         STRING),\n  SB_OPT(\"mysql-ssl-ca\", \"path name of the CA file\", NULL, STRING),\n  SB_OPT(\"mysql-ssl-cert\",\n         \"path name of the client public key certificate file\", NULL, STRING),\n  SB_OPT(\"mysql-ssl-cipher\", \"use specific cipher for SSL connections\", \"\",\n         STRING),\n  SB_OPT(\"mysql-compression\", \"use compression, if available in the \"\n         \"client library\", \"off\", BOOL),\n  SB_OPT(\"mysql-compression-algorithms\", \"compression algorithms to use\",\n\t \"zlib\", STRING),\n  SB_OPT(\"mysql-debug\", \"trace all client library calls\", \"off\", BOOL),\n  SB_OPT(\"mysql-ignore-errors\", \"list of errors to ignore, or \\\"all\\\"\",\n         \"1213,1020,1205\", LIST),\n  SB_OPT(\"mysql-dry-run\", \"Dry run, pretend that all MySQL client API \"\n         \"calls are successful without executing them\", \"off\", BOOL),\n\n  SB_OPT_END\n};\n\ntypedef struct\n{\n  sb_list_t          *hosts;\n  sb_list_t          *ports;\n  sb_list_t          *sockets;\n  const char         *user;\n  const char         *password;\n  const char         *db;\n#ifdef HAVE_MYSQL_OPT_SSL_MODE\n  unsigned int       ssl_mode;\n#endif\n  bool               use_ssl;\n  const char         *ssl_key;\n  const char         *ssl_cert;\n  const char         *ssl_ca;\n  const char         *ssl_cipher;\n  unsigned char      use_compression;\n#ifdef MYSQL_OPT_COMPRESSION_ALGORITHMS\n  const char         *compression_alg;\n#endif\n  unsigned char      debug;\n  sb_list_t          *ignored_errors;\n  unsigned int       dry_run;\n} mysql_drv_args_t;\n\ntypedef struct\n{\n  MYSQL        *mysql;\n  const char   *host;\n  const char   *user;\n  const char   *password;\n  const char   *db;\n  unsigned int port;\n  char         *socket;\n} db_mysql_conn_t;\n\n#ifdef HAVE_MYSQL_OPT_SSL_MODE\ntypedef struct {\n  const char *name;\n  enum mysql_ssl_mode mode;\n} ssl_mode_map_t;\n#endif\n\n\n/* Structure used for DB-to-MySQL bind types map */\n\ntypedef struct\n{\n  db_bind_type_t   db_type;\n  int              my_type;\n} db_mysql_bind_map_t;\n\n/* DB-to-MySQL bind types map */\ndb_mysql_bind_map_t db_mysql_bind_map[] =\n{\n  {DB_TYPE_TINYINT,   MYSQL_TYPE_TINY},\n  {DB_TYPE_SMALLINT,  MYSQL_TYPE_SHORT},\n  {DB_TYPE_INT,       MYSQL_TYPE_LONG},\n  {DB_TYPE_BIGINT,    MYSQL_TYPE_LONGLONG},\n  {DB_TYPE_FLOAT,     MYSQL_TYPE_FLOAT},\n  {DB_TYPE_DOUBLE,    MYSQL_TYPE_DOUBLE},\n  {DB_TYPE_DATETIME,  MYSQL_TYPE_DATETIME},\n  {DB_TYPE_TIMESTAMP, MYSQL_TYPE_TIMESTAMP},\n  {DB_TYPE_CHAR,      MYSQL_TYPE_STRING},\n  {DB_TYPE_VARCHAR,   MYSQL_TYPE_VAR_STRING},\n  {DB_TYPE_NONE,      0}\n};\n\n/* MySQL driver capabilities */\n\nstatic drv_caps_t mysql_drv_caps =\n{\n  1,\n  0,\n  1,\n  0,\n  0,\n  1\n};\n\n\n\nstatic mysql_drv_args_t args;          /* driver args */\n\nstatic char use_ps; /* whether server-side prepared statemens should be used */\n\n/* Positions in the list of hosts/ports/sockets. Protected by pos_mutex */\nstatic sb_list_item_t *hosts_pos;\nstatic sb_list_item_t *ports_pos;\nstatic sb_list_item_t *sockets_pos;\n\nstatic pthread_mutex_t pos_mutex;\n\n#ifdef HAVE_MYSQL_OPT_SSL_MODE\n\n#if MYSQL_VERSION_ID < 50711\n/*\n  In MySQL 5.6 the only valid SSL mode is SSL_MODE_REQUIRED. Define\n  SSL_MODE_DISABLED to enable the 'disabled' default value for --mysql-ssl\n*/\n#define SSL_MODE_DISABLED 1\n#endif\n\nstatic ssl_mode_map_t ssl_mode_names[] = {\n  {\"DISABLED\", SSL_MODE_DISABLED},\n#if MYSQL_VERSION_ID >= 50711\n  {\"PREFERRED\", SSL_MODE_PREFERRED},\n#endif\n  {\"REQUIRED\", SSL_MODE_REQUIRED},\n#if MYSQL_VERSION_ID >= 50711\n  {\"VERIFY_CA\", SSL_MODE_VERIFY_CA},\n  {\"VERIFY_IDENTITY\", SSL_MODE_VERIFY_IDENTITY},\n#endif\n  {NULL, 0}\n};\n#endif\n\n/* MySQL driver operations */\n\nstatic int mysql_drv_init(void);\nstatic int mysql_drv_thread_init(int);\nstatic int mysql_drv_describe(drv_caps_t *);\nstatic int mysql_drv_connect(db_conn_t *);\nstatic int mysql_drv_reconnect(db_conn_t *);\nstatic int mysql_drv_disconnect(db_conn_t *);\nstatic int mysql_drv_prepare(db_stmt_t *, const char *, size_t);\nstatic int mysql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t);\nstatic int mysql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t);\nstatic db_error_t mysql_drv_execute(db_stmt_t *, db_result_t *);\nstatic db_error_t mysql_drv_stmt_next_result(db_stmt_t *, db_result_t *);\nstatic int mysql_drv_fetch(db_result_t *);\nstatic int mysql_drv_fetch_row(db_result_t *, db_row_t *);\nstatic db_error_t mysql_drv_query(db_conn_t *, const char *, size_t,\n                           db_result_t *);\nstatic bool mysql_drv_more_results(db_conn_t *);\nstatic db_error_t mysql_drv_next_result(db_conn_t *, db_result_t *);\nstatic int mysql_drv_free_results(db_result_t *);\nstatic int mysql_drv_close(db_stmt_t *);\nstatic int mysql_drv_thread_done(int);\nstatic int mysql_drv_done(void);\n\n/* MySQL driver definition */\n\nstatic db_driver_t mysql_driver =\n{\n  .sname = \"mysql\",\n  .lname = \"MySQL driver\",\n  .args = mysql_drv_args,\n  .ops = {\n    .init = mysql_drv_init,\n    .thread_init = mysql_drv_thread_init,\n    .describe = mysql_drv_describe,\n    .connect = mysql_drv_connect,\n    .disconnect = mysql_drv_disconnect,\n    .reconnect = mysql_drv_reconnect,\n    .prepare = mysql_drv_prepare,\n    .bind_param = mysql_drv_bind_param,\n    .bind_result = mysql_drv_bind_result,\n    .execute = mysql_drv_execute,\n    .stmt_next_result = mysql_drv_stmt_next_result,\n    .fetch = mysql_drv_fetch,\n    .fetch_row = mysql_drv_fetch_row,\n    .more_results = mysql_drv_more_results,\n    .next_result = mysql_drv_next_result,\n    .free_results = mysql_drv_free_results,\n    .close = mysql_drv_close,\n    .query = mysql_drv_query,\n    .thread_done = mysql_drv_thread_done,\n    .done = mysql_drv_done\n  }\n};\n\n\n/* Local functions */\n\nstatic int get_mysql_bind_type(db_bind_type_t);\n\n/* Register MySQL driver */\n\n\nint register_driver_mysql(sb_list_t *drivers)\n{\n  SB_LIST_ADD_TAIL(&mysql_driver.listitem, drivers);\n\n  return 0;\n}\n\n\n/* MySQL driver initialization */\n\n\nint mysql_drv_init(void)\n{\n  pthread_mutex_init(&pos_mutex, NULL);\n\n  args.hosts = sb_get_value_list(\"mysql-host\");\n  if (SB_LIST_IS_EMPTY(args.hosts))\n  {\n    log_text(LOG_FATAL, \"No MySQL hosts specified, aborting\");\n    return 1;\n  }\n  hosts_pos = SB_LIST_ITEM_NEXT(args.hosts);\n\n  args.ports = sb_get_value_list(\"mysql-port\");\n  if (SB_LIST_IS_EMPTY(args.ports))\n  {\n    log_text(LOG_FATAL, \"No MySQL ports specified, aborting\");\n    return 1;\n  }\n  ports_pos = SB_LIST_ITEM_NEXT(args.ports);\n\n  args.sockets = sb_get_value_list(\"mysql-socket\");\n  sockets_pos = args.sockets;\n\n  args.user = sb_get_value_string(\"mysql-user\");\n  args.password = sb_get_value_string(\"mysql-password\");\n  args.db = sb_get_value_string(\"mysql-db\");\n\n  args.ssl_cipher = sb_get_value_string(\"mysql-ssl-cipher\");\n  args.ssl_key = sb_get_value_string(\"mysql-ssl-key\");\n  args.ssl_cert = sb_get_value_string(\"mysql-ssl-cert\");\n  args.ssl_ca = sb_get_value_string(\"mysql-ssl-ca\");\n\n#ifdef HAVE_MYSQL_OPT_SSL_MODE\n  const char * const ssl_mode_string = sb_get_value_string(\"mysql-ssl\");\n\n  args.ssl_mode = 0;\n\n  for (int i = 0; ssl_mode_names[i].name != NULL; i++) {\n    if (!strcasecmp(ssl_mode_string, ssl_mode_names[i].name)) {\n      args.ssl_mode = ssl_mode_names[i].mode;\n      break;\n    }\n  }\n\n  if (args.ssl_mode == 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for --mysql-ssl: '%s'\", ssl_mode_string);\n    return 1;\n  }\n\n  args.use_ssl = (args.ssl_mode != SSL_MODE_DISABLED);\n#else\n  args.use_ssl = sb_get_value_flag(\"mysql-ssl\");\n#endif\n\n  args.use_compression = sb_get_value_flag(\"mysql-compression\");\n#ifdef MYSQL_OPT_COMPRESSION_ALGORITHMS\n  args.compression_alg = sb_get_value_string(\"mysql-compression-algorithms\");\n#endif\n\n  args.debug = sb_get_value_flag(\"mysql-debug\");\n  if (args.debug)\n    sb_globals.verbosity = LOG_DEBUG;\n\n  args.ignored_errors = sb_get_value_list(\"mysql-ignore-errors\");\n\n  args.dry_run = sb_get_value_flag(\"mysql-dry-run\");\n\n  use_ps = 0;\n  mysql_drv_caps.prepared_statements = 1;\n  if (db_globals.ps_mode != DB_PS_MODE_DISABLE)\n    use_ps = 1;\n\n  DEBUG(\"mysql_library_init(%d, %p, %p)\", 0, NULL, NULL);\n  mysql_library_init(0, NULL, NULL);\n\n  return 0;\n}\n\n/* Thread-local driver initialization */\n\nint mysql_drv_thread_init(int thread_id)\n{\n  (void) thread_id; /* unused */\n\n  const my_bool rc = mysql_thread_init();\n  DEBUG(\"mysql_thread_init() = %d\", (int) rc);\n\n  return rc != 0;\n}\n\n/* Thread-local driver deinitialization */\n\nint mysql_drv_thread_done(int thread_id)\n{\n  (void) thread_id; /* unused */\n\n  DEBUG(\"mysql_thread_end(%s)\", \"\");\n  mysql_thread_end();\n\n  return 0;\n}\n\n/* Describe database capabilities */\n\nint mysql_drv_describe(drv_caps_t *caps)\n{\n  *caps = mysql_drv_caps;\n\n  return 0;\n}\n\n\nstatic int mysql_drv_real_connect(db_mysql_conn_t *db_mysql_con)\n{\n  MYSQL          *con = db_mysql_con->mysql;\n\n#ifdef HAVE_MYSQL_OPT_SSL_MODE\n  DEBUG(\"mysql_options(%p,%s,%d)\", con, \"MYSQL_OPT_SSL_MODE\", args.ssl_mode);\n  mysql_options(con, MYSQL_OPT_SSL_MODE, &args.ssl_mode);\n#endif\n\n  if (args.use_ssl)\n  {\n    DEBUG(\"mysql_ssl_set(%p, \\\"%s\\\", \\\"%s\\\", \\\"%s\\\", NULL, \\\"%s\\\")\", con,\n          SAFESTR(args.ssl_key), SAFESTR(args.ssl_cert), SAFESTR(args.ssl_ca),\n          SAFESTR(args.ssl_cipher));\n\n    mysql_ssl_set(con, args.ssl_key, args.ssl_cert, args.ssl_ca, NULL,\n                  args.ssl_cipher);\n  }\n\n  if (args.use_compression)\n  {\n    DEBUG(\"mysql_options(%p, %s, %s)\",con, \"MYSQL_OPT_COMPRESS\", \"NULL\");\n    mysql_options(con, MYSQL_OPT_COMPRESS, NULL);\n\n#ifdef MYSQL_OPT_COMPRESSION_ALGORITHMS\n    DEBUG(\"mysql_options(%p, %s, %s)\",con, \"MYSQL_OPT_COMPRESSION_ALGORITHMS\", args.compression_alg);\n    mysql_options(con, MYSQL_OPT_COMPRESSION_ALGORITHMS, args.compression_alg);\n#endif\n  }\n\n  DEBUG(\"mysql_real_connect(%p, \\\"%s\\\", \\\"%s\\\", \\\"%s\\\", \\\"%s\\\", %u, \\\"%s\\\", %s)\",\n        con,\n        SAFESTR(db_mysql_con->host),\n        SAFESTR(db_mysql_con->user),\n        SAFESTR(db_mysql_con->password),\n        SAFESTR(db_mysql_con->db),\n        db_mysql_con->port,\n        SAFESTR(db_mysql_con->socket),\n        (MYSQL_VERSION_ID >= 50000) ? \"CLIENT_MULTI_STATEMENTS\" : \"0\"\n        );\n\n  return mysql_real_connect(con,\n                            db_mysql_con->host,\n                            db_mysql_con->user,\n                            db_mysql_con->password,\n                            db_mysql_con->db,\n                            db_mysql_con->port,\n                            db_mysql_con->socket,\n#if MYSQL_VERSION_ID >= 50000\n                            CLIENT_MULTI_STATEMENTS\n#else\n                            0\n#endif\n                            ) == NULL;\n}\n\n\n/* Connect to MySQL database */\n\n\nint mysql_drv_connect(db_conn_t *sb_conn)\n{\n  MYSQL           *con;\n  db_mysql_conn_t *db_mysql_con;\n\n  if (args.dry_run)\n    return 0;\n\n  db_mysql_con = (db_mysql_conn_t *) calloc(1, sizeof(db_mysql_conn_t));\n\n  if (db_mysql_con == NULL)\n    return 1;\n\n  con = (MYSQL *) malloc(sizeof(MYSQL));\n  if (con == NULL)\n    return 1;\n\n  db_mysql_con->mysql = con;\n\n  DEBUG(\"mysql_init(%p)\", con);\n  mysql_init(con);\n\n  pthread_mutex_lock(&pos_mutex);\n\n  if (SB_LIST_IS_EMPTY(args.sockets))\n  {\n    db_mysql_con->socket = NULL;\n    db_mysql_con->host = SB_LIST_ENTRY(hosts_pos, value_t, listitem)->data;\n    db_mysql_con->port =\n      atoi(SB_LIST_ENTRY(ports_pos, value_t, listitem)->data);\n\n    /*\n       Pick the next port in args.ports. If there are no more ports in the list,\n       move to the next available host and get the first port again.\n    */\n    ports_pos = SB_LIST_ITEM_NEXT(ports_pos);\n    if (ports_pos == args.ports) {\n      hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);\n      if (hosts_pos == args.hosts)\n        hosts_pos = SB_LIST_ITEM_NEXT(hosts_pos);\n\n      ports_pos = SB_LIST_ITEM_NEXT(ports_pos);\n    }\n  }\n  else\n  {\n    db_mysql_con->host = \"localhost\";\n\n    /*\n       The sockets list may be empty. So unlike hosts/ports the loop invariant\n       here is that sockets_pos points to the previous one and should be\n       advanced before using it, not after.\n     */\n    sockets_pos = SB_LIST_ITEM_NEXT(sockets_pos);\n    if (sockets_pos == args.sockets)\n      sockets_pos = SB_LIST_ITEM_NEXT(sockets_pos);\n\n    db_mysql_con->socket = SB_LIST_ENTRY(sockets_pos, value_t, listitem)->data;\n  }\n  pthread_mutex_unlock(&pos_mutex);\n\n  db_mysql_con->user = args.user;\n  db_mysql_con->password = args.password;\n  db_mysql_con->db = args.db;\n\n  if (mysql_drv_real_connect(db_mysql_con))\n  {\n    if (!SB_LIST_IS_EMPTY(args.sockets))\n      log_text(LOG_FATAL, \"unable to connect to MySQL server on socket '%s', \"\n               \"aborting...\", db_mysql_con->socket);\n    else\n      log_text(LOG_FATAL, \"unable to connect to MySQL server on host '%s', \"\n               \"port %u, aborting...\",\n               db_mysql_con->host, db_mysql_con->port);\n    log_text(LOG_FATAL, \"error %d: %s\", mysql_errno(con),\n             mysql_error(con));\n    free(db_mysql_con);\n    free(con);\n    return 1;\n  }\n\n  if (args.use_ssl)\n  {\n    DEBUG(\"mysql_get_ssl_cipher(con): \\\"%s\\\"\",\n          SAFESTR(mysql_get_ssl_cipher(con)));\n  }\n\n  sb_conn->ptr = db_mysql_con;\n\n  return 0;\n}\n\n\n/* Disconnect from MySQL database */\n\n\nint mysql_drv_disconnect(db_conn_t *sb_conn)\n{\n  db_mysql_conn_t *db_mysql_con = sb_conn->ptr;\n\n  if (args.dry_run)\n    return 0;\n  if (db_mysql_con != NULL && db_mysql_con->mysql != NULL)\n  {\n    DEBUG(\"mysql_close(%p)\", db_mysql_con->mysql);\n    mysql_close(db_mysql_con->mysql);\n    free(db_mysql_con->mysql);\n    free(db_mysql_con);\n  }\n\n  return 0;\n}\n\n\n/* Prepare statement */\n\n\nint mysql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len)\n{\n  MYSQL_STMT *mystmt;\n  unsigned int rc;\n\n  if (args.dry_run)\n    return 0;\n\n  db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) stmt->connection->ptr;\n  MYSQL      *con = db_mysql_con->mysql;\n\n  if (con == NULL)\n    return 1;\n\n  if (use_ps)\n  {\n    mystmt = mysql_stmt_init(con);\n    DEBUG(\"mysql_stmt_init(%p) = %p\", con, mystmt);\n    if (mystmt == NULL)\n    {\n      log_text(LOG_FATAL, \"mysql_stmt_init() failed\");\n      return 1;\n    }\n    stmt->ptr = (void *)mystmt;\n    DEBUG(\"mysql_stmt_prepare(%p, \\\"%s\\\", %u) = %p\", mystmt, query,\n          (unsigned int) len, stmt->ptr);\n    if (mysql_stmt_prepare(mystmt, query, len))\n    {\n      /* Check if this statement in not supported */\n      rc = mysql_errno(con);\n      DEBUG(\"mysql_errno(%p) = %u\", con, rc);\n      if (rc == ER_UNSUPPORTED_PS)\n      {\n        log_text(LOG_INFO,\n                 \"Failed to prepare query \\\"%s\\\" (%d: %s), using emulation\",\n                 query, rc, mysql_error(con));\n        goto emulate;\n      }\n      else\n      {\n        log_text(LOG_FATAL, \"mysql_stmt_prepare() failed\");\n        log_text(LOG_FATAL, \"MySQL error: %d \\\"%s\\\"\", rc,\n                 mysql_error(con));\n        DEBUG(\"mysql_stmt_close(%p)\", mystmt);\n        mysql_stmt_close(mystmt);\n        return 1;\n      }\n    }\n\n    stmt->query = strdup(query);\n\n    return 0;\n  }\n\n emulate:\n\n  /* Use client-side PS */\n  stmt->emulated = 1;\n  stmt->query = strdup(query);\n\n  return 0;\n}\n\n\nstatic void convert_to_mysql_bind(MYSQL_BIND *mybind, db_bind_t *bind)\n{\n  mybind->buffer_type = get_mysql_bind_type(bind->type);\n  mybind->buffer = bind->buffer;\n  mybind->buffer_length = bind->max_len;\n  mybind->length = bind->data_len;\n  /*\n    Reuse the buffer passed by the caller to avoid conversions. This is only\n    valid if sizeof(char) == sizeof(mybind->is_null[0]). Depending on the\n    version of the MySQL client library, the type of MYSQL_BIND::is_null[0] can\n    be either my_bool or bool, but sizeof(bool) is not defined by the C\n    standard. We assume it to be 1 on most platforms to simplify code and Lua\n    API.\n  */\n#if SIZEOF_BOOL > 1\n# error This code assumes sizeof(bool) == 1!\n#endif\n  mybind->is_null = (my_bool *) bind->is_null;\n}\n\n\n/* Bind parameters for prepared statement */\n\n\nint mysql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len)\n{\n  MYSQL_BIND   *bind;\n  unsigned int i;\n  my_bool rc;\n  unsigned long param_count;\n\n  if (args.dry_run)\n    return 0;\n\n  db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) stmt->connection->ptr;\n  MYSQL        *con = db_mysql_con->mysql;\n\n  if (con == NULL)\n    return 1;\n\n  if (!stmt->emulated)\n  {\n    if (stmt->ptr == NULL)\n      return 1;\n    /* Validate parameters count */\n    param_count = mysql_stmt_param_count(stmt->ptr);\n    DEBUG(\"mysql_stmt_param_count(%p) = %lu\", stmt->ptr, param_count);\n    if (param_count != len)\n    {\n      log_text(LOG_FATAL, \"Wrong number of parameters to mysql_stmt_bind_param\");\n      return 1;\n    }\n    /* Convert sysbench bind structures to MySQL ones */\n    bind = (MYSQL_BIND *)calloc(len, sizeof(MYSQL_BIND));\n    if (bind == NULL)\n      return 1;\n    for (i = 0; i < len; i++)\n      convert_to_mysql_bind(&bind[i], &params[i]);\n\n    rc = mysql_stmt_bind_param(stmt->ptr, bind);\n    DEBUG(\"mysql_stmt_bind_param(%p, %p) = %d\", stmt->ptr, bind, rc);\n    if (rc)\n    {\n      log_text(LOG_FATAL, \"mysql_stmt_bind_param() failed\");\n      log_text(LOG_FATAL, \"MySQL error: %d \\\"%s\\\"\", mysql_errno(con),\n                 mysql_error(con));\n      free(bind);\n      return 1;\n    }\n    free(bind);\n\n    return 0;\n  }\n\n  /* Use emulation */\n  if (stmt->bound_param != NULL)\n    free(stmt->bound_param);\n  stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t));\n  if (stmt->bound_param == NULL)\n    return 1;\n  memcpy(stmt->bound_param, params, len * sizeof(db_bind_t));\n  stmt->bound_param_len = len;\n\n  return 0;\n\n}\n\n\n/* Bind results for prepared statement */\n\n\nint mysql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len)\n{\n  MYSQL_BIND   *bind;\n  unsigned int i;\n  my_bool rc;\n\n  if (args.dry_run)\n    return 0;\n\n  db_mysql_conn_t *db_mysql_con =(db_mysql_conn_t *) stmt->connection->ptr;\n  MYSQL        *con = db_mysql_con->mysql;\n\n  if (con == NULL || stmt->ptr == NULL)\n    return 1;\n\n  /* Convert sysbench bind structures to MySQL ones */\n  bind = (MYSQL_BIND *)calloc(len, sizeof(MYSQL_BIND));\n  if (bind == NULL)\n    return 1;\n  for (i = 0; i < len; i++)\n    convert_to_mysql_bind(&bind[i], &params[i]);\n\n  rc = mysql_stmt_bind_result(stmt->ptr, bind);\n  DEBUG(\"mysql_stmt_bind_result(%p, %p) = %d\", stmt->ptr, bind, rc);\n  if (rc)\n  {\n    free(bind);\n    return 1;\n  }\n  free(bind);\n\n  return 0;\n}\n\n/* Reset connection to the server by reconnecting with the same parameters. */\n\nstatic int mysql_drv_reconnect(db_conn_t *sb_con)\n{\n  db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) sb_con->ptr;\n  MYSQL *con = db_mysql_con->mysql;\n\n  log_text(LOG_DEBUG, \"Reconnecting\");\n\n  DEBUG(\"mysql_close(%p)\", con);\n  mysql_close(con);\n\n  while (mysql_drv_real_connect(db_mysql_con))\n  {\n    if (sb_globals.error)\n      return DB_ERROR_FATAL;\n\n    usleep(1000);\n  }\n\n  log_text(LOG_DEBUG, \"Reconnected\");\n\n  return DB_ERROR_IGNORABLE;\n}\n\n\n/*\n  Check if the error in a given connection should be fatal or ignored according\n  to the list of errors in --mysql-ignore-errors.\n*/\n\n\nstatic db_error_t check_error(db_conn_t *sb_con, const char *func,\n                              const char *query, sb_counter_type_t *counter)\n{\n  sb_list_item_t *pos;\n  unsigned int   tmp;\n  db_mysql_conn_t *db_mysql_con = (db_mysql_conn_t *) sb_con->ptr;\n  MYSQL          *con = db_mysql_con->mysql;\n\n  const unsigned int error = mysql_errno(con);\n  DEBUG(\"mysql_errno(%p) = %u\", con, sb_con->sql_errno);\n\n  sb_con->sql_errno = (int) error;\n\n  sb_con->sql_state = mysql_sqlstate(con);\n  DEBUG(\"mysql_state(%p) = %s\", con, SAFESTR(sb_con->sql_state));\n\n  sb_con->sql_errmsg = mysql_error(con);\n  DEBUG(\"mysql_error(%p) = %s\", con, SAFESTR(sb_con->sql_errmsg));\n\n  /*\n    Check if the error code is specified in --mysql-ignore-errors, and return\n    DB_ERROR_IGNORABLE if so, or DB_ERROR_FATAL otherwise\n  */\n  SB_LIST_FOR_EACH(pos, args.ignored_errors)\n  {\n    const char *val = SB_LIST_ENTRY(pos, value_t, listitem)->data;\n\n    tmp = (unsigned int) atoi(val);\n\n    if (error == tmp || !strcmp(val, \"all\"))\n    {\n      log_text(LOG_DEBUG, \"Ignoring error %u %s, \", error, sb_con->sql_errmsg);\n\n      /* Check if we should reconnect */\n      switch (error)\n      {\n      case CR_SERVER_LOST:\n      case CR_SERVER_GONE_ERROR:\n      case CR_TCP_CONNECTION:\n      case CR_SERVER_LOST_EXTENDED:\n\n        *counter = SB_CNT_RECONNECT;\n\n        return mysql_drv_reconnect(sb_con);\n\n      default:\n\n        break;\n      }\n\n      *counter = SB_CNT_ERROR;\n\n      return DB_ERROR_IGNORABLE;\n    }\n  }\n\n  if (query)\n    log_text(LOG_FATAL, \"%s returned error %u (%s) for query '%s'\",\n             func, error, sb_con->sql_errmsg, query);\n  else\n    log_text(LOG_FATAL, \"%s returned error %u (%s)\",\n             func, error, sb_con->sql_errmsg);\n\n  *counter = SB_CNT_ERROR;\n\n  return DB_ERROR_FATAL;\n}\n\n/* Execute prepared statement */\n\n\ndb_error_t mysql_drv_execute(db_stmt_t *stmt, db_result_t *rs)\n{\n  db_conn_t       *con = stmt->connection;\n  char            *buf = NULL;\n  unsigned int    buflen = 0;\n  unsigned int    i, j, vcnt;\n  char            need_realloc;\n  int             n;\n\n  if (args.dry_run)\n    return DB_ERROR_NONE;\n\n  con->sql_errno = 0;\n  con->sql_state = NULL;\n  con->sql_errmsg = NULL;\n\n  if (!stmt->emulated)\n  {\n    if (stmt->ptr == NULL)\n    {\n      log_text(LOG_DEBUG,\n               \"ERROR: exiting mysql_drv_execute(), uninitialized statement\");\n      return DB_ERROR_FATAL;\n    }\n\n    int err = mysql_stmt_execute(stmt->ptr);\n    DEBUG(\"mysql_stmt_execute(%p) = %d\", stmt->ptr, err);\n\n    if (err)\n      return check_error(con, \"mysql_stmt_execute()\", stmt->query,\n                         &rs->counter);\n\n    err = mysql_stmt_store_result(stmt->ptr);\n    DEBUG(\"mysql_stmt_store_result(%p) = %d\", stmt->ptr, err);\n\n    if (err)\n      return check_error(con, \"mysql_stmt_store_result()\", NULL, &rs->counter);\n\n    if (mysql_stmt_errno(stmt->ptr) == 0 &&\n        mysql_stmt_field_count(stmt->ptr) == 0)\n    {\n      rs->nrows = (uint32_t) mysql_stmt_affected_rows(stmt->ptr);\n      DEBUG(\"mysql_stmt_affected_rows(%p) = %u\", stmt->ptr,\n            (unsigned) rs->nrows);\n\n      rs->counter = (rs->nrows > 0) ? SB_CNT_WRITE : SB_CNT_OTHER;\n\n      return DB_ERROR_NONE;\n    }\n\n    rs->counter = SB_CNT_READ;\n\n    rs->nrows = (uint32_t) mysql_stmt_num_rows(stmt->ptr);\n    DEBUG(\"mysql_stmt_num_rows(%p) = %u\", rs->statement->ptr,\n          (unsigned) (rs->nrows));\n\n    rs->nfields = (uint32_t) mysql_stmt_field_count(stmt->ptr);\n    DEBUG(\"mysql_stmt_field_count(%p) = %u\", rs->statement->ptr,\n          (unsigned) (rs->nfields));\n\n    return DB_ERROR_NONE;\n  }\n\n  /* Use emulation */\n  /* Build the actual query string from parameters list */\n  need_realloc = 1;\n  vcnt = 0;\n  for (i = 0, j = 0; stmt->query[i] != '\\0'; i++)\n  {\n  again:\n    if (j+1 >= buflen || need_realloc)\n    {\n      buflen = (buflen > 0) ? buflen * 2 : 256;\n      buf = realloc(buf, buflen);\n      if (buf == NULL)\n      {\n        log_text(LOG_DEBUG, \"ERROR: exiting mysql_drv_execute(), memory allocation failure\");\n        return DB_ERROR_FATAL;\n      }\n      need_realloc = 0;\n    }\n\n    if (stmt->query[i] != '?')\n    {\n      buf[j++] = stmt->query[i];\n      continue;\n    }\n\n    n = db_print_value(stmt->bound_param + vcnt, buf + j, (int)(buflen - j));\n    if (n < 0)\n    {\n      need_realloc = 1;\n      goto again;\n    }\n    j += (unsigned int)n;\n    vcnt++;\n  }\n  buf[j] = '\\0';\n\n  db_error_t rc = mysql_drv_query(con, buf, j, rs);\n\n  free(buf);\n\n  return rc;\n}\n\n/* Retrieve the next result of a prepared statement */\n\ndb_error_t mysql_drv_stmt_next_result(db_stmt_t *stmt, db_result_t *rs)\n{\n  db_conn_t       *con = stmt->connection;\n\n  if (args.dry_run)\n    return DB_ERROR_NONE;\n\n  con->sql_errno = 0;\n  con->sql_state = NULL;\n  con->sql_errmsg = NULL;\n\n  if (stmt->emulated)\n    return mysql_drv_next_result(con, rs);\n\n  if (stmt->ptr == NULL)\n    {\n      log_text(LOG_DEBUG,\n               \"ERROR: exiting mysql_drv_stmt_next_result(), \"\n               \"uninitialized statement\");\n      return DB_ERROR_FATAL;\n    }\n\n  int err = mysql_stmt_next_result(stmt->ptr);\n  DEBUG(\"mysql_stmt_next_result(%p) = %d\", stmt->ptr, err);\n\n  if (SB_UNLIKELY(err > 0))\n    return check_error(con, \"mysql_drv_stmt_next_result()\", stmt->query,\n                       &rs->counter);\n\n  if (err == -1)\n  {\n    rs->counter = SB_CNT_OTHER;\n    return DB_ERROR_NONE;\n  }\n\n  err = mysql_stmt_store_result(stmt->ptr);\n  DEBUG(\"mysql_stmt_store_result(%p) = %d\", stmt->ptr, err);\n\n  if (err)\n    return check_error(con, \"mysql_stmt_store_result()\", NULL, &rs->counter);\n\n  if (mysql_stmt_errno(stmt->ptr) == 0 &&\n      mysql_stmt_field_count(stmt->ptr) == 0)\n  {\n    rs->nrows = (uint32_t) mysql_stmt_affected_rows(stmt->ptr);\n    DEBUG(\"mysql_stmt_affected_rows(%p) = %u\", stmt->ptr,\n          (unsigned) rs->nrows);\n\n    rs->counter = (rs->nrows > 0) ? SB_CNT_WRITE : SB_CNT_OTHER;\n\n    return DB_ERROR_NONE;\n  }\n\n  rs->counter = SB_CNT_READ;\n\n  rs->nrows = (uint32_t) mysql_stmt_num_rows(stmt->ptr);\n  DEBUG(\"mysql_stmt_num_rows(%p) = %u\", rs->statement->ptr,\n        (unsigned) (rs->nrows));\n\n  rs->nfields = (uint32_t) mysql_stmt_field_count(stmt->ptr);\n  DEBUG(\"mysql_stmt_field_count(%p) = %u\", rs->statement->ptr,\n        (unsigned) (rs->nfields));\n\n  return DB_ERROR_NONE;\n}\n\n\n/* Execute SQL query */\n\n\ndb_error_t mysql_drv_query(db_conn_t *sb_conn, const char *query, size_t len,\n                           db_result_t *rs)\n{\n  db_mysql_conn_t *db_mysql_con;\n  MYSQL *con;\n\n  if (args.dry_run)\n    return DB_ERROR_NONE;\n\n  sb_conn->sql_errno = 0;\n  sb_conn->sql_state = NULL;\n  sb_conn->sql_errmsg = NULL;\n\n  db_mysql_con = (db_mysql_conn_t *)sb_conn->ptr;\n  con = db_mysql_con->mysql;\n\n  int err = mysql_real_query(con, query, len);\n  DEBUG(\"mysql_real_query(%p, \\\"%s\\\", %zd) = %d\", con, query, len, err);\n\n  if (SB_UNLIKELY(err != 0))\n    return check_error(sb_conn, \"mysql_drv_query()\", query, &rs->counter);\n\n  /* Store results and get query type */\n  MYSQL_RES *res = mysql_store_result(con);\n  DEBUG(\"mysql_store_result(%p) = %p\", con, res);\n\n  if (res == NULL)\n  {\n    if (mysql_errno(con) == 0 && mysql_field_count(con) == 0)\n    {\n      /* Not a select. Check if it was a DML */\n      uint32_t nrows = (uint32_t) mysql_affected_rows(con);\n      if (nrows > 0)\n      {\n        rs->counter = SB_CNT_WRITE;\n        rs->nrows = nrows;\n      }\n      else\n        rs->counter = SB_CNT_OTHER;\n\n      return DB_ERROR_NONE;\n    }\n\n    return check_error(sb_conn, \"mysql_store_result()\", NULL, &rs->counter);\n  }\n\n  rs->counter = SB_CNT_READ;\n  rs->ptr = (void *)res;\n\n  rs->nrows = mysql_num_rows(res);\n  DEBUG(\"mysql_num_rows(%p) = %u\", res, (unsigned int) rs->nrows);\n\n  rs->nfields = mysql_num_fields(res);\n  DEBUG(\"mysql_num_fields(%p) = %u\", res, (unsigned int) rs->nfields);\n\n  return DB_ERROR_NONE;\n}\n\n\n/* Fetch row from result set of a prepared statement */\n\n\nint mysql_drv_fetch(db_result_t *rs)\n{\n  /* NYI */\n  (void)rs;  /* unused */\n\n  if (args.dry_run)\n    return DB_ERROR_NONE;\n\n  return 1;\n}\n\n/* Fetch row from result set of a query */\n\nint mysql_drv_fetch_row(db_result_t *rs, db_row_t *row)\n{\n  MYSQL_ROW my_row;\n\n  if (args.dry_run)\n    return DB_ERROR_NONE;\n\n  my_row = mysql_fetch_row(rs->ptr);\n  DEBUG(\"mysql_fetch_row(%p) = %p\", rs->ptr, my_row);\n\n  unsigned long *lengths = mysql_fetch_lengths(rs->ptr);\n  DEBUG(\"mysql_fetch_lengths(%p) = %p\", rs->ptr, lengths);\n\n  if (lengths == NULL)\n    return DB_ERROR_IGNORABLE;\n\n  for (size_t i = 0; i < rs->nfields; i++)\n  {\n    row->values[i].len = lengths[i];\n    row->values[i].ptr = my_row[i];\n  }\n\n  return DB_ERROR_NONE;\n}\n\n/* Check if more result sets are available */\n\nbool mysql_drv_more_results(db_conn_t *sb_conn)\n{\n  db_mysql_conn_t *db_mysql_con;\n  MYSQL *con;\n\n  if (args.dry_run)\n    return false;\n\n  db_mysql_con = (db_mysql_conn_t *)sb_conn->ptr;\n  con = db_mysql_con->mysql;\n\n  bool res = mysql_more_results(con);\n  DEBUG(\"mysql_more_results(%p) = %d\", con, res);\n\n  return res;\n}\n\n/* Retrieve the next result set */\n\ndb_error_t mysql_drv_next_result(db_conn_t *sb_conn, db_result_t *rs)\n{\n  db_mysql_conn_t *db_mysql_con;\n  MYSQL *con;\n\n  if (args.dry_run)\n    return DB_ERROR_NONE;\n\n  sb_conn->sql_errno = 0;\n  sb_conn->sql_state = NULL;\n  sb_conn->sql_errmsg = NULL;\n\n  db_mysql_con = (db_mysql_conn_t *)sb_conn->ptr;\n  con = db_mysql_con->mysql;\n\n  int err = mysql_next_result(con);\n  DEBUG(\"mysql_next_result(%p) = %d\", con, err);\n\n  if (SB_UNLIKELY(err > 0))\n    return check_error(sb_conn, \"mysql_drv_next_result()\", NULL, &rs->counter);\n\n  if (err == -1)\n  {\n    rs->counter = SB_CNT_OTHER;\n    return DB_ERROR_NONE;\n  }\n\n  /* Store results and get query type */\n  MYSQL_RES *res = mysql_store_result(con);\n  DEBUG(\"mysql_store_result(%p) = %p\", con, res);\n\n  if (res == NULL)\n  {\n    if (mysql_errno(con) == 0 && mysql_field_count(con) == 0)\n    {\n      /* Not a select. Check if it was a DML */\n      uint32_t nrows = (uint32_t) mysql_affected_rows(con);\n      if (nrows > 0)\n      {\n        rs->counter = SB_CNT_WRITE;\n        rs->nrows = nrows;\n      }\n      else\n        rs->counter = SB_CNT_OTHER;\n\n      return DB_ERROR_NONE;\n    }\n\n    return check_error(sb_conn, \"mysql_store_result()\", NULL, &rs->counter);\n  }\n\n  rs->counter = SB_CNT_READ;\n  rs->ptr = (void *)res;\n\n  rs->nrows = mysql_num_rows(res);\n  DEBUG(\"mysql_num_rows(%p) = %u\", res, (unsigned int) rs->nrows);\n\n  rs->nfields = mysql_num_fields(res);\n  DEBUG(\"mysql_num_fields(%p) = %u\", res, (unsigned int) rs->nfields);\n\n  return DB_ERROR_NONE;\n}\n\n/* Free result set */\n\nint mysql_drv_free_results(db_result_t *rs)\n{\n  if (args.dry_run)\n    return 0;\n\n  /* Is this a result set of a prepared statement? */\n  if (rs->statement != NULL && rs->statement->emulated == 0)\n  {\n    DEBUG(\"mysql_stmt_free_result(%p)\", rs->statement->ptr);\n    mysql_stmt_free_result(rs->statement->ptr);\n    rs->ptr = NULL;\n  }\n\n  if (rs->ptr != NULL)\n  {\n    DEBUG(\"mysql_free_result(%p)\", rs->ptr);\n    mysql_free_result((MYSQL_RES *)rs->ptr);\n    rs->ptr = NULL;\n  }\n\n  return 0;\n}\n\n\n/* Close prepared statement */\n\n\nint mysql_drv_close(db_stmt_t *stmt)\n{\n  if (args.dry_run)\n    return 0;\n\n  if (stmt->query)\n  {\n    free(stmt->query);\n    stmt->query = NULL;\n  }\n\n  if (stmt->ptr == NULL)\n    return 1;\n\n  int rc = mysql_stmt_close(stmt->ptr);\n  DEBUG(\"mysql_stmt_close(%p) = %d\", stmt->ptr, rc);\n\n  stmt->ptr = NULL;\n\n  return rc;\n}\n\n\n/* Uninitialize driver */\nint mysql_drv_done(void)\n{\n  if (args.dry_run)\n    return 0;\n\n  mysql_library_end();\n\n  return 0;\n}\n\n/* Map SQL data type to bind_type value in MYSQL_BIND */\n\nint get_mysql_bind_type(db_bind_type_t type)\n{\n  unsigned int i;\n\n  for (i = 0; db_mysql_bind_map[i].db_type != DB_TYPE_NONE; i++)\n    if (db_mysql_bind_map[i].db_type == type)\n      return db_mysql_bind_map[i].my_type;\n\n  return -1;\n}\n"
  },
  {
    "path": "src/drivers/pgsql/Makefile.am",
    "content": "# Copyright (C) 2005 MySQL AB\n# Copyright (C) 2005-2015 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbpgsql.a\n\nlibsbpgsql_a_SOURCES = drv_pgsql.c\nlibsbpgsql_a_CPPFLAGS = -g $(PGSQL_CFLAGS) $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/drivers/pgsql/drv_pgsql.c",
    "content": "/* Copyright (C) 2005 MySQL AB\n   Copyright (C) 2005-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n\n#include <libpq-fe.h>\n\n#include \"sb_options.h\"\n#include \"db_driver.h\"\n#include \"sb_rand.h\"\n\n#define xfree(ptr) ({ if (ptr) free((void *)ptr); ptr = NULL; })\n\n/* Maximum length of text representation of bind parameters */\n#define MAX_PARAM_LENGTH 256UL\n\n/* PostgreSQL driver arguments */\n\nstatic sb_arg_t pgsql_drv_args[] =\n{\n  SB_OPT(\"pgsql-host\", \"PostgreSQL server host\", \"localhost\", STRING),\n  SB_OPT(\"pgsql-port\", \"PostgreSQL server port\", \"5432\", INT),\n  SB_OPT(\"pgsql-user\", \"PostgreSQL user\", \"sbtest\", STRING),\n  SB_OPT(\"pgsql-password\", \"PostgreSQL password\", \"\", STRING),\n  SB_OPT(\"pgsql-db\", \"PostgreSQL database name\", \"sbtest\", STRING),\n  SB_OPT(\"pgsql-sslmode\", \"PostgreSQL SSL mode (disable, allow, prefer, require, verify-ca, verify-full)\", \"prefer\", STRING),\n\n  SB_OPT_END\n};\n\ntypedef struct\n{\n  char               *host;\n  char               *port;\n  char               *user;\n  char               *password;\n  char               *db;\n} pgsql_drv_args_t;\n\n/* Structure used for DB-to-PgSQL bind types map */\n\ntypedef struct\n{\n  db_bind_type_t   db_type;\n  int              pg_type;\n} db_pgsql_bind_map_t;\n\n/* DB-to-PgSQL bind types map */\ndb_pgsql_bind_map_t db_pgsql_bind_map[] =\n{\n  {DB_TYPE_TINYINT,   0},\n  {DB_TYPE_SMALLINT,  21},\n  {DB_TYPE_INT,       23},\n  {DB_TYPE_BIGINT,    20},\n  {DB_TYPE_FLOAT,     700},\n  {DB_TYPE_DOUBLE,    701},\n  {DB_TYPE_DATETIME,  0},\n  {DB_TYPE_TIMESTAMP, 1114},\n  {DB_TYPE_CHAR,      18},\n  {DB_TYPE_VARCHAR,   1043},\n  {DB_TYPE_NONE,      0}\n};\n\n/* PgSQL driver capabilities */\n\nstatic drv_caps_t pgsql_drv_caps =\n{\n  1,    /* multi_rows_insert */\n  1,    /* prepared_statements */\n  0,    /* auto_increment */\n  0,    /* needs_commit */\n  1,    /* serial */\n  0,    /* unsigned int */\n};\n\n/* Describes the PostgreSQL prepared statement */\ntypedef struct pg_stmt\n{\n  char     *name;\n  int      prepared;\n  int      nparams;\n  Oid      *ptypes;\n  char     **pvalues;\n} pg_stmt_t;\n\nstatic pgsql_drv_args_t args;          /* driver args */\n\nstatic char use_ps; /* whether server-side prepared statemens should be used */\n\n/* PgSQL driver operations */\n\nstatic int pgsql_drv_init(void);\nstatic int pgsql_drv_describe(drv_caps_t *);\nstatic int pgsql_drv_connect(db_conn_t *);\nstatic int pgsql_drv_disconnect(db_conn_t *);\nstatic int pgsql_drv_reconnect(db_conn_t *);\nstatic int pgsql_drv_prepare(db_stmt_t *, const char *, size_t);\nstatic int pgsql_drv_bind_param(db_stmt_t *, db_bind_t *, size_t);\nstatic int pgsql_drv_bind_result(db_stmt_t *, db_bind_t *, size_t);\nstatic db_error_t pgsql_drv_execute(db_stmt_t *, db_result_t *);\nstatic int pgsql_drv_fetch(db_result_t *);\nstatic int pgsql_drv_fetch_row(db_result_t *, db_row_t *);\nstatic db_error_t pgsql_drv_query(db_conn_t *, const char *, size_t,\n                                  db_result_t *);\nstatic int pgsql_drv_free_results(db_result_t *);\nstatic int pgsql_drv_close(db_stmt_t *);\nstatic int pgsql_drv_done(void);\n\n/* PgSQL driver definition */\n\nstatic db_driver_t pgsql_driver =\n{\n  .sname = \"pgsql\",\n  .lname = \"PostgreSQL driver\",\n  .args = pgsql_drv_args,\n  .ops =\n  {\n    .init = pgsql_drv_init,\n    .describe = pgsql_drv_describe,\n    .connect = pgsql_drv_connect,\n    .disconnect = pgsql_drv_disconnect,\n    .reconnect = pgsql_drv_reconnect,\n    .prepare = pgsql_drv_prepare,\n    .bind_param = pgsql_drv_bind_param,\n    .bind_result = pgsql_drv_bind_result,\n    .execute = pgsql_drv_execute,\n    .fetch = pgsql_drv_fetch,\n    .fetch_row = pgsql_drv_fetch_row,\n    .free_results = pgsql_drv_free_results,\n    .close = pgsql_drv_close,\n    .query = pgsql_drv_query,\n    .done = pgsql_drv_done\n  }\n};\n\n\n/* Local functions */\n\nstatic int get_pgsql_bind_type(db_bind_type_t);\nstatic int get_unique_stmt_name(char *, int);\n\n/* Register PgSQL driver */\n\n\nint register_driver_pgsql(sb_list_t *drivers)\n{\n  SB_LIST_ADD_TAIL(&pgsql_driver.listitem, drivers);\n\n  return 0;\n}\n\n/* PgSQL driver initialization */\n\nint pgsql_drv_init(void)\n{\n  args.host = sb_get_value_string(\"pgsql-host\");\n  args.port = sb_get_value_string(\"pgsql-port\");\n  args.user = sb_get_value_string(\"pgsql-user\");\n  args.password = sb_get_value_string(\"pgsql-password\");\n\n  char * dbname = sb_get_value_string(\"pgsql-db\");\n  char * sslmode = sb_get_value_string(\"pgsql-sslmode\");\n\n  args.db = malloc(strlen(\"dbname= sslmode=\") +\n                   strlen(dbname) +\n                   strlen(sslmode) +\n                   1);\n  sprintf(args.db, \"dbname=%s sslmode=%s\", dbname, sslmode);\n\n  use_ps = 0;\n  pgsql_drv_caps.prepared_statements = 1;\n  if (db_globals.ps_mode != DB_PS_MODE_DISABLE)\n    use_ps = 1;\n  \n  return 0;\n}\n\n\n/* Describe database capabilities */\n\n\nint pgsql_drv_describe(drv_caps_t *caps)\n{\n  PGconn *con;\n  \n  *caps = pgsql_drv_caps;\n\n  /* Determine the server version */\n  con = PQsetdbLogin(args.host,\n                     args.port,\n                     NULL,\n                     NULL,\n                     args.db,\n                     args.user,\n                     args.password);\n  if (PQstatus(con) != CONNECTION_OK)\n  {\n    log_text(LOG_FATAL, \"Connection to database failed: %s\",\n             PQerrorMessage(con));\n    PQfinish(con);\n    return 1;\n  }\n\n  /* Support for multi-row INSERTs is not available before 8.2 */\n  if (PQserverVersion(con) < 80200)\n    caps->multi_rows_insert = 0;\n\n  PQfinish(con);\n  \n  return 0;\n}\n\nstatic void empty_notice_processor(void *arg, const char *msg)\n{\n  (void) arg; /* unused */\n  (void) msg; /* unused */\n}\n\n/* Connect to database */\n\nint pgsql_drv_connect(db_conn_t *sb_conn)\n{\n  PGconn *con;\n\n  con = PQsetdbLogin(args.host,\n                     args.port,\n                     NULL,\n                     NULL,\n                     args.db,\n                     args.user,\n                     args.password);\n  if (PQstatus(con) != CONNECTION_OK)\n  {\n    log_text(LOG_FATAL, \"Connection to database failed: %s\",\n             PQerrorMessage(con));\n    PQfinish(con);\n    return 1;\n  }\n\n  /* Silence the default notice receiver spitting NOTICE message to stderr */\n  PQsetNoticeProcessor(con, empty_notice_processor, NULL);\n  sb_conn->ptr = con;\n  \n  return 0;\n}\n\n/* Disconnect from database */\n\nint pgsql_drv_disconnect(db_conn_t *sb_conn)\n{\n  PGconn *con = (PGconn *)sb_conn->ptr;\n\n  /* These might be allocated in pgsql_check_status() */\n  xfree(sb_conn->sql_state);\n  xfree(sb_conn->sql_errmsg);\n\n  if (con != NULL)\n    PQfinish(con);\n\n  return 0;\n}\n\n/* Disconnect from database */\n\nint pgsql_drv_reconnect(db_conn_t *sb_conn)\n{\n  if (pgsql_drv_disconnect(sb_conn))\n    return DB_ERROR_FATAL;\n\n  while (pgsql_drv_connect(sb_conn))\n  {\n    if (sb_globals.error)\n      return DB_ERROR_FATAL;\n  }\n\n  return DB_ERROR_IGNORABLE;\n}\n\n\n/* Prepare statement */\n\n\nint pgsql_drv_prepare(db_stmt_t *stmt, const char *query, size_t len)\n{\n  PGconn       *con = (PGconn *)stmt->connection->ptr;\n  PGresult     *pgres;\n  pg_stmt_t    *pgstmt;\n  char         *buf = NULL;\n  unsigned int vcnt;\n  unsigned int need_realloc;\n  unsigned int i,j;\n  unsigned int buflen;\n  int          n;\n  char         name[32];\n\n  (void) len; /* unused */\n\n  if (con == NULL)\n    return 1;\n\n  if (!use_ps)\n  {\n    /* Use client-side PS */\n    stmt->emulated = 1;\n    stmt->query = strdup(query);\n\n    return 0;\n  }\n\n  /* Convert query to PgSQL-style named placeholders */\n  need_realloc = 1;\n  vcnt = 1;\n  buflen = 0;\n  for (i = 0, j = 0; query[i] != '\\0'; i++)\n  {\n  again:\n    if (j+1 >= buflen || need_realloc)\n    {\n      buflen = (buflen > 0) ? buflen * 2 : 256;\n      buf = realloc(buf, buflen);\n      if (buf == NULL)\n        goto error;\n      need_realloc = 0;\n    }\n\n    if (query[i] != '?')\n    {\n      buf[j++] = query[i];\n      continue;\n    }\n\n    n = snprintf(buf + j, buflen - j, \"$%d\", vcnt);\n    if (n < 0 || n >= (int)(buflen - j))\n    {\n      need_realloc = 1;\n      goto again;\n    }\n\n    j += n;\n    vcnt++;\n  }\n  buf[j] = '\\0';\n\n  /* Store the query to be prepared later on the first bind_param call */\n  stmt->query = strdup(buf);\n  free(buf);\n  \n  pgstmt = (pg_stmt_t *)calloc(1, sizeof(pg_stmt_t));\n  if (pgstmt == NULL)\n    goto error;\n  /* Generate random statement name */\n  get_unique_stmt_name(name, sizeof(name));\n  pgstmt->name = strdup(name);\n  pgstmt->nparams = vcnt - 1;\n\n  /*\n    Special keys for statements without parameters, since we don't need\n    to know the types of arguments, and no calls to bind_param() will be made\n  */\n  if (pgstmt->nparams == 0)\n  {\n    /* Do prepare */\n    pgres = PQprepare(con, pgstmt->name, stmt->query, pgstmt->nparams,\n                      NULL);\n    \n    if (PQresultStatus(pgres) != PGRES_COMMAND_OK)\n    {\n      log_text(LOG_FATAL, \"PQprepare() failed: %s\", PQerrorMessage(con));\n\n      PQclear(pgres);\n\n      free(stmt->query);\n      free(pgstmt->name);\n      free(pgstmt);\n\n      return 1;\n    }\n    PQclear(pgres);\n    pgstmt->prepared = 1;\n  }\n\n  stmt->ptr = pgstmt;\n  \n  return 0;\n\n error:\n\n  return 1;\n}\n\n\n/* Bind parameters for prepared statement */\n\n\nint pgsql_drv_bind_param(db_stmt_t *stmt, db_bind_t *params, size_t len)\n{\n  PGconn       *con = (PGconn *)stmt->connection->ptr;\n  PGresult     *pgres;\n  pg_stmt_t    *pgstmt;\n  unsigned int i;\n  \n  if (con == NULL)\n    return 1;\n\n  if (stmt->bound_param != NULL)\n    free(stmt->bound_param);\n  stmt->bound_param = (db_bind_t *)malloc(len * sizeof(db_bind_t));\n  if (stmt->bound_param == NULL)\n    return 1;\n  memcpy(stmt->bound_param, params, len * sizeof(db_bind_t));\n  stmt->bound_param_len = len;\n \n  if (stmt->emulated)\n    return 0;\n\n  pgstmt = stmt->ptr;\n  if (pgstmt->prepared)\n    return 0;\n  \n  /* Prepare statement here, since we need to know types of parameters */\n  /* Validate parameters count */\n  if ((unsigned)pgstmt->nparams != len)\n  {\n    log_text(LOG_ALERT, \"wrong number of parameters in prepared statement\");\n    log_text(LOG_DEBUG, \"counted: %d, passed to bind_param(): %zd\",\n             pgstmt->nparams, len);\n    return 1;\n  }\n\n  pgstmt->ptypes = (Oid *)malloc(len * sizeof(int));\n  if (pgstmt->ptypes == NULL)\n    return 1;\n\n  /* Convert sysbench data types to PgSQL ones */\n  for (i = 0; i < len; i++)\n    pgstmt->ptypes[i] = get_pgsql_bind_type(params[i].type);\n\n  /* Do prepare */\n  pgres = PQprepare(con, pgstmt->name, stmt->query, pgstmt->nparams,\n                    pgstmt->ptypes);\n\n  if (PQresultStatus(pgres) != PGRES_COMMAND_OK)\n  {\n    log_text(LOG_FATAL, \"PQprepare() failed: %s\", PQerrorMessage(con));\n    return 1;\n  }\n\n  PQclear(pgres);\n\n  pgstmt->pvalues = (char **)calloc(len, sizeof(char *));\n  if (pgstmt->pvalues == NULL)\n    return 1;\n      \n  /* Allocate buffers for bind parameters */\n  for (i = 0; i < len; i++)\n  {\n    if (pgstmt->pvalues[i] != NULL)\n    {\n      free(pgstmt->pvalues[i]);\n    }\n\n    pgstmt->pvalues[i] = (char *)malloc(MAX_PARAM_LENGTH);\n    if (pgstmt->pvalues[i] == NULL)\n      return 1;\n  }\n  pgstmt->prepared = 1;\n\n  return 0;\n}\n\n\n/* Bind results for prepared statement */\n\n\nint pgsql_drv_bind_result(db_stmt_t *stmt, db_bind_t *params, size_t len)\n{\n  /* unused */\n  (void)stmt;\n  (void)params;\n  (void)len;\n  \n  return 0;\n}\n\n\n/* Check query execution status */\n\n\nstatic db_error_t pgsql_check_status(db_conn_t *con, PGresult *pgres,\n                                     const char *funcname, const char *query,\n                                     db_result_t *rs)\n{\n  ExecStatusType status;\n  db_error_t     rc;\n  PGconn * const pgcon = con->ptr;\n\n  status = PQresultStatus(pgres);\n  switch(status) {\n  case PGRES_TUPLES_OK:\n    rs->nrows = PQntuples(pgres);\n    rs->nfields = PQnfields(pgres);\n    rs->counter = SB_CNT_READ;\n\n    rc = DB_ERROR_NONE;\n\n    break;\n\n  case PGRES_COMMAND_OK:\n    rs->nrows = strtoul(PQcmdTuples(pgres), NULL, 10);;\n    rs->counter = (rs->nrows > 0) ? SB_CNT_WRITE : SB_CNT_OTHER;\n    rc = DB_ERROR_NONE;\n\n    /*\n      Since we are not returning a result set, the SQL layer will never call\n      pgsql_drv_free_results(). So we must call PQclear() here.\n    */\n    PQclear(pgres);\n\n    break;\n\n  case PGRES_FATAL_ERROR:\n    rs->nrows = 0;\n    rs->counter = SB_CNT_ERROR;\n\n    /*\n      Duplicate strings here, because PostgreSQL will deallocate them on\n      PQclear() call below. They will be deallocated either on subsequent calls\n      to pgsql_check_status() or in pgsql_drv_disconnect().\n    */\n    xfree(con->sql_state);\n    xfree(con->sql_errmsg);\n\n    con->sql_state = strdup(PQresultErrorField(pgres, PG_DIAG_SQLSTATE));\n    con->sql_errmsg = strdup(PQresultErrorField(pgres, PG_DIAG_MESSAGE_PRIMARY));\n\n    if (!strcmp(con->sql_state, \"40P01\") /* deadlock_detected */ ||\n        !strcmp(con->sql_state, \"23505\") /* unique violation */ ||\n        !strcmp(con->sql_state, \"40001\"))/* serialization_failure */\n    {\n      PGresult *tmp;\n      tmp = PQexec(pgcon, \"ROLLBACK\");\n      PQclear(tmp);\n      rc = DB_ERROR_IGNORABLE;\n    }\n    else\n    {\n      log_text(LOG_FATAL, \"%s() failed: %d %s\", funcname, status,\n               con->sql_errmsg);\n\n      if (query != NULL)\n        log_text(LOG_FATAL, \"failed query was: %s\", query);\n\n      rc =  DB_ERROR_FATAL;\n    }\n\n    PQclear(pgres);\n\n    break;\n\n  default:\n    rs->nrows = 0;\n    rs->counter = SB_CNT_ERROR;\n    rc = DB_ERROR_FATAL;\n  }\n\n  return rc;\n}\n\n\n/* Execute prepared statement */\n\n\ndb_error_t pgsql_drv_execute(db_stmt_t *stmt, db_result_t *rs)\n{\n  db_conn_t       *con = stmt->connection;\n  PGconn          *pgcon = (PGconn *)con->ptr;\n  PGresult        *pgres;\n  pg_stmt_t       *pgstmt;\n  char            *buf = NULL;\n  unsigned int    buflen = 0;\n  unsigned int    i, j, vcnt;\n  char            need_realloc;\n  int             n;\n  db_error_t      rc;\n  unsigned long   len;\n\n  con->sql_errno = 0;\n  xfree(con->sql_state);\n  xfree(con->sql_errmsg);\n\n  if (!stmt->emulated)\n  {\n    pgstmt = stmt->ptr;\n    if (pgstmt == NULL)\n    {\n      log_text(LOG_DEBUG,\n               \"ERROR: exiting mysql_drv_execute(), uninitialized statement\");\n      return DB_ERROR_FATAL;\n    }\n\n    /* Convert sysbench bind structures to PgSQL data */\n    for (i = 0; i < (unsigned)pgstmt->nparams; i++)\n    {\n      if (stmt->bound_param[i].is_null && *(stmt->bound_param[i].is_null))\n        continue;\n\n      switch (stmt->bound_param[i].type) {\n        case DB_TYPE_CHAR:\n        case DB_TYPE_VARCHAR:\n\n          len = stmt->bound_param[i].data_len[0];\n\n          memcpy(pgstmt->pvalues[i], stmt->bound_param[i].buffer,\n                 SB_MIN(MAX_PARAM_LENGTH, len));\n          /* PostgreSQL requires a zero-terminated string */\n          pgstmt->pvalues[i][len] = '\\0';\n\n          break;\n        default:\n          db_print_value(stmt->bound_param + i, pgstmt->pvalues[i],\n                         MAX_PARAM_LENGTH);\n      }\n    }\n\n    pgres = PQexecPrepared(pgcon, pgstmt->name, pgstmt->nparams,\n                           (const char **)pgstmt->pvalues, NULL, NULL, 1);\n\n    rc = pgsql_check_status(con, pgres, \"PQexecPrepared\", NULL, rs);\n\n    rs->ptr = (rs->counter == SB_CNT_READ) ? (void *) pgres : NULL;\n\n    return rc;\n  }\n\n  /* Use emulation */\n  /* Build the actual query string from parameters list */\n  need_realloc = 1;\n  vcnt = 0;\n  for (i = 0, j = 0; stmt->query[i] != '\\0'; i++)\n  {\n  again:\n    if (j+1 >= buflen || need_realloc)\n    {\n      buflen = (buflen > 0) ? buflen * 2 : 256;\n      buf = realloc(buf, buflen);\n      if (buf == NULL)\n        return DB_ERROR_FATAL;\n      need_realloc = 0;\n    }\n\n    if (stmt->query[i] != '?')\n    {\n      buf[j++] = stmt->query[i];\n      continue;\n    }\n\n    n = db_print_value(stmt->bound_param + vcnt, buf + j, buflen - j);\n    if (n < 0)\n    {\n      need_realloc = 1;\n      goto again;\n    }\n    j += n;\n    vcnt++;\n  }\n  buf[j] = '\\0';\n\n  rc = pgsql_drv_query(con, buf, j, rs);\n\n  free(buf);\n\n  return rc;\n}\n\n\n/* Execute SQL query */\n\n\ndb_error_t pgsql_drv_query(db_conn_t *sb_conn, const char *query, size_t len,\n                           db_result_t *rs)\n{\n  PGconn         *pgcon = sb_conn->ptr;\n  PGresult       *pgres;\n  db_error_t     rc;\n\n  (void)len; /* unused */\n\n  sb_conn->sql_errno = 0;\n  xfree(sb_conn->sql_state);\n  xfree(sb_conn->sql_errmsg);\n\n  pgres = PQexec(pgcon, query);\n  rc = pgsql_check_status(sb_conn, pgres, \"PQexec\", query, rs);\n\n  rs->ptr = (rs->counter == SB_CNT_READ) ? (void *) pgres : NULL;\n\n  return rc;\n}\n\n\n/* Fetch row from result set of a prepared statement */\n\n\nint pgsql_drv_fetch(db_result_t *rs)\n{\n  /* NYI */\n  (void)rs;\n\n  return 1;\n}\n\n\n/* Fetch row from result set of a query */\n\n\nint pgsql_drv_fetch_row(db_result_t *rs, db_row_t *row)\n{\n  intptr_t rownum;\n  int      i;\n\n  /*\n    Use row->ptr as a row number, rather than a pointer to avoid dynamic\n    memory management.\n  */\n  rownum = (intptr_t) row->ptr;\n  if (rownum >= (int) rs->nrows)\n    return DB_ERROR_IGNORABLE;\n\n  for (i = 0; i < (int) rs->nfields; i++)\n  {\n    /*\n      PQgetvalue() returns an empty string, not a NULL value for a NULL\n      field. Callers of this function expect a NULL pointer in this case.\n    */\n    if (PQgetisnull(rs->ptr, rownum, i))\n      row->values[i].ptr = NULL;\n    else\n    {\n      row->values[i].len = PQgetlength(rs->ptr, rownum, i);\n      row->values[i].ptr = PQgetvalue(rs->ptr, rownum, i);\n    }\n  }\n\n  row->ptr = (void *) (rownum + 1);\n\n  return DB_ERROR_NONE;\n}\n\n\n/* Free result set */\n\n\nint pgsql_drv_free_results(db_result_t *rs)\n{\n  if (rs->ptr != NULL)\n  {\n    PQclear((PGresult *)rs->ptr);\n    rs->ptr = NULL;\n\n    rs->row.ptr = 0;\n    return 0;\n  }\n\n  return 1;\n}\n\n\n/* Close prepared statement */\n\n\nint pgsql_drv_close(db_stmt_t *stmt)\n{\n  pg_stmt_t *pgstmt = stmt->ptr;\n  int       i;\n  \n  if (pgstmt == NULL)\n    return 1;\n\n  if (pgstmt->name != NULL)\n    free(pgstmt->name);\n  if (pgstmt->ptypes != NULL)\n    free(pgstmt->ptypes);\n  if (pgstmt->pvalues != NULL)\n  {\n    for (i = 0; i < pgstmt->nparams; i++)\n      if (pgstmt->pvalues[i] != NULL)\n        free(pgstmt->pvalues[i]);\n    free(pgstmt->pvalues);\n  }\n\n  xfree(stmt->ptr);\n\n  return 0;\n}\n\n\n/* Uninitialize driver */\nint pgsql_drv_done(void)\n{\n  return 0;\n}\n\n\n/* Map SQL data type to bind_type value in MYSQL_BIND */\n\n\nint get_pgsql_bind_type(db_bind_type_t type)\n{\n  unsigned int i;\n\n  for (i = 0; db_pgsql_bind_map[i].db_type != DB_TYPE_NONE; i++)\n    if (db_pgsql_bind_map[i].db_type == type)\n      return db_pgsql_bind_map[i].pg_type;\n\n  return -1;\n}\n\n\nint get_unique_stmt_name(char *name, int len)\n{\n  return snprintf(name, len, \"sbstmt%d%d\",\n                  (int) sb_rand_uniform_uint64(),\n                  (int) sb_rand_uniform_uint64());\n}\n"
  },
  {
    "path": "src/lua/Makefile.am",
    "content": "# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nSUBDIRS = internal\n\ndist_pkgdata_SCRIPTS = bulk_insert.lua \\\n             oltp_delete.lua \\\n             oltp_insert.lua \\\n             oltp_read_only.lua \\\n             oltp_read_write.lua \\\n             oltp_point_select.lua \\\n             oltp_update_index.lua \\\n             oltp_update_non_index.lua \\\n             oltp_write_only.lua\\\n             select_random_points.lua \\\n             select_random_ranges.lua\n\ndist_pkgdata_DATA = oltp_common.lua\n"
  },
  {
    "path": "src/lua/bulk_insert.lua",
    "content": "#!/usr/bin/env sysbench\n-- -------------------------------------------------------------------------- --\n-- Bulk insert benchmark: do multi-row INSERTs concurrently in --threads\n-- threads with each thread inserting into its own table. The number of INSERTs\n-- executed by each thread is controlled by either --time or --events.\n-- -------------------------------------------------------------------------- --\n\ncursize=0\n\nfunction thread_init()\n   drv = sysbench.sql.driver()\n   con = drv:connect()\nend\n\nfunction prepare()\n   local i\n\n   local drv = sysbench.sql.driver()\n   local con = drv:connect()\n\n   for i = 1, sysbench.opt.threads do\n      print(\"Creating table 'sbtest\" .. i .. \"'...\")\n      con:query(string.format([[\n        CREATE TABLE IF NOT EXISTS sbtest%d (\n          id INTEGER NOT NULL,\n          k INTEGER DEFAULT '0' NOT NULL,\n          PRIMARY KEY (id))]], i))\n   end\nend\n\nfunction event()\n   if (cursize == 0) then\n      con:bulk_insert_init(\"INSERT INTO sbtest\" .. sysbench.tid+1 .. \" VALUES\")\n   end\n\n   cursize = cursize + 1\n\n   con:bulk_insert_next(\"(\" .. cursize .. \",\" .. cursize .. \")\")\nend\n\nfunction thread_done()\n   con:bulk_insert_done()\n   con:disconnect()\nend\n\nfunction cleanup()\n   local i\n\n   local drv = sysbench.sql.driver()\n   local con = drv:connect()\n\n   for i = 1, sysbench.opt.threads do\n      print(\"Dropping table 'sbtest\" .. i .. \"'...\")\n      con:query(\"DROP TABLE IF EXISTS sbtest\" .. i )\n   end\nend\n"
  },
  {
    "path": "src/lua/empty-test.lua",
    "content": "#!/usr/bin/env sysbench\n\n-- you can run this script like this:\n-- $ ./empty-test.lua --cpu-max-prime=20000 --threads=8 --histogram --report-interval=1 run\n\nsysbench.cmdline.options = {\n    -- the default values for built-in options are currently ignored, see \n    -- https://github.com/akopytov/sysbench/issues/151\n    [\"cpu-max-prime\"] = {\"CPU maximum prime\", 10000},\n    [\"threads\"] = {\"Number of threads\", 1},\n    [\"histogram\"] = {\"Show histogram\", \"off\"},\n    [\"report-interval\"] = {\"Report interval\", 1}\n}\n\nfunction event()\nend\n\nfunction sysbench.hooks.report_cumulative(stat)\n    local seconds = stat.time_interval\n    print(string.format([[\n{\n    \"errors\": %4.0f,\n    \"events\": %4.0f,\n    \"latency_avg\": %4.10f,\n    \"latency_max\": %4.10f,\n    \"latency_min\": %4.10f,\n    \"latency_pct\": %4.10f,\n    \"latency_sum\": %4.10f,\n    \"other\": %4.0f,\n    \"reads\": %4.0f,\n    \"reconnects\": %4.0f,\n    \"threads_running\": %4.0f,\n    \"time_interval\": %4.10f,\n    \"time_total\": %4.10f,\n    \"writes\": %4.0f\n}\n]], \n    stat.errors, \n    stat.events, \n    stat.latency_avg, \n    stat.latency_max, \n    stat.latency_min, \n    stat.latency_pct, \n    stat.latency_sum, \n    stat.other, \n    stat.reads, \n    stat.reconnects, \n    stat.threads_running, \n    stat.time_interval, \n    stat.time_total, \n    stat.writes))\nend\n"
  },
  {
    "path": "src/lua/internal/Makefile.am",
    "content": "# Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nBUILT_SOURCES = sysbench.lua.h sysbench.rand.lua.h sysbench.sql.lua.h \\\n                sysbench.cmdline.lua.h \\\n                sysbench.histogram.lua.h\n\nCLEANFILES = $(BUILT_SOURCES)\n\nEXTRA_DIST = $(BUILT_SOURCES:.h=)\n\nSUFFIXES = .lua .lua.h\n\n.lua.lua.h:\n\t@echo \"Creating $@ from $<\"\n\t@var=$$(echo $< | sed 's/\\./_/g')\t&& \\\n\t( echo \"unsigned char $${var}[] =\" \t&& \\\n\tsed -e 's/\\\\/\\\\\\\\/g'\t\t\t\\\n\t    -e 's/\"/\\\\\"/g'\t\t\t\\\n\t    -e 's/^/  \"/g'\t\t\t\\\n\t    -e 's/$$/\\\\n\"/g' $< \t\t&& \\\n\techo \";\"\t\t\t\t&& \\\n\techo \"size_t $${var}_len = sizeof($${var}) - 1;\" ) > $@\n"
  },
  {
    "path": "src/lua/internal/sysbench.cmdline.lua",
    "content": "-- Copyright (C) 2017-2018 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Command line option handling\n-- ----------------------------------------------------------------------\n\nffi = require(\"ffi\")\n\nffi.cdef[[\n/* The following has been copied from sb_option.h */\n\ntypedef enum\n{\n  SB_ARG_TYPE_NULL,\n  SB_ARG_TYPE_BOOL,\n  SB_ARG_TYPE_INT,\n  SB_ARG_TYPE_SIZE,\n  SB_ARG_TYPE_DOUBLE,\n  SB_ARG_TYPE_STRING,\n  SB_ARG_TYPE_LIST,\n  SB_ARG_TYPE_FILE,\n  SB_ARG_TYPE_MAX\n} sb_arg_type_t;\n\n/* Option validation function */\ntypedef bool sb_opt_validate_t(const char *, const char *);\n\n/* Test option definition */\ntypedef struct\n{\n  const char         *name;\n  const char         *desc;\n  const char         *value;\n  sb_arg_type_t      type;\n  sb_opt_validate_t  *validate;\n} sb_arg_t;\n\nint sb_lua_set_test_args(sb_arg_t *args, size_t len);\n]]\n\nsysbench.cmdline.ARG_NULL = ffi.C.SB_ARG_TYPE_NULL\nsysbench.cmdline.ARG_BOOL = ffi.C.SB_ARG_TYPE_BOOL\nsysbench.cmdline.ARG_INT = ffi.C.SB_ARG_TYPE_INT\nsysbench.cmdline.ARG_SIZE = ffi.C.SB_ARG_TYPE_SIZE\nsysbench.cmdline.ARG_DOUBLE = ffi.C.SB_ARG_TYPE_DOUBLE\nsysbench.cmdline.ARG_STRING = ffi.C.SB_ARG_TYPE_STRING\nsysbench.cmdline.ARG_LIST = ffi.C.SB_ARG_TYPE_LIST\nsysbench.cmdline.ARG_FILE = ffi.C.SB_ARG_TYPE_FILE\nsysbench.cmdline.ARG_MAX = ffi.C.SB_ARG_TYPE_MAX\n\n-- Attribute indicating that a custom command can be executed in parallel\nsysbench.cmdline.PARALLEL_COMMAND = true\n\nlocal arg_types = {\n   boolean = sysbench.cmdline.ARG_BOOL,\n   string = sysbench.cmdline.ARG_STRING,\n   number = sysbench.cmdline.ARG_DOUBLE,\n   table = sysbench.cmdline.ARG_LIST\n}\n\nlocal function __genOrderedIndex( t )\n   local orderedIndex = {}\n   for key in pairs(t) do\n      table.insert( orderedIndex, key )\n   end\n   table.sort( orderedIndex )\n   return orderedIndex\nend\n\nlocal function orderedNext(t, state)\n   local key = nil\n   if state == nil then\n      t.__orderedIndex = __genOrderedIndex( t )\n      key = t.__orderedIndex[1]\n   else\n      for i = 1,table.getn(t.__orderedIndex) do\n         if t.__orderedIndex[i] == state then\n            key = t.__orderedIndex[i+1]\n         end\n      end\n   end\n\n   if key then\n      return key, t[key]\n   end\n\n   t.__orderedIndex = nil\n   return\nend\n\nlocal function orderedPairs(t)\n   return orderedNext, t, nil\nend\n\n-- Parse command line options definitions, if present in the script as a\n-- 'sysbench.cmdline.options' table. If no such table exists, or if there a\n-- parsing error, return false. Return true on success. After parsing the\n-- command line arguments, option values are available as the sysbench.opt\n-- table.\nfunction sysbench.cmdline.read_cmdline_options()\n   if sysbench.cmdline.options == nil then\n      return true\n   end\n\n   local t = type(sysbench.cmdline.options)\n   assert(t == \"table\", \"wrong type for sysbench.cmdline.options: \" .. t)\n\n   local i = 0\n   for name, def in pairs(sysbench.cmdline.options) do\n      i = i+1\n   end\n\n   local args = ffi.new('sb_arg_t[?]', i)\n   i = 0\n\n   for name, def in orderedPairs(sysbench.cmdline.options) do\n      -- name\n      assert(type(name) == \"string\" and type(def) == \"table\",\n             \"wrong table structure in sysbench.cmdline.options\")\n      args[i].name = name\n\n      -- description\n      assert(def[1] ~= nil, \"nil description for option \" .. name)\n      args[i].desc = def[1]\n\n      if type(def[2]) == \"table\" then\n         assert(type(def[3]) == \"nil\" or\n                   type(def[3]) == sysbench.cmdline.ARG_LIST,\n                \"wrong type for list option \" .. name)\n         args[i].value = table.concat(def[2], ',')\n      else\n         if type(def[2]) == \"boolean\" then\n            args[i].value = def[2] and 'on' or 'off'\n         elseif type(def[2]) == \"number\" then\n            args[i].value = tostring(def[2])\n         else\n            args[i].value = def[2]\n         end\n      end\n\n      -- type\n      local t = def[3]\n      if t == nil then\n         if def[2] ~= nil then\n            -- Try to determine the type by the default value\n            t = arg_types[type(def[2])]\n         else\n            t = sysbench.cmdline.ARG_STRING\n         end\n      end\n\n      assert(t ~= nil, \"cannot determine type for option \" .. name)\n      args[i].type = t\n\n      -- validation function\n      args[i].validate = def[4]\n\n      i = i + 1\n   end\n\n   return ffi.C.sb_lua_set_test_args(args, i) == 0\nend\n\nfunction sysbench.cmdline.command_defined(name)\n   return type(sysbench.cmdline.commands) == \"table\" and\n      sysbench.cmdline.commands[name] ~= nil and\n      sysbench.cmdline.commands[name][1] ~= nil\nend\n\nfunction sysbench.cmdline.command_parallel(name)\n   return sysbench.cmdline.command_defined(name) and\n      sysbench.cmdline.commands[name][2] == sysbench.cmdline.PARALLEL_COMMAND\nend\n\nfunction sysbench.cmdline.call_command(name)\n   if not sysbench.cmdline.command_defined(name) then\n      return false\n   end\n\n   local rc = sysbench.cmdline.commands[name][1]()\n\n   if rc == nil then\n      -- handle the case when the command does not return and value as success\n      return true\n   else\n      -- otherwise return success for any returned value other than false\n      return rc and true or false\n   end\nend\n\nffi.cdef[[\nvoid sb_print_test_options(void);\n]]\n\n-- ----------------------------------------------------------------------\n-- Print descriptions of command line options, if defined by\n-- sysbench.cmdline.options\n-- ----------------------------------------------------------------------\nfunction sysbench.cmdline.print_test_options()\n   ffi.C.sb_print_test_options()\nend\n"
  },
  {
    "path": "src/lua/internal/sysbench.histogram.lua",
    "content": "-- Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Bounded histograms API\n-- ----------------------------------------------------------------------\n\nffi = require(\"ffi\")\n\nsysbench.histogram = {}\n\nffi.cdef[[\ntypedef struct histogram sb_histogram_t;\n\n/*\n  Allocate a new histogram and initialize it with sb_histogram_init().\n*/\nsb_histogram_t *sb_histogram_new(size_t size, double range_min,\n                                 double range_max);\n\n/*\n  Deallocate a histogram allocated with sb_histogram_new().\n*/\nvoid sb_histogram_delete(sb_histogram_t *h);\n\n/* Update histogram with a given value. */\nvoid sb_histogram_update(sb_histogram_t *h, double value);\n\n/*\n  Print a given histogram to stdout\n*/\nvoid sb_histogram_print(sb_histogram_t *h);\n]]\n\nlocal histogram = {}\n\nfunction histogram:update(value)\n   ffi.C.sb_histogram_update(self, value)\nend\n\nfunction histogram:print()\n   ffi.C.sb_histogram_print(self)\nend\n\nlocal histogram_mt = {\n   __index = histogram,\n   __tostring = '<sb_histogram>'\n}\nffi.metatype('sb_histogram_t', histogram_mt)\n\nfunction sysbench.histogram.new(size, range_min, range_max)\n   local h = ffi.C.sb_histogram_new(size, range_min, range_max)\n\n   return ffi.gc(h, ffi.C.sb_histogram_delete)\nend\n"
  },
  {
    "path": "src/lua/internal/sysbench.lua",
    "content": "-- Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nffi = require(\"ffi\")\n\nffi.cdef[[\nvoid sb_event_start(int thread_id);\nvoid sb_event_stop(int thread_id);\nbool sb_more_events(int thread_id);\n]]\n\n-- ----------------------------------------------------------------------\n-- Main event loop. This is a Lua version of sysbench.c:thread_run()\n-- ----------------------------------------------------------------------\nfunction thread_run(thread_id)\n   while ffi.C.sb_more_events(thread_id) do\n      ffi.C.sb_event_start(thread_id)\n\n      local success, ret\n      repeat\n         success, ret = pcall(event, thread_id)\n\n         if not success then\n            if type(ret) == \"table\" and\n               ret.errcode == sysbench.error.RESTART_EVENT\n            then\n               if sysbench.hooks.before_restart_event then\n                  sysbench.hooks.before_restart_event(ret)\n               end\n            else\n               error(ret, 2) -- propagate unknown errors\n            end\n         end\n      until success\n\n      -- Stop the benchmark if event() returns a value other than nil or false\n      if ret then\n         break\n      end\n\n      ffi.C.sb_event_stop(thread_id)\n   end\nend\n\n-- ----------------------------------------------------------------------\n-- Hooks\n-- ----------------------------------------------------------------------\n\nsysbench.hooks = {\n   -- sql_error_ignorable = <func>,\n   -- report_intermediate = <func>,\n   -- report_cumulative = <func>\n}\n\n-- Report statistics in the CSV format. Add the following to your\n-- script to replace the default human-readable reports\n--\n-- sysbench.hooks.report_intermediate = sysbench.report_csv\nfunction sysbench.report_csv(stat)\n   local seconds = stat.time_interval\n   print(string.format(\"%.0f,%u,%4.2f,\" ..\n                          \"%4.2f,%4.2f,%4.2f,%4.2f,\" ..\n                          \"%4.2f,%4.2f,\" ..\n                          \"%4.2f\",\n                       stat.time_total,\n                       stat.threads_running,\n                       stat.events / seconds,\n                       (stat.reads + stat.writes + stat.other) / seconds,\n                       stat.reads / seconds,\n                       stat.writes / seconds,\n                       stat.other / seconds,\n                       stat.latency_pct * 1000,\n                       stat.errors / seconds,\n                       stat.reconnects / seconds\n   ))\nend\n\n-- Report statistics in the JSON format. Add the following to your\n-- script to replace the default human-readable reports\n--\n-- sysbench.hooks.report_intermediate = sysbench.report_json\nfunction sysbench.report_json(stat)\n   if not gobj then\n      io.write('[\\n')\n      -- hack to print the closing bracket when the Lua state of the reporting\n      -- thread is closed\n      gobj = newproxy(true)\n      getmetatable(gobj).__gc = function () io.write('\\n]\\n') end\n   else\n      io.write(',\\n')\n   end\n\n   local seconds = stat.time_interval\n   io.write(([[\n  {\n    \"time\": %4.0f,\n    \"threads\": %u,\n    \"tps\": %4.2f,\n    \"qps\": {\n      \"total\": %4.2f,\n      \"reads\": %4.2f,\n      \"writes\": %4.2f,\n      \"other\": %4.2f\n    },\n    \"latency\": %4.2f,\n    \"errors\": %4.2f,\n    \"reconnects\": %4.2f\n  }]]):format(\n            stat.time_total,\n            stat.threads_running,\n            stat.events / seconds,\n            (stat.reads + stat.writes + stat.other) / seconds,\n            stat.reads / seconds,\n            stat.writes / seconds,\n            stat.other / seconds,\n            stat.latency_pct * 1000,\n            stat.errors / seconds,\n            stat.reconnects / seconds\n   ))\nend\n\n-- Report statistics in the default human-readable format. You can use it if you\n-- want to augment default reports with your own statistics. Call it from your\n-- own report hook, e.g.:\n--\n-- function sysbench.hooks.report_intermediate(stat)\n--   print(\"my stat: \", val)\n--   sysbench.report_default(stat)\n-- end\nfunction sysbench.report_default(stat)\n   local seconds = stat.time_interval\n   print(string.format(\"[ %.0fs ] thds: %u tps: %4.2f qps: %4.2f \" ..\n                          \"(r/w/o: %4.2f/%4.2f/%4.2f) lat (ms,%u%%): %4.2f \" ..\n                          \"err/s %4.2f reconn/s: %4.2f\",\n                       stat.time_total,\n                       stat.threads_running,\n                       stat.events / seconds,\n                       (stat.reads + stat.writes + stat.other) / seconds,\n                       stat.reads / seconds,\n                       stat.writes / seconds,\n                       stat.other / seconds,\n                       sysbench.opt.percentile,\n                       stat.latency_pct * 1000,\n                       stat.errors / seconds,\n                       stat.reconnects / seconds\n   ))\nend\n"
  },
  {
    "path": "src/lua/internal/sysbench.rand.lua",
    "content": "-- Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nffi = require(\"ffi\")\n\n-- ----------------------------------------------------------------------\n-- Pseudo-random number generation API\n-- ----------------------------------------------------------------------\n\nsysbench.rand = {}\n\nffi.cdef[[\nuint64_t sb_rand_uniform_uint64(void);\nuint32_t sb_rand_default(uint32_t, uint32_t);\nuint32_t sb_rand_uniform(uint32_t, uint32_t);\nuint32_t sb_rand_gaussian(uint32_t, uint32_t);\nuint32_t sb_rand_pareto(uint32_t, uint32_t);\nuint32_t sb_rand_zipfian(uint32_t, uint32_t);\nuint32_t sb_rand_unique(void);\nvoid sb_rand_str(const char *, char *);\nuint32_t sb_rand_varstr(char *, uint32_t, uint32_t);\ndouble sb_rand_uniform_double(void);\n]]\n\nfunction sysbench.rand.uniform_uint64()\n   return ffi.C.sb_rand_uniform_uint64()\nend\n\nfunction sysbench.rand.default(a, b)\n   return ffi.C.sb_rand_default(a, b)\nend\n\nfunction sysbench.rand.uniform(a, b)\n   return ffi.C.sb_rand_uniform(a, b)\nend\n\nfunction sysbench.rand.gaussian(a, b)\n   return ffi.C.sb_rand_gaussian(a, b)\nend\n\nfunction sysbench.rand.pareto(a, b)\n   return ffi.C.sb_rand_pareto(a, b)\nend\n\nfunction sysbench.rand.zipfian(a, b)\n   return ffi.C.sb_rand_zipfian(a, b)\nend\n\nfunction sysbench.rand.unique()\n   return ffi.C.sb_rand_unique()\nend\n\nfunction sysbench.rand.string(fmt)\n   local buflen = #fmt\n   local buf = ffi.new(\"uint8_t[?]\", buflen)\n   ffi.C.sb_rand_str(fmt, buf)\n   return ffi.string(buf, buflen)\nend\n\nfunction sysbench.rand.varstring(min_len, max_len)\n   assert(min_len <= max_len)\n   assert(max_len > 0)\n   local buflen = max_len\n   local buf = ffi.new(\"uint8_t[?]\", buflen)\n   local nchars = ffi.C.sb_rand_varstr(buf, min_len, max_len)\n   return ffi.string(buf, nchars)\nend\n\nfunction sysbench.rand.uniform_double()\n   return ffi.C.sb_rand_uniform_double()\nend\n"
  },
  {
    "path": "src/lua/internal/sysbench.sql.lua",
    "content": "-- Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- SQL API\n-- ----------------------------------------------------------------------\n\nffi = require(\"ffi\")\n\nsysbench.sql = {}\n\nffi.cdef[[\n/*\n  The following definitions have been copied with modifications from db_driver.h\n*/\n\ntypedef enum\n{\n  DB_ERROR_NONE,                /* no error(s) */\n  DB_ERROR_IGNORABLE,           /* error should be ignored as defined by command\n                                line arguments or a custom error handler */\n  DB_ERROR_FATAL                /* non-ignorable error */\n} sql_error_t;\n\ntypedef struct\n{\n  const char      *sname;    /* short name */\n  const char      *lname;    /* long name */\n\n  const char      opaque[?];\n} sql_driver;\n\ntypedef struct {\n  uint32_t        len;         /* Value length */\n  const char      *ptr;        /* Value string */\n} sql_value;\n\n/* Result set row definition */\n\ntypedef struct\n{\n  void            *ptr;        /* Driver-specific row data */\n  sql_value       *values;     /* Array of column values */\n} sql_row;\n\n/* Statistic counter types */\n\ntypedef enum\n{\n  SB_CNT_OTHER,\n  SB_CNT_READ,\n  SB_CNT_WRITE,\n  SB_CNT_TRX,\n  SB_CNT_ERROR,\n  SB_CNT_RECONNECT,\n  SB_CNT_BYTES_READ,\n  SB_CNT_BYTES_WRITTEN,\n  SB_CNT_MAX\n} sb_counter_type;\n\ntypedef struct\n{\n  sql_error_t     error;             /* Driver-independent error code */\n  int             sql_errno;         /* Driver-specific error code */\n  const char      *sql_state;        /* Database-specific SQL state */\n  const char      *sql_errmsg;       /* Database-specific error message */\n  sql_driver      *driver;           /* DB driver for this connection */\n\n  const char      opaque[?];\n} sql_connection;\n\ntypedef struct\n{\n  sql_connection  *connection;\n\n  const char      opaque[?];\n} sql_statement;\n\n/* Result set definition */\n\ntypedef struct\n{\n  sb_counter_type   counter;     /* Statistical counter type */\n  uint32_t       nrows;         /* Number of affected rows */\n  uint32_t       nfields;       /* Number of fields */\n  sql_statement  *statement;    /* Pointer to prepared statement (if used) */\n  void           *ptr;          /* Pointer to driver-specific data */\n  sql_row        row;           /* Last fetched row */\n} sql_result;\n\ntypedef enum\n{\n  SQL_TYPE_NONE,\n  SQL_TYPE_TINYINT,\n  SQL_TYPE_SMALLINT,\n  SQL_TYPE_INT,\n  SQL_TYPE_BIGINT,\n  SQL_TYPE_FLOAT,\n  SQL_TYPE_DOUBLE,\n  SQL_TYPE_TIME,\n  SQL_TYPE_DATE,\n  SQL_TYPE_DATETIME,\n  SQL_TYPE_TIMESTAMP,\n  SQL_TYPE_CHAR,\n  SQL_TYPE_VARCHAR\n} sql_bind_type_t;\n\ntypedef struct\n{\n  sql_bind_type_t   type;\n  void             *buffer;\n  unsigned long    *data_len;\n  unsigned long    max_len;\n  char             *is_null;\n} sql_bind;\n\nsql_driver *db_create(const char *);\nint db_destroy(sql_driver *drv);\n\nsql_connection *db_connection_create(sql_driver * drv);\nint db_connection_close(sql_connection *con);\nint db_connection_reconnect(sql_connection *con);\nvoid db_connection_free(sql_connection *con);\n\nint db_bulk_insert_init(sql_connection *, const char *, size_t);\nint db_bulk_insert_next(sql_connection *, const char *, size_t);\nint db_bulk_insert_done(sql_connection *);\n\nsql_result *db_query(sql_connection *con, const char *query, size_t len);\n\nsql_row *db_fetch_row(sql_result *rs);\n\nsql_statement *db_prepare(sql_connection *con, const char *query, size_t len);\nint db_bind_param(sql_statement *stmt, sql_bind *params, size_t len);\nint db_bind_result(sql_statement *stmt, sql_bind *results, size_t len);\nsql_result *db_execute(sql_statement *stmt);\nsql_result *db_stmt_next_result(sql_statement *stmt);\nint db_close(sql_statement *stmt);\n\nbool db_more_results(sql_connection *con);\nsql_result *db_next_result(sql_connection *con);\nint db_free_results(sql_result *);\n]]\n\nlocal sql_driver = ffi.typeof('sql_driver *')\nlocal sql_connection = ffi.typeof('sql_connection *')\nlocal sql_statement = ffi.typeof('sql_statement *')\nlocal sql_bind = ffi.typeof('sql_bind');\nlocal sql_result = ffi.typeof('sql_result');\nlocal sql_value = ffi.typeof('sql_value');\nlocal sql_row = ffi.typeof('sql_row');\n\nsysbench.sql.type =\n{\n      NONE = ffi.C.SQL_TYPE_NONE,\n      TINYINT = ffi.C.SQL_TYPE_TINYINT,\n      SMALLINT = ffi.C.SQL_TYPE_SMALLINT,\n      INT = ffi.C.SQL_TYPE_INT,\n      BIGINT = ffi.C.SQL_TYPE_BIGINT,\n      FLOAT = ffi.C.SQL_TYPE_FLOAT,\n      DOUBLE = ffi.C.SQL_TYPE_DOUBLE,\n      TIME = ffi.C.SQL_TYPE_TIME,\n      DATE = ffi.C.SQL_TYPE_DATE,\n      DATETIME = ffi.C.SQL_TYPE_DATETIME,\n      TIMESTAMP = ffi.C.SQL_TYPE_TIMESTAMP,\n      CHAR = ffi.C.SQL_TYPE_CHAR,\n      VARCHAR = ffi.C.SQL_TYPE_VARCHAR\n   }\n\n-- Initialize a given SQL driver and return a handle to it to create\n-- connections. A nil driver name (i.e. no function argument) initializes the\n-- default driver, i.e. the one specified with --db-driver on the command line.\nfunction sysbench.sql.driver(driver_name)\n   local drv = ffi.C.db_create(driver_name)\n   if (drv == nil) then\n      error(\"failed to initialize the DB driver\", 2)\n   end\n   return ffi.gc(drv, ffi.C.db_destroy)\nend\n\n-- sql_driver methods\nlocal driver_methods = {}\n\nfunction driver_methods.connect(self)\n   local con = ffi.C.db_connection_create(self)\n   if con == nil then\n      error(\"connection creation failed\", 2)\n   end\n   return ffi.gc(con, ffi.C.db_connection_free)\nend\n\nfunction driver_methods.name(self)\n   return ffi.string(self.sname)\nend\n\n-- sql_driver metatable\nlocal driver_mt = {\n   __index = driver_methods,\n   __gc = ffi.C.db_destroy,\n   __tostring = function() return '<sql_driver>' end,\n}\nffi.metatype(\"sql_driver\", driver_mt)\n\n-- sql_connection methods\nlocal connection_methods = {}\n\nfunction connection_methods.disconnect(self)\n   return assert(ffi.C.db_connection_close(self) == 0)\nend\n\nfunction connection_methods.reconnect(self)\n   return assert(ffi.C.db_connection_reconnect(self) == 0)\nend\n\nfunction connection_methods.check_error(self, rs, query)\n   if rs ~= nil or self.error == sysbench.sql.error.NONE then\n      return rs\n   end\n\n   if self.sql_state == nil or self.sql_errmsg == nil then\n      -- It must be an API error, don't bother trying to downgrade it an\n      -- ignorable error\n      error(\"SQL API error\", 3)\n   end\n\n   local sql_state = ffi.string(self.sql_state)\n   local sql_errmsg = ffi.string(self.sql_errmsg)\n\n   -- Create an error descriptor containing connection, failed query, SQL error\n   -- number, state and error message provided by the SQL driver\n   errdesc = {\n      connection = self,\n      query = query,\n      sql_errno = self.sql_errno,\n      sql_state = sql_state,\n      sql_errmsg = sql_errmsg\n   }\n\n   -- Check if the error has already been marked as ignorable by the driver, or\n   -- there is an error hook that allows downgrading it to IGNORABLE\n   if (self.error == sysbench.sql.error.FATAL and\n          type(sysbench.hooks.sql_error_ignorable) == \"function\" and\n          sysbench.hooks.sql_error_ignorable(errdesc)) or\n      self.error == sysbench.sql.error.IGNORABLE\n   then\n      -- Throw a 'restart event' exception that can be caught by the user script\n      -- to do some extra steps to restart a transaction (e.g. reprepare\n      -- statements after a reconnect). Otherwise it will be caught by\n      -- thread_run() in sysbench.lua, in which case the entire current event\n      -- will be restarted without extra processing.\n      errdesc.errcode = sysbench.error.RESTART_EVENT\n      error(errdesc, 3)\n   end\n\n   -- Just throw a regular error message on a fatal error\n   error(string.format(\"SQL error, errno = %d, state = '%s': %s\",\n                       self.sql_errno, sql_state, sql_errmsg), 2)\nend\n\nfunction connection_methods.query(self, query)\n   local rs = ffi.C.db_query(self, query, #query)\n   return self:check_error(rs, query)\nend\n\nfunction connection_methods.more_results(self)\n   return ffi.C.db_more_results(self)\nend\n\nfunction connection_methods.next_result(self)\n   local rs = ffi.C.db_next_result(self)\n   return self:check_error(rs, \"\");\nend\n\nfunction connection_methods.bulk_insert_init(self, query)\n   return assert(ffi.C.db_bulk_insert_init(self, query, #query) == 0,\n                 \"db_bulk_insert_init() failed\")\nend\n\nfunction connection_methods.bulk_insert_next(self, val)\n   return assert(ffi.C.db_bulk_insert_next(self, val, #val) == 0,\n                 \"db_bulk_insert_next() failed\")\nend\n\nfunction connection_methods.bulk_insert_done(self)\n   return assert(ffi.C.db_bulk_insert_done(self) == 0,\n                 \"db_bulk_insert_done() failed\")\nend\n\nfunction connection_methods.prepare(self, query)\n   local stmt = ffi.C.db_prepare(self, query, #query)\n   if stmt == nil then\n      self:check_error(nil, query)\n   end\n   return stmt\nend\n\n-- A convenience wrapper around sql_connection:query() and\n-- sql_result:fetch_row(). Executes the specified query and returns the first\n-- row from the result set, if available, or nil otherwise\nfunction connection_methods.query_row(self, query)\n   local rs = self:query(query)\n\n   if rs == nil or rs.nrows == 0 then\n      return nil\n   end\n\n   return unpack(rs:fetch_row(), 1, rs.nfields)\nend\n\n-- sql_connection metatable\nlocal connection_mt = {\n   __index = connection_methods,\n   __tostring = function() return '<sql_connection>' end,\n   __gc = ffi.C.db_connection_free,\n}\nffi.metatype(\"sql_connection\", connection_mt)\n\n-- sql_param\nlocal sql_param = {}\nfunction sql_param.set(self, value)\n   local sql_type = sysbench.sql.type\n   local btype = self.type\n\n   if (value == nil) then\n      self.is_null[0] = true\n      return\n   end\n\n   self.is_null[0] = false\n\n   if btype == sql_type.TINYINT or\n      btype == sql_type.SMALLINT or\n      btype == sql_type.INT or\n      btype == sql_type.BIGINT or\n      btype == sql_type.FLOAT or\n      btype == sql_type.DOUBLE\n   then\n      self.buffer[0] = value\n   elseif btype == sql_type.CHAR or\n      btype == sql_type.VARCHAR\n   then\n      local len = #value\n      len = self.max_len < len and self.max_len or len\n      ffi.copy(self.buffer, value, len)\n      self.data_len[0] = len\n   else\n      error(\"Unsupported argument type: \" .. btype, 2)\n   end\nend\n\nfunction sql_param.set_rand_str(self, fmt)\n   local sql_type = sysbench.sql.type\n   local btype = self.type\n\n   self.is_null[0] = false\n\n   if btype == sql_type.CHAR or\n      btype == sql_type.VARCHAR\n   then\n      local len = #fmt\n      len = self.max_len < len and self.max_len or len\n      ffi.C.sb_rand_str(fmt, self.buffer)\n      self.data_len[0] = len\n   else\n      error(\"Unsupported argument type: \" .. btype, 2)\n   end\nend\n\nsql_param.__index = sql_param\nsql_param.__tostring = function () return '<sql_param>' end\n\n-- sql_statement methods\nlocal statement_methods = {}\n\nfunction statement_methods.bind_create(self, btype, max_len)\n   local sql_type = sysbench.sql.type\n\n   local param = setmetatable({}, sql_param)\n\n   if btype == sql_type.TINYINT or\n      btype == sql_type.SMALLINT or\n      btype == sql_type.INT or\n      btype == sql_type.BIGINT\n   then\n      param.type = sql_type.BIGINT\n      param.buffer = ffi.new('int64_t[1]')\n      param.max_len = 8\n   elseif btype == sql_type.FLOAT or\n      btype == sql_type.DOUBLE\n   then\n      param.type = sql_type.DOUBLE\n      param.buffer = ffi.new('double[1]')\n      param.max_len = 8\n   elseif btype == sql_type.CHAR or\n      btype == sql_type.VARCHAR\n   then\n      param.type = sql_type.VARCHAR\n      param.buffer = ffi.new('char[?]', max_len)\n      param.max_len = max_len\n   else\n      error(\"Unsupported argument type: \" .. btype, 2)\n   end\n\n   param.data_len = ffi.new('unsigned long[1]')\n   param.is_null = ffi.new('char[1]')\n\n   return param\nend\n\nfunction statement_methods.bind_param(self, ...)\n   local len = select('#', ...)\n   if len  < 1 then return nil end\n\n   local binds = ffi.new(\"sql_bind[?]\", len)\n\n   for i, param in ipairs({...}) do\n      binds[i-1].type = param.type\n      binds[i-1].buffer = param.buffer\n      binds[i-1].data_len = param.data_len\n      binds[i-1].max_len = param.max_len\n      binds[i-1].is_null = param.is_null\n   end\n   return ffi.C.db_bind_param(self, binds, len)\nend\n\nfunction statement_methods.execute(self)\n   local rs = ffi.C.db_execute(self)\n   return self.connection:check_error(rs, '<prepared statement>')\nend\n\nfunction statement_methods.next_result(self)\n   local rs = ffi.C.db_stmt_next_result(self)\n   return self.connection:check_error(rs, '<prepared statement>')\nend\n\nfunction statement_methods.close(self)\n   return ffi.C.db_close(self)\nend\n\n-- sql_statement metatable\nlocal statement_mt = {\n   __index = statement_methods,\n   __tostring = function() return '<sql_statement>' end,\n   __gc = ffi.C.db_close,\n}\nffi.metatype(\"sql_statement\", statement_mt)\n\nlocal bind_mt = {\n   __tostring = function() return '<sql_bind>' end,\n}\nffi.metatype(\"sql_bind\", bind_mt)\n\n-- sql_result methods\nlocal result_methods = {}\n\n-- Returns the next row of values from a result set, or nil if there are no more\n-- rows to fetch. Values are returned as an array, i.e. a table with numeric\n-- indexes starting from 1. The total number of values (i.e. fields in a result\n-- set) can be obtained from sql_result.nfields.\nfunction result_methods.fetch_row(self)\n   local res = {}\n   local row = ffi.C.db_fetch_row(self)\n\n   if row == nil then\n      return nil\n   end\n\n   for i = 0, self.nfields-1 do\n      if row.values[i].ptr ~= nil then -- not a NULL value\n         res[i+1] = ffi.string(row.values[i].ptr, tonumber(row.values[i].len))\n      end\n   end\n\n   return res\nend\n\nfunction result_methods.free(self)\n   return assert(ffi.C.db_free_results(self) == 0, \"db_free_results() failed\")\nend\n\n-- sql_results metatable\nlocal result_mt = {\n   __index = result_methods,\n   __tostring = function() return '<sql_result>' end,\n   __gc = ffi.C.db_free_results\n}\nffi.metatype(\"sql_result\", result_mt)\n\n-- error codes\nsysbench.sql.error = {}\nsysbench.sql.error.NONE = ffi.C.DB_ERROR_NONE\nsysbench.sql.error.IGNORABLE = ffi.C.DB_ERROR_IGNORABLE\nsysbench.sql.error.FATAL = ffi.C.DB_ERROR_FATAL\n"
  },
  {
    "path": "src/lua/oltp_common.lua",
    "content": "-- Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- -----------------------------------------------------------------------------\n-- Common code for OLTP benchmarks.\n-- -----------------------------------------------------------------------------\n\nfunction init()\n   assert(event ~= nil,\n          \"this script is meant to be included by other OLTP scripts and \" ..\n             \"should not be called directly.\")\nend\n\nif sysbench.cmdline.command == nil then\n   error(\"Command is required. Supported commands: prepare, warmup, run, \" ..\n            \"cleanup, help\")\nend\n\n-- Command line options\nsysbench.cmdline.options = {\n   table_size =\n      {\"Number of rows per table\", 10000},\n   range_size =\n      {\"Range size for range SELECT queries\", 100},\n   tables =\n      {\"Number of tables\", 1},\n   point_selects =\n      {\"Number of point SELECT queries per transaction\", 10},\n   simple_ranges =\n      {\"Number of simple range SELECT queries per transaction\", 1},\n   sum_ranges =\n      {\"Number of SELECT SUM() queries per transaction\", 1},\n   order_ranges =\n      {\"Number of SELECT ORDER BY queries per transaction\", 1},\n   distinct_ranges =\n      {\"Number of SELECT DISTINCT queries per transaction\", 1},\n   index_updates =\n      {\"Number of UPDATE index queries per transaction\", 1},\n   non_index_updates =\n      {\"Number of UPDATE non-index queries per transaction\", 1},\n   delete_inserts =\n      {\"Number of DELETE/INSERT combinations per transaction\", 1},\n   range_selects =\n      {\"Enable/disable all range SELECT queries\", true},\n   auto_inc =\n   {\"Use AUTO_INCREMENT column as Primary Key (for MySQL), \" ..\n       \"or its alternatives in other DBMS. When disabled, use \" ..\n       \"client-generated IDs\", true},\n   create_table_options =\n      {\"Extra CREATE TABLE options\", \"\"},\n   skip_trx =\n      {\"Don't start explicit transactions and execute all queries \" ..\n          \"in the AUTOCOMMIT mode\", false},\n   secondary =\n      {\"Use a secondary index in place of the PRIMARY KEY\", false},\n   create_secondary =\n      {\"Create a secondary index in addition to the PRIMARY KEY\", true},\n   reconnect =\n      {\"Reconnect after every N events. The default (0) is to not reconnect\",\n       0},\n   mysql_storage_engine =\n      {\"Storage engine, if MySQL is used\", \"innodb\"},\n   pgsql_variant =\n      {\"Use this PostgreSQL variant when running with the \" ..\n          \"PostgreSQL driver. The only currently supported \" ..\n          \"variant is 'redshift'. When enabled, \" ..\n          \"create_secondary is automatically disabled, and \" ..\n          \"delete_inserts is set to 0\"}\n}\n\n-- Prepare the dataset. This command supports parallel execution, i.e. will\n-- benefit from executing with --threads > 1 as long as --tables > 1\nfunction cmd_prepare()\n   local drv = sysbench.sql.driver()\n   local con = drv:connect()\n\n   for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables,\n   sysbench.opt.threads do\n     create_table(drv, con, i)\n   end\nend\n\n-- Preload the dataset into the server cache. This command supports parallel\n-- execution, i.e. will benefit from executing with --threads > 1 as long as\n-- --tables > 1\n--\n-- PS. Currently, this command is only meaningful for MySQL/InnoDB benchmarks\nfunction cmd_warmup()\n   local drv = sysbench.sql.driver()\n   local con = drv:connect()\n\n   assert(drv:name() == \"mysql\", \"warmup is currently MySQL only\")\n\n   -- Do not create on disk tables for subsequent queries\n   con:query(\"SET tmp_table_size=2*1024*1024*1024\")\n   con:query(\"SET max_heap_table_size=2*1024*1024*1024\")\n\n   for i = sysbench.tid % sysbench.opt.threads + 1, sysbench.opt.tables,\n   sysbench.opt.threads do\n      local t = \"sbtest\" .. i\n      print(\"Preloading table \" .. t)\n      con:query(\"ANALYZE TABLE sbtest\" .. i)\n      con:query(string.format(\n                   \"SELECT AVG(id) FROM \" ..\n                      \"(SELECT * FROM %s FORCE KEY (PRIMARY) \" ..\n                      \"LIMIT %u) t\",\n                   t, sysbench.opt.table_size))\n      con:query(string.format(\n                   \"SELECT COUNT(*) FROM \" ..\n                      \"(SELECT * FROM %s WHERE k LIKE '%%0%%' LIMIT %u) t\",\n                   t, sysbench.opt.table_size))\n   end\nend\n\n-- Implement parallel prepare and warmup commands, define 'prewarm' as an alias\n-- for 'warmup'\nsysbench.cmdline.commands = {\n   prepare = {cmd_prepare, sysbench.cmdline.PARALLEL_COMMAND},\n   warmup = {cmd_warmup, sysbench.cmdline.PARALLEL_COMMAND},\n   prewarm = {cmd_warmup, sysbench.cmdline.PARALLEL_COMMAND}\n}\n\n\n-- Template strings of random digits with 11-digit groups separated by dashes\n\n-- 10 groups, 119 characters\nlocal c_value_template = \"###########-###########-###########-\" ..\n   \"###########-###########-###########-\" ..\n   \"###########-###########-###########-\" ..\n   \"###########\"\n\n-- 5 groups, 59 characters\nlocal pad_value_template = \"###########-###########-###########-\" ..\n   \"###########-###########\"\n\nfunction get_c_value()\n   return sysbench.rand.string(c_value_template)\nend\n\nfunction get_pad_value()\n   return sysbench.rand.string(pad_value_template)\nend\n\nfunction create_table(drv, con, table_num)\n   local id_index_def, id_def\n   local engine_def = \"\"\n   local extra_table_options = \"\"\n   local query\n\n   if sysbench.opt.secondary then\n     id_index_def = \"KEY xid\"\n   else\n     id_index_def = \"PRIMARY KEY\"\n   end\n\n   if drv:name() == \"mysql\"\n   then\n      if sysbench.opt.auto_inc then\n         id_def = \"INTEGER NOT NULL AUTO_INCREMENT\"\n      else\n         id_def = \"INTEGER NOT NULL\"\n      end\n      engine_def = \"/*! ENGINE = \" .. sysbench.opt.mysql_storage_engine .. \" */\"\n   elseif drv:name() == \"pgsql\"\n   then\n      if not sysbench.opt.auto_inc then\n         id_def = \"INTEGER NOT NULL\"\n      elseif pgsql_variant == 'redshift' then\n        id_def = \"INTEGER IDENTITY(1,1)\"\n      else\n        id_def = \"SERIAL\"\n      end\n   else\n      error(\"Unsupported database driver:\" .. drv:name())\n   end\n\n   print(string.format(\"Creating table 'sbtest%d'...\", table_num))\n\n   query = string.format([[\nCREATE TABLE sbtest%d(\n  id %s,\n  k INTEGER DEFAULT '0' NOT NULL,\n  c CHAR(120) DEFAULT '' NOT NULL,\n  pad CHAR(60) DEFAULT '' NOT NULL,\n  %s (id)\n) %s %s]],\n      table_num, id_def, id_index_def, engine_def,\n      sysbench.opt.create_table_options)\n\n   con:query(query)\n\n   if (sysbench.opt.table_size > 0) then\n      print(string.format(\"Inserting %d records into 'sbtest%d'\",\n                          sysbench.opt.table_size, table_num))\n   end\n\n   if sysbench.opt.auto_inc then\n      query = \"INSERT INTO sbtest\" .. table_num .. \"(k, c, pad) VALUES\"\n   else\n      query = \"INSERT INTO sbtest\" .. table_num .. \"(id, k, c, pad) VALUES\"\n   end\n\n   con:bulk_insert_init(query)\n\n   local c_val\n   local pad_val\n\n   for i = 1, sysbench.opt.table_size do\n\n      c_val = get_c_value()\n      pad_val = get_pad_value()\n\n      if (sysbench.opt.auto_inc) then\n         query = string.format(\"(%d, '%s', '%s')\",\n                               sysbench.rand.default(1, sysbench.opt.table_size),\n                               c_val, pad_val)\n      else\n         query = string.format(\"(%d, %d, '%s', '%s')\",\n                               i,\n                               sysbench.rand.default(1, sysbench.opt.table_size),\n                               c_val, pad_val)\n      end\n\n      con:bulk_insert_next(query)\n   end\n\n   con:bulk_insert_done()\n\n   if sysbench.opt.create_secondary then\n      print(string.format(\"Creating a secondary index on 'sbtest%d'...\",\n                          table_num))\n      con:query(string.format(\"CREATE INDEX k_%d ON sbtest%d(k)\",\n                              table_num, table_num))\n   end\nend\n\nlocal t = sysbench.sql.type\nlocal stmt_defs = {\n   point_selects = {\n      \"SELECT c FROM sbtest%u WHERE id=?\",\n      t.INT},\n   simple_ranges = {\n      \"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ?\",\n      t.INT, t.INT},\n   sum_ranges = {\n      \"SELECT SUM(k) FROM sbtest%u WHERE id BETWEEN ? AND ?\",\n       t.INT, t.INT},\n   order_ranges = {\n      \"SELECT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c\",\n       t.INT, t.INT},\n   distinct_ranges = {\n      \"SELECT DISTINCT c FROM sbtest%u WHERE id BETWEEN ? AND ? ORDER BY c\",\n      t.INT, t.INT},\n   index_updates = {\n      \"UPDATE sbtest%u SET k=k+1 WHERE id=?\",\n      t.INT},\n   non_index_updates = {\n      \"UPDATE sbtest%u SET c=? WHERE id=?\",\n      {t.CHAR, 120}, t.INT},\n   deletes = {\n      \"DELETE FROM sbtest%u WHERE id=?\",\n      t.INT},\n   inserts = {\n      \"INSERT INTO sbtest%u (id, k, c, pad) VALUES (?, ?, ?, ?)\",\n      t.INT, t.INT, {t.CHAR, 120}, {t.CHAR, 60}},\n}\n\nfunction prepare_begin()\n   stmt.begin = con:prepare(\"BEGIN\")\nend\n\nfunction prepare_commit()\n   stmt.commit = con:prepare(\"COMMIT\")\nend\n\nfunction prepare_for_each_table(key)\n   for t = 1, sysbench.opt.tables do\n      stmt[t][key] = con:prepare(string.format(stmt_defs[key][1], t))\n\n      local nparam = #stmt_defs[key] - 1\n\n      if nparam > 0 then\n         param[t][key] = {}\n      end\n\n      for p = 1, nparam do\n         local btype = stmt_defs[key][p+1]\n         local len\n\n         if type(btype) == \"table\" then\n            len = btype[2]\n            btype = btype[1]\n         end\n         if btype == sysbench.sql.type.VARCHAR or\n            btype == sysbench.sql.type.CHAR then\n               param[t][key][p] = stmt[t][key]:bind_create(btype, len)\n         else\n            param[t][key][p] = stmt[t][key]:bind_create(btype)\n         end\n      end\n\n      if nparam > 0 then\n         stmt[t][key]:bind_param(unpack(param[t][key]))\n      end\n   end\nend\n\nfunction prepare_point_selects()\n   prepare_for_each_table(\"point_selects\")\nend\n\nfunction prepare_simple_ranges()\n   prepare_for_each_table(\"simple_ranges\")\nend\n\nfunction prepare_sum_ranges()\n   prepare_for_each_table(\"sum_ranges\")\nend\n\nfunction prepare_order_ranges()\n   prepare_for_each_table(\"order_ranges\")\nend\n\nfunction prepare_distinct_ranges()\n   prepare_for_each_table(\"distinct_ranges\")\nend\n\nfunction prepare_index_updates()\n   prepare_for_each_table(\"index_updates\")\nend\n\nfunction prepare_non_index_updates()\n   prepare_for_each_table(\"non_index_updates\")\nend\n\nfunction prepare_delete_inserts()\n   prepare_for_each_table(\"deletes\")\n   prepare_for_each_table(\"inserts\")\nend\n\nfunction thread_init()\n   drv = sysbench.sql.driver()\n   con = drv:connect()\n\n   -- Create global nested tables for prepared statements and their\n   -- parameters. We need a statement and a parameter set for each combination\n   -- of connection/table/query\n   stmt = {}\n   param = {}\n\n   for t = 1, sysbench.opt.tables do\n      stmt[t] = {}\n      param[t] = {}\n   end\n\n   -- This function is a 'callback' defined by individual benchmark scripts\n   prepare_statements()\nend\n\n-- Close prepared statements\nfunction close_statements()\n   for t = 1, sysbench.opt.tables do\n      for k, s in pairs(stmt[t]) do\n         stmt[t][k]:close()\n      end\n   end\n   if (stmt.begin ~= nil) then\n      stmt.begin:close()\n   end\n   if (stmt.commit ~= nil) then\n      stmt.commit:close()\n   end\nend\n\nfunction thread_done()\n   close_statements()\n   con:disconnect()\nend\n\nfunction cleanup()\n   local drv = sysbench.sql.driver()\n   local con = drv:connect()\n\n   for i = 1, sysbench.opt.tables do\n      print(string.format(\"Dropping table 'sbtest%d'...\", i))\n      con:query(\"DROP TABLE IF EXISTS sbtest\" .. i )\n   end\nend\n\nlocal function get_table_num()\n   return sysbench.rand.uniform(1, sysbench.opt.tables)\nend\n\nlocal function get_id()\n   return sysbench.rand.default(1, sysbench.opt.table_size)\nend\n\nfunction begin()\n   stmt.begin:execute()\nend\n\nfunction commit()\n   stmt.commit:execute()\nend\n\nfunction execute_point_selects()\n   local tnum = get_table_num()\n   local i\n\n   for i = 1, sysbench.opt.point_selects do\n      param[tnum].point_selects[1]:set(get_id())\n\n      stmt[tnum].point_selects:execute()\n   end\nend\n\nlocal function execute_range(key)\n   local tnum = get_table_num()\n\n   for i = 1, sysbench.opt[key] do\n      local id = get_id()\n\n      param[tnum][key][1]:set(id)\n      param[tnum][key][2]:set(id + sysbench.opt.range_size - 1)\n\n      stmt[tnum][key]:execute()\n   end\nend\n\nfunction execute_simple_ranges()\n   execute_range(\"simple_ranges\")\nend\n\nfunction execute_sum_ranges()\n   execute_range(\"sum_ranges\")\nend\n\nfunction execute_order_ranges()\n   execute_range(\"order_ranges\")\nend\n\nfunction execute_distinct_ranges()\n   execute_range(\"distinct_ranges\")\nend\n\nfunction execute_index_updates()\n   local tnum = get_table_num()\n\n   for i = 1, sysbench.opt.index_updates do\n      param[tnum].index_updates[1]:set(get_id())\n\n      stmt[tnum].index_updates:execute()\n   end\nend\n\nfunction execute_non_index_updates()\n   local tnum = get_table_num()\n\n   for i = 1, sysbench.opt.non_index_updates do\n      param[tnum].non_index_updates[1]:set_rand_str(c_value_template)\n      param[tnum].non_index_updates[2]:set(get_id())\n\n      stmt[tnum].non_index_updates:execute()\n   end\nend\n\nfunction execute_delete_inserts()\n   local tnum = get_table_num()\n\n   for i = 1, sysbench.opt.delete_inserts do\n      local id = get_id()\n      local k = get_id()\n\n      param[tnum].deletes[1]:set(id)\n\n      param[tnum].inserts[1]:set(id)\n      param[tnum].inserts[2]:set(k)\n      param[tnum].inserts[3]:set_rand_str(c_value_template)\n      param[tnum].inserts[4]:set_rand_str(pad_value_template)\n\n      stmt[tnum].deletes:execute()\n      stmt[tnum].inserts:execute()\n   end\nend\n\n-- Re-prepare statements if we have reconnected, which is possible when some of\n-- the listed error codes are in the --mysql-ignore-errors list\nfunction sysbench.hooks.before_restart_event(errdesc)\n   if errdesc.sql_errno == 2013 or -- CR_SERVER_LOST\n      errdesc.sql_errno == 2055 or -- CR_SERVER_LOST_EXTENDED\n      errdesc.sql_errno == 2006 or -- CR_SERVER_GONE_ERROR\n      errdesc.sql_errno == 2011    -- CR_TCP_CONNECTION\n   then\n      close_statements()\n      prepare_statements()\n   end\nend\n\nfunction check_reconnect()\n   if sysbench.opt.reconnect > 0 then\n      transactions = (transactions or 0) + 1\n      if transactions % sysbench.opt.reconnect == 0 then\n         close_statements()\n         con:reconnect()\n         prepare_statements()\n      end\n   end\nend\n"
  },
  {
    "path": "src/lua/oltp_delete.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Delete-Only OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   prepare_for_each_table(\"deletes\")\nend\n\nfunction event()\n   local tnum = sysbench.rand.uniform(1, sysbench.opt.tables)\n   local id = sysbench.rand.default(1, sysbench.opt.table_size)\n\n   param[tnum].deletes[1]:set(id)\n   stmt[tnum].deletes:execute()\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_insert.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Insert-Only OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nsysbench.cmdline.commands.prepare = {\n   function ()\n      if (not sysbench.opt.auto_inc) then\n         -- Create empty tables on prepare when --auto-inc is off, since IDs\n         -- generated on prepare may collide later with values generated by\n         -- sysbench.rand.unique()\n         sysbench.opt.table_size=0\n      end\n\n      cmd_prepare()\n   end,\n   sysbench.cmdline.PARALLEL_COMMAND\n}\n\nfunction prepare_statements()\n   -- We do not use prepared statements here, but oltp_common.sh expects this\n   -- function to be defined\nend\n\nfunction event()\n   local table_name = \"sbtest\" .. sysbench.rand.uniform(1, sysbench.opt.tables)\n   local k_val = sysbench.rand.default(1, sysbench.opt.table_size)\n   local c_val = get_c_value()\n   local pad_val = get_pad_value()\n\n   if (drv:name() == \"pgsql\" and sysbench.opt.auto_inc) then\n      con:query(string.format(\"INSERT INTO %s (k, c, pad) VALUES \" ..\n                                 \"(%d, '%s', '%s')\",\n                              table_name, k_val, c_val, pad_val))\n   else\n      if (sysbench.opt.auto_inc) then\n         i = 0\n      else\n         -- Convert a uint32_t value to SQL INT\n         i = sysbench.rand.unique() - 2147483648\n      end\n\n      con:query(string.format(\"INSERT INTO %s (id, k, c, pad) VALUES \" ..\n                                 \"(%d, %d, '%s', '%s')\",\n                              table_name, i, k_val, c_val, pad_val))\n   end\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_point_select.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- OLTP Point Select benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   -- use 1 query per event, rather than sysbench.opt.point_selects which\n   -- defaults to 10 in other OLTP scripts\n   sysbench.opt.point_selects=1\n\n   prepare_point_selects()\nend\n\nfunction event()\n   execute_point_selects()\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_read_only.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Read-Only OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   prepare_point_selects()\n\n   if not sysbench.opt.skip_trx then\n      prepare_begin()\n      prepare_commit()\n   end\n\n   if sysbench.opt.range_selects then\n      prepare_simple_ranges()\n      prepare_sum_ranges()\n      prepare_order_ranges()\n      prepare_distinct_ranges()\n   end\nend\n\nfunction event()\n   if not sysbench.opt.skip_trx then\n      begin()\n   end\n\n   execute_point_selects()\n\n   if sysbench.opt.range_selects then\n      execute_simple_ranges()\n      execute_sum_ranges()\n      execute_order_ranges()\n      execute_distinct_ranges()\n   end\n\n   if not sysbench.opt.skip_trx then\n      commit()\n   end\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_read_write.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Read/Write OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   if not sysbench.opt.skip_trx then\n      prepare_begin()\n      prepare_commit()\n   end\n\n   prepare_point_selects()\n\n   if sysbench.opt.range_selects then\n      prepare_simple_ranges()\n      prepare_sum_ranges()\n      prepare_order_ranges()\n      prepare_distinct_ranges()\n   end\n\n   prepare_index_updates()\n   prepare_non_index_updates()\n   prepare_delete_inserts()\nend\n\nfunction event()\n   if not sysbench.opt.skip_trx then\n      begin()\n   end\n\n   execute_point_selects()\n\n   if sysbench.opt.range_selects then\n      execute_simple_ranges()\n      execute_sum_ranges()\n      execute_order_ranges()\n      execute_distinct_ranges()\n   end\n\n   execute_index_updates()\n   execute_non_index_updates()\n   execute_delete_inserts()\n\n   if not sysbench.opt.skip_trx then\n      commit()\n   end\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_update_index.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Update-Index OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   prepare_index_updates()\nend\n\nfunction event()\n   execute_index_updates(con)\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_update_non_index.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Update-Non-Index OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   prepare_non_index_updates()\nend\n\nfunction event()\n   execute_non_index_updates()\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/oltp_write_only.lua",
    "content": "#!/usr/bin/env sysbench\n-- Copyright (C) 2006-2017 Alexey Kopytov <akopytov@gmail.com>\n\n-- This program is free software; you can redistribute it and/or modify\n-- it under the terms of the GNU General Public License as published by\n-- the Free Software Foundation; either version 2 of the License, or\n-- (at your option) any later version.\n\n-- This program is distributed in the hope that it will be useful,\n-- but WITHOUT ANY WARRANTY; without even the implied warranty of\n-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n-- GNU General Public License for more details.\n\n-- You should have received a copy of the GNU General Public License\n-- along with this program; if not, write to the Free Software\n-- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\n-- ----------------------------------------------------------------------\n-- Write-Only OLTP benchmark\n-- ----------------------------------------------------------------------\n\nrequire(\"oltp_common\")\n\nfunction prepare_statements()\n   if not sysbench.opt.skip_trx then\n      prepare_begin()\n      prepare_commit()\n   end\n\n   prepare_index_updates()\n   prepare_non_index_updates()\n   prepare_delete_inserts()\nend\n\nfunction event()\n   if not sysbench.opt.skip_trx then\n      begin()\n   end\n\n   execute_index_updates()\n   execute_non_index_updates()\n   execute_delete_inserts()\n\n   if not sysbench.opt.skip_trx then\n      commit()\n   end\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/prime-test.lua",
    "content": "#!/usr/bin/env sysbench\n\n-- you can run this script like this:\n-- $ ./prime-test.lua --cpu-max-prime=20000 --threads=8 --histogram --report-interval=1 run\n\nsysbench.cmdline.options = {\n    -- the default values for built-in options are currently ignored, see \n    -- https://github.com/akopytov/sysbench/issues/151\n    [\"cpu-max-prime\"] = {\"CPU maximum prime\", 10000},\n    [\"threads\"] = {\"Number of threads\", 1},\n    [\"histogram\"] = {\"Show histogram\", \"off\"},\n    [\"report-interval\"] = {\"Report interval\", 1}\n}\n\nfunction event()\n    local n = 0\n    for c = 3, sysbench.opt.cpu_max_prime do\n        local t = math.sqrt(c)\n        local isprime = true\n        for l = 2, t do\n            if c % l == 0 then\n                isprime = false\n                break\n            end\n        end\n        if isprime then\n            n = n + 1\n        end\n    end\nend\n\nfunction sysbench.hooks.report_cumulative(stat)\n    local seconds = stat.time_interval\n    print(string.format([[\n{\n    \"errors\": %4.0f,\n    \"events\": %4.0f,\n    \"latency_avg\": %4.10f,\n    \"latency_max\": %4.10f,\n    \"latency_min\": %4.10f,\n    \"latency_pct\": %4.10f,\n    \"latency_sum\": %4.10f,\n    \"other\": %4.0f,\n    \"reads\": %4.0f,\n    \"reconnects\": %4.0f,\n    \"threads_running\": %4.0f,\n    \"time_interval\": %4.10f,\n    \"time_total\": %4.10f,\n    \"writes\": %4.0f\n}\n]], \n    stat.errors, \n    stat.events, \n    stat.latency_avg, \n    stat.latency_max, \n    stat.latency_min, \n    stat.latency_pct, \n    stat.latency_sum, \n    stat.other, \n    stat.reads, \n    stat.reconnects, \n    stat.threads_running, \n    stat.time_interval, \n    stat.time_total, \n    stat.writes))\nend\n"
  },
  {
    "path": "src/lua/select_random_points.lua",
    "content": "#!/usr/bin/env sysbench\n-- This test is designed for testing MariaDB's key_cache_segments for MyISAM,\n-- and should work with other storage engines as well.\n--\n-- For details about key_cache_segments please refer to:\n-- http://kb.askmonty.org/v/segmented-key-cache\n--\n\nrequire(\"oltp_common\")\n\n-- Add random_points to the list of standard OLTP options\nsysbench.cmdline.options.random_points =\n   {\"Number of random points in the IN() clause in generated SELECTs\", 10}\n\n-- Override standard prepare/cleanup OLTP functions, as this benchmark does not\n-- support multiple tables\noltp_prepare = prepare\noltp_cleanup = cleanup\n\nfunction prepare()\n   assert(sysbench.opt.tables == 1, \"this benchmark does not support \" ..\n             \"--tables > 1\")\n   oltp_prepare()\nend\n\nfunction cleanup()\n   assert(sysbench.opt.tables == 1, \"this benchmark does not support \" ..\n             \"--tables > 1\")\n   oltp_cleanup()\nend\n\nfunction thread_init()\n   drv = sysbench.sql.driver()\n   con = drv:connect()\n\n   local points = string.rep(\"?, \", sysbench.opt.random_points - 1) .. \"?\"\n\n   stmt = con:prepare(string.format([[\n        SELECT id, k, c, pad\n          FROM sbtest1\n          WHERE k IN (%s)\n        ]], points))\n\n   params = {}\n   for j = 1, sysbench.opt.random_points do\n      params[j] = stmt:bind_create(sysbench.sql.type.INT)\n   end\n\n   stmt:bind_param(unpack(params))\n\n   rlen = sysbench.opt.table_size / sysbench.opt.threads\n\n   thread_id = sysbench.tid % sysbench.opt.threads\nend\n\nfunction thread_done()\n   stmt:close()\n   con:disconnect()\nend\n\nfunction event()\n   -- To prevent overlapping of our range queries we need to partition the whole\n   -- table into 'threads' segments and then make each thread work with its\n   -- own segment.\n   for i = 1, sysbench.opt.random_points do\n      local rmin = rlen * thread_id\n      local rmax = rmin + rlen\n      params[i]:set(sysbench.rand.default(rmin, rmax))\n   end\n\n   stmt:execute()\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/lua/select_random_ranges.lua",
    "content": "#!/usr/bin/env sysbench\n-- This test is designed for testing MariaDB's key_cache_segments for MyISAM,\n-- and should work with other storage engines as well.\n--\n-- For details about key_cache_segments please refer to:\n-- http://kb.askmonty.org/v/segmented-key-cache\n--\n\nrequire(\"oltp_common\")\n\n-- Add --number-of-ranges and --delta to the list of standard OLTP options\nsysbench.cmdline.options.number_of_ranges =\n   {\"Number of random BETWEEN ranges per SELECT\", 10}\nsysbench.cmdline.options.delta =\n   {\"Size of BETWEEN ranges\", 5}\n\n-- Override standard prepare/cleanup OLTP functions, as this benchmark does not\n-- support multiple tables\noltp_prepare = prepare\noltp_cleanup = cleanup\n\nfunction prepare()\n   assert(sysbench.opt.tables == 1, \"this benchmark does not support \" ..\n             \"--tables > 1\")\n   oltp_prepare()\nend\n\nfunction cleanup()\n   assert(sysbench.opt.tables == 1, \"this benchmark does not support \" ..\n             \"--tables > 1\")\n   oltp_cleanup()\nend\n\nfunction thread_init()\n   drv = sysbench.sql.driver()\n   con = drv:connect()\n\n   local ranges = string.rep(\"k BETWEEN ? AND ? OR \",\n                             sysbench.opt.number_of_ranges - 1) ..\n      \"k BETWEEN ? AND ?\"\n\n   stmt = con:prepare(string.format([[\n        SELECT count(k)\n          FROM sbtest1\n          WHERE %s]], ranges))\n\n   params = {}\n   for j = 1, sysbench.opt.number_of_ranges*2 do\n      params[j] = stmt:bind_create(sysbench.sql.type.INT)\n   end\n\n   stmt:bind_param(unpack(params))\n\n   rlen = sysbench.opt.table_size / sysbench.opt.threads\n\n   thread_id = sysbench.tid % sysbench.opt.threads\nend\n\nfunction thread_done()\n   stmt:close()\n   con:disconnect()\nend\n\nfunction event()\n   -- To prevent overlapping of our range queries we need to partition the whole\n   -- table into 'threads' segments and then make each thread work with its\n   -- own segment.\n   for i = 1, sysbench.opt.number_of_ranges*2, 2 do\n      local rmin = rlen * thread_id\n      local rmax = rmin + rlen\n      local val = sysbench.rand.default(rmin, rmax)\n      params[i]:set(val)\n      params[i+1]:set(val + sysbench.opt.delta)\n   end\n\n   stmt:execute()\n\n   check_reconnect()\nend\n"
  },
  {
    "path": "src/sb_barrier.c",
    "content": "/*\n   Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/*\n   Thread barrier implementation. It differs from pthread_barrier_t in two ways:\n\n   - it's more portable (will also work on OS X).\n\n   - it allows defining a callback function which is called right before\n     signaling the participating threads to continue, i.e. as soon as the\n     required number of threads reach the barrier. The callback can also signal\n     an error to sb_barrier_wait() callers by returning a non-zero value. In\n     which case sb_barrier_wait() returns a negative value to all callers.\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#include \"sb_barrier.h\"\n\nint sb_barrier_init(sb_barrier_t *barrier, unsigned int count,\n                    sb_barrier_cb_t callback, void *arg)\n{\n  if (count == 0)\n    return 1;\n\n  if (pthread_mutex_init(&barrier->mutex, NULL) ||\n      pthread_cond_init(&barrier->cond, NULL))\n    return 1;\n\n  barrier->init_count = count;\n  barrier->count = count;\n  barrier->callback = callback;\n  barrier->arg = arg;\n  barrier->serial = 0;\n  barrier->error = 0;\n\n  return 0;\n}\n\n\nint sb_barrier_wait(sb_barrier_t *barrier)\n{\n  int res;\n\n  pthread_mutex_lock(&barrier->mutex);\n\n  if (!--barrier->count)\n  {\n    barrier->serial++;\n    barrier->count = barrier->init_count;\n\n    res = SB_BARRIER_SERIAL_THREAD;\n\n    pthread_cond_broadcast(&barrier->cond);\n\n    if (barrier->callback != NULL && barrier->callback(barrier->arg) != 0)\n    {\n      barrier->error = 1;\n      res = -1;\n    }\n\n    pthread_mutex_unlock(&barrier->mutex);\n\n  }\n  else\n  {\n    unsigned int serial = barrier->serial;\n\n    do {\n      pthread_cond_wait(&barrier->cond, &barrier->mutex);\n    } while (serial == barrier->serial);\n\n    res = barrier->error ? -1 : 0;\n\n    pthread_mutex_unlock(&barrier->mutex);\n  }\n\n  return res;\n}\n\n\nvoid sb_barrier_destroy(sb_barrier_t *barrier)\n{\n  pthread_mutex_destroy(&barrier->mutex);\n  pthread_cond_destroy(&barrier->cond);\n}\n"
  },
  {
    "path": "src/sb_barrier.h",
    "content": "/*\n   Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/* Thread barrier implementation. */\n\n#ifndef SB_BARRIER_H\n#define SB_BARRIER_H\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n#define SB_BARRIER_SERIAL_THREAD 1\n\ntypedef int (*sb_barrier_cb_t)(void *);\n\ntypedef struct {\n  unsigned int     count;\n  unsigned int     init_count;\n  unsigned int     serial;\n  pthread_mutex_t  mutex;\n  pthread_cond_t   cond;\n  sb_barrier_cb_t  callback;\n  void             *arg;\n  int              error;\n} sb_barrier_t;\n\nint sb_barrier_init(sb_barrier_t *barrier, unsigned int count,\n                    sb_barrier_cb_t callback, void *arg);\n\nint sb_barrier_wait(sb_barrier_t *barrier);\n\nvoid sb_barrier_destroy(sb_barrier_t *barrier);\n\n#endif /* SB_BARRIER_H */\n"
  },
  {
    "path": "src/sb_ck_pr.h",
    "content": "/*\n   Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/*\n * This file incorporates work covered by the following copyright and\n * permission notice:\n *\n * Copyright 2010 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n  Compatibility wrappers for ConcurrencyKit functions. ConcurrencyKit does not\n  implement 64-bit atomic primitives on some 32-bit architectures (e.g. x86,\n  ARMv6) natively. Newer versions support the CK_USE_CC_BUILTINS define which\n  allows resorting to compiler builtins emulating 64-bit atomics on 32-bit\n  architectures. However, one might want to build with an old,\n  distribution-provided CK version where that option is not available. For those\n  versions, define 64-bit atomics as aliases to GCC builtins. A cleaner solution\n  would be to define the corresponding sysbench data structures as 32-bit\n  integers on those architectures, but the amount of extra code to implement and\n  support is not worth it. Code below has been copied with modifications from\n  gcc/ck_pr.h from the ConcurrencyKit distribution.\n*/\n\n#ifndef SB_CK_H\n#define SB_CK_H\n\n#include \"ck_pr.h\"\n\n#if !defined(CK_F_PR_LOAD_64)\n\n#ifndef __GNUC__\n#  error Unsupported platform\n#endif\n\n#include <ck_cc.h>\n\n#define CK_PR_ACCESS(x) (*(volatile __typeof__(x) *)&(x))\n\n#define CK_PR_LOAD(S, M, T)\t\t \t\t\t\\\n        CK_CC_INLINE static T\t\t\t\t\t\\\n        ck_pr_md_load_##S(const M *target)\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                T r;\t\t\t\t\t\t\\\n                ck_pr_barrier();\t\t\t\t\\\n                r = CK_PR_ACCESS(*(const T *)target);\t\t\\\n                ck_pr_barrier();\t\t\t\t\\\n                return (r);\t\t\t\t\t\\\n        }\t\t\t\t\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_md_store_##S(M *target, T v)\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                ck_pr_barrier();\t\t\t\t\\\n                CK_PR_ACCESS(*(T *)target) = v;\t\t\t\\\n                ck_pr_barrier();\t\t\t\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\n#define CK_PR_LOAD_S(S, T) CK_PR_LOAD(S, T, T)\n\nCK_PR_LOAD_S(64, uint64_t)\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#define CK_PR_LOAD_SAFE(SRC, TYPE) ck_pr_md_load_##TYPE((SRC))\n\n#define CK_PR_STORE_SAFE(DST, VAL, TYPE)\t\t\t\\\n    ck_pr_md_store_##TYPE(\t\t\t\t\t\\\n        ((void)sizeof(*(DST) = (VAL)), (DST)),\t\t\t\\\n        (VAL))\n\n#define ck_pr_load_64(SRC) CK_PR_LOAD_SAFE((SRC), 64)\n#define ck_pr_store_64(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 64)\n\n/*\n * Atomic compare and swap.\n */\n#define CK_PR_CAS(S, M, T)\t\t\t\t\t\t\t\\\n        CK_CC_INLINE static bool\t\t\t\t\t\t\\\n        ck_pr_cas_##S(M *target, T compare, T set)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\t\t\\\n                bool z;\t\t\t\t\t\t\t\t\\\n                z = __sync_bool_compare_and_swap((T *)target, compare, set);\t\\\n                return z;\t\t\t\t\t\t\t\\\n        }\n\n#define CK_PR_CAS_S(S, T) CK_PR_CAS(S, T, T)\n\nCK_PR_CAS_S(64, uint64_t)\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n#define CK_PR_CAS_O(S, T)\t\t\t\t\t\t\\\n        CK_CC_INLINE static bool\t\t\t\t\t\\\n        ck_pr_cas_##S##_value(T *target, T compare, T set, T *v)\t\\\n        {\t\t\t\t\t\t\t\t\\\n                set = __sync_val_compare_and_swap(target, compare, set);\\\n                *v = set;\t\t\t\t\t\t\\\n                return (set == compare);\t\t\t\t\\\n        }\n\nCK_PR_CAS_O(64, uint64_t)\n\n#undef CK_PR_CAS_O\n\n/*\n * Atomic store-only binary operations.\n */\n#define CK_PR_BINARY(K, S, M, T)\t\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_##K##_##S(M *target, T d)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                d = __sync_fetch_and_##K((T *)target, d);\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\n#define CK_PR_BINARY_S(K, S, T) CK_PR_BINARY(K, S, T, T)\n\n#define CK_PR_GENERATE(K)\t\t\t\\\n        CK_PR_BINARY_S(K, 64, uint64_t)\n\nCK_PR_GENERATE(add)\nCK_PR_GENERATE(sub)\nCK_PR_GENERATE(and)\nCK_PR_GENERATE(or)\nCK_PR_GENERATE(xor)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\n#define CK_PR_UNARY(S, M, T)\t\t\t\\\n        CK_CC_INLINE static void\t\t\\\n        ck_pr_inc_##S(M *target)\t\t\\\n        {\t\t\t\t\t\\\n                ck_pr_add_##S(target, (T)1);\t\\\n                return;\t\t\t\t\\\n        }\t\t\t\t\t\\\n        CK_CC_INLINE static void\t\t\\\n        ck_pr_dec_##S(M *target)\t\t\\\n        {\t\t\t\t\t\\\n                ck_pr_sub_##S(target, (T)1);\t\\\n                return;\t\t\t\t\\\n        }\n\n#define CK_PR_UNARY_S(S, M) CK_PR_UNARY(S, M, M)\n\nCK_PR_UNARY_S(64, uint64_t)\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\n#define CK_PR_FAA(S, M, T, C)\t\t\t\t\t\t\\\n        CK_CC_INLINE static C\t\t\t\t\t\t\\\n        ck_pr_faa_##S(M *target, T delta)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\t\\\n                C punt;\t\t\t\t\t\t\t\\\n                punt = (C)ck_pr_md_load_##S(target);\t\t\t\\\n                previous = (T)punt;\t\t\t\t\t\\\n                while (ck_pr_cas_##S##_value(target,\t\t\t\\\n                                             (C)previous,\t\t\\\n                                             (C)(previous + delta),\t\\\n                                             &previous) == false)\t\\\n                        ck_pr_stall();\t\t\t\t\t\\\n                                                                        \\\n                return ((C)previous);\t\t\t\t\t\\\n        }\n\n#define CK_PR_FAS(S, M, C)\t\t\t\t\t\t\\\n        CK_CC_INLINE static C\t\t\t\t\t\t\\\n        ck_pr_fas_##S(M *target, C update)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                C previous;\t\t\t\t\t\t\\\n                previous = ck_pr_md_load_##S(target);\t\t\t\\\n                while (ck_pr_cas_##S##_value(target,\t\t\t\\\n                                             previous,\t\t\t\\\n                                             update,\t\t\t\\\n                                             &previous) == false)\t\\\n                        ck_pr_stall();\t\t\t\t\t\\\n                                                                        \\\n                return (previous);\t\t\t\t\t\\\n        }\n\n#define CK_PR_FAA_S(S, M) CK_PR_FAA(S, M, M, M)\n#define CK_PR_FAS_S(S, M) CK_PR_FAS(S, M, M)\n\nCK_PR_FAA_S(64, uint64_t)\nCK_PR_FAS_S(64, uint64_t)\n\n#undef CK_PR_FAA_S\n#undef CK_PR_FAA\n#undef CK_PR_FAS_S\n#undef CK_PR_FAS\n\n#endif /* !CK_F_PR_LOAD_64*/\n#endif /* SB_CK_H */\n"
  },
  {
    "path": "src/sb_counter.c",
    "content": "/*\n   Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#include \"sb_counter.h\"\n#include \"sysbench.h\"\n#include \"sb_util.h\"\n#include \"sb_ck_pr.h\"\n\nsb_counters_t *sb_counters CK_CC_CACHELINE;\n\nstatic sb_counters_t last_intermediate_counters;\nstatic sb_counters_t last_cumulative_counters;\n\n/* Initialize per-thread stats */\n\nint sb_counters_init(void)\n{\n  SB_COMPILE_TIME_ASSERT(sizeof(sb_counters_t) % CK_MD_CACHELINE == 0);\n\n  sb_counters = sb_alloc_per_thread_array(sizeof(sb_counters_t));\n\n  return sb_counters == NULL;\n}\n\nvoid sb_counters_done(void)\n{\n  if (sb_counters != NULL)\n  {\n    free(sb_counters);\n    sb_counters = NULL;\n  }\n}\n\nstatic void sb_counters_merge(sb_counters_t dst)\n{\n  for (size_t t = 0; t < SB_CNT_MAX; t++)\n    for (size_t i = 0; i < sb_globals.threads; i++)\n      dst[t] += sb_counter_val(i, t);\n}\n\nstatic void sb_counters_checkpoint(sb_counters_t dst, sb_counters_t cp)\n{\n  for (size_t i = 0; i < SB_CNT_MAX; i++)\n  {\n    uint64_t tmp = cp[i];\n    cp[i] = dst[i];\n    dst[i] = dst[i] - tmp;\n  }\n}\n\n/*\n  Return aggregate counter values since the last intermediate report. This is\n  not thread-safe as it updates the global last report state, so it must be\n  called from a single thread.\n*/\nvoid sb_counters_agg_intermediate(sb_counters_t val)\n{\n  memset(val, 0, sizeof(sb_counters_t));\n\n  sb_counters_merge(val);\n  sb_counters_checkpoint(val, last_intermediate_counters);\n}\n\n/*\n  Return aggregate counter values since the last cumulative report. This is\n  not thread-safe as it updates the global last report state, so it must be\n  called from a single thread.\n*/\nvoid sb_counters_agg_cumulative(sb_counters_t val)\n{\n  memset(val, 0, sizeof(sb_counters_t));\n\n  sb_counters_merge(val);\n  sb_counters_checkpoint(val, last_cumulative_counters);\n}\n"
  },
  {
    "path": "src/sb_counter.h",
    "content": "/*\n   Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_COUNTER_H\n#define SB_COUNTER_H\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <inttypes.h>\n#endif\n\n#include \"sb_util.h\"\n#include \"sb_ck_pr.h\"\n\n/* Statistic counter types */\n\ntypedef enum {\n  SB_CNT_OTHER,         /* unknown type of queries */\n  SB_CNT_READ,          /* reads */\n  SB_CNT_WRITE,         /* writes */\n  SB_CNT_EVENT,         /* events */\n  SB_CNT_ERROR,         /* errors */\n  SB_CNT_RECONNECT,     /* reconnects */\n  SB_CNT_BYTES_READ,    /* bytes read */\n  SB_CNT_BYTES_WRITTEN, /* bytes written */\n  SB_CNT_MAX\n} sb_counter_type_t;\n\n/*\n  sizeof(sb_counters_t) must be a multiple of CK_MD_CACHELINE to avoid cache\n  line sharing.\n*/\ntypedef uint64_t\nsb_counters_t[SB_ALIGN(SB_CNT_MAX * sizeof(uint64_t), CK_MD_CACHELINE) /\n              sizeof(uint64_t)];\n\nextern sb_counters_t *sb_counters;\n\nint sb_counters_init(void);\n\nvoid sb_counters_done(void);\n\n/*\n  Cannot use C99 inline here, because CK atomic primitives use static inlines\n  which in turn leads to compiler warnings. So for performance reasons the\n  following functions are defined 'static inline' too everywhere except sb_lua.c\n  where they are declared and defined as external linkage functions to be\n  available from LuaJIT FFI.\n*/\n#ifndef SB_LUA_EXPORT\n# define SB_LUA_INLINE static inline\n#else\n# define SB_LUA_INLINE\nuint64_t sb_counter_val(int thread_id, sb_counter_type_t type);\nvoid sb_counter_add(int thread_id, sb_counter_type_t type, uint64_t val);\nvoid sb_counter_inc(int thread_id, sb_counter_type_t type);\n#endif\n\n/* Return the current value for a given counter */\nSB_LUA_INLINE\nuint64_t sb_counter_val(int thread_id, sb_counter_type_t type)\n{\n  return ck_pr_load_64(&sb_counters[thread_id][type]);\n}\n\n/* Add a given value to a given stat counter for a given thread */\nSB_LUA_INLINE\nvoid sb_counter_add(int thread_id, sb_counter_type_t type, uint64_t val)\n{\n  ck_pr_store_64(&sb_counters[thread_id][type],\n                 sb_counter_val(thread_id, type) + val);\n}\n\n/* Increment a given stat counter for a given thread  */\nSB_LUA_INLINE\nvoid sb_counter_inc(int thread_id, sb_counter_type_t type)\n{\n  sb_counter_add(thread_id, type, 1);\n}\n\n#undef SB_LUA_INLINE\n\n/*\n  Return aggregate counter values since the last intermediate report. This is\n  not thread-safe as it updates the global last report state, so it must be\n  called from a single thread.\n*/\nvoid sb_counters_agg_intermediate(sb_counters_t val);\n\n/*\n  Return aggregate counter values since the last cumulative report. This is\n  not thread-safe as it updates the global last report state, so it must be\n  called from a single thread.\n*/\nvoid sb_counters_agg_cumulative(sb_counters_t val);\n\n#endif\n"
  },
  {
    "path": "src/sb_global.h",
    "content": "/* Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/* Global and portability-related macros */\n\n#ifndef SB_GLOBAL_H\n#define SB_GLOBAL_H\n\n#ifdef HAVE_CONFIG_H\n#include \"config.h\"\n#endif\n\n#endif /* SB_GLOBAL_H */\n"
  },
  {
    "path": "src/sb_histogram.c",
    "content": "/* Copyright (C) 2011-2018 Alexey Kopytov.\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n# include <stdlib.h>\n#endif\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n#ifdef HAVE_MATH_H\n# include <math.h>\n#endif\n\n#include \"sysbench.h\"\n#include \"sb_histogram.h\"\n#include \"sb_logger.h\"\n#include \"sb_rand.h\"\n\n#include \"sb_ck_pr.h\"\n#include \"ck_cc.h\"\n\n#include \"sb_util.h\"\n\n\n/*\n   Number of slots for current histogram array. TODO: replace this constant with\n   some autodetection code based on the number of available cores or some such.\n*/\n#define SB_HISTOGRAM_NSLOTS 128\n\n/* Global latency histogram */\nsb_histogram_t sb_latency_histogram CK_CC_CACHELINE;\n\n\nint sb_histogram_init(sb_histogram_t *h, size_t size,\n                      double range_min, double range_max)\n{\n  size_t i;\n  uint64_t *tmp;\n\n  /* Allocate memory for cumulative_array + temp_array + all slot arrays */\n  tmp = (uint64_t *) calloc(size * (SB_HISTOGRAM_NSLOTS + 2), sizeof(uint64_t));\n  h->interm_slots = (uint64_t **) malloc(SB_HISTOGRAM_NSLOTS *\n                                         sizeof(uint64_t *));\n\n  if (tmp == NULL || h->interm_slots == NULL)\n  {\n    log_text(LOG_FATAL,\n             \"Failed to allocate memory for a histogram object, size = %zd\",\n             size);\n    return 1;\n  }\n\n  h->cumulative_array = tmp;\n  tmp += size;\n\n  h->temp_array = tmp;\n  tmp += size;\n\n  for (i = 0; i < SB_HISTOGRAM_NSLOTS; i++)\n  {\n    h->interm_slots[i] = tmp;\n    tmp += size;\n  }\n\n  h->range_deduct = log(range_min);\n  h->range_mult = (size - 1) / (log(range_max) - h->range_deduct);\n\n  h->range_min = range_min;\n  h->range_max = range_max;\n\n  h->array_size = size;\n\n  pthread_rwlock_init(&h->lock, NULL);\n\n  return 0;\n}\n\n\nvoid sb_histogram_update(sb_histogram_t *h, double value)\n{\n  size_t      slot;\n  ssize_t     i;\n\n  slot = sb_rand_uniform_uint64() % SB_HISTOGRAM_NSLOTS;\n\n  i = floor((log(value) - h->range_deduct) * h->range_mult + 0.5);\n  if (SB_UNLIKELY(i < 0))\n    i = 0;\n  else if (SB_UNLIKELY(i >= (ssize_t) (h->array_size)))\n    i = h->array_size - 1;\n\n  ck_pr_inc_64(&h->interm_slots[slot][i]);\n}\n\n\ndouble sb_histogram_get_pct_intermediate(sb_histogram_t *h,\n                                         double percentile)\n{\n  size_t   i, s;\n  uint64_t nevents, ncur, nmax;\n  double   res;\n\n  nevents = 0;\n\n  /*\n    This can be called concurrently with other sb_histogram_get_pct_*()\n    functions, so use the lock to protect shared structures. This will not block\n    sb_histogram_update() calls, but we make sure we don't lose any concurrent\n    increments by atomically fetching each array element and replacing it with\n    0.\n  */\n  pthread_rwlock_wrlock(&h->lock);\n\n  /*\n    Merge intermediate slots into temp_array.\n  */\n  const size_t size = h->array_size;\n  uint64_t * const array = h->temp_array;\n\n  for (i = 0; i < size; i++)\n  {\n    array[i] = ck_pr_fas_64(&h->interm_slots[0][i], 0);\n    nevents += array[i];\n  }\n\n  for (s = 1; s < SB_HISTOGRAM_NSLOTS; s++)\n  {\n    for (i = 0; i < size; i++)\n    {\n      uint64_t t;\n\n      t = ck_pr_fas_64(&h->interm_slots[s][i], 0);\n\n      array[i] += t;\n      nevents += t;\n    }\n  }\n\n  /*\n    Now that we have an aggregate 'snapshot' of current arrays and the total\n    number of events in it, calculate the current, intermediate percentile value\n    to return.\n  */\n  nmax = floor(nevents * percentile / 100 + 0.5);\n\n  ncur = 0;\n  for (i = 0; i < size; i++)\n  {\n    ncur += array[i];\n    if (ncur >= nmax)\n      break;\n  }\n\n  res = exp(i / h->range_mult + h->range_deduct);\n\n  /* Finally, add temp_array into accumulated values in cumulative_array. */\n  for (i = 0; i < size; i++)\n  {\n    h->cumulative_array[i] += array[i];\n  }\n\n  h->cumulative_nevents += nevents;\n\n  pthread_rwlock_unlock(&h->lock);\n\n  return res;\n}\n\n\n/*\n  Aggregate arrays from intermediate slots into cumulative_array. This should be\n  called with the histogram lock write-locked.\n*/\nstatic void merge_intermediate_into_cumulative(sb_histogram_t *h)\n{\n  size_t   i, s;\n  uint64_t nevents;\n\n  nevents = h->cumulative_nevents;\n\n  const size_t size = h->array_size;\n  uint64_t * const array = h->cumulative_array;\n\n  for (s = 0; s < SB_HISTOGRAM_NSLOTS; s++)\n  {\n    for (i = 0; i < size; i++)\n    {\n      uint64_t t = ck_pr_fas_64(&h->interm_slots[s][i], 0);\n      array[i] += t;\n      nevents += t;\n    }\n  }\n\n  h->cumulative_nevents = nevents;\n}\n\n\n/*\n  Calculate a given percentile from the cumulative array. This should be called\n  with the histogram lock either read- or write-locked.\n*/\nstatic double get_pct_cumulative(sb_histogram_t *h, double percentile)\n{\n  size_t   i;\n  uint64_t ncur, nmax;\n\n  nmax = floor(h->cumulative_nevents * percentile / 100 + 0.5);\n\n  ncur = 0;\n  for (i = 0; i < h->array_size; i++)\n  {\n    ncur += h->cumulative_array[i];\n    if (ncur >= nmax)\n      break;\n  }\n\n  return exp(i / h->range_mult + h->range_deduct);\n}\n\n\ndouble sb_histogram_get_pct_cumulative(sb_histogram_t *h, double percentile)\n{\n  double res;\n\n  /*\n    This can be called concurrently with other sb_histogram_get_pct_*()\n    functions, so use the lock to protect shared structures. This will not block\n    sb_histogram_update() calls, but we make sure we don't lose any concurrent\n    increments by atomically fetching each array element and replacing it with\n    0.\n  */\n  pthread_rwlock_wrlock(&h->lock);\n\n  merge_intermediate_into_cumulative(h);\n\n  res = get_pct_cumulative(h, percentile);\n\n  pthread_rwlock_unlock(&h->lock);\n\n  return res;\n}\n\n\ndouble sb_histogram_get_pct_checkpoint(sb_histogram_t *h,\n                                       double percentile)\n{\n  double   res;\n\n  /*\n    This can be called concurrently with other sb_histogram_get_pct_*()\n    functions, so use the lock to protect shared structures. This will not block\n    sb_histogram_update() calls, but we make sure we don't lose any concurrent\n    increments by atomically fetching each array element and replacing it with\n    0.\n  */\n  pthread_rwlock_wrlock(&h->lock);\n\n  merge_intermediate_into_cumulative(h);\n\n  res = get_pct_cumulative(h, percentile);\n\n  /* Reset the cumulative array */\n  memset(h->cumulative_array, 0, h->array_size * sizeof(uint64_t));\n  h->cumulative_nevents = 0;\n\n  pthread_rwlock_unlock(&h->lock);\n\n  return res;\n}\n\n\nvoid sb_histogram_print(sb_histogram_t *h)\n{\n  uint64_t maxcnt;\n  int      width;\n  size_t   i;\n\n  pthread_rwlock_wrlock(&h->lock);\n\n  merge_intermediate_into_cumulative(h);\n\n  uint64_t * const array = h->cumulative_array;\n\n  maxcnt = 0;\n  for (i = 0; i < h->array_size; i++)\n  {\n    if (array[i] > maxcnt)\n      maxcnt = array[i];\n  }\n\n  if (maxcnt == 0)\n    return;\n\n  printf(\"       value  ------------- distribution ------------- count\\n\");\n\n  for (i = 0; i < h->array_size; i++)\n  {\n    if (array[i] == 0)\n      continue;\n\n    width = floor(array[i] * (double) 40 / maxcnt + 0.5);\n\n    printf(\"%12.3f |%-40.*s %lu\\n\",\n           exp(i / h->range_mult + h->range_deduct),          /* value */\n           width, \"****************************************\", /* distribution */\n           (unsigned long) array[i]);                /* count */\n  }\n\n  pthread_rwlock_unlock(&h->lock);\n}\n\n\nvoid sb_histogram_done(sb_histogram_t *h)\n{\n  pthread_rwlock_destroy(&h->lock);\n\n  free(h->cumulative_array);\n  free(h->interm_slots);\n}\n\n/*\n  Allocate a new histogram and initialize it with sb_histogram_init().\n*/\n\nsb_histogram_t *sb_histogram_new(size_t size, double range_min,\n                                 double range_max)\n{\n  sb_histogram_t *h;\n\n  if ((h = malloc(sizeof(*h))) == NULL)\n    return NULL;\n\n  if (sb_histogram_init(h, size, range_min, range_max))\n  {\n    free(h);\n    return NULL;\n  }\n\n  return h;\n}\n\n/*\n  Deallocate a histogram allocated with sb_histogram_new().\n*/\n\nvoid sb_histogram_delete(sb_histogram_t *h)\n{\n  sb_histogram_done(h);\n  free(h);\n}\n"
  },
  {
    "path": "src/sb_histogram.h",
    "content": "/* Copyright (C) 2011-2017 Alexey Kopytov.\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_HISTOGRAM_H\n#define SB_HISTOGRAM_H\n\n#include <stdint.h>\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\ntypedef struct {\n  /*\n     Cumulative histogram array. Updated 'on demand' by\n     sb_histogram_get_pct_intermediate(). Protected by 'lock'.\n  */\n  uint64_t              *cumulative_array;\n  /*\n     Total number of events in cumulative_array. Updated on demand by\n     sb_histogram_get_pct_intermediate(). Protected by 'lock'.\n  */\n  uint64_t              cumulative_nevents;\n  /*\n    Temporary array for intermediate percentile calculations. Protected by\n    'lock'.\n  */\n  uint64_t              *temp_array;\n  /*\n     Intermediate histogram values are split into multiple slots and updated\n     with atomics. Aggregations into cumulative values is performed by\n     sb_histogram_get_pct_intermediate() function.\n  */\n  uint64_t              **interm_slots;\n  /* Number of elements in each array */\n  size_t                array_size;\n  /* Lower bound of values to track */\n  double                range_min;\n  /* Upper bound of values to track */\n  double                range_max;\n  /* Value to deduct to calculate histogram range based on array element */\n  double                range_deduct;\n  /* Value to multiply to calculate histogram range based array element */\n  double                range_mult;\n  /*\n     rwlock to protect cumulative_array and cumulative_nevents from concurrent\n     updates.\n  */\n  pthread_rwlock_t      lock;\n} sb_histogram_t;\n\n/* Global latency histogram */\nextern sb_histogram_t sb_latency_histogram;\n\n/*\n  Allocate a new histogram and initialize it with sb_histogram_init().\n*/\nsb_histogram_t *sb_histogram_new(size_t size, double range_min,\n                                 double range_max);\n\n/*\n  Deallocate a histogram allocated with sb_histogram_new().\n*/\nvoid sb_histogram_delete(sb_histogram_t *h);\n\n/*\n  Initialize a new histogram object with a given array size and value bounds.\n*/\nint sb_histogram_init(sb_histogram_t *h, size_t size,\n                      double range_min, double range_max);\n\n/* Update histogram with a given value. */\nvoid sb_histogram_update(sb_histogram_t *h, double value);\n\n/*\n  Calculate a given percentile value from the intermediate histogram values,\n  then merge intermediate values into cumulative ones atomically, i.e. in a way\n  that no concurrent updates are lost and will be accounted in either the\n  current or later merge of intermediate clues.\n*/\ndouble sb_histogram_get_pct_intermediate(sb_histogram_t *h, double percentile);\n\n/*\n  Merge intermediate histogram values into cumulative ones and calculate a given\n  percentile value from the cumulative array.\n*/\ndouble sb_histogram_get_pct_cumulative(sb_histogram_t *h, double percentile);\n\n/*\n   Similar to sb_histogram_get_pct_cumulative(), but also resets cumulative\n   stats right after calculating the returned percentile. The reset happens\n   atomically so that no conucrrent updates are lost after percentile\n   calculation. This is currently used only by 'checkpoint' reports.\n*/\ndouble sb_histogram_get_pct_checkpoint(sb_histogram_t *h, double percentile);\n\n/*\n  Print a given histogram to stdout\n*/\nvoid sb_histogram_print(sb_histogram_t *h);\n\n/* Destroy a given histogram object */\nvoid sb_histogram_done(sb_histogram_t *h);\n\n#endif\n"
  },
  {
    "path": "src/sb_list.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2014 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_LIST_H\n\n#define SB_LIST_H\n\ntypedef struct sb_list_item_t\n{\n    struct sb_list_item_t *next_p;\n    struct sb_list_item_t *prev_p;\n}\nsb_list_item_t;\n\ntypedef sb_list_item_t sb_list_item;\ntypedef sb_list_item_t sb_list_t ;\n\n#ifndef offsetof\n# define offsetof(type, member) ((size_t) &((type *)0)->member)\n#endif\n\n#define SB_LIST_DECLARE(name) \\\n    SB_LIST_T name = { &(name), &(name) }\n\n#define SB_LIST_INIT(head_p) \\\n    do { \\\n        (head_p)->next_p = (head_p); \\\n        (head_p)->prev_p = (head_p); \\\n    } while (0)\n\n#define SB_LIST_ITEM_INIT(item_p) \\\n    SB_LIST_INIT(item_p)\n\n#define SB_LIST_ADD(item_p, head_p) \\\n    do { \\\n        (item_p)->next_p = (head_p)->next_p; \\\n        (item_p)->prev_p = (head_p); \\\n        (head_p)->next_p = (item_p); \\\n        (item_p)->next_p->prev_p = (item_p); \\\n    } while (0)\n\n#define SB_LIST_ADD_TAIL(item_p, head_p) \\\n    do { \\\n        (item_p)->prev_p = (head_p)->prev_p; \\\n        (item_p)->next_p = (head_p); \\\n        (head_p)->prev_p = (item_p); \\\n        (item_p)->prev_p->next_p = (item_p); \\\n    } while (0);\n\n#define SB_LIST_DELETE(old_item_p) \\\n    do { \\\n        (old_item_p)->next_p->prev_p = (old_item_p)->prev_p; \\\n        (old_item_p)->prev_p->next_p = (old_item_p)->next_p; \\\n    } while (0)\n\n#define SB_LIST_REPLACE(item_p, old_item_p) \\\n    do { \\\n        (item_p)->next_p = (old_item_p)->next_p; \\\n        (item_p)->prev_p = (old_item_p)->prev_p; \\\n        (item_p)->next_p->prev_p = (item_p); \\\n        (item_p)->prev_p->next_p = (item_p); \\\n    } while (0)\n\n#define SB_LIST_IS_EMPTY(head_p) \\\n    ((head_p)->next_p == (head_p))\n\n#define SB_LIST_ITEM_IN_LIST(item_p) \\\n    ((item_p)->next_p != (item_p))\n\n#define SB_LIST_ITEM_FIRST(item_p, head_p) \\\n  ((item_p)->prev_p != (head_p))\n\n#define SB_LIST_ITEM_LAST(item_p, head_p) \\\n  ((item_p)->next_p == (head_p))\n\n#define SB_LIST_ITEM_NEXT(item_p) \\\n  ((item_p)->next_p)\n\n#define SB_LIST_ITEM_PREV(item_p)               \\\n  ((item_p)->prev_p)\n    \n#define SB_LIST_ENTRY(ptr, type, member)            \\\n    ((type *)(void *)(((char *)(ptr) - offsetof(type, member))))\n\n#define SB_LIST_ONCE(pos_p, head_p) \\\n    pos_p= (head_p)->next_p; if (pos_p != (head_p))\n\n#define SB_LIST_FOR_EACH(pos_p, head_p) \\\n  for (pos_p = (head_p)->next_p; pos_p != (head_p); pos_p = pos_p->next_p)\n\n#define SB_LIST_ENUM_START(head_p) \\\n  (head_p)\n\n#define SB_LIST_ENUM_NEXT(pos_p, head_p)                         \\\n  ((pos_p->next_p != (head_p)) ? (pos_p->next_p) : NULL)\n\n#define SB_LIST_FOR_EACH_SAFE(pos_p, temp_p, head_p) \\\n    for (pos_p = (head_p)->next_p, temp_p = (pos_p)->next_p; pos_p != (head_p); \\\n        pos_p = temp_p, temp_p = (pos_p)->next_p)\n\n#define SB_LIST_FOR_EACH_REV_SAFE(pos_p, temp_p, head_p) \\\n    for (pos_p = (head_p)->prev_p, temp_p = (pos_p)->prev_p; pos_p != (head_p); \\\n        pos_p = temp_p, temp_p = (pos_p)->prev_p)\n\n#endif /* SB_LIST_H */\n"
  },
  {
    "path": "src/sb_logger.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n# include <stdarg.h>\n# include <string.h>\n#endif\n#ifdef HAVE_ERRNO_H\n# include <errno.h>\n#endif\n#ifdef HAVE_MATH_H\n# include <math.h>\n#endif\n\n#include \"sysbench.h\"\n#include \"sb_list.h\"\n#include \"sb_logger.h\"\n#include \"sb_histogram.h\"\n\n#include \"ck_cc.h\"\n\n#define TEXT_BUFFER_SIZE 4096\n#define ERROR_BUFFER_SIZE 256\n\n/*\n   Use 1024-element array for latency histogram tracking values between 0.001\n   milliseconds and 100 seconds.\n*/\n#define OPER_LOG_GRANULARITY 1024\n#define OPER_LOG_MIN_VALUE   1e-3\n#define OPER_LOG_MAX_VALUE   1E5\n\n/* Array of message handlers (one chain per message type) */\n\nstatic sb_list_t handlers[LOG_MSG_TYPE_MAX];\n\n/* set after logger initialization */\nstatic unsigned char initialized; \n\nstatic pthread_mutex_t text_mutex;\nstatic unsigned int    text_cnt;\nstatic char            text_buf[TEXT_BUFFER_SIZE];\n\n\nstatic int text_handler_init(void);\nstatic int text_handler_process(log_msg_t *msg);\n\nstatic int oper_handler_init(void);\nstatic int oper_handler_done(void);\n\n/* Built-in log handlers */\n\n/* Text messages handler */\n\nstatic sb_arg_t text_handler_args[] =\n{\n  SB_OPT(\"verbosity\", \"verbosity level {5 - debug, 0 - only critical messages}\",\n         \"3\", INT),\n\n  SB_OPT_END\n};\n\nstatic log_handler_t text_handler = {\n  {\n    &text_handler_init,\n    &text_handler_process,\n    NULL,\n  },\n  text_handler_args,\n  {0,0}\n};\n\n/* Operation start/stop messages handler */\n\nstatic sb_arg_t oper_handler_args[] =\n{\n  SB_OPT(\"percentile\", \"percentile to calculate in latency statistics (1-100). \"\n         \"Use the special value of 0 to disable percentile calculations\",\n         \"95\", INT),\n  SB_OPT(\"histogram\", \"print latency histogram in report\", \"off\", BOOL),\n\n  SB_OPT_END\n};\n\nstatic log_handler_t oper_handler = {\n  {\n    oper_handler_init,\n    NULL,\n    oper_handler_done,\n  },\n  oper_handler_args,\n  {0,0}\n};\n\n\n/* Register logger and all handlers */\n\n\nint log_register(void)\n{\n  unsigned int i;\n\n  for (i = 0; i < LOG_MSG_TYPE_MAX; i++)\n    SB_LIST_INIT(handlers + i);\n\n  log_add_handler(LOG_MSG_TYPE_TEXT, &text_handler);\n  log_add_handler(LOG_MSG_TYPE_OPER, &oper_handler);\n\n  return 0;\n}\n\n\n/* Display command line options for registered log handlers */\n\n\nvoid log_print_help(void)\n{\n  unsigned int    i;\n  sb_list_item_t  *pos;\n  log_handler_t   *handler;\n\n  printf(\"Log options:\\n\");\n\n  for (i = 0; i < LOG_MSG_TYPE_MAX; i++)\n  {\n    SB_LIST_FOR_EACH(pos, handlers + i)\n    {\n      handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);\n      if (handler->args != NULL)\n\tsb_print_options(handler->args);\n    }\n  }\n}\n\n\n/* Initialize logger and all handlers */\n\n\nint log_init(void)\n{\n  unsigned int    i;\n  sb_list_item_t  *pos;\n  log_handler_t   *handler;\n\n  for (i = 0; i < LOG_MSG_TYPE_MAX; i++)\n  {\n    SB_LIST_FOR_EACH(pos, handlers + i)\n    {\n      handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);\n      if (handler->ops.init != NULL && handler->ops.init())\n        return 1;\n    }\n  }\n\n  /* required to let log_text() pass messages to handlers */\n  initialized = 1; \n  \n  return 0;\n}\n\n\n/* Uninitialize logger and all handlers */\n\n\nvoid log_done(void)\n{\n  unsigned int    i;\n  sb_list_item_t  *pos;\n  log_handler_t   *handler;\n\n  for (i = 0; i < LOG_MSG_TYPE_MAX; i++)\n  {\n    SB_LIST_FOR_EACH(pos, handlers + i)\n    {\n      handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);\n      if (handler->ops.done != NULL)\n        handler->ops.done();\n    }\n  }\n\n  initialized = 0;\n}  \n\n\n/* Add handler for a specified type of messages */\n\n\nint log_add_handler(log_msg_type_t type, log_handler_t *handler)\n{\n  if (type <= LOG_MSG_TYPE_MIN || type >= LOG_MSG_TYPE_MAX)\n    return 1;\n\n  if (handler->args != NULL)\n    sb_register_arg_set(handler->args);\n  \n  SB_LIST_ADD_TAIL(&handler->listitem, handlers + type);\n\n  return 0;\n}\n\n\n/* Main function to dispatch log messages */\n\n\nvoid log_msg(log_msg_t *msg)\n{\n  sb_list_item_t  *pos;\n  log_handler_t   *handler;\n  \n  SB_LIST_FOR_EACH(pos, handlers + msg->type)\n  {\n    handler = SB_LIST_ENTRY(pos, log_handler_t, listitem);\n    if (handler->ops.process != NULL)\n      handler->ops.process(msg);\n  }\n}\n\nstatic const char *get_msg_prefix(log_msg_priority_t priority)\n{\n  const char * prefix;\n\n  switch (priority) {\n    case LOG_FATAL:\n      prefix = \"FATAL: \";\n      break;\n    case LOG_ALERT:\n      prefix = \"ALERT: \";\n      break;\n    case LOG_WARNING:\n      prefix = \"WARNING: \";\n      break;\n    case LOG_DEBUG:\n      prefix = \"DEBUG: \";\n      break;\n    default:\n      prefix = \"\";\n      break;\n  }\n\n  return prefix;\n}\n\n/* printf-like wrapper to log text messages */\n\n\nvoid log_text(log_msg_priority_t priority, const char *fmt, ...)\n{\n  log_msg_t      msg;\n  log_msg_text_t text_msg;\n  char           buf[TEXT_BUFFER_SIZE];\n  va_list        ap;\n  int            n, clen, maxlen;\n\n  maxlen = TEXT_BUFFER_SIZE;\n  clen = 0;\n\n  va_start(ap, fmt);\n  n = vsnprintf(buf + clen, maxlen, fmt, ap);\n  va_end(ap);\n  if (n < 0 || n >= maxlen)\n    n = maxlen;\n  clen += n;\n  maxlen -= n;\n  snprintf(buf + clen, maxlen, \"\\n\");\n\n  /*\n    No race condition here because log_init() is supposed to be called\n    in a single-threaded stage\n  */\n  if (!initialized)\n  {\n    printf(\"%s%s\", get_msg_prefix(priority), buf);\n\n    return;\n  }\n\n  msg.type = LOG_MSG_TYPE_TEXT;\n  msg.data = (void *)&text_msg;\n  text_msg.priority = priority;\n  text_msg.text = buf;\n  text_msg.flags = 0;\n\n  log_msg(&msg);\n}\n\n\n/*\n  variant of log_text() which prepends log lines with the elapsed time of a\n  specified timer.\n*/\n\n\nvoid log_timestamp(log_msg_priority_t priority, double seconds,\n                   const char *fmt, ...)\n{\n  log_msg_t      msg;\n  log_msg_text_t text_msg;\n  char           buf[TEXT_BUFFER_SIZE];\n  va_list        ap;\n  int            n, clen, maxlen;\n\n  maxlen = TEXT_BUFFER_SIZE;\n  clen = 0;\n\n  n = snprintf(buf, maxlen, \"[ %.0fs ] \", seconds);\n  clen += n;\n  maxlen -= n;\n\n  va_start(ap, fmt);\n  n = vsnprintf(buf + clen, maxlen, fmt, ap);\n  va_end(ap);\n  if (n < 0 || n >= maxlen)\n    n = maxlen;\n  clen += n;\n  maxlen -= n;\n  snprintf(buf + clen, maxlen, \"\\n\");\n\n  /*\n    No race condition here because log_init() is supposed to be called\n    in a single-threaded stage\n  */\n  if (!initialized)\n  {\n    printf(\"%s%s\", get_msg_prefix(priority), buf);\n\n    return;\n  }\n\n  msg.type = LOG_MSG_TYPE_TEXT;\n  msg.data = (void *)&text_msg;\n  text_msg.priority = priority;\n  text_msg.text = buf;\n  /* Skip duplicate checks */\n  text_msg.flags = LOG_MSG_TEXT_ALLOW_DUPLICATES;\n\n  log_msg(&msg);\n}\n\n\n/* printf-like wrapper to log system error messages */\n\n\nvoid log_errno(log_msg_priority_t priority, const char *fmt, ...)\n{\n  char           buf[TEXT_BUFFER_SIZE];\n  char           errbuf[ERROR_BUFFER_SIZE];\n  va_list        ap;\n  int            n;\n  int            old_errno;\n  char           *tmp;\n\n  old_errno = errno;\n#ifdef HAVE_STRERROR_R\n#ifdef STRERROR_R_CHAR_P\n  tmp = strerror_r(old_errno, errbuf, sizeof(errbuf));\n#else\n  strerror_r(old_errno, errbuf, sizeof(errbuf));\n  tmp = errbuf;\n#endif /* STRERROR_R_CHAR_P */\n#else /* !HAVE_STRERROR_P */\n  strncpy(errbuf, strerror(old_errno), sizeof(errbuf));\n  tmp = errbuf;\n#endif /* HAVE_STRERROR_P */\n\n  va_start(ap, fmt);\n  n = vsnprintf(buf, TEXT_BUFFER_SIZE, fmt, ap);\n  va_end(ap);\n  if (n < 0 || n == TEXT_BUFFER_SIZE)\n    return;\n  snprintf(buf + n, TEXT_BUFFER_SIZE - n, \" errno = %d (%s)\", old_errno,\n           tmp);\n\n  log_text(priority, \"%s\", buf);\n}\n\n\n\n/* Initialize text handler */\n\n\nint text_handler_init(void)\n{\n#ifdef HAVE_SETVBUF\n  /* Set stdout to unbuffered mode */\n  setvbuf(stdout, NULL, _IONBF, 0);\n#endif\n  \n  sb_globals.verbosity = sb_get_value_int(\"verbosity\");\n\n  if (sb_globals.verbosity > LOG_DEBUG)\n  {\n    printf(\"Invalid value for verbosity: %d\\n\", sb_globals.verbosity);\n    return 1;\n  }\n\n  pthread_mutex_init(&text_mutex, NULL);\n  text_cnt = 0;\n  text_buf[0] = '\\0';\n  \n  return 0;\n}\n\n\n/* Print text message to the log */\n\n\nint text_handler_process(log_msg_t *msg)\n{\n  log_msg_text_t *text_msg = (log_msg_text_t *)msg->data;\n\n  if (text_msg->priority > sb_globals.verbosity)\n    return 0;\n\n  if (!(text_msg->flags & LOG_MSG_TEXT_ALLOW_DUPLICATES))\n  {\n    pthread_mutex_lock(&text_mutex);\n    if (!strcmp(text_buf, text_msg->text))\n    {\n      text_cnt++;\n      pthread_mutex_unlock(&text_mutex);\n\n      return 0;\n    }\n    else\n    {\n      if (text_cnt > 0)\n        printf(\"(last message repeated %u times)\\n\", text_cnt);\n\n      text_cnt = 0;\n      strncpy(text_buf, text_msg->text, TEXT_BUFFER_SIZE);\n    }\n    pthread_mutex_unlock(&text_mutex);\n  }\n\n  printf(\"%s%s\", get_msg_prefix(text_msg->priority), text_msg->text);\n\n  return 0;\n}\n\n\n/* Initialize operation messages handler */\n\n\nint oper_handler_init(void)\n{\n  int          tmp;\n\n  tmp = sb_get_value_int(\"percentile\");\n  if (tmp < 0 || tmp > 100)\n  {\n    log_text(LOG_FATAL, \"Invalid value for --percentile: %d\",\n             tmp);\n    return 1;\n  }\n  sb_globals.percentile = tmp;\n\n  sb_globals.histogram = sb_get_value_flag(\"histogram\");\n  if (sb_globals.percentile == 0 && sb_globals.histogram != 0)\n  {\n    log_text(LOG_FATAL, \"--histogram cannot be used with --percentile=0\");\n    return 1;\n  }\n\n  if (sb_histogram_init(&sb_latency_histogram, OPER_LOG_GRANULARITY,\n                        OPER_LOG_MIN_VALUE, OPER_LOG_MAX_VALUE))\n    return 1;\n\n  return 0;\n}\n\n\n/* Uninitialize operations messages handler */\n\nint oper_handler_done(void)\n{\n  sb_histogram_done(&sb_latency_histogram);\n\n  return 0;\n}\n"
  },
  {
    "path": "src/sb_logger.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2016 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_LOGGER_H\n#define SB_LOGGER_H\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n#include \"sb_util.h\"\n#include \"sb_options.h\"\n#include \"sb_timer.h\"\n#include \"sb_histogram.h\"\n\n/* Text message flags (used in the 'flags' field of log_text_msg_t) */\n\n#define LOG_MSG_TEXT_ALLOW_DUPLICATES 1\n\n/* Message types definition */\n\ntypedef enum {\n  LOG_MSG_TYPE_MIN,           /* used for internal purposes */\n  LOG_MSG_TYPE_TEXT,          /* arbitrary text messages */\n  LOG_MSG_TYPE_OPER,          /* operation start/stop messages */\n  LOG_MSG_TYPE_MAX            /* used for internal purposes */\n} log_msg_type_t;\n\n/* Message priorities definition */\n\ntypedef enum {\n  LOG_FATAL,     /* system is unusable */\n  LOG_ALERT,     /* user actions must be taken */\n  LOG_WARNING,   /* warnings */\n  LOG_NOTICE,    /* normal but significant messages */\n  LOG_INFO,      /* informational messages */   \n  LOG_DEBUG,     /* debug-level messages */\n  LOG_MAX        /* used for internal purposes */\n} log_msg_priority_t;\n\n/* Text message definition */\n\ntypedef struct {\n  log_msg_priority_t priority;\n  char               *text;\n  unsigned int       flags;\n} log_msg_text_t;\n\n/* Operation start/stop message definition */\n\ntypedef enum {\n  LOG_MSG_OPER_START,\n  LOG_MSG_OPER_STOP\n} log_msg_oper_action_t;\n\ntypedef struct {\n  log_msg_oper_action_t action;\n  int                   thread_id;\n} log_msg_oper_t;\n\n/* General log message definition */\n\ntypedef struct {\n  log_msg_type_t type;\n  void           *data;\n} log_msg_t;\n\n/* Log handler operations definition */\n\ntypedef int log_op_register(void);          /* register handler options */\ntypedef int log_op_init(void);              /* initialize log handler */\ntypedef int log_op_process(log_msg_t *msg); /* process message */\ntypedef int log_op_done(void);              /* uninitialize log handler */\n\n/* Log handler operations structure */\n\ntypedef struct {\n  log_op_init     *init;\n  log_op_process  *process;\n  log_op_done     *done;\n} log_handler_ops_t;\n\n/* Log handler definition */\n\ntypedef struct {\n  log_handler_ops_t ops;          /* handler operations */\n  sb_arg_t             *args;     /* handler arguments */\n  sb_list_item_t       listitem;  /* can be linked in a list */\n} log_handler_t;\n\n/* Register logger */\n\nint log_register(void);\n\n/* Display command line options for all register log handlers */\n\nvoid log_print_help(void);\n\n/* Initialize logger */\n\nint log_init(void);\n\n/* Add handler for a specified type of messages */\n\nint log_add_handler(log_msg_type_t type, log_handler_t *handler);\n\n/* Main function to dispatch log messages */\n\nvoid log_msg(log_msg_t *);\n\n/* printf-like wrapper to log text messages */\n\nvoid log_text(log_msg_priority_t priority, const char *fmt, ...)\n  SB_ATTRIBUTE_FORMAT(printf, 2, 3);\n\n/*\n  variant of log_text() which prepends log lines with a elapsed time of the\n  specified timer.\n*/\n\nvoid log_timestamp(log_msg_priority_t priority, double seconds,\n                   const char *fmt, ...)\n  SB_ATTRIBUTE_FORMAT(printf, 3, 4);\n\n/* printf-like wrapper to log system error messages */\n\nvoid log_errno(log_msg_priority_t priority, const char *fmt, ...)\n  SB_ATTRIBUTE_FORMAT(printf, 2, 3);\n\n/* Uninitialize logger */\n\nvoid log_done(void);\n\n#endif /* SB_LOGGER_H */\n"
  },
  {
    "path": "src/sb_lua.c",
    "content": "/* Copyright (C) 2006 MySQL AB\n   Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_LIBGEN_H\n# include <libgen.h>\n#endif\n\n#include \"sb_lua.h\"\n#include \"lua.h\"\n#include \"lualib.h\"\n#include \"lauxlib.h\"\n\n#define SB_LUA_EXPORT\n#include \"sb_counter.h\"\n#undef SB_LUA_EXPORT\n\n#include \"db_driver.h\"\n#include \"sb_rand.h\"\n#include \"sb_thread.h\"\n\n#include \"sb_ck_pr.h\"\n\n/*\n  Auto-generated headers for internal scripts. If you add a new header here,\n  make sure it is also added to the internal_scripts array below.\n*/\n#include \"lua/internal/sysbench.lua.h\"\n#include \"lua/internal/sysbench.cmdline.lua.h\"\n#include \"lua/internal/sysbench.rand.lua.h\"\n#include \"lua/internal/sysbench.sql.lua.h\"\n#include \"lua/internal/sysbench.histogram.lua.h\"\n\n#define EVENT_FUNC \"event\"\n#define PREPARE_FUNC \"prepare\"\n#define CLEANUP_FUNC \"cleanup\"\n#define HELP_FUNC \"help\"\n#define THREAD_INIT_FUNC \"thread_init\"\n#define THREAD_DONE_FUNC \"thread_done\"\n#define THREAD_RUN_FUNC \"thread_run\"\n#define INIT_FUNC \"init\"\n#define DONE_FUNC \"done\"\n#define REPORT_INTERMEDIATE_HOOK \"report_intermediate\"\n#define REPORT_CUMULATIVE_HOOK \"report_cumulative\"\n\n#define xfree(ptr) ({ if ((ptr) != NULL) free((void *) ptr); ptr = NULL; })\n\n/* Interpreter context */\n\ntypedef struct {\n  db_conn_t *con;      /* Database connection */\n  db_driver_t *driver;\n  lua_State *L;\n} sb_lua_ctxt_t;\n\ntypedef struct {\n  int            id;\n  db_bind_type_t type;\n  void           *buf;\n  unsigned long  buflen;\n  char           is_null;\n} sb_lua_bind_t;\n\ntypedef struct {\n  const char *name;\n  const unsigned char *source;\n  /* Use a pointer, since _len variables are not compile-time constants */\n  size_t *source_len;\n} internal_script_t;\n\ntypedef enum {\n  SB_LUA_ERROR_NONE,\n  SB_LUA_ERROR_RESTART_EVENT\n} sb_lua_error_t;\n\nbool sb_lua_more_events(int);\nint sb_lua_set_test_args(sb_arg_t *, size_t);\n\n/* Lua interpreter states */\n\nstatic lua_State **states CK_CC_CACHELINE;\n\nstatic sb_test_t sbtest CK_CC_CACHELINE;\n\nstatic TLS sb_lua_ctxt_t tls_lua_ctxt CK_CC_CACHELINE;\n\n/* List of pre-loaded internal scripts */\nstatic internal_script_t internal_scripts[] = {\n  {\"sysbench.rand.lua\", sysbench_rand_lua, &sysbench_rand_lua_len},\n  {\"sysbench.lua\", sysbench_lua, &sysbench_lua_len},\n  {\"sysbench.cmdline.lua\", sysbench_cmdline_lua, &sysbench_cmdline_lua_len},\n  {\"sysbench.sql.lua\", sysbench_sql_lua, &sysbench_sql_lua_len},\n  {\"sysbench.histogram.lua\", sysbench_histogram_lua,\n   &sysbench_histogram_lua_len},\n  {NULL, NULL, 0}\n};\n\n/* Main (global) interpreter state */\nstatic lua_State *gstate;\n\n/* Custom command name */\nstatic const char * sb_lua_custom_command;\n\n/* Lua test operations */\n\nstatic int sb_lua_op_init(void);\nstatic int sb_lua_op_done(void);\nstatic int sb_lua_op_thread_init(int);\nstatic int sb_lua_op_thread_run(int);\nstatic int sb_lua_op_thread_done(int);\n\nstatic sb_operations_t lua_ops = {\n   .init = sb_lua_op_init,\n   .thread_init = sb_lua_op_thread_init,\n   .thread_done = sb_lua_op_thread_done,\n   .report_intermediate = db_report_intermediate,\n   .report_cumulative = db_report_cumulative,\n   .done = sb_lua_op_done\n};\n\n/* Lua test commands */\nstatic int sb_lua_cmd_prepare(void);\nstatic int sb_lua_cmd_cleanup(void);\nstatic int sb_lua_cmd_help(void);\n\n/* Initialize interpreter state */\nstatic lua_State *sb_lua_new_state(void);\n\n/* Close interpretet state */\nstatic int sb_lua_close_state(lua_State *);\n\nstatic int read_cmdline_options(lua_State *L);\nstatic bool sb_lua_hook_defined(lua_State *, const char *);\nstatic bool sb_lua_hook_push(lua_State *, const char *);\nstatic void sb_lua_report_intermediate(sb_stat_t *);\nstatic void sb_lua_report_cumulative(sb_stat_t *);\n\nstatic int sb_lua_do_jitcmd(lua_State *L, const char *cmd);\n\nstatic void call_error(lua_State *L, const char *name)\n{\n  const char * const err = lua_tostring(L, -1);\n  log_text(LOG_FATAL, \"`%s' function failed: %s\", name,\n           err ? err : \"(not a string)\");\n  lua_pop(L, 1);\n}\n\nstatic void report_error(lua_State *L)\n{\n  const char * const err = lua_tostring(L, -1);\n  log_text(LOG_FATAL, \"%s\", err ? err : \"(not a string)\");\n  lua_pop(L, 1);\n}\n\nstatic bool func_available(lua_State *L, const char *func)\n{\n  lua_getglobal(L, func);\n  bool rc = lua_isfunction(L, -1);\n  lua_pop(L, 1);\n\n  return rc;\n}\n\n/* Export command line options */\n\nstatic int do_export_options(lua_State *L, bool global)\n{\n  sb_list_item_t *pos;\n  option_t       *opt;\n  char           *tmp;\n\n  if (!global)\n  {\n    lua_getglobal(L, \"sysbench\");\n    lua_pushliteral(L, \"opt\");\n    lua_newtable(L);\n  }\n\n  pos = sb_options_enum_start();\n  while ((pos = sb_options_enum_next(pos, &opt)) != NULL)\n  {\n    /*\n      The only purpose of the following check if to keep compatibility with\n      legacy scripts where options were exported to the global namespace. In\n      which case name collisions with user-defined functions and variables might\n      occur. For example, the --help option might redefine the help() function.\n    */\n    if (global)\n    {\n      lua_getglobal(L, opt->name);\n      if (lua_isfunction(L, -1))\n      {\n        lua_pop(L, 1);\n        continue;\n      }\n      lua_pop(L, 1);\n    }\n    else\n    {\n      lua_pushstring(L, opt->name);\n    }\n\n    switch (opt->type)\n    {\n      case SB_ARG_TYPE_BOOL:\n        lua_pushboolean(L, sb_opt_to_flag(opt));\n        break;\n      case SB_ARG_TYPE_INT:\n        lua_pushnumber(L, sb_opt_to_int(opt));\n        break;\n      case SB_ARG_TYPE_DOUBLE:\n        lua_pushnumber(L, sb_opt_to_double(opt));\n        break;\n      case SB_ARG_TYPE_SIZE:\n        lua_pushnumber(L, sb_opt_to_size(opt));\n        break;\n      case SB_ARG_TYPE_STRING:\n        tmp = sb_opt_to_string(opt);\n        lua_pushstring(L, tmp ? tmp : \"\");\n        break;\n      case SB_ARG_TYPE_LIST:\n        lua_newtable(L);\n\n        sb_list_item_t *val;\n        int count = 1;\n\n        SB_LIST_FOR_EACH(val, sb_opt_to_list(opt))\n        {\n          lua_pushstring(L, SB_LIST_ENTRY(val, value_t, listitem)->data);\n          lua_rawseti(L, -2, count++);\n        }\n\n        break;\n      case SB_ARG_TYPE_FILE:\n        /* no need to export anything */\n        lua_pushnil(L);\n        break;\n      default:\n        log_text(LOG_WARNING, \"Global option '%s' will not be exported, because\"\n                 \" the type is unknown\", opt->name);\n        lua_pushnil(L);\n        break;\n    }\n\n    /* set var = value */\n    if (global)\n      lua_setglobal(L, opt->name);\n    else\n      lua_settable(L, -3);\n  }\n\n  if (!global)\n    lua_settable(L, -3); /* set sysbench.opt */\n\n  return 0;\n}\n\n/*\n  Export option values to the 'sysbench.opt' table.\n*/\n\nstatic int export_options(lua_State *L)\n{\n  if (do_export_options(L, false))\n    return 1;\n\n  return 0;\n}\n\n/* Load a specified Lua script */\n\nsb_test_t *sb_load_lua(const char *testname)\n{\n  if (testname != NULL)\n  {\n    char *tmp = strdup(testname);\n    sbtest.sname = strdup(basename(tmp));\n    sbtest.lname = tmp;\n  }\n  else\n  {\n    sbtest.sname = strdup(\"<stdin>\");\n    sbtest.lname = NULL;\n  }\n\n  /* Initialize global interpreter state */\n  gstate = sb_lua_new_state();\n  if (gstate == NULL)\n    goto error;\n\n  if (read_cmdline_options(gstate))\n    goto error;\n\n  /* Test commands */\n  if (func_available(gstate, PREPARE_FUNC))\n    sbtest.builtin_cmds.prepare = &sb_lua_cmd_prepare;\n\n  if (func_available(gstate, CLEANUP_FUNC))\n    sbtest.builtin_cmds.cleanup = &sb_lua_cmd_cleanup;\n\n  if (func_available(gstate, HELP_FUNC))\n    sbtest.builtin_cmds.help = &sb_lua_cmd_help;\n\n  /* Test operations */\n  sbtest.ops = lua_ops;\n\n  if (func_available(gstate, THREAD_RUN_FUNC))\n    sbtest.ops.thread_run = &sb_lua_op_thread_run;\n\n  if (sb_lua_hook_defined(gstate, REPORT_INTERMEDIATE_HOOK))\n    sbtest.ops.report_intermediate = sb_lua_report_intermediate;\n\n  if (sb_lua_hook_defined(gstate, REPORT_CUMULATIVE_HOOK))\n    sbtest.ops.report_cumulative = sb_lua_report_cumulative;\n\n  /* Allocate per-thread interpreters array */\n  states = (lua_State **)calloc(sb_globals.threads, sizeof(lua_State *));\n  if (states == NULL)\n    goto error;\n\n  return &sbtest;\n\n error:\n\n  sb_lua_done();\n\n  return NULL;\n}\n\n\nvoid sb_lua_done(void)\n{\n  sb_lua_close_state(gstate);\n  gstate = NULL;\n\n  xfree(states);\n\n  if (sbtest.args != NULL)\n  {\n    for (size_t i = 0; sbtest.args[i].name != NULL; i++)\n    {\n      xfree(sbtest.args[i].name);\n      xfree(sbtest.args[i].desc);\n      xfree(sbtest.args[i].value);\n    }\n\n    xfree(sbtest.args);\n  }\n\n  xfree(sbtest.sname);\n  xfree(sbtest.lname);\n}\n\n\n/* Initialize Lua script */\n\nint sb_lua_op_init(void)\n{\n  if (export_options(gstate))\n      return 1;\n\n  lua_getglobal(gstate, INIT_FUNC);\n  if (!lua_isnil(gstate, -1))\n  {\n    if (lua_pcall(gstate, 0, 0, 0))\n    {\n      call_error(gstate, INIT_FUNC);\n      return 1;\n    }\n  }\n\n  if (!func_available(gstate, EVENT_FUNC))\n  {\n    log_text(LOG_FATAL, \"cannot find the event() function in %s\",\n             sbtest.sname);\n    return 1;\n  }\n\n  return 0;\n}\n\nint sb_lua_op_thread_init(int thread_id)\n{\n  lua_State * L;\n\n  L = sb_lua_new_state();\n  if (L == NULL)\n    return 1;\n\n  states[thread_id] = L;\n\n  if (export_options(L))\n    return 1;\n\n  lua_getglobal(L, THREAD_INIT_FUNC);\n  if (!lua_isnil(L, -1))\n  {\n    lua_pushnumber(L, thread_id);\n\n    if (lua_pcall(L, 1, 1, 0))\n    {\n      call_error(L, THREAD_INIT_FUNC);\n      return 1;\n    }\n  }\n\n  return 0;\n}\n\nint sb_lua_op_thread_run(int thread_id)\n{\n  lua_State * const L = states[thread_id];\n\n  lua_getglobal(L, THREAD_RUN_FUNC);\n  lua_pushnumber(L, thread_id);\n\n  if (lua_pcall(L, 1, 1, 0))\n  {\n    call_error(L, THREAD_RUN_FUNC);\n    return 1;\n  }\n\n  return 0;\n}\n\nint sb_lua_op_thread_done(int thread_id)\n{\n  lua_State * const L = states[thread_id];\n  int rc = 0;\n\n  lua_getglobal(L, THREAD_DONE_FUNC);\n  if (!lua_isnil(L, -1))\n  {\n    lua_pushnumber(L, thread_id);\n\n    if (lua_pcall(L, 1, 1, 0))\n    {\n      call_error(L, THREAD_DONE_FUNC);\n      rc = 1;\n    }\n  }\n\n  sb_lua_close_state(L);\n\n  return rc;\n}\n\nint sb_lua_op_done(void)\n{\n  lua_getglobal(gstate, DONE_FUNC);\n  if (!lua_isnil(gstate, -1))\n  {\n    if (lua_pcall(gstate, 0, 0, 0))\n    {\n      call_error(gstate, DONE_FUNC);\n      return 1;\n    }\n  }\n\n  sb_lua_done();\n\n  return 0;\n}\n\n/* Pre-load internal scripts */\n\nstatic int load_internal_scripts(lua_State *L)\n{\n  for (internal_script_t *s = internal_scripts; s->name != NULL; s++)\n  {\n    if (luaL_loadbuffer(L, (const char *) s->source, s->source_len[0], s->name))\n    {\n      log_text(LOG_FATAL, \"failed to load internal module '%s': %s\",\n               s->name, lua_tostring(L, -1));\n      lua_pop(L, 1);\n      return 1;\n    }\n\n    lua_call(L, 0, 0);\n  }\n\n  return 0;\n}\n\nstatic void sb_lua_var_number(lua_State *L, const char *name, lua_Number n)\n{\n    lua_pushstring(L, name);\n    lua_pushnumber(L, n);\n    lua_settable(L, -3);\n}\n\nstatic void sb_lua_var_string(lua_State *L, const char *name, const char *s)\n{\n    lua_pushstring(L, name);\n    lua_pushstring(L, s);\n    lua_settable(L, -3);\n}\n\n/*\n  Set package.path and package.cpath in a given environment. Also honor\n  LUA_PATH/LUA_CPATH to mimic the default Lua behavior.\n*/\nstatic void sb_lua_set_paths(lua_State *L)\n{\n  lua_getglobal(L, \"package\");\n\n  int top = lua_gettop(L);\n\n  lua_pushliteral(L, \"./?.lua;\");\n  lua_pushliteral(L, \"./?/init.lua;\");\n  lua_pushliteral(L, \"./src/lua/?.lua;\");\n\n  const char *home = getenv(\"HOME\");\n  if (home != NULL)\n  {\n    lua_pushstring(L, home);\n    lua_pushliteral(L, \"/.luarocks/share/lua/5.1/?.lua;\");\n    lua_pushstring(L, home);\n    lua_pushliteral(L, \"/.luarocks/share/lua/5.1/?/init.lua;\");\n    lua_pushstring(L, home);\n    lua_pushliteral(L, \"/.luarocks/share/lua/?.lua;\");\n    lua_pushstring(L, home);\n    lua_pushliteral(L, \"/.luarocks/share/lua/?/init.lua;\");\n  }\n\n  lua_pushliteral(L, \"/usr/local/share/lua/5.1/?.lua;\");\n  lua_pushliteral(L, \"/usr/share/lua/5.1/?.lua;\");\n  lua_pushliteral(L, DATADIR \"/?.lua;\");\n\n  lua_concat(L, lua_gettop(L) - top);\n\n  /* Mimic the default Lua behavior with respect to LUA_PATH and ';;' */\n  const char *path = getenv(\"LUA_PATH\");\n  if (path != NULL)\n  {\n    const char *def = lua_tostring(L, -1);\n    path = luaL_gsub(L, path, \";;\", \";\\1;\");\n    luaL_gsub(L, path, \"\\1\", def);\n    lua_remove(L, -2);\n    lua_remove(L, -2);\n  }\n  lua_setfield(L, top, \"path\");\n\n  lua_pushliteral(L, \"./?\" DLEXT \";\");\n  if (home != NULL) {\n    lua_pushstring(L, home);\n    lua_pushliteral(L, \"/.luarocks/lib/lua/5.1/?\" DLEXT \";\");\n    lua_pushstring(L, home);\n    lua_pushliteral(L, \"/.luarocks/lib/lua/?\" DLEXT \";\");\n  }\n\n  lua_pushliteral(L, \"/usr/local/lib/lua/5.1/?\" DLEXT \";\");\n  lua_pushliteral(L, \"/usr/lib/lua/5.1/?\" DLEXT \";\");\n  lua_pushliteral(L, LIBDIR \";\");\n\n  lua_concat(L, lua_gettop(L) - top);\n\n  /* Mimic the default Lua behavior with respect to LUA_CPATH and ';;' */\n  path = getenv(\"LUA_CPATH\");\n  if (path != NULL)\n  {\n    const char *def = lua_tostring(L, -1);\n    path = luaL_gsub(L, path, \";;\", \";\\1;\");\n    luaL_gsub(L, path, \"\\1\", def);\n    lua_remove(L, -2);\n    lua_remove(L, -2);\n  }\n  lua_setfield(L, top, \"cpath\");\n\n  lua_pop(L, 1); /* package */\n}\n\n/* Create a deep copy of the 'args' array and store it in sbtest.args */\n\nint sb_lua_set_test_args(sb_arg_t *args, size_t len)\n{\n  sbtest.args = malloc((len + 1) * sizeof(sb_arg_t));\n\n  for (size_t i = 0; i < len; i++)\n  {\n    sbtest.args[i].name = strdup(args[i].name);\n    sbtest.args[i].desc = strdup(args[i].desc);\n    sbtest.args[i].type = args[i].type;\n\n    sbtest.args[i].value = args[i].value != NULL ? strdup(args[i].value) : NULL;\n    sbtest.args[i].validate = args[i].validate;\n  }\n\n  sbtest.args[len] = (sb_arg_t) {.name = NULL};\n\n  return 0;\n}\n\n/*\n  Parse command line options definitions, if present in the script as a\n  sysbench.cmdline.options table. If there was a parsing error, return 1. Return\n  0 on success.\n*/\n\nstatic int read_cmdline_options(lua_State *L)\n{\n  lua_getglobal(L, \"sysbench\");\n  lua_getfield(L, -1, \"cmdline\");\n  lua_getfield(L, -1, \"read_cmdline_options\");\n\n  if (!lua_isfunction(L, -1))\n  {\n    log_text(LOG_WARNING,\n             \"Cannot find sysbench.cmdline.read_cmdline_options()\");\n    lua_pop(L, 3);\n\n    return 1;\n  }\n\n  if (lua_pcall(L, 0, 1, 0) != 0)\n  {\n    call_error(L, \"sysbench.cmdline.read_cmdline_options\");\n    lua_pop(L, 2);\n    return 1;\n  }\n\n  int rc = lua_toboolean(L, -1) == 0;\n\n  lua_pop(L, 3);\n\n  return rc;\n}\n\n/* Allocate and initialize new interpreter state */\n\nstatic lua_State *sb_lua_new_state(void)\n{\n  lua_State      *L;\n\n  L = luaL_newstate();\n\n  luaL_openlibs(L);\n\n  if (sb_globals.luajit_cmd && sb_lua_do_jitcmd(L, sb_globals.luajit_cmd))\n    return NULL;\n\n  sb_lua_set_paths(L);\n\n  /* Export variables into per-state 'sysbench' table */\n\n  lua_newtable(L);\n\n  /* sysbench.tid */\n  sb_lua_var_number(L, \"tid\", sb_tls_thread_id);\n\n  lua_pushliteral(L, \"error\");\n  lua_newtable(L);\n\n  sb_lua_var_number(L, \"NONE\", SB_LUA_ERROR_NONE);\n  sb_lua_var_number(L, \"RESTART_EVENT\", SB_LUA_ERROR_RESTART_EVENT);\n\n  lua_settable(L, -3); /* sysbench.error */\n\n   /* sysbench.version */\n  sb_lua_var_string(L, \"version\", PACKAGE_VERSION);\n   /* sysbench.version_string */\n  sb_lua_var_string(L, \"version_string\",\n                    PACKAGE_NAME \" \" PACKAGE_VERSION SB_GIT_SHA);\n\n  lua_pushliteral(L, \"cmdline\");\n  lua_newtable(L);\n\n  lua_pushliteral(L, \"argv\");\n  lua_createtable(L, sb_globals.argc, 0);\n\n  for (int i = 0; i < sb_globals.argc; i++)\n  {\n    lua_pushstring(L, sb_globals.argv[i]);\n    lua_rawseti(L, -2, i);\n  }\n\n  lua_settable(L, -3); /* sysbench.cmdline.argv */\n\n  /* Export command name as sysbench.cmdline.command */\n  if (sb_globals.cmdname)\n  {\n    lua_pushliteral(L, \"command\");\n    lua_pushstring(L, sb_globals.cmdname);\n    lua_settable(L, -3);\n  }\n\n  /* Export script path as sysbench.cmdline.script_path */\n  sb_lua_var_string(L, \"script_path\", sbtest.lname);\n\n  lua_settable(L, -3); /* sysbench.cmdline */\n\n  lua_setglobal(L, \"sysbench\");\n\n  luaL_newmetatable(L, \"sysbench.stmt\");\n  luaL_newmetatable(L, \"sysbench.rs\");\n\n  if (load_internal_scripts(L))\n    return NULL;\n\n  int rc;\n\n  if ((rc = luaL_loadfile(L, sbtest.lname)) != 0)\n  {\n    if (rc != LUA_ERRFILE)\n      goto loaderr;\n\n    /* Try to handle the given string as a module name */\n    lua_getglobal(L, \"require\");\n    lua_pushstring(L, sbtest.lname);\n    if (lua_pcall(L, 1, 1, 0))\n    {\n      const char *msg = lua_tostring(L, -1);\n      if (msg && strncmp(msg, \"module \", 7))\n        goto loaderr;\n\n      log_text(LOG_FATAL, \"Cannot find benchmark '%s': no such built-in test, \"\n               \"file or module\", sbtest.lname);\n\n      return NULL;\n    }\n  }\n  else if (lua_pcall(L, 0, 0, 0))\n    goto loaderr;\n\n  /* Create new L context */\n  tls_lua_ctxt.L = L;\n\n  return L;\n\nloaderr:\n  report_error(L);\n\n  return NULL;\n}\n\n/* Close interpreter state */\n\nint sb_lua_close_state(lua_State *state)\n{\n  sb_lua_ctxt_t * const ctxt = &tls_lua_ctxt;\n\n  if (state != NULL)\n    lua_close(state);\n\n  if (ctxt != NULL)\n    ctxt->L = NULL;\n\n  return 0;\n}\n\n/* Execute a given command */\nstatic int execute_command(const char *cmd)\n{\n  if (export_options(gstate))\n    return 1;\n\n  lua_getglobal(gstate, cmd);\n\n  if (lua_pcall(gstate, 0, 1, 0) != 0)\n  {\n    call_error(gstate, cmd);\n    return 1;\n  }\n\n  lua_pop(gstate, 1);\n\n  return 0;\n}\n\n/* Prepare command */\n\nint sb_lua_cmd_prepare(void)\n{\n  return execute_command(PREPARE_FUNC);\n}\n\n/* Cleanup command */\n\nint sb_lua_cmd_cleanup(void)\n{\n  return execute_command(CLEANUP_FUNC);\n}\n\n/* Help command */\n\nint sb_lua_cmd_help(void)\n{\n  return execute_command(HELP_FUNC);\n}\n\n/* Check if a specified hook exists */\n\nstatic bool sb_lua_hook_defined(lua_State *L, const char *name)\n{\n  if (L == NULL)\n    return false;\n\n  lua_getglobal(L, \"sysbench\");\n  lua_getfield(L, -1, \"hooks\");\n  lua_getfield(L, -1, name);\n\n  bool rc = lua_isfunction(L, -1);\n\n  lua_pop(L, 3);\n\n  return rc;\n}\n\n/* Push a specified hook on stack */\n\nstatic bool sb_lua_hook_push(lua_State *L, const char *name)\n{\n  if (L == NULL)\n    return false;\n\n  lua_getglobal(L, \"sysbench\");\n  lua_getfield(L, -1, \"hooks\");\n  lua_getfield(L, -1, name);\n\n  if (!lua_isfunction(L, -1))\n  {\n    lua_pop(L, 3);\n    return false;\n  }\n\n  lua_remove(L, -2); /* hooks */\n  lua_remove(L, -2); /* sysbench */\n\n  return true;\n}\n\n\nbool sb_lua_loaded(void)\n{\n  return gstate != NULL;\n}\n\n/* Check if a specified custom command exists */\n\nbool sb_lua_custom_command_defined(const char *name)\n{\n  lua_State * const L = gstate;\n\n  lua_getglobal(L, \"sysbench\");\n  lua_getfield(L, -1, \"cmdline\");\n  lua_getfield(L, -1, \"command_defined\");\n\n  if (!lua_isfunction(L, -1))\n  {\n    log_text(LOG_WARNING,\n             \"Cannot find the sysbench.cmdline.command_defined function\");\n    lua_pop(L, 3);\n\n    return 1;\n  }\n\n  lua_pushstring(L, name);\n\n  if (lua_pcall(L, 1, 1, 0) != 0)\n  {\n    call_error(L, \"sysbench.cmdline.command_defined\");\n    lua_pop(L, 2);\n    return 1;\n  }\n\n  bool rc = lua_toboolean(L, -1);\n\n  lua_pop(L, 3);\n\n  return rc;\n}\n\n/* Check if a specified custom command supports parallel execution */\n\nstatic bool sb_lua_custom_command_parallel(const char *name)\n{\n  lua_State * const L = gstate;\n\n  lua_getglobal(L, \"sysbench\");\n  lua_getfield(L, -1, \"cmdline\");\n  lua_getfield(L, -1, \"command_parallel\");\n\n  if (!lua_isfunction(L, -1))\n  {\n    log_text(LOG_WARNING,\n             \"Cannot find the sysbench.cmdline.command_parallel function\");\n    lua_pop(L, 3);\n\n    return 1;\n  }\n\n  lua_pushstring(L, name);\n\n  if (lua_pcall(L, 1, 1, 0) != 0)\n  {\n    call_error(L, \"sysbench.cmdline.command_parallel\");\n    lua_pop(L, 2);\n    return 1;\n  }\n\n  bool rc = lua_toboolean(L, -1);\n\n  lua_pop(L, 3);\n\n  return rc;\n}\n\nstatic int call_custom_command(lua_State *L)\n{\n  if (export_options(L))\n    return 1;\n\n  lua_getglobal(L, \"sysbench\");\n  lua_getfield(L, -1, \"cmdline\");\n  lua_getfield(L, -1, \"call_command\");\n\n  if (!lua_isfunction(L, -1))\n  {\n    log_text(LOG_WARNING,\n             \"Cannot find the sysbench.cmdline.call_command function\");\n    lua_pop(L, 3);\n\n    return 1;\n  }\n\n  lua_pushstring(L, sb_lua_custom_command);\n\n  if (lua_pcall(L, 1, 1, 0) != 0)\n  {\n    call_error(L, \"sysbench.cmdline.call_command\");\n    lua_pop(L, 2);\n    return 1;\n  }\n\n  bool rc = lua_toboolean(L, -1);\n\n  lua_pop(L, 3);\n\n  return rc ? EXIT_SUCCESS : EXIT_FAILURE;\n}\n\n\nstatic void *cmd_worker_thread(void *arg)\n{\n  sb_thread_ctxt_t   *ctxt= (sb_thread_ctxt_t *)arg;\n\n  sb_tls_thread_id = ctxt->id;\n\n  /* Initialize thread-local RNG state */\n  sb_rand_thread_init();\n\n  lua_State * const L = sb_lua_new_state();\n\n  if (L == NULL)\n  {\n    log_text(LOG_FATAL, \"failed to create a thread to execute command\");\n    return NULL;\n  }\n\n  call_custom_command(L);\n\n  sb_lua_close_state(L);\n\n  return NULL;\n}\n\n/* Call a specified custom command */\n\nint sb_lua_call_custom_command(const char *name)\n{\n  sb_lua_custom_command = name;\n\n  if (sb_lua_custom_command_parallel(name) && sb_globals.threads > 1)\n  {\n    int err;\n\n    if ((err = sb_thread_create_workers(cmd_worker_thread)))\n      return err;\n\n    return sb_thread_join_workers();\n  }\n\n  return call_custom_command(gstate);\n}\n\n#define stat_to_number(name) sb_lua_var_number(L, #name, stat->name)\n\nstatic void stat_to_lua_table(lua_State *L, sb_stat_t *stat)\n{\n  lua_newtable(L);\n  stat_to_number(threads_running);\n  stat_to_number(time_interval);\n  stat_to_number(time_total);\n  stat_to_number(latency_pct);\n  stat_to_number(events);\n  stat_to_number(reads);\n  stat_to_number(writes);\n  stat_to_number(other);\n  stat_to_number(errors);\n  stat_to_number(reconnects);\n}\n\n/* Call sysbench.hooks.report_intermediate */\n\nstatic void sb_lua_report_intermediate(sb_stat_t *stat)\n{\n  lua_State * const L = tls_lua_ctxt.L;\n\n  if (!sb_lua_hook_push(L, REPORT_INTERMEDIATE_HOOK))\n    return;\n\n  stat_to_lua_table(L, stat);\n\n  /*\n    The following is only available for intermediate reports with tx_rate > 0\n  */\n  stat_to_number(queue_length);\n  stat_to_number(concurrency);\n\n  if (lua_pcall(L, 1, 0, 0))\n  {\n    call_error(L, REPORT_INTERMEDIATE_HOOK);\n  }\n}\n\n/* Call sysbench.hooks.report_cumulative */\n\nstatic void sb_lua_report_cumulative(sb_stat_t *stat)\n{\n  lua_State * const L = tls_lua_ctxt.L;\n\n  /*\n    This may be called either from a separate checkpoint thread (in which case\n    options are exported by sb_lua_report_thread_init(), or from the master\n    thread on benchmark exit. In the latter case, options must be exported, as\n    we don't normally do that for the global Lua state.\n  */\n  if (L == gstate)\n    export_options(L);\n\n  if (!sb_lua_hook_push(L, REPORT_CUMULATIVE_HOOK))\n    return;\n\n  stat_to_lua_table(L, stat);\n\n  /* The following stats are only available for cumulative reports */\n  stat_to_number(latency_min);\n  stat_to_number(latency_max);\n  stat_to_number(latency_avg);\n  stat_to_number(latency_sum);\n\n  if (lua_pcall(L, 1, 0, 0))\n  {\n    call_error(L, REPORT_CUMULATIVE_HOOK);\n  }\n}\n\n#undef stat_to_number\n\n\nint sb_lua_report_thread_init(void)\n{\n  if (tls_lua_ctxt.L == NULL)\n  {\n    sb_lua_new_state();\n    export_options(tls_lua_ctxt.L);\n  }\n\n  return 0;\n}\n\nvoid sb_lua_report_thread_done(void *arg)\n{\n  (void) arg; /* unused */\n\n  if (sb_lua_loaded())\n    sb_lua_close_state(tls_lua_ctxt.L);\n}\n\n/*\n  Perform a LuaJIT engine control command. This is taken with modifications from\n  luajit.c\n*/\n\nint sb_lua_do_jitcmd(lua_State *L, const char *cmd)\n{\n  const char *opt = strchr(cmd, '=');\n\n  lua_pushlstring(L, cmd, opt ? (size_t) (opt - cmd) : strlen(cmd));\n  lua_getfield(L, LUA_REGISTRYINDEX, \"_LOADED\");\n  lua_getfield(L, -1, \"jit\");  /* Get jit.* module table. */\n  lua_remove(L, -2);\n  lua_pushvalue(L, -2);\n  lua_gettable(L, -2);  /* Lookup library function. */\n\n  if (!lua_isfunction(L, -1))\n  {\n    lua_pop(L, 2);  /* Drop non-function and jit.* table, keep module name. */\n\n    /* Load add-on module. */\n    lua_getglobal(L, \"require\");\n    lua_pushliteral(L, \"jit.\");\n    lua_pushvalue(L, -3);\n    lua_concat(L, 2);\n\n    if (lua_pcall(L, 1, 1, 0))\n    {\n      const char *msg = lua_tostring(L, -1);\n      if (msg && !strncmp(msg, \"module \", 7))\n        goto nomodule;\n      call_error(L, \"require\");\n      return 1;\n    }\n\n    lua_getfield(L, -1, \"start\");\n    if (lua_isnil(L, -1)) {\n  nomodule:\n      log_text(LOG_FATAL,\n               \"unknown luaJIT command or jit.* modules not installed\");\n      return 1;\n    }\n    lua_remove(L, -2);  /* Drop module table. */\n  }\n  else\n  {\n    lua_remove(L, -2);  /* Drop jit.* table. */\n  }\n  lua_remove(L, -2);  /* Drop module name. */\n\n  int narg = 0;\n\n  if (opt && *++opt)\n  {\n    for (;;)\n    {\n      /* Split arguments. */\n      const char *p = strchr(opt, ',');\n      narg++;\n\n      if (!p)\n        break;\n\n      if (p == opt)\n        lua_pushnil(L);\n      else\n        lua_pushlstring(L, opt, (size_t) (p - opt));\n\n      opt = p + 1;\n    }\n\n    if (*opt)\n      lua_pushstring(L, opt);\n    else\n      lua_pushnil(L);\n  }\n\n  if (lua_pcall(L, narg, 0, 0))\n  {\n    call_error(L, \"lua_pcall\");\n    return 1;\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "src/sb_lua.h",
    "content": "/* Copyright (C) 2006 MySQL AB\n   Copyright (C) 2006-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#include \"sysbench.h\"\n#include \"lua.h\"\n\n/* Load a specified Lua script */\n\nsb_test_t *sb_load_lua(const char *testname);\n\nvoid sb_lua_done(void);\n\nint sb_lua_hook_call(lua_State *L, const char *name);\n\nbool sb_lua_custom_command_defined(const char *name);\n\nint sb_lua_call_custom_command(const char *name);\n\nint sb_lua_report_thread_init(void);\n\nvoid sb_lua_report_thread_done(void *);\n\nbool sb_lua_loaded(void);\n"
  },
  {
    "path": "src/sb_options.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n# include <stdlib.h>\n# include <string.h>\n# include <ctype.h>\n#endif\n\n#ifdef HAVE_LIMITS_H\n# include <limits.h>\n#endif\n\n#include \"sb_options.h\"\n#include \"sysbench.h\"\n\n#define VALUE_DELIMITER '='\n#define VALUE_SEPARATOR ','\n#define COMMENT_CHAR '#'\n\n#define MAXSTRLEN 256\n\n/* Global options list */\nstatic sb_list_t options;\n\n/* List of size modifiers (kilo, mega, giga, tera) */\nstatic const char sizemods[] = \"KMGT\";\n\n/* Convert dashes to underscores in option names */\n\nstatic void convert_dashes(char *);\n\n/* Compare option names */\n\nstatic int opt_name_cmp(const char *, const char *);\n\n/*\n  Array of option formats as displayed by sb_print_options(). The order and\n  number of elements must match sb_arg_type_t!\n*/\nstatic char *opt_formats[] = {\n  NULL,\t\t\t/* SB_ARG_TYPE_NULL */\n  \"[=on|off]\",\t\t/* SB_ARG_TYPE_FLAG */\n  \"=N\",\t\t\t/* SB_ARG_TYPE_INT */\n  \"=SIZE\",\t\t/* SB_ARG_TYPE_SIZE */\n  \"=N\",\t\t\t/* SB_ARG_TYPE_DOUBLE */\n  \"=STRING\",    \t/* SB_ARG_TYPE_STRING */\n  \"=[LIST,...]\",\t/* SB_ARG_TYPE_LIST */\n  \"=FILENAME\"\t\t/* SB_ARG_TYPE_FILE */\n};\n\n/* Initialize options library */\n\n\nint sb_options_init(void)\n{\n  SB_LIST_INIT(&options);\n\n  return 0;\n}\n\n/* Release resource allocated by the options library */\n\nint sb_options_done(void)\n{\n  free_options(&options);\n\n  return 0;\n}\n\n\n/* Register set of command line arguments */\n\n\nint sb_register_arg_set(sb_arg_t *set)\n{\n  unsigned int i;\n\n  for (i=0; set[i].name != NULL; i++)\n  {\n    option_t * const opt = set_option(set[i].name, set[i].value, set[i].type);\n    if (opt == NULL)\n      return 1;\n    opt->validate = set->validate;\n  }\n\n  return 0;\n}\n\noption_t *sb_find_option(const char *name)\n{\n  return find_option(&options, name);\n}\n\nstatic void read_config_file(const char *filename)\n{\n  /* read config options from file */\n  FILE *fp = fopen(filename, \"r\");\n  if (!fp) {\n    perror(filename);\n  } else {\n    read_config(fp, &options);\n    fclose(fp);\n  }\n}\n\noption_t *set_option(const char *name, const char *value, sb_arg_type_t type)\n{\n  option_t *opt;\n  char     *tmpbuf;\n  char     *tmp;\n\n  opt = add_option(&options, name);\n  if (opt == NULL)\n    return NULL;\n  free_values(&opt->values);\n  opt->type = type;\n\n  if (opt->validate != NULL && !opt->validate(name, value))\n    return NULL;\n\n  if (type != SB_ARG_TYPE_BOOL && (value == NULL || value[0] == '\\0'))\n    return opt;\n\n  switch (type) {\n    case SB_ARG_TYPE_BOOL:\n      if (value == NULL || !strcmp(value, \"on\") ||\n          !strcmp(value, \"true\") || !strcmp(value, \"1\"))\n      {\n        add_value(&opt->values, \"on\");\n      }\n      else if (strcmp(value, \"off\") && strcmp(value, \"false\") &&\n               strcmp(value, \"0\"))\n      {\n        return NULL;\n      }\n      break;\n    case SB_ARG_TYPE_INT:\n    case SB_ARG_TYPE_SIZE:\n    case SB_ARG_TYPE_DOUBLE:\n    case SB_ARG_TYPE_STRING:\n      add_value(&opt->values, value);\n      break;\n    case SB_ARG_TYPE_LIST:\n      if (value == NULL)\n        break;\n\n      tmpbuf = strdup(value);\n      tmp = tmpbuf;\n\n      for (tmp = strtok(tmp, \",\"); tmp != NULL; tmp = strtok(NULL, \",\"))\n        add_value(&opt->values, tmp);\n\n      free(tmpbuf);\n\n      break;\n    case SB_ARG_TYPE_FILE:\n      read_config_file(value);\n      break;\n    default:\n      printf(\"Unknown argument type: %d\", type);\n      return NULL;\n  }\n\n  return opt;\n}\n\n\nvoid sb_print_options(sb_arg_t *opts)\n{\n  unsigned int i;\n  unsigned int len;\n  unsigned int maxlen;\n  char         *fmt;\n  \n  /* Count the maximum name length */\n  for (i = 0, maxlen = 0; opts[i].name != NULL; i++)\n  {\n    len = strlen(opts[i].name);\n    len += (opts[i].type < SB_ARG_TYPE_MAX) ?\n      strlen(opt_formats[opts[i].type]) : 8 /* =UNKNOWN */;\n    if (len > maxlen)\n      maxlen = len;\n  }\n\n  for (i = 0; opts[i].name != NULL; i++)\n  {\n    if (opts[i].type < SB_ARG_TYPE_MAX)\n      fmt = opt_formats[opts[i].type];\n    else\n      fmt = \"=UNKNOWN\";\n\n    printf(\"  --%s%-*s%s\", opts[i].name,\n           (int)(maxlen - strlen(opts[i].name) + 1), fmt,\n           opts[i].desc);\n    if (opts[i].value != NULL)\n      printf(\" [%s]\", opts[i].value);\n    printf(\"\\n\");\n  }\n  printf(\"\\n\");\n}\n\n\nint sb_opt_to_flag(option_t *opt)\n{\n  return !SB_LIST_IS_EMPTY(&opt->values);\n}\n\n\nint sb_get_value_flag(const char *name)\n{\n  option_t *opt;\n\n  opt = find_option(&options, name);\n  if (opt == NULL)\n    return 0;\n\n  return sb_opt_to_flag(opt);\n}\n\n\nint sb_opt_to_int(option_t *opt)\n{\n  value_t        *val;\n  sb_list_item_t *pos;\n  long           res;\n  char           *endptr;\n\n  SB_LIST_ONCE(pos, &opt->values)\n  {\n    val = SB_LIST_ENTRY(pos, value_t, listitem);\n    res = strtol(val->data, &endptr, 10);\n    if (*endptr != '\\0' || res > INT_MAX || res < INT_MIN)\n    {\n      fprintf(stderr, \"Invalid value for the '%s' option: '%s'\\n\",\n              opt->name, val->data);\n      exit(EXIT_FAILURE);\n    }\n    return (int) res;\n  }\n\n  return 0;\n}  \n\n\nint sb_get_value_int(const char *name)\n{\n  option_t       *opt;\n\n  opt = find_option(&options, name);\n  if (opt == NULL)\n    return 0;\n\n  return sb_opt_to_int(opt);;\n}\n\n\nunsigned long long sb_opt_to_size(option_t *opt)\n{\n  value_t             *val;\n  sb_list_item_t      *pos;\n  unsigned long long  res = 0;\n  char                mult = 0;\n  int                 rc;\n  unsigned int        i, n;\n  char                *c;\n\n  SB_LIST_ONCE(pos, &opt->values)\n  {\n    val = SB_LIST_ENTRY(pos, value_t, listitem);\n    /*\n     * Reimplentation of sscanf(val->data, \"%llu%c\", &res, &mult), since\n     * there is no standard on how to specify long long values\n     */\n    res = 0;\n    for (rc = 0, c = val->data; *c != '\\0'; c++)\n    {\n      if (*c < '0' || *c > '9')\n      {\n        if (rc == 1)\n        {\n          rc = 2;\n          mult = *c;\n        }\n        break;\n      }\n      rc = 1;\n      res = res * 10 + *c - '0';\n    }\n\n    if (rc == 2)\n    {\n      for (n = 0; sizemods[n] != '\\0'; n++)\n        if (toupper(mult) == sizemods[n])\n          break;\n      if (sizemods[n] != '\\0')\n      {\n        for (i = 0; i <= n; i++)\n          res *= 1024;\n      }\n      else\n        res = 0; /* Unknown size modifier */\n    }\n  }\n\n  return res;\n}\n\n\nunsigned long long sb_get_value_size(const char *name)\n{\n  option_t            *opt;\n \n  opt = find_option(&options, name);\n  if (opt == NULL)\n    return 0;\n\n  return sb_opt_to_size(opt);\n}\n\n\ndouble sb_opt_to_double(option_t *opt)\n{\n  value_t        *val;\n  sb_list_item_t *pos;\n  double          res = 0;\n\n  SB_LIST_FOR_EACH(pos, &opt->values)\n  {\n    val = SB_LIST_ENTRY(pos, value_t, listitem);\n    res = strtod(val->data, NULL);\n  }\n\n  return res;\n}\n\n\ndouble sb_get_value_double(const char *name)\n{\n  option_t       *opt;\n\n  opt = find_option(&options, name);\n  if (opt == NULL)\n    return 0;\n\n  return sb_opt_to_double(opt);\n}\n\n\nchar *sb_opt_to_string(option_t *opt)\n{\n  value_t        *val;\n  sb_list_item_t *pos;\n\n  SB_LIST_ONCE(pos, &opt->values)\n  {\n    val = SB_LIST_ENTRY(pos, value_t, listitem);\n    return val->data;\n  }\n\n  return NULL;\n}\n\n\nchar *sb_get_value_string(const char *name)\n{\n  option_t       *opt;\n\n  opt = find_option(&options, name);\n  if (opt == NULL)\n    return NULL;\n\n  return sb_opt_to_string(opt);\n}\n\n\nbool sb_opt_copy(const char *to, const char *from)\n{\n  option_t *opt = find_option(&options, from);\n\n  if (opt == NULL)\n    return false;\n\n  set_option(to, sb_opt_to_string(opt), opt->type);\n\n  return true;\n}\n\n\nsb_list_t *sb_opt_to_list(option_t *opt)\n{\n  return &opt->values;\n}\n\n\nsb_list_t *sb_get_value_list(const char *name)\n{\n  option_t       *opt;\n\n  opt = find_option(&options, name);\n  if (opt == NULL)\n    return NULL;\n\n  return sb_opt_to_list(opt);\n}\n\n\nchar *sb_print_value_size(char *buf, unsigned int buflen, double value)\n{\n  unsigned int i;\n\n  for (i = 0; i < sizeof(sizemods) && value >= 1024; i++, value /= 1024)\n    /* empty */ ;\n\n  if (i > 0)\n    snprintf(buf, buflen, \"%.5g%ci\", value, sizemods[i-1]);\n  else\n    snprintf(buf, buflen, \"%.5g\", value);\n\n  return buf;\n}\n\n\nvalue_t *new_value()\n{\n  value_t *newval;\n  \n  newval = (value_t *)malloc(sizeof(value_t));\n  if (newval != NULL)\n    memset(newval, 0, sizeof(value_t));\n\n  return newval;\n}\n\n\noption_t *new_option()\n{\n  option_t *newopt;\n  \n  newopt = (option_t *)malloc(sizeof(option_t));\n  if (newopt != NULL)\n  {\n    memset(newopt, 0, sizeof(option_t));\n    SB_LIST_INIT(&newopt->values);\n  }\n  \n  return newopt;\n}\n\n\nvoid free_values(sb_list_t *values)\n{\n  sb_list_item_t *next;\n  sb_list_item_t *cur;\n  value_t        *val;\n\n  if (values == NULL)\n    return;\n\n  SB_LIST_FOR_EACH_SAFE(cur, next, values)\n    {\n    val = SB_LIST_ENTRY(cur, value_t, listitem);\n    if (val->data != NULL)\n      free(val->data);\n    SB_LIST_DELETE(cur);\n    free(val);\n  }\n}\n\n\nvoid free_options(sb_list_t *options)\n{\n  sb_list_item_t *next;\n  sb_list_item_t *cur;\n  option_t       *opt;\n\n  if (options == NULL)\n    return;\n\n  SB_LIST_FOR_EACH_SAFE(cur, next, options)\n  {\n    opt = SB_LIST_ENTRY(cur, option_t, listitem);\n    if (opt->name != NULL)\n      free(opt->name);\n    free_values(&opt->values);\n    free(opt);\n  }\n}  \n\n\nint remove_value(sb_list_t *values, char *valname)\n{\n  value_t *  value;\n  \n  if (values == NULL || valname == NULL)\n    return 1;\n\n  if ((value = find_value(values, valname)) == NULL)\n    return 1;\n  if (value->data != NULL)\n  {\n    free(value->data);\n  }\n  SB_LIST_DELETE(&value->listitem);\n  free(value);\n  \n  return 0;\n}\n\n\nint remove_option(sb_list_t * options, char * optname)\n{\n  option_t *  option;\n  \n  if (options == NULL || optname == NULL)\n    return 1;\n\n  if ((option = find_option(options, optname)) == NULL)\n    return 1;\n  free_values(&option->values);\n  if (option->name != NULL)\n    free(option->name);\n  SB_LIST_DELETE(&option->listitem);\n  free(option);\n  \n  return 0;\n} \n\n\nvalue_t *add_value(sb_list_t *values, const char *data)\n{\n  value_t *newval;\n  \n  if (values == NULL || data == NULL)\n    return NULL;\n  \n  if ((newval = new_value()) == NULL)\n    return NULL;\n  if ((newval->data = strdup(data)) == NULL)\n  {\n    free(newval);\n    return NULL;\n  }\n  \n  SB_LIST_ADD_TAIL(&newval->listitem, values);\n  \n  return newval;\n}\n\n\nvalue_t *find_value(sb_list_t *values, const char *data)\n{\n  sb_list_item_t *pos;\n  value_t        *value; \n  \n  if (values == NULL || data == NULL)\n    return NULL;\n\n  SB_LIST_FOR_EACH(pos, values)\n  {\n    value = SB_LIST_ENTRY(pos, value_t, listitem);\n    if (!strcmp(value->data, data))\n      return value;\n  }\n  \n  return NULL;\n}\n\n\noption_t *add_option(sb_list_t *options, const char *name)\n{\n  option_t *option;\n  \n  if (options == NULL || name == NULL)\n    return NULL;\n\n  if ((option = find_option(options, name)) != NULL)\n    return option; \n\n  if ((option = new_option()) == NULL)\n    return NULL;\n\n  option->name = strdup(name);\n  convert_dashes(option->name);\n  \n  SB_LIST_ADD_TAIL(&option->listitem, options);\n\n  return option;\n}\n\n\nvoid convert_dashes(char *s)\n{\n  while (*s != '\\0')\n  {\n    if (*s == '-')\n      *s = '_';\n    s++;\n  }\n}\n\n\nint opt_name_cmp(const char *s1, const char *s2)\n{\n  for (/* empty */; *s1 != '\\0'; s1++, s2++)\n  {\n    if (*s1 == *s2)\n      continue;\n\n    if ((*s1 != '-' && *s1 != '_') || (*s2 != '-' && *s2 != '_'))\n      break;\n  }\n\n  return *s1 - *s2;\n}\n\n\noption_t *find_option(sb_list_t *options, const char *name)\n{\n  sb_list_item_t *pos;\n  option_t       *opt;    \n  \n  if (options == NULL || name == NULL)\n    return NULL;\n\n  SB_LIST_FOR_EACH(pos, options)\n  {\n    opt = SB_LIST_ENTRY(pos, option_t, listitem);\n    if (!opt_name_cmp(opt->name, name))\n      return opt;\n  }\n  \n  return NULL;\n}\n\n\nsb_list_item_t *sb_options_enum_start(void)\n{\n  return SB_LIST_ENUM_START(&options);\n}\n\nsb_list_item_t *sb_options_enum_next(sb_list_item_t *pos, option_t **opt)\n{\n  pos = SB_LIST_ENUM_NEXT(pos, &options);\n  if (pos == NULL)\n    return NULL;\n\n  *opt = SB_LIST_ENTRY(pos, option_t, listitem);\n\n  return pos;\n}\n\n\nsb_list_t *read_config(FILE *fp, sb_list_t *options)\n{\n  char        buf[MAXSTRLEN];\n  char        *tmp;\n  char        qc;\n  option_t    *newopt;\n  int         optlen;\n  int         nline;\n  \n  if (fp == NULL || options == NULL)\n    return NULL;\n  \n  nline = 0;\n  while (fgets(buf, MAXSTRLEN, fp) != NULL)\n  {\n    nline++;\n\n    tmp = strchr(buf, VALUE_DELIMITER);\n    if (tmp == NULL)\n      continue;\n    if (*tmp != '\\0')\n      *tmp++ = '\\0';\n\n    if ((newopt = add_option(options, buf)) == NULL)\n      return NULL;\n\n    free_values(&newopt->values);\n    while (*tmp != '\\0')\n    {\n      if (isspace((int)*tmp))\n      {\n        tmp++;\n        continue;\n      }\n      if (*tmp == COMMENT_CHAR)\n        break;\n      else if (*tmp == '\\'' || *tmp == '\\\"')\n      {\n        qc = *tmp;\n        for (tmp++, optlen = 0; tmp[optlen] != '\\0' && tmp[optlen] != qc;\n             optlen++)\n        {\n          /* Empty */\n        }\n        if (tmp[optlen] == '\\0') {\n          fprintf(stderr, \"unexpected EOL on line %d\\n\", nline);\n          return NULL;\n        }\n        tmp[optlen++] = '\\0';\n        add_value(&newopt->values, tmp);\n        for (tmp = tmp + optlen; *tmp != '\\0' && *tmp != VALUE_SEPARATOR; tmp++)\n        {\n          /* Empty */\n        }\n        if (*tmp == VALUE_SEPARATOR)\n          tmp++;\n      } else {\n        for (optlen = 0; tmp[optlen] != '\\0' && tmp[optlen] != VALUE_SEPARATOR\n                         && !isspace(tmp[optlen]);\n             optlen++)\n        {\n          /* Empty */\n        }\n\n        if (tmp[optlen] != '\\0')\n          tmp[optlen++] = '\\0';\n\n        add_value(&newopt->values, tmp);\n        tmp += optlen;\n      }\n    }\n  }\n\n  return options;\n}\n\n\nint write_config(FILE *fp, sb_list_t *options)\n{\n  option_t       *opt;\n  value_t        *val;\n  sb_list_item_t *pos_opt;\n  sb_list_item_t *pos_val;\n\n  if (fp == NULL || options == NULL)\n    return 1;\n\n  SB_LIST_FOR_EACH(pos_opt, options)\n  {\n    opt = SB_LIST_ENTRY(pos_opt, option_t, listitem);\n    if (opt->ignore || opt->name == NULL)\n      continue;\n    opt->ignore = 1;\n    fprintf(fp, \"%s %c \", opt->name, VALUE_DELIMITER);\n    SB_LIST_FOR_EACH(pos_val, &opt->values)\n    {\n      val = SB_LIST_ENTRY(pos_val, value_t, listitem);\n      if (!val->ignore && val->data != NULL)\n        fprintf(fp, \"%s\", val->data);\n      if (!SB_LIST_ITEM_LAST(pos_val, &opt->values))\n        fprintf(fp, \"%c \", VALUE_SEPARATOR);\n    }\n    fputc('\\n', fp);\n  }\n    \n  return 0;\n}\n"
  },
  {
    "path": "src/sb_options.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef OPTIONS_H\n#define OPTIONS_H\n\n#include <stdio.h>\n#include <stdbool.h>\n\n#include \"sb_list.h\"\n\n/* Helper option declaration macros */\n#define SB_OPT(n, d, v, t)                   \\\n  { .name = (n),                             \\\n    .desc = (d),                             \\\n    .type = SB_ARG_TYPE_##t,                 \\\n    .value = (v) }\n\n#define SB_OPT_END { .type = SB_ARG_TYPE_NULL }\n\n/* Option types definition */\n\ntypedef enum\n{\n  SB_ARG_TYPE_NULL,\n  SB_ARG_TYPE_BOOL,\n  SB_ARG_TYPE_INT,\n  SB_ARG_TYPE_SIZE,\n  SB_ARG_TYPE_DOUBLE,\n  SB_ARG_TYPE_STRING,\n  SB_ARG_TYPE_LIST,\n  SB_ARG_TYPE_FILE,\n  SB_ARG_TYPE_MAX\n} sb_arg_type_t;\n\n/* Option validation function */\ntypedef bool sb_opt_validate_t(const char *, const char *);\n\n/* Test option definition */\ntypedef struct\n{\n  const char         *name;\n  const char         *desc;\n  const char         *value;\n  sb_arg_type_t      type;\n  sb_opt_validate_t  *validate;\n} sb_arg_t;\n\ntypedef struct\n{\n  char            *data;\n  char            ignore;\n\n  sb_list_item_t  listitem;\n} value_t;\n\ntypedef struct\n{\n  char            *name;\n  sb_arg_type_t   type;\n  sb_list_t       values;\n  char            ignore;\n\n  sb_opt_validate_t *validate;\n\n  sb_list_item_t  listitem;\n} option_t;\n  \n/* Initilize options library */\nint sb_options_init(void);\n\n/* Release resource allocated by the options library */\nint sb_options_done(void);\n\n/* Register set of command line arguments */\nint sb_register_arg_set(sb_arg_t *set);\n\n/* Set value 'value' of type 'type' for option 'name' */\noption_t *set_option(const char *name, const char *value, sb_arg_type_t type);\n\n/* Find option specified by 'name' */\noption_t *sb_find_option(const char *name);\n\n/* Print list of options specified by 'opts' */\nvoid sb_print_options(sb_arg_t *opts);\n\nint sb_get_value_flag(const char *name);\n\nint sb_get_value_int(const char *name);\n\nunsigned long long sb_get_value_size(const char *name);\n\ndouble sb_get_value_double(const char *name);\n\nchar *sb_get_value_string(const char *name);\n\nsb_list_t *sb_get_value_list(const char *name);\n\nchar *sb_print_value_size(char *buf, unsigned int buflen, double value);\n\nint sb_opt_to_flag(option_t *);\n\nint sb_opt_to_int(option_t *);\n\nunsigned long long sb_opt_to_size(option_t *);\n\ndouble sb_opt_to_double(option_t *);\n\nchar *sb_opt_to_string(option_t *);\n\nsb_list_t *sb_opt_to_list(option_t *);\n\nbool sb_opt_copy(const char *to, const char *from);\n\nsb_list_item_t *sb_options_enum_start(void);\n\nsb_list_item_t *sb_options_enum_next(sb_list_item_t *, option_t **);\n\nvalue_t *new_value(void);\n\noption_t *new_option(void);\n\nvoid free_values(sb_list_t *);\n\nvoid free_options(sb_list_t *);\n\nvalue_t *add_value(sb_list_t *, const char *);\n\nvalue_t *find_value(sb_list_t *, const char *);\n\noption_t *add_option(sb_list_t *, const char *);\n\noption_t *find_option(sb_list_t *, const char *);\n\nint remove_value(sb_list_t *, char *);\n\nint remove_option(sb_list_t *, char *);\n    \nsb_list_t *read_config(FILE *, sb_list_t *);\n\nint write_config(FILE *, sb_list_t *);\n\n#endif /* OPTIONS_H */\n\n"
  },
  {
    "path": "src/sb_rand.c",
    "content": "/*\n   Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/*\n * This file incorporates work covered by the following copyright and\n * permission notice:\n * Licensed to the Apache Software Foundation (ASF) under one or more\n * contributor license agreements.  See the NOTICE file distributed with\n * this work for additional information regarding copyright ownership.\n * The ASF licenses this file to You under the Apache License, Version 2.0\n * (the \"License\"); you may not use this file except in compliance with\n * the License.  You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#include <stdlib.h>\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n#ifdef HAVE_MATH_H\n# include <math.h>\n#endif\n\n#include \"sb_options.h\"\n#include \"sb_rand.h\"\n#include \"sb_logger.h\"\n\n#include \"sb_ck_pr.h\"\n\nTLS sb_rng_state_t sb_rng_state CK_CC_CACHELINE;\n\n/* Exported variables */\nint sb_rand_seed; /* optional seed set on the command line */\n\n/* Random numbers command line options */\n\nstatic sb_arg_t rand_args[] =\n{\n  SB_OPT(\"rand-type\",\n         \"random numbers distribution {uniform, gaussian, pareto, zipfian} \"\n         \"to use by default\", \"uniform\", STRING),\n  SB_OPT(\"rand-seed\",\n         \"seed for random number generator. When 0, the current time is \"\n         \"used as an RNG seed.\", \"0\", INT),\n  SB_OPT(\"rand-pareto-h\", \"shape parameter for the Pareto distribution\",\n         \"0.2\", DOUBLE),\n  SB_OPT(\"rand-zipfian-exp\",\n         \"shape parameter (exponent, theta) for the Zipfian distribution\",\n         \"0.8\", DOUBLE),\n\n  SB_OPT_END\n};\n\nstatic rand_dist_t rand_type;\n/* pointer to the default PRNG as defined by --rand-type */\nstatic uint32_t (*rand_func)(uint32_t, uint32_t);\nstatic unsigned int rand_iter;\nstatic unsigned int rand_pct;\nstatic unsigned int rand_res;\n\n/*\n  Pre-computed FP constants to avoid unnecessary conversions and divisions at\n  runtime.\n*/\nstatic double rand_iter_mult;\nstatic double rand_pct_mult;\nstatic double rand_pct_2_mult;\nstatic double rand_res_mult;\n\n/* parameters for Pareto distribution */\nstatic double pareto_h; /* parameter h */\nstatic double pareto_power; /* parameter pre-calculated by h */\n\n/* parameter and precomputed values for the Zipfian distribution */\nstatic double zipf_exp;\nstatic double zipf_s;\nstatic double zipf_hIntegralX1;\n\n/* Unique sequence generator state */\nstatic uint32_t rand_unique_index CK_CC_CACHELINE;\nstatic uint32_t rand_unique_offset;\n\nextern inline uint64_t sb_rand_uniform_uint64(void);\nextern inline double sb_rand_uniform_double(void);\nextern inline uint64_t xoroshiro_rotl(const uint64_t, int);\nextern inline uint64_t xoroshiro_next(uint64_t s[2]);\n\nstatic void rand_unique_seed(uint32_t index, uint32_t offset);\n\n/* Helper functions for the Zipfian distribution */\nstatic double hIntegral(double x, double e);\nstatic double hIntegralInverse(double x, double e);\nstatic double h(double x, double e);\nstatic double helper1(double x);\nstatic double helper2(double x);\n\nint sb_rand_register(void)\n{\n  sb_register_arg_set(rand_args);\n\n  return 0;\n}\n\n/* Initialize random numbers generation */\n\nint sb_rand_init(void)\n{\n  char     *s;\n\n  sb_rand_seed = sb_get_value_int(\"rand-seed\");\n\n  s = sb_get_value_string(\"rand-type\");\n  if (!strcmp(s, \"uniform\"))\n  {\n    rand_type = DIST_TYPE_UNIFORM;\n    rand_func = &sb_rand_uniform;\n  }\n  else if (!strcmp(s, \"gaussian\"))\n  {\n    rand_type = DIST_TYPE_GAUSSIAN;\n    rand_func = &sb_rand_gaussian;\n  }\n  else if (!strcmp(s, \"pareto\"))\n  {\n    rand_type = DIST_TYPE_PARETO;\n    rand_func = &sb_rand_pareto;\n  }\n  else if (!strcmp(s, \"zipfian\"))\n  {\n    rand_type = DIST_TYPE_ZIPFIAN;\n    rand_func = &sb_rand_zipfian;\n  }\n  else\n  {\n    log_text(LOG_FATAL, \"Invalid random numbers distribution: %s.\", s);\n    return 1;\n  }\n\n  rand_iter = sb_get_value_int(\"rand-spec-iter\");\n  rand_iter_mult = 1.0 / rand_iter;\n\n  rand_pct = sb_get_value_int(\"rand-spec-pct\");\n  rand_pct_mult = rand_pct / 100.0;\n  rand_pct_2_mult = rand_pct / 200.0;\n\n  rand_res = sb_get_value_int(\"rand-spec-res\");\n  rand_res_mult = 100.0 / (100.0 - rand_res);\n\n  pareto_h  = sb_get_value_double(\"rand-pareto-h\");\n  pareto_power = log(pareto_h) / log(1.0-pareto_h);\n\n  zipf_exp = sb_get_value_double(\"rand-zipfian-exp\");\n  if (zipf_exp < 0)\n  {\n    log_text(LOG_FATAL, \"--rand-zipfian-exp must be >= 0\");\n    return 1;\n  }\n\n  zipf_s = 2 - hIntegralInverse(hIntegral(2.5, zipf_exp) - h(2, zipf_exp),\n                                zipf_exp);\n  zipf_hIntegralX1 = hIntegral(1.5, zipf_exp) - 1;\n\n  /* Seed PRNG for the main thread. Worker threads do their own seeding */\n  sb_rand_thread_init();\n\n  /* Seed the unique sequence generator */\n  rand_unique_seed(random(), random());\n\n  return 0;\n}\n\n\nvoid sb_rand_print_help(void)\n{\n  printf(\"Pseudo-Random Numbers Generator options:\\n\");\n\n  sb_print_options(rand_args);\n}\n\n\nvoid sb_rand_done(void)\n{\n}\n\n/* Initialize thread-local RNG state */\n\nvoid sb_rand_thread_init(void)\n{\n  /* We use libc PRNG to seed xoroshiro128+ */\n  sb_rng_state[0] = (((uint64_t) random()) << 32) |\n    (((uint64_t) random()) & UINT32_MAX);\n  sb_rng_state[1] = (((uint64_t) random()) << 32) |\n    (((uint64_t) random()) & UINT32_MAX);\n}\n\n/*\n  Return random number in the specified range with distribution specified\n  with the --rand-type command line option\n*/\n\nuint32_t sb_rand_default(uint32_t a, uint32_t b)\n{\n  return rand_func(a,b);\n}\n\n/* uniform distribution */\n\nuint32_t sb_rand_uniform(uint32_t a, uint32_t b)\n{\n  return a + sb_rand_uniform_double() * (b - a + 1);\n}\n\n/* gaussian distribution */\n\nuint32_t sb_rand_gaussian(uint32_t a, uint32_t b)\n{\n  double       sum;\n  double       t;\n  unsigned int i;\n\n  t = b - a + 1;\n  for(i=0, sum=0; i < rand_iter; i++)\n    sum += sb_rand_uniform_double() * t;\n\n  return a + (uint32_t) (sum * rand_iter_mult) ;\n}\n\n/* Pareto distribution */\n\nuint32_t sb_rand_pareto(uint32_t a, uint32_t b)\n{\n  return a + (uint32_t) ((b - a + 1) *\n                         pow(sb_rand_uniform_double(), pareto_power));\n}\n\n/* Generate random string */\n\nvoid sb_rand_str(const char *fmt, char *buf)\n{\n  unsigned int i;\n\n  for (i=0; fmt[i] != '\\0'; i++)\n  {\n    if (fmt[i] == '#')\n      buf[i] = sb_rand_uniform('0', '9');\n    else if (fmt[i] == '@')\n      buf[i] = sb_rand_uniform('a', 'z');\n    else\n      buf[i] = fmt[i];\n  }\n}\n\n/*\n  Generates a random string of ASCII characters between '0' and 'z' of a length\n  between min and max. buf should have enough room for max len bytes. Returns\n  the number of characters written into the buffer.\n */\n\nuint32_t sb_rand_varstr(char *buf, uint32_t min_len, uint32_t max_len)\n{\n  unsigned int i;\n  uint32_t num_chars;\n  if (max_len == 0) {\n    return 0; /* we can't be sure buf is long enough to populate, so be safe */\n  }\n  if (min_len > max_len)\n  {\n    min_len = 1;\n  }\n\n  num_chars = sb_rand_uniform(min_len, max_len);\n  for (i=0; i < num_chars; i++)\n  {\n    buf[i] = sb_rand_uniform('0', 'z');\n  }\n  return num_chars;\n}\n\n/*\n  Unique random sequence generator. This is based on public domain code from\n  https://github.com/preshing/RandomSequence\n*/\n\nstatic uint32_t rand_unique_permute(uint32_t x)\n{\n  static const uint32_t prime = UINT32_C(4294967291);\n\n  if (x >= prime)\n    return x; /* The 5 integers out of range are mapped to themselves. */\n\n  uint32_t residue = ((uint64_t) x * x) % prime;\n  return (x <= prime / 2) ? residue : prime - residue;\n}\n\n\nstatic void rand_unique_seed(uint32_t index, uint32_t offset)\n{\n  rand_unique_index = rand_unique_permute(rand_unique_permute(index) +\n                                          0x682f0161);\n  rand_unique_offset = rand_unique_permute(rand_unique_permute(offset) +\n                                          0x46790905);\n}\n\n/* This is safe to be called concurrently from multiple threads */\n\nuint32_t sb_rand_unique(void)\n{\n  uint32_t index = ck_pr_faa_32(&rand_unique_index, 1);\n\n  return rand_unique_permute((rand_unique_permute(index) + rand_unique_offset) ^\n                             0x5bf03635);\n}\n\n/*\n  Implementation of the Zipf distribution is based on\n  RejectionInversionZipfSampler.java from the Apache Commons RNG project\n  (https://commons.apache.org/proper/commons-rng/) implementing the rejection\n  inversion sampling method for a descrete, bounded Zipf distribution that is in\n  turn based on the method described in:\n\n  Wolfgang Hörmann and Gerhard Derflinger. \"Rejection-inversion to generate\n  variates from monotone discrete distributions\", ACM Transactions on Modeling\n  and Computer Simulation, (TOMACS) 6.3 (1996): 169-184.\n*/\n\nstatic uint32_t sb_rand_zipfian_int(uint32_t n, double e, double s,\n                                    double hIntegralX1)\n{\n  /*\n    The paper describes an algorithm for exponents larger than 1 (Algorithm\n    ZRI).\n\n    The original method uses\n\n    H(x) = (v + x)^(1 - q) / (1 - q)\n\n    as the integral of the hat function.  This function is undefined for q = 1,\n    which is the reason for the limitation of the exponent.  If instead the\n    integral function\n\n    H(x) = ((v + x)^(1 - q) - 1) / (1 - q)\n\n    is used, for which a meaningful limit exists for q = 1, the method works for\n    all positive exponents.  The following implementation uses v = 0 and\n    generates integral number in the range [1, numberOfElements].  This is\n    different to the original method where v is defined to be positive and\n    numbers are taken from [0, i_max].  This explains why the implementation\n    looks slightly different.\n  */\n  const double hIntegralNumberOfElements = hIntegral(n + 0.5, e);\n\n  for (;;)\n  {\n    double u = hIntegralNumberOfElements + sb_rand_uniform_double() *\n      (hIntegralX1 - hIntegralNumberOfElements);\n    /* u is uniformly distributed in (hIntegralX1, hIntegralNumberOfElements] */\n\n    double x = hIntegralInverse(u, e);\n    uint32_t k = (uint32_t) (x + 0.5);\n\n    /*\n      Limit k to the range [1, numberOfElements] if it would be outside due to\n      numerical inaccuracies.\n    */\n    if (SB_UNLIKELY(k < 1))\n      k = 1;\n    else if (SB_UNLIKELY(k > n))\n      k = n;\n\n    /*\n      Here, the distribution of k is given by:\n\n      P(k = 1) = C * (hIntegral(1.5) - hIntegralX1) = C\n      P(k = m) = C * (hIntegral(m + 1/2) - hIntegral(m - 1/2)) for m >= 2\n\n      where C = 1 / (hIntegralNumberOfElements - hIntegralX1)\n    */\n\n    if (k - x <= s || u >= hIntegral(k + 0.5, e) - h(k, e))\n    {\n      /*\n        Case k = 1:\n\n        The right inequality is always true, because replacing k by 1 gives u >=\n        hIntegral(1.5) - h(1) = hIntegralX1 and u is taken from (hIntegralX1,\n        hIntegralNumberOfElements].\n\n        Therefore, the acceptance rate for k = 1 is P(accepted | k = 1) = 1 and\n        the probability that 1 is returned as random value is P(k = 1 and\n        accepted) = P(accepted | k = 1) * P(k = 1) = C = C / 1^exponent\n\n        Case k >= 2:\n\n        The left inequality (k - x <= s) is just a short cut to avoid the more\n        expensive evaluation of the right inequality (u >= hIntegral(k + 0.5) -\n        h(k)) in many cases.\n\n        If the left inequality is true, the right inequality is also true:\n          Theorem 2 in the paper is valid for all positive exponents, because\n          the requirements h'(x) = -exponent/x^(exponent + 1) < 0 and\n          (-1/hInverse'(x))'' = (1+1/exponent) * x^(1/exponent-1) >= 0 are both\n          fulfilled.  Therefore, f(x) = x - hIntegralInverse(hIntegral(x + 0.5)\n          - h(x)) is a non-decreasing function. If k - x <= s holds, k - x <= s\n          + f(k) - f(2) is obviously also true which is equivalent to -x <=\n          -hIntegralInverse(hIntegral(k + 0.5) - h(k)), -hIntegralInverse(u) <=\n          -hIntegralInverse(hIntegral(k + 0.5) - h(k)), and finally u >=\n          hIntegral(k + 0.5) - h(k).\n\n        Hence, the right inequality determines the acceptance rate: P(accepted |\n        k = m) = h(m) / (hIntegrated(m+1/2) - hIntegrated(m-1/2)) The\n        probability that m is returned is given by P(k = m and accepted) =\n        P(accepted | k = m) * P(k = m) = C * h(m) = C / m^exponent.\n\n      In both cases the probabilities are proportional to the probability mass\n      function of the Zipf distribution.\n      */\n\n      return k;\n    }\n  }\n}\n\nuint32_t sb_rand_zipfian(uint32_t a, uint32_t b)\n{\n  /* sb_rand_zipfian_int() returns a number in the range [1, b - a + 1] */\n  return a +\n    sb_rand_zipfian_int(b - a + 1, zipf_exp, zipf_s, zipf_hIntegralX1) - 1;\n}\n\n/*\n  H(x) is defined as\n\n  (x^(1 - exponent) - 1) / (1 - exponent), exponent != 1\n  log(x), if exponent == 1\n\n  H(x) is an integral function of h(x), the derivative of H(x) is h(x).\n*/\n\nstatic double hIntegral(double x, double e)\n{\n  const double logX = log(x);\n  return helper2((1 - e) * logX) * logX;\n}\n\n/* h(x) = 1 / x^exponent */\n\nstatic double h(double x, double e)\n{\n  return exp(-e * log(x));\n}\n\n/* The inverse function of H(x) */\n\nstatic double hIntegralInverse(double x, double e)\n{\n  double t = x * (1 -e);\n  if (t < -1)\n  {\n    /*\n      Limit value to the range [-1, +inf).\n      t could be smaller than -1 in some rare cases due to numerical errors.\n    */\n    t = -1;\n  }\n\n  return exp(helper1(t) * x);\n}\n\n/*\n Helper function that calculates log(1 + x) / x.\n\n A Taylor series expansion is used, if x is close to 0.\n*/\n\nstatic double helper1(double x)\n{\n  if (fabs(x) > 1e-8)\n    return log1p(x) / x;\n  else\n    return 1 - x * (0.5 - x * (0.33333333333333333 - 0.25 * x));\n}\n\n/*\n Helper function that calculates (exp(x) - 1) / x.\n\n A Taylor series expansion is used, if x is close to 0.\n*/\n\nstatic double helper2(double x)\n{\n  if (fabs(x) > 1e-8)\n    return expm1(x) / x;\n  else\n    return 1 + x * 0.5 * (1 + x * 0.33333333333333333 * (1 + 0.25 * x));\n}\n"
  },
  {
    "path": "src/sb_rand.h",
    "content": "/*\n   Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_RAND_H\n#define SB_RAND_H\n\n#include <stdlib.h>\n\n#include \"xoroshiro128plus.h\"\n\n/* Random numbers distributions */\ntypedef enum\n{\n  DIST_TYPE_UNIFORM,\n  DIST_TYPE_GAUSSIAN,\n  DIST_TYPE_PARETO,\n  DIST_TYPE_ZIPFIAN\n} rand_dist_t;\n\ntypedef uint64_t sb_rng_state_t [2];\n\n/* optional seed set on the command line */\nextern int sb_rand_seed;\n\n/* Thread-local RNG state */\nextern TLS sb_rng_state_t sb_rng_state;\n\n/* Return a uniformly distributed pseudo-random 64-bit unsigned integer */\ninline uint64_t sb_rand_uniform_uint64(void)\n{\n  return xoroshiro_next(sb_rng_state);\n}\n\n/* Return a uniformly distributed pseudo-random double in the [0, 1) interval */\ninline double sb_rand_uniform_double(void)\n{\n  const uint64_t x = sb_rand_uniform_uint64();\n  const union { uint64_t i; double d; } u = { .i = UINT64_C(0x3FF) << 52 | x >> 12 };\n\n  return u.d - 1.0;\n}\n\nint sb_rand_register(void);\nvoid sb_rand_print_help(void);\nint sb_rand_init(void);\nvoid sb_rand_done(void);\nvoid sb_rand_thread_init(void);\n\n/* Generator functions */\nuint32_t sb_rand_default(uint32_t, uint32_t);\nuint32_t sb_rand_uniform(uint32_t, uint32_t);\nuint32_t sb_rand_gaussian(uint32_t, uint32_t);\nuint32_t sb_rand_pareto(uint32_t, uint32_t);\nuint32_t sb_rand_zipfian(uint32_t, uint32_t);\nuint32_t sb_rand_unique(void);\nvoid sb_rand_str(const char *, char *);\nuint32_t sb_rand_varstr(char *, uint32_t, uint32_t);\n\n#endif /* SB_RAND_H */\n"
  },
  {
    "path": "src/sb_thread.c",
    "content": "/*\n   Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/*\n   Wrappers around pthread_create() and friends to provide necessary\n   (de-)initialization.\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n#ifndef HAVE_PTHREAD_CANCEL\n#include <signal.h>\n#endif\n\n#include \"sb_thread.h\"\n#include \"sb_rand.h\"\n#include \"sb_logger.h\"\n#include \"sysbench.h\"\n#include \"sb_ck_pr.h\"\n\npthread_attr_t  sb_thread_attr;\n\n/* Thread descriptors */\nstatic sb_thread_ctxt_t *threads;\n\n/* Stack size for each thread */\nstatic int thread_stack_size;\n\nint sb_thread_init(void)\n{\n  thread_stack_size = sb_get_value_size(\"thread-stack-size\");\n  if (thread_stack_size <= 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for thread-stack-size: %d.\\n\", thread_stack_size);\n    return 1;\n  }\n\n  /* initialize attr */\n  pthread_attr_init(&sb_thread_attr);\n#ifdef PTHREAD_SCOPE_SYSTEM\n  pthread_attr_setscope(&sb_thread_attr,PTHREAD_SCOPE_SYSTEM);\n#endif\n  pthread_attr_setstacksize(&sb_thread_attr, thread_stack_size);\n\n#ifdef HAVE_THR_SETCONCURRENCY\n  /* Set thread concurrency (required on Solaris) */\n  thr_setconcurrency(sb_globals.threads);\n#endif\n\n  threads = malloc(sb_globals.threads * sizeof(sb_thread_ctxt_t));\n  if (threads == NULL)\n  {\n    log_text(LOG_FATAL, \"Memory allocation failure.\\n\");\n    return EXIT_FAILURE;\n  }\n\n  return EXIT_SUCCESS;\n}\n\nvoid sb_thread_done(void)\n{\n  if (threads != NULL)\n    free(threads);\n}\n\n#ifndef HAVE_PTHREAD_CANCEL\n#define PTHREAD_CANCELED ((void *) -1)\n\nstruct sb_thread_proxy {\n  void *(*start_routine) (void *);\n  void *arg;\n};\n\nstatic int thread_cancel_signal = SIGUSR1;\n\nstatic void thread_cancel_handler(int sig)\n{\n  if (sig == thread_cancel_signal)\n    pthread_exit(PTHREAD_CANCELED);\n}\n\nstatic int install_thread_signal_handler(void) {\n  struct sigaction action;\n  memset(&action, 0, sizeof(action));\n  sigemptyset(&action.sa_mask);\n  action.sa_flags = 0;\n  action.sa_handler = thread_cancel_handler;\n  return sigaction(thread_cancel_signal, &action, NULL);\n}\n\nstatic void* thread_start_routine_proxy(void *arg) {\n  struct sb_thread_proxy *proxy = arg;\n  void *(*start_routine) (void *) = proxy->start_routine;\n  void *real_arg = proxy->arg;\n  free(proxy);\n  install_thread_signal_handler();\n  return start_routine(real_arg);\n}\n#endif\n\nint sb_thread_create(pthread_t *thread, const pthread_attr_t *attr,\n                     void *(*start_routine) (void *), void *arg)\n{\n#ifdef HAVE_PTHREAD_CANCEL\n  return pthread_create(thread, attr, start_routine, arg);\n#else\n  struct sb_thread_proxy *proxy = malloc(sizeof(struct sb_thread_proxy));\n  if (!proxy)\n  {\n    return EXIT_FAILURE;\n  }\n  proxy->start_routine = start_routine;\n  proxy->arg = arg;\n  int rv = pthread_create(thread, attr, thread_start_routine_proxy, proxy);\n  if (rv)\n  {\n    free(proxy);\n  }\n  return rv;\n#endif\n}\n\nint sb_thread_join(pthread_t thread, void **retval)\n{\n  return pthread_join(thread, retval);\n}\n\nint sb_thread_cancel(pthread_t thread)\n{\n#ifdef HAVE_PTHREAD_CANCEL\n  return pthread_cancel(thread);\n#else\n  return pthread_kill(thread, thread_cancel_signal);\n#endif\n}\n\nint sb_thread_create_workers(void *(*worker_routine)(void*))\n{\n  unsigned int i;\n\n  log_text(LOG_NOTICE, \"Initializing worker threads...\\n\");\n\n  for(i = 0; i < sb_globals.threads; i++)\n  {\n    threads[i].id = i;\n  }\n\n\n  for(i = 0; i < sb_globals.threads; i++)\n  {\n    int err;\n\n    if ((err = sb_thread_create(&(threads[i].thread), &sb_thread_attr,\n                                worker_routine, (void*)(threads + i))) != 0)\n    {\n      log_errno(LOG_FATAL, \"sb_thread_create() for thread #%d failed.\", i);\n      return EXIT_FAILURE;\n    }\n  }\n\n  return EXIT_SUCCESS;\n}\n\n\nint sb_thread_join_workers(void)\n{\n  for(unsigned i = 0; i < sb_globals.threads; i++)\n  {\n    int err;\n\n    if((err = sb_thread_join(threads[i].thread, NULL)) != 0)\n      log_errno(LOG_FATAL, \"sb_thread_join() for thread #%d failed.\", i);\n\n    ck_pr_dec_uint(&sb_globals.threads_running);\n  }\n\n  return EXIT_SUCCESS;\n}\n"
  },
  {
    "path": "src/sb_thread.h",
    "content": "/*\n   Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n/*\n   Wrappers around pthread_create() and friends to provide necessary\n   (de-)initialization.\n*/\n\n#ifndef SB_THREAD_H\n#define SB_THREAD_H\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n/* Thread context definition */\n\ntypedef struct\n{\n  pthread_t     thread;\n  unsigned int  id;\n} sb_thread_ctxt_t;\n\nextern pthread_attr_t sb_thread_attr;\n\nint sb_thread_create(pthread_t *thread, const pthread_attr_t *attr,\n                     void *(*start_routine) (void *), void *arg);\n\nint sb_thread_join(pthread_t thread, void **retval);\n\nint sb_thread_cancel(pthread_t thread);\n\nint sb_thread_create_workers(void *(*worker_routine)(void*));\n\nint sb_thread_join_workers(void);\n\nint sb_thread_init(void);\n\nvoid sb_thread_done(void);\n\n#endif /* SB_THREAD_H */\n"
  },
  {
    "path": "src/sb_timer.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n#endif\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n\n#include \"sb_logger.h\"\n#include \"sb_timer.h\"\n#include \"sb_util.h\"\n\n/* Some functions for simple time operations */\n\n/* initialize timer */\n\nvoid sb_timer_init(sb_timer_t *t)\n{\n  SB_COMPILE_TIME_ASSERT(sizeof(sb_timer_t) % CK_MD_CACHELINE == 0);\n\n  memset(&t->time_start, 0, sizeof(struct timespec));\n  memset(&t->time_end, 0, sizeof(struct timespec));\n\n  ck_spinlock_init(&t->lock);\n\n  sb_timer_reset(t);\n}\n\n/* Reset timer counters, but leave the current state intact */\n\nvoid sb_timer_reset(sb_timer_t *t)\n{\n  t->min_time = UINT64_MAX;\n  t->max_time = 0;\n  t->sum_time = 0;\n  t->events = 0;\n  t->queue_time = 0;\n}\n\n/* Clone a timer */\n\nvoid sb_timer_copy(sb_timer_t *to, sb_timer_t *from)\n{\n  memcpy(to, from, sizeof(sb_timer_t));\n\n  ck_spinlock_init(&to->lock);\n}\n\n/* check whether the timer is running */\n\nbool sb_timer_running(sb_timer_t *t)\n{\n  return TIMESPEC_DIFF(t->time_start, t->time_end) > 0;\n}\n\n/*\n  get time elapsed since the previous call to sb_timer_current() for the\n  specified timer without stopping it.  The first call returns time elapsed\n  since the timer was started.\n*/\n\nuint64_t sb_timer_current(sb_timer_t *t)\n{\n  struct timespec tmp;\n  uint64_t        res;\n\n  SB_GETTIME(&tmp);\n  res = TIMESPEC_DIFF(tmp, t->time_start);\n  t->time_start = tmp;\n\n  return res;\n}\n\n/*\n  Atomically reset a given timer after copying its state into the timer pointed\n  to by 'old'.\n*/\n\nvoid sb_timer_checkpoint(sb_timer_t *t, sb_timer_t *old)\n{\n  ck_spinlock_lock(&t->lock);\n\n  memcpy(old, t, sizeof(*old));\n  ck_spinlock_init(&old->lock);\n\n  sb_timer_reset(t);\n\n  ck_spinlock_unlock(&t->lock);\n}\n\n/* get average time per event */\n\n\nuint64_t sb_timer_avg(sb_timer_t *t)\n{\n  if(t->events == 0)\n    return 0; /* return zero if there were no events */\n  return (t->sum_time / t->events);\n}\n\n\n/* get total time for all events */\n\n\nuint64_t sb_timer_sum(sb_timer_t *t)\n{\n  return t->sum_time;\n}\n\n\n/* get minimum time */\n\n\nuint64_t sb_timer_min(sb_timer_t *t)\n{\n  if (t->events == 0)\n    return 0;\n  return t->min_time;\n}\n\n\n/* get maximum time */\n\n\nuint64_t sb_timer_max(sb_timer_t *t)\n{\n  return t->max_time;\n}\n\n\n/* sum data from several timers. used in summing data from multiple threads */\n\n\nsb_timer_t sb_timer_merge(sb_timer_t *t1, sb_timer_t *t2)\n{\n  sb_timer_t t;\n\n  /* Initialize to avoid warnings */\n  memset(&t, 0, sizeof(sb_timer_t));\n\n  t.sum_time = t1->sum_time+t2->sum_time;\n  t.events = t1->events+t2->events;\n\n  if (t1->max_time > t2->max_time)\n    t.max_time = t1->max_time;\n  else \n    t.max_time = t2->max_time;\n\n  if (t1->min_time<t2->min_time)\n    t.min_time = t1->min_time;\n  else \n    t.min_time = t2->min_time;\n     \n  return t;       \n}\n"
  },
  {
    "path": "src/sb_timer.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_TIMER_H\n#define SB_TIMER_H\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef TIME_WITH_SYS_TIME\n# include <sys/time.h>\n# include <time.h>\n#else\n# if HAVE_SYS_TIME_H\n#  include <sys/time.h>\n# else\n#  include <time.h>\n# endif\n#endif\n\n#include <stdint.h>\n#include <stdbool.h>\n\n#include \"sb_util.h\"\n#include \"ck_spinlock.h\"\n\n#define NS_PER_SEC 1000000000\n#define US_PER_SEC 1000000\n#define MS_PER_SEC 1000\n#define NS_PER_MS (NS_PER_SEC / MS_PER_SEC)\n\n/* Convert nanoseconds to seconds and vice versa */\n#define NS2SEC(nsec) ((nsec) / (double) NS_PER_SEC)\n#define SEC2NS(sec)  ((uint64_t) (sec) * NS_PER_SEC)\n\n/* Convert nanoseconds to milliseconds and vice versa */\n#define NS2MS(nsec) ((nsec) / (double) NS_PER_MS)\n#define MS2NS(sec)  ((sec) * (uint64_t) NS_PER_MS)\n\n/* Convert milliseconds to seconds and vice versa */\n#define MS2SEC(msec) ((msec) / (double) MS_PER_SEC)\n#define SEC2MS(sec) ((sec) * MS_PER_SEC)\n\n/* Difference between two 'timespec' values in nanoseconds */\n#define TIMESPEC_DIFF(a,b) (SEC2NS(a.tv_sec - b.tv_sec) + \\\n\t\t\t    (a.tv_nsec - b.tv_nsec))\n\n/* Wrapper over various *gettime* functions */\n#ifdef HAVE_CLOCK_GETTIME\n# define SB_GETTIME(tsp) clock_gettime(CLOCK_MONOTONIC, tsp)\n#else\n# define SB_GETTIME(tsp)                        \\\n  do {                                          \\\n    struct timeval tv;                          \\\n    gettimeofday(&tv, NULL);                    \\\n    (tsp)->tv_sec = tv.tv_sec;                  \\\n    (tsp)->tv_nsec = tv.tv_usec * 1000;         \\\n  } while (0)\n#endif\n\ntypedef enum {TIMER_UNINITIALIZED, TIMER_INITIALIZED, TIMER_STOPPED, \\\n              TIMER_RUNNING} timer_state_t;\n\n/* Timer structure definition */\n\ntypedef struct\n{\n  struct timespec time_start;\n  struct timespec time_end;\n  uint64_t        events;\n  uint64_t        queue_time;\n  uint64_t        min_time;\n  uint64_t        max_time;\n  uint64_t        sum_time;\n\n  ck_spinlock_t   lock;\n\n  char pad[SB_CACHELINE_PAD(sizeof(struct timespec)*2 + sizeof(uint64_t)*5 +\n                            sizeof(ck_spinlock_t))];\n} sb_timer_t;\n\n\nstatic inline int sb_nanosleep(uint64_t ns)\n{\n  struct timespec ts = { ns / NS_PER_SEC, ns % NS_PER_SEC };\n  return nanosleep(&ts, NULL);\n}\n\n/* timer control functions */\n\n/* Initialize timer */\nvoid sb_timer_init(sb_timer_t *);\n\n/* Reset timer counters, but leave the current state intact */\nvoid sb_timer_reset(sb_timer_t *t);\n\n/* check whether the timer is running */\nbool sb_timer_running(sb_timer_t *t);\n\n/* start timer */\nstatic inline void sb_timer_start(sb_timer_t *t)\n{\n  ck_spinlock_lock(&t->lock);\n\n  SB_GETTIME(&t->time_start);\n\n  ck_spinlock_unlock(&t->lock);\n}\n\n/* stop timer */\nstatic inline uint64_t sb_timer_stop(sb_timer_t *t)\n{\n  ck_spinlock_lock(&t->lock);\n\n  SB_GETTIME(&t->time_end);\n\n  uint64_t elapsed = TIMESPEC_DIFF(t->time_end, t->time_start) + t->queue_time;\n\n  t->events++;\n  t->sum_time += elapsed;\n\n  if (SB_UNLIKELY(elapsed < t->min_time))\n    t->min_time = elapsed;\n  if (SB_UNLIKELY(elapsed > t->max_time))\n    t->max_time = elapsed;\n\n  ck_spinlock_unlock(&t->lock);\n\n  return elapsed;\n}\n\n/*\n  get the current timer value in nanoseconds without affecting its state, i.e.\n  is safe to be used concurrently on a shared timer.\n*/\nstatic inline uint64_t sb_timer_value(sb_timer_t *t)\n{\n  struct timespec ts;\n\n  SB_GETTIME(&ts);\n  return TIMESPEC_DIFF(ts, t->time_start) + t->queue_time;\n}\n\n/* Clone a timer */\nvoid sb_timer_copy(sb_timer_t *to, sb_timer_t *from);\n\n/*\n  get time elapsed since the previous call to sb_timer_checkpoint() for the\n  specified timer without stopping it.  The first call returns time elapsed\n  since the timer was started.\n*/\nuint64_t sb_timer_current(sb_timer_t *t);\n\n/*\n  Atomically reset a given timer after copying its state into the timer pointed\n  to by 'old'.\n*/\nvoid sb_timer_checkpoint(sb_timer_t *t, sb_timer_t *old);\n\n/* get average time per event */\nuint64_t sb_timer_avg(sb_timer_t *);\n\n/* get total time for all events */\nuint64_t sb_timer_sum(sb_timer_t *);\n\n/* get minimum time */\nuint64_t sb_timer_min(sb_timer_t *);\n\n/* get maximum time */\nuint64_t sb_timer_max(sb_timer_t *);\n\n/* sum data from two timers. used in summing data from multiple threads */\nsb_timer_t sb_timer_merge(sb_timer_t *, sb_timer_t *);\n\n#endif /* SB_TIMER_H */\n"
  },
  {
    "path": "src/sb_util.c",
    "content": "/*\n   Copyright (C) 2017-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdlib.h>\n# include <inttypes.h>\n#endif\n\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\n\n#include \"sb_util.h\"\n#include \"sb_logger.h\"\n\n/*\n  Allocate a buffer of a specified size such that the address is a multiple of a\n  specified alignment.\n*/\n\nvoid *sb_memalign(size_t size, size_t alignment)\n{\n  void *buf;\n\n#ifdef HAVE_POSIX_MEMALIGN\n  int ret= posix_memalign(&buf, alignment, size);\n  if (ret != 0)\n    buf = NULL;\n#elif defined(HAVE_MEMALIGN)\n  buf = memalign(alignment, size);\n#elif defined(HAVE_VALLOC)\n  /* Allocate on page boundary */\n  (void) alignment; /* unused */\n  buffer = valloc(size);\n#else\n# error Cannot find an aligned allocation library function!\n#endif\n\n  return buf;\n}\n\n/* Get OS page size */\n\nsize_t sb_getpagesize(void)\n{\n#ifdef _SC_PAGESIZE\n  return sysconf(_SC_PAGESIZE);\n#else\n  return getpagesize();\n#endif\n}\n"
  },
  {
    "path": "src/sb_util.h",
    "content": "/*\n   Copyright (C) 2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_UTIL_H\n#define SB_UTIL_H\n\n/*\n  General utility macros and functions.\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_UNISTD_H\n# include <unistd.h>\n#endif\n\n#include \"ck_md.h\"\n#include \"ck_cc.h\"\n\n#ifdef HAVE_FUNC_ATTRIBUTE_FORMAT\n# define SB_ATTRIBUTE_FORMAT(style, m, n) __attribute__((format(style, m, n)))\n#else\n# define SB_ATTRIBUTE_FORMAT(style, m, n)\n#endif\n\n#ifdef HAVE_FUNC_ATTRIBUTE_UNUSED\n# define SB_ATTRIBUTE_UNUSED __attribute__((unused))\n#else\n# define SB_ATTRIBUTE_UNUSED\n#endif\n\n#if defined(__MACH__)\n# define DLEXT \".dylib\"\n#else\n# define DLEXT \".so\"\n#endif\n\n/*\n  Calculate the smallest multiple of m that is not smaller than n, when m is a\n  power of 2.\n*/\n#define SB_ALIGN(n, m) (((n) + ((m) - 1)) & ~((m) - 1))\n\n/*\n  Calculate padding, i.e. distance from n to SB_ALIGN(n, m), where m is a power\n  of 2.\n*/\n#define SB_PAD(n, m) (SB_ALIGN((n),(m)) - (n))\n\n/* Calculate padding to cache line size. */\n#define SB_CACHELINE_PAD(n) (SB_PAD((n), CK_MD_CACHELINE))\n\n/* Minimum/maximum values */\n#ifdef __GNUC__\n#  define SB_MIN(a,b)           \\\n  ({ __typeof__ (a) _a = (a);   \\\n    __typeof__ (b) _b = (b);    \\\n    _a < _b ? _a : _b; })\n#  define SB_MAX(a,b)           \\\n  ({ __typeof__ (a) _a = (a);   \\\n    __typeof__ (b) _b = (b);    \\\n    _a > _b ? _a : _b; })\n#else\n#  define SB_MIN(a,b) (((a) < (b)) ? (a) : (b))\n#  define SB_MAX(a,b) (((a) > (b)) ? (a) : (b))\n#endif /* __GNUC__ */\n\n#define SB_LIKELY(x) CK_CC_LIKELY(x)\n#define SB_UNLIKELY(x) CK_CC_UNLIKELY(x)\n\n/* SB_CONTAINER_OF */\n#ifdef __GNUC__\n#  define SB_MEMBER_TYPE(type, member) __typeof__ (((type *)0)->member)\n#else\n#  define SB_MEMBER_TYPE(type, member) const void\n#endif /* __GNUC__ */\n\n#define SB_CONTAINER_OF(ptr, type, member) ((type *)(void *)(           \\\n    (char *)(SB_MEMBER_TYPE(type, member) *){ ptr } - offsetof(type, member)))\n\n/* Compile-time assertion */\n#define SB_COMPILE_TIME_ASSERT(expr)                                    \\\n  do {                                                                  \\\n    typedef char cta[(expr) ? 1 : -1] SB_ATTRIBUTE_UNUSED;              \\\n  } while(0)\n\n#ifdef HAVE_ISATTY\n# define SB_ISATTY() isatty(0)\n#else\n# error No isatty() implementation for this platform!\n#endif\n\n/*\n  Allocate a buffer of a specified size such that the address is a multiple of a\n  specified alignment.\n*/\nvoid *sb_memalign(size_t size, size_t alignment);\n\n/* Get OS page size */\nsize_t sb_getpagesize(void);\n\n#endif /* SB_UTIL_H */\n"
  },
  {
    "path": "src/sysbench.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n# include <stdlib.h>\n#endif\n\n#ifdef HAVE_STRING_H\n# include <string.h>\n#endif\n#ifdef HAVE_STRINGS_H\n# include <strings.h>\n#endif\n\n#ifdef HAVE_UNISTD_H \n# include <unistd.h>\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#ifdef HAVE_ERRNO_H\n# include <errno.h>\n#endif\n#ifdef HAVE_FCNTL_H\n# include <fcntl.h>\n#endif\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n#ifdef HAVE_THREAD_H\n# include <thread.h>\n#endif\n#ifdef HAVE_MATH_H\n# include <math.h>\n#endif\n#ifdef HAVE_SCHED_H\n# include <sched.h>\n#endif\n#ifdef HAVE_SIGNAL_H\n# include <signal.h>\n#endif\n#ifdef HAVE_LIMITS_H\n# include <limits.h>\n#endif\n\n#include <luajit.h>\n\n#include \"sysbench.h\"\n#include \"sb_options.h\"\n#include \"sb_lua.h\"\n#include \"db_driver.h\"\n#include \"sb_rand.h\"\n#include \"sb_thread.h\"\n#include \"sb_barrier.h\"\n\n#include \"ck_cc.h\"\n#include \"ck_ring.h\"\n\n#define VERSION_STRING PACKAGE\" \"PACKAGE_VERSION SB_GIT_SHA\n\n/* Maximum queue length for the tx-rate mode. Must be a power of 2 */\n#define MAX_QUEUE_LEN 131072\n\n/*\n  Extra thread ID assigned to background threads. This may be used as an index\n  into per-thread arrays (see comment in sb_alloc_per_thread_array().\n*/\n#define SB_BACKGROUND_THREAD_ID sb_globals.threads\n\n/* General options */\nsb_arg_t general_args[] =\n{\n  SB_OPT(\"threads\", \"number of threads to use\", \"1\", INT),\n  SB_OPT(\"events\", \"limit for total number of events\", \"0\", INT),\n  SB_OPT(\"time\", \"limit for total execution time in seconds\", \"10\", INT),\n  SB_OPT(\"warmup-time\", \"execute events for this many seconds with statistics \"\n         \"disabled before the actual benchmark run with statistics enabled\",\n         \"0\", INT),\n  SB_OPT(\"forced-shutdown\",\n         \"number of seconds to wait after the --time limit before forcing \"\n         \"shutdown, or 'off' to disable\", \"off\", STRING),\n  SB_OPT(\"thread-stack-size\", \"size of stack per thread\", \"64K\", SIZE),\n  SB_OPT(\"thread-init-timeout\", \"wait time in seconds for worker threads to initialize\", \"30\", INT),\n  SB_OPT(\"rate\", \"average transactions rate. 0 for unlimited rate\", \"0\", INT),\n  SB_OPT(\"report-interval\", \"periodically report intermediate statistics with \"\n         \"a specified interval in seconds. 0 disables intermediate reports\",\n         \"0\", INT),\n  SB_OPT(\"report-checkpoints\", \"dump full statistics and reset all counters at \"\n         \"specified points in time. The argument is a list of comma-separated \"\n         \"values representing the amount of time in seconds elapsed from start \"\n         \"of test when report checkpoint(s) must be performed. Report \"\n         \"checkpoints are off by default.\", \"\", LIST),\n  SB_OPT(\"debug\", \"print more debugging info\", \"off\", BOOL),\n  SB_OPT(\"validate\", \"perform validation checks where possible\", \"off\", BOOL),\n  SB_OPT(\"help\", \"print help and exit\", \"off\", BOOL),\n  SB_OPT(\"version\", \"print version and exit\", \"off\", BOOL),\n  SB_OPT(\"config-file\", \"File containing command line options\", NULL, FILE),\n  SB_OPT(\"luajit-cmd\", \"perform LuaJIT control command. This option is \"\n         \"equivalent to 'luajit -j'. See LuaJIT documentation for more \"\n         \"information\", NULL, STRING),\n\n  SB_OPT_END\n};\n\n/* List of available tests */\nsb_list_t        tests;\n\n/* Global variables */\nsb_globals_t     sb_globals;\nsb_test_t        *current_test;\n\n/* Barrier to ensure we start the benchmark run when all workers are ready */\nstatic sb_barrier_t worker_barrier;\n\n/* Wait at most this number of seconds for worker threads to initialize */\nstatic int thread_init_timeout;\n\n/* Barrier to signal reporting threads */\nstatic sb_barrier_t report_barrier;\n\n/* structures to handle queue of events, needed for tx_rate mode */\nstatic pthread_mutex_t    queue_mutex;\nstatic pthread_cond_t     queue_cond;\nstatic uint64_t           queue_array[MAX_QUEUE_LEN] CK_CC_CACHELINE;\nstatic ck_ring_buffer_t   queue_ring_buffer[MAX_QUEUE_LEN] CK_CC_CACHELINE;\nstatic ck_ring_t          queue_ring CK_CC_CACHELINE;\n\nstatic int report_thread_created CK_CC_CACHELINE;\nstatic int checkpoints_thread_created;\nstatic int eventgen_thread_created;\n\n/* per-thread timers for response time stats */\nstatic sb_timer_t *timers;\n\n/* Temporary copy of timers for checkpoint reports */\nstatic sb_timer_t *timers_copy;\n\n/* Global execution timer */\nsb_timer_t      sb_exec_timer CK_CC_CACHELINE;\n\n/* timers for intermediate/checkpoint reports */\nsb_timer_t sb_intermediate_timer CK_CC_CACHELINE;\nsb_timer_t sb_checkpoint_timer   CK_CC_CACHELINE;\n\nTLS int sb_tls_thread_id;\n\nstatic void print_header(void);\nstatic void print_help(void);\nstatic void print_run_mode(sb_test_t *);\n\n#ifdef HAVE_ALARM\nstatic void sigalrm_thread_init_timeout_handler(int sig)\n{\n  if (sig != SIGALRM)\n    return;\n\n  log_text(LOG_FATAL,\n           \"Worker threads failed to initialize within %u seconds!\",\n           thread_init_timeout);\n\n  exit(2);\n}\n\n/* Default intermediate reports handler */\n\nvoid sb_report_intermediate(sb_stat_t *stat)\n{\n  log_timestamp(LOG_NOTICE, stat->time_total,\n                \"thds: %\" PRIu32 \" eps: %4.2f lat (ms,%u%%): %4.2f\",\n                stat->threads_running,\n                stat->events / stat->time_interval,\n                sb_globals.percentile,\n                SEC2MS(stat->latency_pct));\n  if (sb_globals.tx_rate > 0)\n    log_timestamp(LOG_NOTICE, stat->time_total,\n                  \"queue length: %\" PRIu64 \" concurrency: %\" PRIu64,\n                  stat->queue_length, stat->concurrency);\n}\n\n\nstatic void report_get_common_stat(sb_stat_t *stat, sb_counters_t cnt)\n{\n  memset(stat, 0, sizeof(sb_stat_t));\n\n  stat->threads_running = sb_globals.threads_running;\n\n  stat->events =        cnt[SB_CNT_EVENT];\n  stat->reads =         cnt[SB_CNT_READ];\n  stat->writes =        cnt[SB_CNT_WRITE];\n  stat->other =         cnt[SB_CNT_OTHER];\n  stat->errors =        cnt[SB_CNT_ERROR];\n  stat->reconnects =    cnt[SB_CNT_RECONNECT];\n  stat->bytes_read =    cnt[SB_CNT_BYTES_READ];\n  stat->bytes_written = cnt[SB_CNT_BYTES_WRITTEN];\n\n  stat->time_total = NS2SEC(sb_timer_value(&sb_exec_timer)) -\n    sb_globals.warmup_time;\n}\n\n\nstatic void report_intermediate(void)\n{\n  sb_stat_t stat;\n  sb_counters_t cnt;\n\n  /*\n    sb_globals.report_interval may be set to 0 by the master thread to\n    silence intermediate reports at the end of the test\n  */\n  if (ck_pr_load_uint(&sb_globals.report_interval) == 0)\n    return;\n\n  sb_counters_agg_intermediate(cnt);\n  report_get_common_stat(&stat, cnt);\n\n  stat.latency_pct =\n    MS2SEC(sb_histogram_get_pct_intermediate(&sb_latency_histogram,\n                                             sb_globals.percentile));\n\n  stat.time_interval = NS2SEC(sb_timer_current(&sb_intermediate_timer));\n\n  if (sb_globals.tx_rate > 0)\n  {\n    stat.queue_length = ck_ring_size(&queue_ring);\n    stat.concurrency = ck_pr_load_int(&sb_globals.concurrency);\n  }\n\n  if (current_test && current_test->ops.report_intermediate)\n    current_test->ops.report_intermediate(&stat);\n  else\n    sb_report_intermediate(&stat);\n}\n\n/* Default cumulative reports handler */\n\nvoid sb_report_cumulative(sb_stat_t *stat)\n{\n  const unsigned int nthreads = sb_globals.threads;\n\n  if (sb_globals.forced_shutdown_in_progress)\n  {\n    /*\n      In case we print statistics on forced shutdown, there may be (potentially\n      long running or hung) transactions which are still in progress.\n\n      We still want to reflect them in statistics, so stop running timers to\n      consider long transactions as done at the forced shutdown time, and print\n      a counter of still running transactions.\n    */\n    unsigned unfinished = 0;\n\n    for (unsigned i = 0; i < nthreads; i++)\n    {\n      if (sb_timer_running(&timers_copy[i]))\n      {\n        unfinished++;\n        sb_timer_stop(&timers_copy[i]);\n      };\n    }\n\n    if (unfinished > 0)\n    {\n      log_text(LOG_NOTICE, \"\");\n      log_text(LOG_NOTICE, \"Number of unfinished transactions on \"\n               \"forced shutdown: %u\", unfinished);\n    }\n  }\n\n  log_text(LOG_NOTICE, \"\");\n  log_text(LOG_NOTICE, \"Throughput:\");\n  log_text(LOG_NOTICE, \"    events/s (eps):                      %.4f\",\n           stat->events / stat->time_interval);\n  log_text(LOG_NOTICE, \"    time elapsed:                        %.4fs\",\n           stat->time_total);\n  log_text(LOG_NOTICE, \"    total number of events:              %\" PRIu64,\n           stat->events);\n\n  log_text(LOG_NOTICE, \"\");\n\n  log_text(LOG_NOTICE, \"Latency (ms):\");\n  log_text(LOG_NOTICE, \"         min: %39.2f\",\n           SEC2MS(stat->latency_min));\n  log_text(LOG_NOTICE, \"         avg: %39.2f\",\n           SEC2MS(stat->latency_avg));\n  log_text(LOG_NOTICE, \"         max: %39.2f\",\n           SEC2MS(stat->latency_max));\n\n  if (sb_globals.percentile > 0)\n    log_text(LOG_NOTICE, \"        %3dth percentile: %27.2f\",\n             sb_globals.percentile, SEC2MS(stat->latency_pct));\n  else\n    log_text(LOG_NOTICE, \"         percentile stats:               disabled\");\n\n  log_text(LOG_NOTICE, \"         sum: %39.2f\",\n           SEC2MS(stat->latency_sum));\n  log_text(LOG_NOTICE, \"\");\n\n  /* Aggregate temporary timers copy */\n  sb_timer_t t;\n  sb_timer_init(&t);\n  for(unsigned i = 0; i < nthreads; i++)\n    t = sb_timer_merge(&t, &timers_copy[i]);\n\n  /* Calculate and print events distribution by threads */\n  const double events_avg = (double) t.events / nthreads;\n  const double time_avg = stat->latency_sum / nthreads;\n\n  double events_stddev = 0;\n  double time_stddev = 0;\n\n  for(unsigned i = 0; i < nthreads; i++)\n  {\n    double diff = fabs(events_avg - timers_copy[i].events);\n    events_stddev += diff * diff;\n\n    diff = fabs(time_avg - NS2SEC(sb_timer_sum(&timers_copy[i])));\n    time_stddev += diff * diff;\n  }\n  events_stddev = sqrt(events_stddev / nthreads);\n  time_stddev = sqrt(time_stddev / nthreads);\n\n  log_text(LOG_NOTICE, \"Threads fairness:\");\n  log_text(LOG_NOTICE, \"    events (avg/stddev):           %.4f/%3.2f\",\n           events_avg, events_stddev);\n  log_text(LOG_NOTICE, \"    execution time (avg/stddev):   %.4f/%3.2f\",\n           time_avg, time_stddev);\n  log_text(LOG_NOTICE, \"\");\n\n  if (sb_globals.debug)\n  {\n    log_text(LOG_DEBUG, \"Verbose per-thread statistics:\\n\");\n    for(unsigned i = 0; i < nthreads; i++)\n    {\n      log_text(LOG_DEBUG, \"    thread #%3d: min: %.4fs  avg: %.4fs  max: %.4fs  \"\n               \"events: %\" PRIu64,\n               i,\n               NS2SEC(sb_timer_min(&timers_copy[i])),\n               NS2SEC(sb_timer_avg(&timers_copy[i])),\n               NS2SEC(sb_timer_max(&timers_copy[i])),\n               timers_copy[i].events);\n      log_text(LOG_DEBUG, \"                 \"\n               \"total time taken by event execution: %.4fs\",\n               NS2SEC(sb_timer_sum(&timers_copy[i])));\n    }\n    log_text(LOG_NOTICE, \"\");\n  }\n}\n\n/* Do a checkpoint, i.e. aggregate and reset collected statistics */\n\nstatic void checkpoint(sb_stat_t *stat)\n{\n  sb_counters_t cnt;\n\n  sb_counters_agg_cumulative(cnt);\n  report_get_common_stat(stat, cnt);\n\n  stat->time_interval = NS2SEC(sb_timer_current(&sb_checkpoint_timer));\n\n  stat->latency_pct =\n    MS2SEC(sb_histogram_get_pct_checkpoint(&sb_latency_histogram,\n                                           sb_globals.percentile));\n\n  /* Atomically reset each timer after copying it into its timers_copy slot */\n  for (size_t i = 0; i < sb_globals.threads; i++)\n    sb_timer_checkpoint(&timers[i], &timers_copy[i]);\n\n}\n\nstatic void report_cumulative(void)\n{\n  sb_stat_t  stat;\n  sb_timer_t t;\n\n  checkpoint(&stat);\n\n  sb_timer_init(&t);\n\n  /* Aggregate temporary timers copy populated by checkpoint() */\n  for(size_t i = 0; i < sb_globals.threads; i++)\n    t = sb_timer_merge(&t, &timers_copy[i]);\n\n  /* Calculate aggregate latency values */\n  stat.latency_min = NS2SEC(sb_timer_min(&t));\n  stat.latency_max = NS2SEC(sb_timer_max(&t));\n  stat.latency_avg = NS2SEC(sb_timer_avg(&t));\n  stat.latency_sum = NS2SEC(sb_timer_sum(&t));\n\n  if (current_test && current_test->ops.report_cumulative)\n    current_test->ops.report_cumulative(&stat);\n  else\n    sb_report_cumulative(&stat);\n}\n\n\nstatic void sigalrm_forced_shutdown_handler(int sig)\n{\n  if (sig != SIGALRM)\n    return;\n\n  sb_globals.forced_shutdown_in_progress = 1;\n\n  sb_timer_stop(&sb_exec_timer);\n  sb_timer_stop(&sb_intermediate_timer);\n  sb_timer_stop(&sb_checkpoint_timer);\n\n  log_text(LOG_FATAL,\n           \"The --max-time limit has expired, forcing shutdown...\");\n\n  report_cumulative();\n\n  log_done();\n\n  exit(2);\n}\n#endif\n\n\nstatic int register_tests(void)\n{\n  SB_LIST_INIT(&tests);\n\n  /* Register tests */\n  return register_test_fileio(&tests)\n    + register_test_cpu(&tests)\n    + register_test_memory(&tests)\n    + register_test_threads(&tests)\n    + register_test_mutex(&tests)\n    + db_register()\n    + sb_rand_register()\n    ;\n}\n\n\n/* Print program header */\n\n\nvoid print_header(void)\n{\n  log_text(LOG_NOTICE,\n           \"%s (using %s %s)\\n\",\n           VERSION_STRING, SB_WITH_LUAJIT, LUAJIT_VERSION);\n}\n\n\n/* Print program usage */\n\n\nvoid print_help(void)\n{\n  sb_list_item_t *pos;\n  sb_test_t      *test;\n  \n  printf(\"Usage:\\n\");\n  printf(\"  sysbench [options]... [testname] [command]\\n\\n\");\n  printf(\"Commands implemented by most tests: prepare run cleanup help\\n\\n\");\n  printf(\"General options:\\n\");\n  sb_print_options(general_args);\n\n  sb_rand_print_help();\n\n  log_print_help();\n\n  db_print_help();\n\n  printf(\"Compiled-in tests:\\n\");\n  SB_LIST_FOR_EACH(pos, &tests)\n  {\n    test = SB_LIST_ENTRY(pos, sb_test_t, listitem);\n    printf(\"  %s - %s\\n\", test->sname, test->lname);\n  }\n  printf(\"\\n\");\n  printf(\"See 'sysbench <testname> help' for a list of options for \"\n         \"each test.\\n\\n\");\n}\n\n/*\n  Set an option value if a default value has been previously set with\n  sb_register_arg_set(), i.e. if it's a 'known' option, or ignore_unknown is\n  'true'. In which case return 0, otherwise return 1.\n*/\n\nstatic int parse_option(char *name, bool ignore_unknown)\n{\n  const char        *value;\n  char              *tmp;\n  option_t          *opt;\n  char              ctmp = 0;\n  int               rc;\n\n  tmp = strchr(name, '=');\n  if (tmp != NULL)\n  {\n    ctmp = *tmp;\n    *tmp = '\\0';\n    value = tmp + 1;\n  }\n  else\n  {\n    value = NULL;\n  }\n\n  opt = sb_find_option(name);\n  if (opt != NULL || ignore_unknown)\n    rc = set_option(name, value,\n                    opt != NULL ? opt->type : SB_ARG_TYPE_STRING) == NULL;\n  else\n    rc =  1;\n\n  if (tmp != NULL)\n    *tmp = ctmp;\n\n  return rc;\n}\n\n/*\n  Parse general command line arguments. Test-specific argument are parsed by\n  parse_test_arguments() at a later stage when a builtin test or a Lua script is\n  known.\n*/\n\nstatic int parse_general_arguments(int argc, char *argv[])\n{\n  const char *      testname;\n  const char *      cmdname;\n\n  /* Set default values for general options */\n  if (sb_register_arg_set(general_args))\n    return 1;\n\n  /* Parse command line arguments */\n  testname = NULL;\n  cmdname = NULL;\n\n  for (int i = 1; i < argc; i++)\n  {\n    if (strncmp(argv[i], \"--\", 2))\n    {\n      if (testname == NULL)\n      {\n        testname = argv[i];\n        continue;\n      }\n\n      if (cmdname == NULL)\n      {\n        cmdname = argv[i];\n        continue;\n      }\n\n      fprintf(stderr, \"Unrecognized command line argument: %s\\n\", argv[i]);\n\n      return 1;\n    }\n    else if (!parse_option(argv[i]+2, false))\n    {\n      /* An option from general_args. Exclude it from future processing */\n      argv[i] = NULL;\n    }\n  }\n\n  sb_globals.testname = testname;\n  sb_globals.cmdname = cmdname;\n\n  return 0;\n}\n\n/* Parse test-specific arguments */\n\nstatic int parse_test_arguments(sb_test_t *test, int argc, char *argv[])\n{\n  /* Set default values */\n  if (test->args != NULL && sb_register_arg_set(test->args))\n    return 1;\n\n  for (int i = 1; i < argc; i++)\n  {\n    /* Skip already parsed and non-option arguments */\n    if (argv[i] == NULL || strncmp(argv[i], \"--\", 2))\n      continue;\n\n    /* At this stage an unrecognized option must throw a error. */\n    if (parse_option(argv[i]+2, false))\n    {\n      fprintf(stderr, \"invalid option: %s\\n\", argv[i]);\n      return 1;\n    }\n\n    argv[i] = NULL;\n  }\n\n  return 0;\n}\n\n\nvoid print_run_mode(sb_test_t *test)\n{\n  log_text(LOG_NOTICE, \"Running the test with following options:\");\n  log_text(LOG_NOTICE, \"Number of threads: %d\", sb_globals.threads);\n\n  if (sb_globals.warmup_time > 0)\n    log_text(LOG_NOTICE, \"Warmup time: %ds\", sb_globals.warmup_time);\n\n  if (sb_globals.tx_rate > 0)\n  {\n    log_text(LOG_NOTICE,\n            \"Target transaction rate: %d/sec\", sb_globals.tx_rate);\n  }\n\n  if (sb_globals.report_interval)\n  {\n    log_text(LOG_NOTICE, \"Report intermediate results every %d second(s)\",\n             sb_globals.report_interval);\n  }\n\n  if (sb_globals.n_checkpoints > 0)\n  {\n    char         list_str[MAX_CHECKPOINTS * 12];\n    char         *tmp = list_str;\n    unsigned int i;\n    int          n, size = sizeof(list_str);\n\n    for (i = 0; i < sb_globals.n_checkpoints - 1; i++)\n    {\n      n = snprintf(tmp, size, \"%u, \", sb_globals.checkpoints[i]);\n      if (n >= size)\n        break;\n      tmp += n;\n      size -= n;\n    }\n    if (i == sb_globals.n_checkpoints - 1)\n      snprintf(tmp, size, \"%u\", sb_globals.checkpoints[i]);\n    log_text(LOG_NOTICE, \"Report checkpoint(s) at %s seconds\",\n             list_str);\n  }\n\n  if (sb_globals.debug)\n    log_text(LOG_NOTICE, \"Debug mode enabled.\\n\");\n  \n  if (sb_globals.validate)\n    log_text(LOG_NOTICE, \"Validation checks: on.\\n\");\n\n  if (sb_rand_seed)\n  {\n    log_text(LOG_NOTICE,\n             \"Initializing random number generator from seed (%d).\\n\",\n             sb_rand_seed);\n    srandom(sb_rand_seed);\n  }\n  else\n  {\n    log_text(LOG_NOTICE,\n             \"Initializing random number generator from current time\\n\");\n    srandom(time(NULL));\n  }\n\n  if (sb_globals.force_shutdown)\n    log_text(LOG_NOTICE, \"Forcing shutdown in %u seconds\",\n             (unsigned) NS2SEC(sb_globals.max_time_ns) + sb_globals.timeout);\n  \n  log_text(LOG_NOTICE, \"\");\n\n  if (test->ops.print_mode != NULL)\n    test->ops.print_mode();\n}\n\nbool sb_more_events(int thread_id)\n{\n  (void) thread_id; /* unused */\n\n  if (sb_globals.error)\n    return false;\n\n  /* Check if we have a time limit */\n  if (sb_globals.max_time_ns > 0 &&\n      SB_UNLIKELY(sb_timer_value(&sb_exec_timer) >= sb_globals.max_time_ns))\n  {\n    log_text(LOG_INFO, \"Time limit exceeded, exiting...\");\n    return false;\n  }\n\n  /* Check if we have a limit on the number of events */\n  const uint64_t max_events = ck_pr_load_64(&sb_globals.max_events);\n  if (max_events > 0 &&\n      SB_UNLIKELY(ck_pr_faa_64(&sb_globals.nevents, 1) >= max_events))\n  {\n    log_text(LOG_INFO, \"Event limit exceeded, exiting...\");\n    return false;\n  }\n\n  /* If we are in tx_rate mode, we take events from queue */\n  if (sb_globals.tx_rate > 0)\n  {\n    void *ptr = NULL;\n\n    while (!ck_ring_dequeue_spmc(&queue_ring, queue_ring_buffer, &ptr) &&\n           !sb_globals.error)\n    {\n      pthread_mutex_lock(&queue_mutex);\n      pthread_cond_wait(&queue_cond, &queue_mutex);\n      pthread_mutex_unlock(&queue_mutex);\n\n      /* Re-check for global error and time limit after waiting */\n\n      if (sb_globals.error)\n        return false;\n\n      if (sb_globals.max_time_ns > 0 &&\n          SB_UNLIKELY(sb_timer_value(&sb_exec_timer) >= sb_globals.max_time_ns))\n      {\n        log_text(LOG_INFO, \"Time limit exceeded, exiting...\");\n        return false;\n      }\n    }\n\n    ck_pr_inc_int(&sb_globals.concurrency);\n\n    timers[thread_id].queue_time = sb_timer_value(&sb_exec_timer) -\n      ((uint64_t *) ptr)[0];\n  }\n\n  return true;\n}\n\n\nvoid sb_event_start(int thread_id)\n{\n  sb_timer_start(&timers[thread_id]);\n}\n\n\nvoid sb_event_stop(int thread_id)\n{\n  sb_timer_t     *timer = &timers[thread_id];\n  long long      value;\n\n  value = sb_timer_stop(timer);\n\n  if (sb_globals.percentile > 0)\n    sb_histogram_update(&sb_latency_histogram, NS2MS(value));\n\n  sb_counter_inc(thread_id, SB_CNT_EVENT);\n\n  if (sb_globals.tx_rate > 0)\n  {\n    ck_pr_dec_int(&sb_globals.concurrency);\n  }\n}\n\n\n/* Main event loop -- the default thread_run implementation */\n\n\nstatic int thread_run(sb_test_t *test, int thread_id)\n{\n  sb_event_t        event;\n  int               rc = 0;\n\n  while (sb_more_events(thread_id) && rc == 0)\n  {\n    event = test->ops.next_event(thread_id);\n    if (event.type == SB_REQ_TYPE_NULL)\n      break;\n\n    sb_event_start(thread_id);\n\n    rc = test->ops.execute_event(&event, thread_id);\n\n    sb_event_stop(thread_id);\n  }\n\n  return rc;\n}\n\n\n/* Main worker thread */\n\n\nstatic void *worker_thread(void *arg)\n{\n  sb_thread_ctxt_t   *ctxt;\n  unsigned int       thread_id;\n  int                rc;\n\n  ctxt = (sb_thread_ctxt_t *)arg;\n  sb_test_t * const test = current_test;\n\n  sb_tls_thread_id = thread_id = ctxt->id;\n\n  /* Initialize thread-local RNG state */\n  sb_rand_thread_init();\n\n  log_text(LOG_DEBUG, \"Worker thread (#%d) started\", thread_id);\n\n  if (test->ops.thread_init != NULL && test->ops.thread_init(thread_id) != 0)\n  {\n    log_text(LOG_DEBUG, \"Worker thread (#%d) failed to initialize!\", thread_id);\n    sb_globals.error = 1;\n    /* Avoid blocking the main thread */\n    sb_barrier_wait(&worker_barrier);\n    return NULL;\n  }\n\n  log_text(LOG_DEBUG, \"Worker thread (#%d) initialized\", thread_id);\n\n  /* Wait for other threads to initialize */\n  if (sb_barrier_wait(&worker_barrier) < 0)\n    return NULL;\n\n  if (test->ops.thread_run != NULL)\n  {\n    /* Use benchmark-provided thread_run implementation */\n    rc = test->ops.thread_run(thread_id);\n  }\n  else\n  {\n    /* Use default thread_run implementation */\n    rc = thread_run(test, thread_id);\n  }\n\n  if (rc != 0)\n    sb_globals.error = 1;\n  else if (test->ops.thread_done != NULL)\n    test->ops.thread_done(thread_id);\n\n  return NULL;\n}\n\n/* Generate exponentially distributed number with a given Lambda */\n\nstatic inline double sb_rand_exp(double lambda)\n{\n  return -lambda * log(1 - sb_rand_uniform_double());\n}\n\nstatic void *eventgen_thread_proc(void *arg)\n{\n  (void)arg; /* unused */\n\n  sb_tls_thread_id = SB_BACKGROUND_THREAD_ID;\n\n  /* Initialize thread-local RNG state */\n  sb_rand_thread_init();\n\n  ck_ring_init(&queue_ring, MAX_QUEUE_LEN);\n\n  if (pthread_mutex_init(&queue_mutex, NULL) ||\n      pthread_cond_init(&queue_cond, NULL))\n  {\n    sb_barrier_wait(&worker_barrier);\n    return NULL;\n  }\n\n  log_text(LOG_DEBUG, \"Event generating thread started\");\n\n  /* Wait for the worker threads to initialize */\n  if (sb_barrier_wait(&worker_barrier) < 0)\n    return NULL;\n\n  eventgen_thread_created = 1;\n\n  /*\n    Get exponentially distributed time intervals in nanoseconds with Lambda =\n    tx_rate. Alternatively, we can use Lambda = tx_rate / 1e9\n  */\n  const double lambda = 1e9 / sb_globals.tx_rate;\n\n  uint64_t curr_ns = sb_timer_value(&sb_exec_timer);\n  uint64_t intr_ns = sb_rand_exp(lambda);\n  uint64_t next_ns = curr_ns + intr_ns;\n\n  for (int i = 0; ; i = (i+1) % MAX_QUEUE_LEN)\n  {\n    curr_ns = sb_timer_value(&sb_exec_timer);\n    intr_ns = sb_rand_exp(lambda);\n    next_ns += intr_ns;\n\n    if (sb_globals.max_time_ns > 0 &&\n        SB_UNLIKELY(curr_ns >= sb_globals.max_time_ns))\n    {\n      /* Wake all waiting threads */\n      pthread_cond_broadcast(&queue_cond);\n      return NULL;\n    }\n\n    if (next_ns > curr_ns)\n      sb_nanosleep(next_ns - curr_ns);\n\n    /* Enqueue a new event */\n    queue_array[i] = sb_timer_value(&sb_exec_timer);\n    if (ck_ring_enqueue_spmc(&queue_ring, queue_ring_buffer,\n                             &queue_array[i]) == false)\n    {\n      sb_globals.error = 1;\n      log_text(LOG_FATAL,\n               \"The event queue is full. This means the worker threads are \"\n               \"unable to keep up with the specified event generation rate\");\n      pthread_cond_broadcast(&queue_cond);\n      return NULL;\n    }\n\n    /* Wake up one waiting thread, if there are any */\n    pthread_cond_signal(&queue_cond);\n  }\n\n  return NULL;\n}\n\n/* Intermediate reports thread */\n\nstatic void *report_thread_proc(void *arg)\n{\n  unsigned long long       pause_ns;\n  unsigned long long       prev_ns;\n  unsigned long long       next_ns;\n  unsigned long long       curr_ns;\n  const unsigned long long interval_ns = SEC2NS(sb_globals.report_interval);\n\n  (void)arg; /* unused */\n\n  sb_tls_thread_id = SB_BACKGROUND_THREAD_ID;\n\n  /* Initialize thread-local RNG state */\n  sb_rand_thread_init();\n\n  if (sb_lua_loaded() && sb_lua_report_thread_init())\n    return NULL;\n\n  pthread_cleanup_push(sb_lua_report_thread_done, NULL);\n\n  log_text(LOG_DEBUG, \"Reporting thread started\");\n\n  /* Wait for the signal from the main thread to start reporting */\n  if (sb_barrier_wait(&report_barrier) < 0)\n    return NULL;\n\n  report_thread_created = 1;\n\n  pause_ns = interval_ns;\n  prev_ns = sb_timer_value(&sb_exec_timer) + interval_ns;\n\n  for (;;)\n  {\n    sb_nanosleep(pause_ns);\n\n    report_intermediate();\n\n    curr_ns = sb_timer_value(&sb_exec_timer);\n    do\n    {\n      next_ns = prev_ns + interval_ns;\n      prev_ns = next_ns;\n    } while (curr_ns >= next_ns);\n    pause_ns = next_ns - curr_ns;\n  }\n\n  pthread_cleanup_pop(1);\n\n  return NULL;\n}\n\n/* Checkpoints reports thread */\n\nstatic void *checkpoints_thread_proc(void *arg)\n{\n  unsigned long long       next_ns;\n  unsigned long long       curr_ns;\n  unsigned int             i;\n\n  (void)arg; /* unused */\n\n  sb_tls_thread_id = SB_BACKGROUND_THREAD_ID;\n\n  /* Initialize thread-local RNG state */\n  sb_rand_thread_init();\n\n  if (sb_lua_loaded() && sb_lua_report_thread_init())\n    return NULL;\n\n  pthread_cleanup_push(sb_lua_report_thread_done, NULL);\n\n  log_text(LOG_DEBUG, \"Checkpoints report thread started\");\n\n  /* Wait for the signal from the main thread to start reporting */\n  if (sb_barrier_wait(&report_barrier) < 0)\n    return NULL;\n\n  checkpoints_thread_created = 1;\n\n  for (i = 0; i < sb_globals.n_checkpoints; i++)\n  {\n    next_ns = SEC2NS(sb_globals.checkpoints[i]);\n    curr_ns = sb_timer_value(&sb_exec_timer);\n    if (next_ns <= curr_ns)\n      continue;\n\n    sb_nanosleep(next_ns - curr_ns);\n\n    log_timestamp(LOG_NOTICE, NS2SEC(sb_timer_value(&sb_exec_timer)),\n                  \"Checkpoint report:\");\n\n    report_cumulative();\n  }\n\n  pthread_cleanup_pop(1);\n\n  return NULL;\n}\n\n/* Callback to start timers when all threads are ready */\n\nstatic int threads_started_callback(void *arg)\n{\n  (void) arg; /* unused */\n\n  /* Report initialization errors to the main thread */\n  if (sb_globals.error)\n    return 1;\n\n  sb_globals.threads_running = sb_globals.threads;\n\n  sb_timer_start(&sb_exec_timer);\n  sb_timer_copy(&sb_intermediate_timer, &sb_exec_timer);\n  sb_timer_copy(&sb_checkpoint_timer, &sb_exec_timer);\n\n  log_text(LOG_NOTICE, \"Threads started!\\n\");\n\n  return 0;\n}\n\n\n/*\n  Main test function: start threads, wait for them to finish and measure time.\n*/\n\nstatic int run_test(sb_test_t *test)\n{\n  int          err;\n  pthread_t    report_thread;\n  pthread_t    checkpoints_thread;\n  pthread_t    eventgen_thread;\n  unsigned int barrier_threads;\n  uint64_t     old_max_events = 0;\n\n  /* initialize test */\n  if (test->ops.init != NULL && test->ops.init() != 0)\n    return 1;\n  \n  /* print test mode */\n  print_run_mode(test);\n\n  /* initialize timers */\n  sb_timer_init(&sb_exec_timer);\n  sb_timer_init(&sb_intermediate_timer);\n  sb_timer_init(&sb_checkpoint_timer);\n\n  /* prepare test */\n  if (test->ops.prepare != NULL && test->ops.prepare() != 0)\n    return 1;\n\n  pthread_mutex_init(&sb_globals.exec_mutex, NULL);\n\n  sb_globals.threads_running = 0;\n\n  /* Calculate the required number of threads for the worker start barrier */\n  barrier_threads = 1 /* main thread */ + sb_globals.threads +\n    (sb_globals.tx_rate > 0) /* event generation thread */;\n\n  if (sb_barrier_init(&worker_barrier, barrier_threads,\n                      threads_started_callback, NULL))\n  {\n    log_errno(LOG_FATAL, \"sb_barrier_init() failed\");\n    return 1;\n  }\n\n  /* Calculate the required number of threads for the report start barrier */\n  barrier_threads = 1 /* main thread */ +\n    (sb_globals.report_interval > 0) /* intermediate reports thread */ +\n    (sb_globals.n_checkpoints > 0) /* checkpoint reports thread */;\n\n  if (sb_barrier_init(&report_barrier, barrier_threads, NULL, NULL))\n  {\n    log_errno(LOG_FATAL, \"sb_barrier_init() failed\");\n    return 1;\n  }\n\n\n  if (sb_globals.report_interval > 0)\n  {\n    /* Create a thread for intermediate statistic reports */\n    if ((err = sb_thread_create(&report_thread, &sb_thread_attr,\n                                &report_thread_proc, NULL)) != 0)\n    {\n      log_errno(LOG_FATAL,\n                \"sb_thread_create() for the reporting thread failed.\");\n      return 1;\n    }\n  }\n\n  if (sb_globals.tx_rate > 0)\n  {\n    if ((err = sb_thread_create(&eventgen_thread, &sb_thread_attr,\n                                &eventgen_thread_proc, NULL)) != 0)\n    {\n      log_errno(LOG_FATAL,\n                \"sb_thread_create() for the reporting thread failed.\");\n      return 1;\n    }\n  }\n\n  if (sb_globals.n_checkpoints > 0)\n  {\n    /* Create a thread for checkpoint statistic reports */\n    if ((err = sb_thread_create(&checkpoints_thread, &sb_thread_attr,\n                                &checkpoints_thread_proc, NULL)) != 0)\n    {\n      log_errno(LOG_FATAL,\n                \"sb_thread_create() for the checkpoint thread failed.\");\n      return 1;\n    }\n  }\n\n  if ((err = sb_thread_create_workers(&worker_thread)))\n    return err;\n\n#ifdef HAVE_ALARM\n  /* Exit with an error if thread initialization timeout expires */\n  signal(SIGALRM, sigalrm_thread_init_timeout_handler);\n\n  alarm(thread_init_timeout);\n#endif\n\n  if (sb_globals.warmup_time > 0)\n  {\n    /* Disable the max_events limit for the warmup stage */\n    old_max_events = sb_globals.max_events;\n    sb_globals.max_events = 0;\n  }\n\n  if (sb_barrier_wait(&worker_barrier) < 0)\n  {\n    log_text(LOG_FATAL, \"Threads initialization failed!\");\n    return 1;\n  }\n\n#ifdef HAVE_ALARM\n  alarm(0);\n\n  if (sb_globals.force_shutdown)\n  {\n    /* Set the alarm to force shutdown */\n    signal(SIGALRM, sigalrm_forced_shutdown_handler);\n\n    alarm(NS2SEC(sb_globals.max_time_ns) + sb_globals.timeout);\n  }\n#endif\n\n  if (sb_globals.warmup_time > 0)\n  {\n    log_text(LOG_NOTICE, \"Warming up for %d seconds...\\n\",\n             sb_globals.warmup_time);\n\n    usleep(sb_globals.warmup_time * 1000000);\n\n    /* Re-enable the max_events limit, if it was set */\n    ck_pr_store_64(&sb_globals.max_events, old_max_events);\n\n    /* Perform a checkpoint to reset previously collected stats */\n    sb_stat_t stat;\n    checkpoint(&stat);\n  }\n\n  /* Signal the report threads to start reporting */\n  if (sb_barrier_wait(&report_barrier) < 0)\n  {\n    log_text(LOG_FATAL, \"Failed to signal reporting threads\");\n    return 1;\n  }\n\n  if ((err = sb_thread_join_workers()))\n    return err;\n\n  sb_timer_stop(&sb_exec_timer);\n  sb_timer_stop(&sb_intermediate_timer);\n  sb_timer_stop(&sb_checkpoint_timer);\n\n  /* Silence periodic reports if they were on */\n  ck_pr_store_uint(&sb_globals.report_interval, 0);\n\n#ifdef HAVE_ALARM\n  alarm(0);\n#endif\n\n  log_text(LOG_INFO, \"Done.\\n\");\n\n  /* cleanup test */\n  if (test->ops.cleanup != NULL && test->ops.cleanup() != 0)\n    return 1;\n\n  if (report_thread_created)\n  {\n    if (sb_thread_cancel(report_thread) || sb_thread_join(report_thread, NULL))\n      log_errno(LOG_FATAL, \"Terminating the reporting thread failed.\");\n  }\n\n  if (eventgen_thread_created)\n  {\n    /*\n      When a time limit is used, the event generation thread may terminate\n      itself.\n    */\n    if ((sb_thread_cancel(eventgen_thread) ||\n         sb_thread_join(eventgen_thread, NULL)) && sb_globals.max_time_ns == 0)\n      log_text(LOG_FATAL, \"Terminating the event generator thread failed.\");\n  }\n\n  if (checkpoints_thread_created)\n  {\n    if (sb_thread_cancel(checkpoints_thread) ||\n        sb_thread_join(checkpoints_thread, NULL))\n      log_errno(LOG_FATAL, \"Terminating the checkpoint thread failed.\");\n  }\n\n  /* print test-specific stats */\n  if (!sb_globals.error)\n  {\n    if (sb_globals.histogram)\n    {\n      log_text(LOG_NOTICE, \"Latency histogram (values are in milliseconds)\");\n      sb_histogram_print(&sb_latency_histogram);\n      log_text(LOG_NOTICE, \" \");\n    }\n\n    report_cumulative();\n  }\n\n  pthread_mutex_destroy(&sb_globals.exec_mutex);\n\n  /* finalize test */\n  if (test->ops.done != NULL)\n    (*(test->ops.done))();\n\n  return sb_globals.error != 0;\n}\n\n\nstatic sb_test_t *find_test(const char *name)\n{\n  sb_list_item_t *pos;\n  sb_test_t      *test;\n\n  SB_LIST_FOR_EACH(pos, &tests)\n  {\n    test = SB_LIST_ENTRY(pos, sb_test_t, listitem);\n    if (!strcmp(test->sname, name))\n      return test;\n  }\n\n  return NULL;\n}\n\n\nstatic int checkpoint_cmp(const void *a_ptr, const void *b_ptr)\n{\n  const unsigned int a = *(const unsigned int *) a_ptr;\n  const unsigned int b = *(const unsigned int *) b_ptr;\n\n  return (int) (a - b);\n}\n\n\nstatic int init(void)\n{\n  option_t *opt;\n  char     *tmp;\n  sb_list_t         *checkpoints_list;\n  sb_list_item_t    *pos_val;\n  value_t           *val;\n\n  sb_globals.threads = sb_get_value_int(\"threads\");\n\n  thread_init_timeout = sb_get_value_int(\"thread-init-timeout\");\n  \n  if (sb_globals.threads <= 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for --threads: %d.\\n\",\n             sb_globals.threads);\n    return 1;\n  }\n\n  sb_globals.max_events = sb_get_value_int(\"events\");\n\n  sb_globals.warmup_time = sb_get_value_int(\"warmup-time\");\n  if (sb_globals.warmup_time < 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for --warmup-time: %d.\\n\",\n             sb_globals.warmup_time);\n    return 1;\n  }\n\n  int max_time = sb_get_value_int(\"time\");\n\n  sb_globals.max_time_ns = SEC2NS(max_time);\n\n  if (!sb_globals.max_events && !sb_globals.max_time_ns)\n    log_text(LOG_WARNING, \"Both event and time limits are disabled, \"\n             \"running an endless test\");\n\n  if (sb_globals.max_time_ns > 0)\n  {\n    /* Adjust the time limit if warmup time has been requested */\n    if (sb_globals.warmup_time > 0)\n    {\n      sb_globals.max_time_ns += SEC2NS(sb_globals.warmup_time);\n    }\n\n    /* Parse the --forced-shutdown value */\n    tmp = sb_get_value_string(\"forced-shutdown\");\n    if (tmp == NULL)\n    {\n      sb_globals.force_shutdown = 1;\n      sb_globals.timeout = NS2SEC(sb_globals.max_time_ns) / 20;\n    }\n    else if (strcasecmp(tmp, \"off\"))\n    {\n      char *endptr;\n    \n      sb_globals.force_shutdown = 1;\n      sb_globals.timeout = (unsigned) strtol(tmp, &endptr, 10);\n      if (*endptr == '%')\n        sb_globals.timeout = (unsigned) (sb_globals.timeout *\n                                         NS2SEC(sb_globals.max_time_ns) / 100);\n      else if (*tmp == '\\0' || *endptr != '\\0')\n      {\n        log_text(LOG_FATAL, \"Invalid value for --forced-shutdown: '%s'\", tmp);\n        return 1;\n      }\n    }\n    else\n      sb_globals.force_shutdown = 0;\n  }\n\n  int err;\n  if ((err = sb_thread_init()))\n    return err;\n\n  sb_globals.debug = sb_get_value_flag(\"debug\");\n  /* Automatically set logger verbosity to 'debug' */\n  if (sb_globals.debug)\n  {\n    opt = sb_find_option(\"verbosity\");\n    if (opt != NULL)\n      set_option(opt->name, \"5\", opt->type);\n  }\n  \n  sb_globals.validate = sb_get_value_flag(\"validate\");\n\n  if (sb_rand_init())\n  {\n    return 1;\n  }\n\n  sb_globals.tx_rate = sb_get_value_int(\"rate\");\n\n  sb_globals.report_interval = sb_get_value_int(\"report-interval\");\n\n  sb_globals.n_checkpoints = 0;\n  checkpoints_list = sb_get_value_list(\"report-checkpoints\");\n  SB_LIST_FOR_EACH(pos_val, checkpoints_list)\n  {\n    char *endptr;\n    long res;\n\n    val = SB_LIST_ENTRY(pos_val, value_t, listitem);\n    res = strtol(val->data, &endptr, 10);\n    if (*endptr != '\\0' || res < 0 || res > INT_MAX)\n    {\n      log_text(LOG_FATAL, \"Invalid value for --report-checkpoints: '%s'\",\n               val->data);\n      return 1;\n    }\n    if (++sb_globals.n_checkpoints > MAX_CHECKPOINTS)\n    {\n      log_text(LOG_FATAL, \"Too many checkpoints in --report-checkpoints \"\n               \"(up to %d can be defined)\", MAX_CHECKPOINTS);\n      return 1;\n    }\n    sb_globals.checkpoints[sb_globals.n_checkpoints-1] = (unsigned int) res;\n  }\n\n  if (sb_globals.n_checkpoints > 0)\n  {\n    qsort(sb_globals.checkpoints, sb_globals.n_checkpoints,\n          sizeof(unsigned int), checkpoint_cmp);\n  }\n\n  /* Initialize timers */\n  timers = sb_alloc_per_thread_array(sizeof(sb_timer_t));\n  timers_copy = sb_alloc_per_thread_array(sizeof(sb_timer_t));\n\n  if (timers == NULL || timers_copy == NULL)\n  {\n    log_text(LOG_FATAL, \"Memory allocation failure\");\n    return 1;\n  }\n\n  for (unsigned i = 0; i < sb_globals.threads; i++)\n    sb_timer_init(&timers[i]);\n\n  /* LuaJIT commands */\n  sb_globals.luajit_cmd = sb_get_value_string(\"luajit-cmd\");\n\n  return 0;\n}\n\n\nint main(int argc, char *argv[])\n{\n  sb_test_t *test = NULL;\n  int rc;\n\n  sb_globals.argc = argc;\n  sb_globals.argv = malloc(argc * sizeof(char *));\n  memcpy(sb_globals.argv, argv, argc * sizeof(char *));\n\n  /* Initialize options library */\n  sb_options_init();\n\n  /* First register the logger */\n  if (log_register())\n    return EXIT_FAILURE;\n\n  /* Register available tests */\n  if (register_tests())\n  {\n    fprintf(stderr, \"Failed to register tests.\\n\");\n    return EXIT_FAILURE;\n  }\n\n  /* Parse command line arguments */\n  if (parse_general_arguments(argc, argv))\n    return EXIT_FAILURE;\n\n  if (sb_get_value_flag(\"help\"))\n  {\n    print_help();\n    return EXIT_SUCCESS;\n  }\n\n  if (sb_get_value_flag(\"version\"))\n  {\n    printf(\"%s\\n\", VERSION_STRING);\n    return EXIT_SUCCESS;\n  }\n  \n  /* Initialize global variables and logger */\n  if (init() || log_init() || sb_counters_init())\n    return EXIT_FAILURE;\n\n  print_header();\n\n  if (sb_globals.testname != NULL && strcmp(sb_globals.testname, \"-\"))\n  {\n    /* Is it a built-in test name? */\n    test = find_test(sb_globals.testname);\n\n    if (test != NULL && sb_globals.cmdname == NULL)\n    {\n      /* Command is a mandatory argument for built-in tests */\n      fprintf(stderr, \"The '%s' test requires a command argument. \"\n              \"See 'sysbench %s help'\\n\", test->sname, test->sname);\n      return EXIT_FAILURE;\n    }\n\n    if (test == NULL)\n    {\n      if ((test = sb_load_lua(sb_globals.testname)) == NULL)\n        return EXIT_FAILURE;\n\n      if (sb_globals.cmdname == NULL)\n      {\n        /* No command specified, there's nothing more todo */\n        return test != NULL ? EXIT_SUCCESS: EXIT_FAILURE;\n      }\n    }\n  }\n  else\n  {\n    sb_globals.testname = NULL;\n\n    if (SB_ISATTY())\n      log_text(LOG_NOTICE, \"Reading the script from the standard input:\\n\");\n\n    test = sb_load_lua(NULL);\n\n    return test != NULL ? EXIT_SUCCESS : EXIT_FAILURE;\n  }\n\n  current_test = test;\n\n  /* Load and parse test-specific options */\n  if (parse_test_arguments(test, argc, argv))\n    return EXIT_FAILURE;\n\n  if (sb_lua_loaded() && sb_lua_custom_command_defined(sb_globals.cmdname))\n  {\n    rc =  sb_lua_call_custom_command(sb_globals.cmdname);\n  }\n  else if (!strcmp(sb_globals.cmdname, \"help\"))\n  {\n    if (test->builtin_cmds.help != NULL)\n    {\n      test->builtin_cmds.help();\n      rc = EXIT_SUCCESS;\n      goto end;\n    }\n    else if (test->args != NULL)\n    {\n      printf(\"%s options:\\n\", test->sname);\n      sb_print_test_options();\n      rc = EXIT_SUCCESS;\n      goto end;\n    }\n\n    /* We don't know want to print as help text, let the user know */\n    fprintf(stderr, \"'%s' test does not implement the 'help' command.\\n\",\n            test->sname);\n    return EXIT_FAILURE;\n  }\n  else if (!strcmp(sb_globals.cmdname, \"prepare\"))\n  {\n    if (test->builtin_cmds.prepare == NULL)\n    {\n      fprintf(stderr, \"'%s' test does not implement the 'prepare' command.\\n\",\n              test->sname);\n      rc = EXIT_FAILURE;\n      goto end;\n    }\n\n    rc = test->builtin_cmds.prepare();\n  }\n  else if (!strcmp(sb_globals.cmdname, \"cleanup\"))\n  {\n    if (test->builtin_cmds.cleanup == NULL)\n    {\n      fprintf(stderr, \"'%s' test does not implement the 'cleanup' command.\\n\",\n              test->sname);\n      rc = EXIT_FAILURE;\n      goto end;\n    }\n\n    rc = test->builtin_cmds.cleanup();\n  }\n  else if (!strcmp(sb_globals.cmdname, \"run\"))\n  {\n    rc = run_test(test) ? EXIT_FAILURE : EXIT_SUCCESS;\n  }\n  else\n  {\n    fprintf(stderr, \"Unknown command: %s\\n\", sb_globals.cmdname);\n    rc = EXIT_FAILURE;\n  }\n\nend:\n  if (sb_lua_loaded())\n    sb_lua_done();\n\n  db_done();\n\n  sb_counters_done();\n\n  log_done();\n\n  sb_options_done();\n\n  sb_rand_done();\n\n  sb_thread_done();\n\n  free(timers);\n  free(timers_copy);\n\n  free(sb_globals.argv);\n\n  return rc;\n}\n\n/* Print a description of available command line options for the current test */\n\nvoid sb_print_test_options(void)\n{\n  if (current_test != NULL)\n    sb_print_options(current_test->args);\n}\n\n/*\n  Allocate an array of objects of the specified size for all threads, both\n  worker and background ones.\n*/\n\nvoid *sb_alloc_per_thread_array(size_t size)\n{\n  /*\n    We want to exclude queries executed by background threads from statistics\n    generated for worker threads.\n\n    To simplify code, we allocate all timers and counters for all worker threads\n    + possible background threads created by sysbench for statistic reports,\n    etc. When executing requests from background threads, extra array slots will\n    be used (it depends on the assigned ID for each thread). When aggregating\n    counters and timers, we only consider slots in the range [0,\n    sb_globals.threads - 1], i.e. ignore statistics generated by background\n    threads. Currently we assign the same single thread ID for all background\n    threads, so they also share the same single slot in each allocated array.\n  */\n  const size_t bsize = (sb_globals.threads + 1) * size;\n\n  void *ptr = sb_memalign(bsize, CK_MD_CACHELINE);\n\n  memset(ptr, 0, bsize);\n\n  return ptr;\n}\n"
  },
  {
    "path": "src/sysbench.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2017 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SYSBENCH_H\n#define SYSBENCH_H\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n# include <stdlib.h>\n# include <string.h>\n# include <stdbool.h>\n#endif\n#ifdef HAVE_UNISTD_H \n# include <unistd.h>\n# include <sys/types.h>\n#endif\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n#include \"sb_list.h\"\n#include \"sb_options.h\"\n#include \"sb_timer.h\"\n#include \"sb_logger.h\"\n\n#include \"tests/sb_cpu.h\"\n#include \"tests/sb_fileio.h\"\n#include \"tests/sb_memory.h\"\n#include \"tests/sb_threads.h\"\n#include \"tests/sb_mutex.h\"\n\n/* Macros to control global execution mutex */\n#define SB_THREAD_MUTEX_LOCK() pthread_mutex_lock(&sb_globals.exec_mutex) \n#define SB_THREAD_MUTEX_UNLOCK() pthread_mutex_unlock(&sb_globals.exec_mutex)\n\n/* Maximum number of elements in --report-checkpoints list */\n#define MAX_CHECKPOINTS 256\n\n/* Request types definition */\n\ntypedef enum\n{\n  SB_REQ_TYPE_NULL,\n  SB_REQ_TYPE_CPU,\n  SB_REQ_TYPE_MEMORY,\n  SB_REQ_TYPE_FILE,\n  SB_REQ_TYPE_SQL,\n  SB_REQ_TYPE_THREADS,\n  SB_REQ_TYPE_MUTEX,\n  SB_REQ_TYPE_SCRIPT\n} sb_event_type_t;\n\n/* Request structure definition */\n\nstruct sb_test; /* Forward declaration */\n\ntypedef struct\n{\n  int              type;\n  struct sb_test_t *test;\n\n  /* type-specific data */\n  union\n  {\n    sb_file_request_t    file_request;\n    sb_threads_request_t threads_request;\n    sb_mutex_request_t   mutex_request;\n  } u;\n} sb_event_t;\n\n/* Statistics */\n\ntypedef struct {\n  uint32_t threads_running;     /* Number of active threads */\n\n  double   time_interval;       /* Time elapsed since the last report */\n  double   time_total;          /* Time elapsed since the benchmark start */\n\n  double   latency_pct;         /* Latency percentile */\n\n  double   latency_min;         /* Minimum latency (cumulative reports only) */\n  double   latency_max;         /* Maximum latency (cumulative reports only) */\n  double   latency_avg;         /* Average latency (cumulative reports only) */\n  double   latency_sum;         /* Sum latency (cumulative reports only) */\n\n  uint64_t events;              /* Number of executed events */\n  uint64_t reads;               /* Number of read operations */\n  uint64_t writes;              /* Number of write operations */\n  uint64_t other;               /* Number of other operations */\n  uint64_t errors;              /* Number of ignored errors */\n  uint64_t reconnects;          /* Number of reconnects to server */\n\n  uint64_t bytes_read;          /* Bytes read */\n  uint64_t bytes_written;       /* Bytes written */\n\n  uint64_t queue_length;        /* Event queue length (tx_rate-only) */\n  uint64_t concurrency;         /* Number of in-flight events (tx_rate-only) */\n} sb_stat_t;\n\n/* Commands */\n\ntypedef int sb_builtin_cmd_func_t(void);\ntypedef int sb_custom_cmd_func_t(int);\n\n/* Test operations definition */\n\ntypedef int sb_op_init(void);\ntypedef int sb_op_prepare(void);\ntypedef int sb_op_thread_init(int);\ntypedef int sb_op_thread_run(int);\ntypedef void sb_op_print_mode(void);\ntypedef sb_event_t sb_op_next_event(int);\ntypedef int sb_op_execute_event(sb_event_t *, int);\ntypedef void sb_op_report(sb_stat_t *);\ntypedef int sb_op_thread_done(int);\ntypedef int sb_op_cleanup(void);\ntypedef int sb_op_done(void);\n\n/* Test commands structure definitions */\n\ntypedef struct\n{\n  sb_builtin_cmd_func_t *help;  /* print help */\n  sb_builtin_cmd_func_t *prepare; /* prepare for the test */\n  sb_builtin_cmd_func_t *run;   /* run the test */\n  sb_builtin_cmd_func_t *cleanup; /* cleanup the test database, files, etc. */\n} sb_builtin_cmds_t;\n\n/* Test operations structure definition */\n\ntypedef struct\n{\n  sb_op_init            *init;            /* initialization function */\n  sb_op_prepare         *prepare;         /* called after timers start,  but\n                                             before thread execution */\n  sb_op_thread_init     *thread_init;     /* thread initialization\n                                             (called when each thread starts) */\n  sb_op_print_mode      *print_mode;      /* print mode function */\n  sb_op_next_event      *next_event;      /* event generation function */\n  sb_op_execute_event   *execute_event;   /* event execution function */\n  sb_op_report          *report_intermediate; /* intermediate reports handler */\n  sb_op_report          *report_cumulative;   /* cumulative reports handler */\n  sb_op_thread_run      *thread_run;      /* main thread loop */\n  sb_op_thread_done     *thread_done;     /* thread finalize function */\n  sb_op_cleanup         *cleanup;         /* called after exit from thread,\n                                             but before timers stop */ \n  sb_op_done            *done;            /* finalize function */\n} sb_operations_t;\n\n/* Test structure definition */\n\ntypedef struct sb_test\n{\n  const char        *sname;\n  const char        *lname;\n  sb_operations_t   ops;\n  sb_builtin_cmds_t builtin_cmds;\n  sb_arg_t          *args;\n\n  sb_list_item_t    listitem;\n} sb_test_t;\n\n/* sysbench global variables */\n\ntypedef struct\n{\n  int             error CK_CC_CACHELINE;        /* global error flag */\n  int             argc;         /* command line arguments count */\n  char            **argv;      /* command line arguments */\n  unsigned int    tx_rate;      /* target transaction rate */\n  uint64_t        max_events;   /* maximum number of events to execute */\n  uint64_t        max_time_ns;  /* total execution time limit */\n  pthread_mutex_t exec_mutex CK_CC_CACHELINE;   /* execution mutex */\n  const char      *testname;    /* test name or script path to execute */\n  const char      *cmdname;     /* command passed from command line */\n  unsigned int    threads CK_CC_CACHELINE;  /* number of threads to use */\n  unsigned int    threads_running;  /* number of threads currently active */\n  unsigned int    report_interval;  /* intermediate reports interval */\n  unsigned int    percentile;   /* percentile rank for latency stats */\n  unsigned int    histogram;    /* show histogram in latency stats */\n  /* array of report checkpoints */\n  unsigned int    checkpoints[MAX_CHECKPOINTS];\n  unsigned int    n_checkpoints; /* number of checkpoints */\n  unsigned char   debug;        /* debug flag */\n  unsigned int    timeout;      /* forced shutdown timeout */\n  unsigned char   validate;     /* validation flag */\n  unsigned char   verbosity CK_CC_CACHELINE;    /* log verbosity */\n  int             concurrency CK_CC_CACHELINE;  /* number of concurrent requests\n                                                when tx-rate is used */\n  int             force_shutdown CK_CC_CACHELINE; /* whether we must force test\n                                                  shutdown */\n  int             forced_shutdown_in_progress;\n  int             warmup_time;  /* warmup time */\n  uint64_t        nevents CK_CC_CACHELINE; /* event counter */\n  const char      *luajit_cmd; /* LuaJIT command */\n} sb_globals_t;\n\nextern sb_globals_t sb_globals CK_CC_CACHELINE;\nextern pthread_mutex_t event_queue_mutex CK_CC_CACHELINE;\n\n/* Global execution timer */\nextern sb_timer_t      sb_exec_timer CK_CC_CACHELINE;\n\n/* timers for checkpoint reports */\nextern sb_timer_t      sb_intermediate_timer;\nextern sb_timer_t      sb_checkpoint_timer;\n\nextern TLS int sb_tls_thread_id;\n\nbool sb_more_events(int thread_id);\nsb_event_t sb_next_event(sb_test_t *test, int thread_id);\nvoid sb_event_start(int thread_id);\nvoid sb_event_stop(int thread_id);\n\n/* Print a description of available command line options for the current test */\nvoid sb_print_test_options(void);\n\n/* Default intermediate reports handler */\nvoid sb_report_intermediate(sb_stat_t *stat);\n\n/* Default cumulative reports handler */\nvoid sb_report_cumulative(sb_stat_t *stat);\n\n/*\n  Allocate an array of objects of the specified size for all threads, both\n  worker and background ones.\n*/\nvoid *sb_alloc_per_thread_array(size_t size);\n\n#endif\n"
  },
  {
    "path": "src/tests/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nSUBDIRS = cpu fileio memory threads mutex\n"
  },
  {
    "path": "src/tests/cpu/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbcpu.a\n\nlibsbcpu_a_SOURCES = sb_cpu.c ../sb_cpu.h\n\nlibsbcpu_a_CPPFLAGS = $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/tests/cpu/sb_cpu.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_MATH_H\n# include <math.h>\n#endif\n\n#include <inttypes.h>\n\n#include \"sysbench.h\"\n\n/* CPU test arguments */\nstatic sb_arg_t cpu_args[] =\n{\n  SB_OPT(\"cpu-max-prime\", \"upper limit for primes generator\", \"10000\", INT),\n\n  SB_OPT_END\n};\n\n/* CPU test operations */\nstatic int cpu_init(void);\nstatic void cpu_print_mode(void);\nstatic sb_event_t cpu_next_event(int thread_id);\nstatic int cpu_execute_event(sb_event_t *, int);\nstatic void cpu_report_cumulative(sb_stat_t *);\nstatic int cpu_done(void);\n\nstatic sb_test_t cpu_test =\n{\n  .sname = \"cpu\",\n  .lname = \"CPU performance test\",\n  .ops = {\n    .init = cpu_init,\n    .print_mode = cpu_print_mode,\n    .next_event = cpu_next_event,\n    .execute_event = cpu_execute_event,\n    .report_cumulative = cpu_report_cumulative,\n    .done = cpu_done\n  },\n  .args = cpu_args\n};\n\n/* Upper limit for primes */\nstatic unsigned int    max_prime;\n\nint register_test_cpu(sb_list_t * tests)\n{\n  SB_LIST_ADD_TAIL(&cpu_test.listitem, tests);\n\n  return 0;\n}\n\nint cpu_init(void)\n{\n  int prime_option= sb_get_value_int(\"cpu-max-prime\");\n  if (prime_option <= 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value of cpu-max-prime: %d.\", prime_option);\n    return 1;\n  }\n  max_prime= (unsigned int)prime_option;\n\n  return 0;\n}\n\n\nsb_event_t cpu_next_event(int thread_id)\n{\n  sb_event_t req;\n\n  (void) thread_id; /* unused */\n\n  req.type = SB_REQ_TYPE_CPU;\n\n  return req;\n}\n\nint cpu_execute_event(sb_event_t *r, int thread_id)\n{\n  unsigned long long c;\n  unsigned long long l;\n  double t;\n  unsigned long long n=0;\n\n  (void)thread_id; /* unused */\n  (void)r; /* unused */\n\n  /* So far we're using very simple test prime number tests in 64bit */\n\n  for(c=3; c < max_prime; c++)\n  {\n    t = sqrt((double)c);\n    for(l = 2; l <= t; l++)\n      if (c % l == 0)\n        break;\n    if (l > t )\n      n++; \n  }\n\n  return 0;\n}\n\nvoid cpu_print_mode(void)\n{\n  log_text(LOG_INFO, \"Doing CPU performance benchmark\\n\");  \n  log_text(LOG_NOTICE, \"Prime numbers limit: %d\\n\", max_prime);\n}\n\n/* Print cumulative stats. */\n\nvoid cpu_report_cumulative(sb_stat_t *stat)\n{\n  log_text(LOG_NOTICE, \"CPU speed:\");\n  log_text(LOG_NOTICE, \"    events per second: %8.2f\",\n           stat->events / stat->time_interval);\n\n  sb_report_cumulative(stat);\n}\n\n\nint cpu_done(void)\n{\n  return 0;\n}\n"
  },
  {
    "path": "src/tests/fileio/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbfileio.a\n\nlibsbfileio_a_SOURCES = sb_fileio.c ../sb_fileio.h crc32.c crc32.h crc32tbl.h\n\nlibsbfileio_a_CPPFLAGS = $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/tests/fileio/crc32.c",
    "content": "/* crc32.c -- compute the CRC-32 of a data stream\n * Copyright (C) 1995-2003 Mark Adler\n * For conditions of distribution and use, see copyright notice in zlib.h\n *\n * Thanks to Rodney Brown <rbrown64@csc.com.au> for his contribution of faster\n * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing\n * tables for updating the shift register in one step with three exclusive-ors\n * instead of four steps with four exclusive-ors.  This results about a factor\n * of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.\n */\n\n/* @(#) $Id$ */\n\n#ifdef MAKECRCH\n#  include <stdio.h>\n#  ifndef DYNAMIC_CRC_TABLE\n#    define DYNAMIC_CRC_TABLE\n#  endif /* !DYNAMIC_CRC_TABLE */\n#endif /* MAKECRCH */\n\n#define local static\n#define STDC\n#define FAR\n#define ZEXPORT\n#define Z_NULL 0\n#define OF(args) args\n#include \"crc32.h\"\n\n#ifndef _WIN32\n#define ptrdiff_t long\n#else\n#include <stdlib.h>\n#endif\n\n/* Find a four-byte integer type for crc32_little() and crc32_big(). */\n#ifndef NOBYFOUR\n#  ifdef STDC           /* need ANSI C limits.h to determine sizes */\n#    include <limits.h>\n#    define BYFOUR\n#    if (UINT_MAX == 0xffffffffUL)\n       typedef unsigned int u4;\n#    else\n#      if (ULONG_MAX == 0xffffffffUL)\n         typedef unsigned long u4;\n#      else\n#        if (USHRT_MAX == 0xffffffffUL)\n           typedef unsigned short u4;\n#        else\n#          undef BYFOUR     /* can't find a four-byte integer type! */\n#        endif\n#      endif\n#    endif\n#  endif /* STDC */\n#endif /* !NOBYFOUR */\n\n/* Definitions for doing the crc four data bytes at a time. */\n#ifdef BYFOUR\n#  define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \\\n                (((w)&0xff00)<<8)+(((w)&0xff)<<24))\n   local unsigned long crc32_little OF((unsigned long,\n                        const unsigned char FAR *, unsigned));\n   local unsigned long crc32_big OF((unsigned long,\n                        const unsigned char FAR *, unsigned));\n#  define TBLS 8\n#else\n#  define TBLS 1\n#endif /* BYFOUR */\n\n#ifdef DYNAMIC_CRC_TABLE\n\nlocal int crc_table_empty = 1;\nlocal unsigned long FAR crc_table[TBLS][256];\nlocal void make_crc_table OF((void));\n#ifdef MAKECRCH\n   local void write_table OF((FILE *, const unsigned long FAR *));\n#endif /* MAKECRCH */\n\n/*\n  Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:\n  x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.\n\n  Polynomials over GF(2) are represented in binary, one bit per coefficient,\n  with the lowest powers in the most significant bit.  Then adding polynomials\n  is just exclusive-or, and multiplying a polynomial by x is a right shift by\n  one.  If we call the above polynomial p, and represent a byte as the\n  polynomial q, also with the lowest power in the most significant bit (so the\n  byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,\n  where a mod b means the remainder after dividing a by b.\n\n  This calculation is done using the shift-register method of multiplying and\n  taking the remainder.  The register is initialized to zero, and for each\n  incoming bit, x^32 is added mod p to the register if the bit is a one (where\n  x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by\n  x (which is shifting right by one and adding x^32 mod p if the bit shifted\n  out is a one).  We start with the highest power (least significant bit) of\n  q and repeat for all eight bits of q.\n\n  The first table is simply the CRC of all possible eight bit values.  This is\n  all the information needed to generate CRCs on data a byte at a time for all\n  combinations of CRC register values and incoming bytes.  The remaining tables\n  allow for word-at-a-time CRC calculation for both big-endian and little-\n  endian machines, where a word is four bytes.\n*/\nlocal void make_crc_table()\n{\n    unsigned long c;\n    int n, k;\n    unsigned long poly;            /* polynomial exclusive-or pattern */\n    /* terms of polynomial defining this crc (except x^32): */\n    static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};\n\n    /* make exclusive-or pattern from polynomial (0xedb88320UL) */\n    poly = 0UL;\n    for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)\n        poly |= 1UL << (31 - p[n]);\n\n    /* generate a crc for every 8-bit value */\n    for (n = 0; n < 256; n++) {\n        c = (unsigned long)n;\n        for (k = 0; k < 8; k++)\n            c = c & 1 ? poly ^ (c >> 1) : c >> 1;\n        crc_table[0][n] = c;\n    }\n\n#ifdef BYFOUR\n    /* generate crc for each value followed by one, two, and three zeros, and\n       then the byte reversal of those as well as the first table */\n    for (n = 0; n < 256; n++) {\n        c = crc_table[0][n];\n        crc_table[4][n] = REV(c);\n        for (k = 1; k < 4; k++) {\n            c = crc_table[0][c & 0xff] ^ (c >> 8);\n            crc_table[k][n] = c;\n            crc_table[k + 4][n] = REV(c);\n        }\n    }\n#endif /* BYFOUR */\n\n  crc_table_empty = 0;\n\n#ifdef MAKECRCH\n    /* write out CRC tables to crc32.h */\n    {\n        FILE *out;\n\n        out = fopen(\"crc32.h\", \"w\");\n        if (out == NULL) return;\n        fprintf(out, \"/* crc32.h -- tables for rapid CRC calculation\\n\");\n        fprintf(out, \" * Generated automatically by crc32.c\\n */\\n\\n\");\n        fprintf(out, \"local const unsigned long FAR \");\n        fprintf(out, \"crc_table[TBLS][256] =\\n{\\n  {\\n\");\n        write_table(out, crc_table[0]);\n#  ifdef BYFOUR\n        fprintf(out, \"#ifdef BYFOUR\\n\");\n        for (k = 1; k < 8; k++) {\n            fprintf(out, \"  },\\n  {\\n\");\n            write_table(out, crc_table[k]);\n        }\n        fprintf(out, \"#endif\\n\");\n#  endif /* BYFOUR */\n        fprintf(out, \"  }\\n};\\n\");\n        fclose(out);\n    }\n#endif /* MAKECRCH */\n}\n\n#ifdef MAKECRCH\nlocal void write_table(out, table)\n    FILE *out;\n    const unsigned long FAR *table;\n{\n    int n;\n\n    for (n = 0; n < 256; n++)\n        fprintf(out, \"%s0x%08lxUL%s\", n % 5 ? \"\" : \"    \", table[n],\n                n == 255 ? \"\\n\" : (n % 5 == 4 ? \",\\n\" : \", \"));\n}\n#endif /* MAKECRCH */\n\n#else /* !DYNAMIC_CRC_TABLE */\n/* ========================================================================\n * Tables of CRC-32s of all single-byte values, made by make_crc_table().\n */\n#include \"crc32tbl.h\"\n#endif /* DYNAMIC_CRC_TABLE */\n\n/* ========================================================================= */\n#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)\n#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1\n\n\n\n/* ========================================================================= */\nunsigned long ZEXPORT crc32(crc, buf, len)\n    unsigned long crc;\n    const unsigned char FAR *buf;\n    unsigned len;\n{\n    if (buf == Z_NULL) return 0UL;\n\n#ifdef DYNAMIC_CRC_TABLE\n    if (crc_table_empty)\n        make_crc_table();\n#endif /* DYNAMIC_CRC_TABLE */\n\n#ifdef BYFOUR\n    if (sizeof(void *) == sizeof(ptrdiff_t)) {\n        u4 endian;\n\n        endian = 1;\n        if (*((unsigned char *)(&endian)))\n            return crc32_little(crc, buf, len);\n        else\n            return crc32_big(crc, buf, len);\n    }\n#endif /* BYFOUR */\n    crc = crc ^ 0xffffffffUL;\n    while (len >= 8) {\n        DO8;\n        len -= 8;\n    }\n    if (len) do {\n        DO1;\n    } while (--len);\n    return crc ^ 0xffffffffUL;\n}\n\n#ifdef BYFOUR\n\n/* ========================================================================= */\n#define DOLIT4 c ^= *buf4++; \\\n        c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \\\n            crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]\n#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4\n\n/* ========================================================================= */\nlocal unsigned long crc32_little(crc, buf, len)\n    unsigned long crc;\n    const unsigned char FAR *buf;\n    unsigned len;\n{\n    register u4 c;\n    register const u4 FAR *buf4;\n\n    c = (u4)crc;\n    c = ~c;\n    while (len && ((ptrdiff_t)buf & 3)) {\n        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);\n        len--;\n    }\n\n    buf4 = (const u4 FAR *)(void *)buf;\n    while (len >= 32) {\n        DOLIT32;\n        len -= 32;\n    }\n    while (len >= 4) {\n        DOLIT4;\n        len -= 4;\n    }\n    buf = (const unsigned char FAR *)buf4;\n\n    if (len) do {\n        c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);\n    } while (--len);\n    c = ~c;\n    return (unsigned long)c;\n}\n\n/* ========================================================================= */\n#define DOBIG4 c ^= *++buf4; \\\n        c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \\\n            crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]\n#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4\n\n/* ========================================================================= */\nlocal unsigned long crc32_big(crc, buf, len)\n    unsigned long crc;\n    const unsigned char FAR *buf;\n    unsigned len;\n{\n    register u4 c;\n    register const u4 FAR *buf4;\n\n    c = REV((u4)crc);\n    c = ~c;\n    while (len && ((ptrdiff_t)buf & 3)) {\n        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);\n        len--;\n    }\n\n    buf4 = (const u4 FAR *)(void *)buf;\n    buf4--;\n    while (len >= 32) {\n        DOBIG32;\n        len -= 32;\n    }\n    while (len >= 4) {\n        DOBIG4;\n        len -= 4;\n    }\n    buf4++;\n    buf = (const unsigned char FAR *)buf4;\n\n    if (len) do {\n        c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);\n    } while (--len);\n    c = ~c;\n    return (unsigned long)(REV(c));\n}\n\n#endif /* BYFOUR */\n"
  },
  {
    "path": "src/tests/fileio/crc32.h",
    "content": "#ifndef CRC32_H\n\n#ifdef HAVE_CONFIG_H\n#include <config.h>\n#endif\n\n#define CRC32_H\n\nextern unsigned long crc32(unsigned long crc, const unsigned char *buf, unsigned len);\n\n#endif\n"
  },
  {
    "path": "src/tests/fileio/crc32tbl.h",
    "content": "/* crc32.h -- tables for rapid CRC calculation\n * Generated automatically by crc32.c\n */\n\nlocal const unsigned long FAR crc_table[TBLS][256] =\n{\n  {\n    0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,\n    0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,\n    0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,\n    0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,\n    0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,\n    0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,\n    0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,\n    0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,\n    0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,\n    0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,\n    0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,\n    0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,\n    0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,\n    0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,\n    0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,\n    0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,\n    0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,\n    0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,\n    0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,\n    0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,\n    0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,\n    0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,\n    0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,\n    0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,\n    0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,\n    0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,\n    0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,\n    0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,\n    0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,\n    0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,\n    0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,\n    0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,\n    0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,\n    0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,\n    0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,\n    0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,\n    0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,\n    0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,\n    0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,\n    0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,\n    0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,\n    0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,\n    0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,\n    0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,\n    0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,\n    0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,\n    0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,\n    0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,\n    0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,\n    0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,\n    0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,\n    0x2d02ef8dUL\n#ifdef BYFOUR\n  },\n  {\n    0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,\n    0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,\n    0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,\n    0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,\n    0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,\n    0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,\n    0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,\n    0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,\n    0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,\n    0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,\n    0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,\n    0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,\n    0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,\n    0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,\n    0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,\n    0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,\n    0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,\n    0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,\n    0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,\n    0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,\n    0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,\n    0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,\n    0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,\n    0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,\n    0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,\n    0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,\n    0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,\n    0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,\n    0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,\n    0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,\n    0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,\n    0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,\n    0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,\n    0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,\n    0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,\n    0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,\n    0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,\n    0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,\n    0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,\n    0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,\n    0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,\n    0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,\n    0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,\n    0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,\n    0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,\n    0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,\n    0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,\n    0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,\n    0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,\n    0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,\n    0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,\n    0x9324fd72UL\n  },\n  {\n    0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,\n    0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,\n    0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,\n    0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,\n    0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,\n    0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,\n    0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,\n    0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,\n    0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,\n    0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,\n    0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,\n    0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,\n    0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,\n    0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,\n    0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,\n    0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,\n    0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,\n    0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,\n    0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,\n    0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,\n    0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,\n    0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,\n    0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,\n    0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,\n    0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,\n    0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,\n    0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,\n    0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,\n    0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,\n    0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,\n    0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,\n    0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,\n    0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,\n    0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,\n    0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,\n    0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,\n    0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,\n    0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,\n    0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,\n    0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,\n    0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,\n    0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,\n    0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,\n    0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,\n    0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,\n    0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,\n    0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,\n    0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,\n    0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,\n    0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,\n    0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,\n    0xbe9834edUL\n  },\n  {\n    0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,\n    0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,\n    0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,\n    0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,\n    0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,\n    0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,\n    0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,\n    0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,\n    0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,\n    0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,\n    0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,\n    0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,\n    0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,\n    0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,\n    0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,\n    0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,\n    0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,\n    0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,\n    0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,\n    0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,\n    0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,\n    0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,\n    0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,\n    0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,\n    0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,\n    0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,\n    0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,\n    0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,\n    0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,\n    0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,\n    0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,\n    0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,\n    0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,\n    0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,\n    0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,\n    0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,\n    0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,\n    0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,\n    0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,\n    0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,\n    0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,\n    0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,\n    0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,\n    0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,\n    0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,\n    0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,\n    0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,\n    0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,\n    0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,\n    0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,\n    0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,\n    0xde0506f1UL\n  },\n  {\n    0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,\n    0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,\n    0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,\n    0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,\n    0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,\n    0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,\n    0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,\n    0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,\n    0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,\n    0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,\n    0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,\n    0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,\n    0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,\n    0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,\n    0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,\n    0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,\n    0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,\n    0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,\n    0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,\n    0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,\n    0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,\n    0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,\n    0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,\n    0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,\n    0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,\n    0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,\n    0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,\n    0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,\n    0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,\n    0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,\n    0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,\n    0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,\n    0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,\n    0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,\n    0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,\n    0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,\n    0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,\n    0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,\n    0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,\n    0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,\n    0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,\n    0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,\n    0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,\n    0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,\n    0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,\n    0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,\n    0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,\n    0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,\n    0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,\n    0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,\n    0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,\n    0x8def022dUL\n  },\n  {\n    0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,\n    0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,\n    0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,\n    0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,\n    0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,\n    0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,\n    0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,\n    0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,\n    0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,\n    0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,\n    0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,\n    0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,\n    0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,\n    0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,\n    0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,\n    0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,\n    0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,\n    0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,\n    0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,\n    0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,\n    0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,\n    0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,\n    0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,\n    0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,\n    0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,\n    0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,\n    0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,\n    0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,\n    0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,\n    0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,\n    0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,\n    0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,\n    0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,\n    0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,\n    0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,\n    0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,\n    0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,\n    0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,\n    0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,\n    0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,\n    0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,\n    0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,\n    0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,\n    0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,\n    0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,\n    0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,\n    0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,\n    0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,\n    0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,\n    0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,\n    0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,\n    0x72fd2493UL\n  },\n  {\n    0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,\n    0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,\n    0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,\n    0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,\n    0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,\n    0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,\n    0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,\n    0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,\n    0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,\n    0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,\n    0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,\n    0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,\n    0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,\n    0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,\n    0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,\n    0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,\n    0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,\n    0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,\n    0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,\n    0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,\n    0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,\n    0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,\n    0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,\n    0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,\n    0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,\n    0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,\n    0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,\n    0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,\n    0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,\n    0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,\n    0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,\n    0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,\n    0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,\n    0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,\n    0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,\n    0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,\n    0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,\n    0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,\n    0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,\n    0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,\n    0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,\n    0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,\n    0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,\n    0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,\n    0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,\n    0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,\n    0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,\n    0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,\n    0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,\n    0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,\n    0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,\n    0xed3498beUL\n  },\n  {\n    0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,\n    0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,\n    0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,\n    0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,\n    0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,\n    0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,\n    0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,\n    0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,\n    0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,\n    0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,\n    0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,\n    0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,\n    0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,\n    0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,\n    0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,\n    0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,\n    0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,\n    0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,\n    0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,\n    0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,\n    0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,\n    0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,\n    0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,\n    0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,\n    0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,\n    0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,\n    0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,\n    0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,\n    0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,\n    0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,\n    0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,\n    0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,\n    0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,\n    0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,\n    0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,\n    0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,\n    0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,\n    0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,\n    0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,\n    0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,\n    0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,\n    0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,\n    0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,\n    0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,\n    0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,\n    0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,\n    0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,\n    0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,\n    0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,\n    0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,\n    0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,\n    0xf10605deUL\n#endif\n  }\n};\n"
  },
  {
    "path": "src/tests/fileio/sb_fileio.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef STDC_HEADERS\n# include <stdio.h>\n# include <stdlib.h>\n# include <inttypes.h>\n#endif\n\n#ifdef HAVE_UNISTD_H \n# include <unistd.h>\n# include <sys/types.h>\n#endif\n#ifdef HAVE_SYS_STAT_H\n# include <sys/stat.h>\n#endif\n#ifdef HAVE_FCNTL_H\n# include <fcntl.h>\n#endif\n#ifdef HAVE_ERRNO_H\n# include <errno.h>\n#endif\n#ifdef HAVE_LIBAIO\n# include <libaio.h>\n#endif\n#ifdef HAVE_SYS_MMAN_H\n# include <sys/mman.h>\n#endif\n\n#include \"sysbench.h\"\n#include \"crc32.h\"\n#include \"sb_histogram.h\"\n#include \"sb_rand.h\"\n#include \"sb_util.h\"\n#include \"sb_counter.h\"\n\n/* Lengths of the checksum and the offset fields in a block */\n#define FILE_CHECKSUM_LENGTH sizeof(int)\n#define FILE_OFFSET_LENGTH sizeof(long)\n\ntypedef int FILE_DESCRIPTOR;\n#define VALID_FILE(fd) (fd >= 0)\n#define SB_INVALID_FILE (-1)\n#define FD_FMT \"%d\"\n\n/* Supported operations in request */\ntypedef enum\n{\n  MODE_READ,\n  MODE_WRITE,\n  MODE_REWRITE,\n  MODE_RND_READ,\n  MODE_RND_WRITE,\n  MODE_RND_RW,\n  MODE_MIXED\n} file_test_mode_t;\n\n/* fsync modes */\ntypedef enum\n{\n  FSYNC_ALL,\n  FSYNC_DATA\n} file_fsync_mode_t;\n\n/* File I/O modes */\ntypedef enum\n{\n  FILE_IO_MODE_SYNC,\n  FILE_IO_MODE_ASYNC,\n  FILE_IO_MODE_MMAP\n} file_io_mode_t;\n\ntypedef enum {\n  SB_FILE_FLAG_SYNC = 1,\n  SB_FILE_FLAG_DSYNC = 2,\n  SB_FILE_FLAG_DIRECTIO = 4\n} file_flags_t;\n\n#ifdef HAVE_LIBAIO\n/* Per-thread async I/O context */\ntypedef struct\n{\n  io_context_t    io_ctxt;      /* AIO context */\n  unsigned int    nrequests;    /* Current number of queued I/O requests */\n  struct io_event *events;      /* Array of events */\n} sb_aio_context_t;\n\n/* Async I/O operation */\ntypedef struct\n{\n  struct iocb   iocb; \n  sb_file_op_t  type;\n  ssize_t       len;\n} sb_aio_oper_t;\n\nstatic sb_aio_context_t *aio_ctxts;\n#endif\n\ntypedef struct\n{\n  void           *buffer;\n  unsigned int    buffer_file_id;\n  long long       buffer_pos;\n} sb_per_thread_t;\n\nstatic sb_per_thread_t\t*per_thread;\n\n/* Test options */\nstatic unsigned int      num_files;\nstatic long long         total_size;\nstatic long long         file_size;\nstatic int               file_block_size;\nstatic file_flags_t      file_extra_flags;\nstatic int               file_fsync_freq;\nstatic int               file_fsync_all;\nstatic int               file_fsync_end;\nstatic file_fsync_mode_t file_fsync_mode;\nstatic double            file_rw_ratio;\nstatic int               file_merged_requests;\nstatic long long         file_request_size;\nstatic file_io_mode_t    file_io_mode;\n#ifdef HAVE_LIBAIO\nstatic unsigned int      file_async_backlog;\n#endif\n\n/* statistical and other \"local\" variables */\nstatic long long       position;      /* current position in file */\nstatic unsigned int    current_file;  /* current file */\nstatic unsigned int    fsynced_file;  /* file number to be fsynced (periodic) */\n\nstatic int is_dirty;               /* any writes after last fsync series ? */\nstatic unsigned int req_performed; /* number of requests done */\n\nstatic const double mebibyte = 1024 * 1024;\nstatic const double megabyte = 1000 * 1000;\n\n#ifdef HAVE_MMAP\n/* Array of file mappings */\nstatic void          **mmaps;\nstatic unsigned long file_page_mask;\n#endif\n\n/* Array of file descriptors */\nstatic FILE_DESCRIPTOR *files;\n\n/* test mode type */\nstatic file_test_mode_t test_mode;\n\n/* Previous request needed for validation */\nstatic sb_file_request_t prev_req;\n\nstatic sb_arg_t fileio_args[] = {\n  SB_OPT(\"file-num\", \"number of files to create\", \"128\", INT),\n  SB_OPT(\"file-block-size\", \"block size to use in all IO operations\", \"16384\",\n         INT),\n  SB_OPT(\"file-total-size\", \"total size of files to create\", \"2G\", SIZE),\n  SB_OPT(\"file-test-mode\",\n         \"test mode {seqwr, seqrewr, seqrd, rndrd, rndwr, rndrw}\", NULL,\n         STRING),\n  SB_OPT(\"file-io-mode\", \"file operations mode {sync,async,mmap}\", \"sync\",\n         STRING),\n#ifdef HAVE_LIBAIO\n  SB_OPT(\"file-async-backlog\",\n         \"number of asynchronous operatons to queue per thread\", \"128\", INT),\n#endif\n  SB_OPT(\"file-extra-flags\",\n         \"list of additional flags to use to open files {sync,dsync,direct}\",\n         \"\", LIST),\n  SB_OPT(\"file-fsync-freq\", \"do fsync() after this number of requests \"\n         \"(0 - don't use fsync())\", \"100\", INT),\n  SB_OPT(\"file-fsync-all\", \"do fsync() after each write operation\", \"off\",\n         BOOL),\n  SB_OPT(\"file-fsync-end\", \"do fsync() at the end of test\", \"on\", BOOL),\n  SB_OPT(\"file-fsync-mode\",\n         \"which method to use for synchronization {fsync, fdatasync}\",\n         \"fsync\", STRING),\n  SB_OPT(\"file-merged-requests\", \"merge at most this number of IO requests \"\n         \"if possible (0 - don't merge)\", \"0\", INT),\n  SB_OPT(\"file-rw-ratio\", \"reads/writes ratio for combined test\", \"1.5\", DOUBLE),\n\n  SB_OPT_END\n};\n\n/* fileio test commands */\nstatic int file_cmd_prepare(void);\nstatic int file_cmd_cleanup(void);\n\n/* fileio test operations */\nstatic int file_init(void);\nstatic void file_print_mode(void);\nstatic int file_prepare(void);\nstatic sb_event_t file_next_event(int thread_id);\nstatic int file_execute_event(sb_event_t *, int);\nstatic int file_thread_done(int);\nstatic int file_done(void);\nstatic void file_report_intermediate(sb_stat_t *);\nstatic void file_report_cumulative(sb_stat_t *);\n\nstatic sb_test_t fileio_test =\n{\n  .sname = \"fileio\",\n  .lname = \"File I/O test\",\n  .ops = {\n    .init = file_init,\n    .prepare = file_prepare,\n    .print_mode = file_print_mode,\n    .next_event = file_next_event,\n    .execute_event = file_execute_event,\n    .report_intermediate = file_report_intermediate,\n    .report_cumulative = file_report_cumulative,\n    .thread_done = file_thread_done,\n    .done = file_done\n  },\n  .builtin_cmds = {\n   .prepare = file_cmd_prepare,\n   .cleanup = file_cmd_cleanup\n  },\n  .args = fileio_args\n};\n\n\nstatic int create_files(void);\nstatic int remove_files(void);\nstatic int parse_arguments(void);\nstatic void init_vars(void);\nstatic sb_event_t file_get_seq_request(void);\nstatic sb_event_t file_get_rnd_request(int thread_id);\nstatic void check_seq_req(sb_file_request_t *, sb_file_request_t *);\nstatic const char *get_io_mode_str(file_io_mode_t mode);\nstatic const char *get_test_mode_str(file_test_mode_t mode);\nstatic void file_fill_buffer(unsigned char *, unsigned int, size_t);\nstatic int file_validate_buffer(unsigned char  *, unsigned int, size_t);\n\n/* File operation wrappers */\nstatic int file_do_fsync(unsigned int, int);\nstatic int file_fsync(unsigned int, int);\nstatic ssize_t file_pread(unsigned int, void *, ssize_t, long long, int);\nstatic ssize_t file_pwrite(unsigned int, void *, ssize_t, long long, int);\n#ifdef HAVE_LIBAIO\nstatic int file_async_init(void);\nstatic int file_async_done(void);\nstatic int file_submit_or_wait(struct iocb *, sb_file_op_t, ssize_t, int);\nstatic int file_wait(int, long);\n#endif\n#ifdef HAVE_MMAP\nstatic int file_mmap_prepare(void);\nstatic int file_mmap_done(void);\n#endif\n\n/* Portability wrappers */\nstatic size_t sb_get_allocation_granularity(void);\nstatic void sb_free_memaligned(void *buf);\nstatic FILE_DESCRIPTOR sb_open(const char *);\nstatic int sb_create(const char *);\n\nint register_test_fileio(sb_list_t *tests)\n{\n  SB_LIST_ADD_TAIL(&fileio_test.listitem, tests);\n\n  return 0;\n}\n\n\nint file_init(void)\n{\n  if (parse_arguments())\n    return 1;\n  \n  files = (FILE_DESCRIPTOR *)malloc(num_files * sizeof(FILE_DESCRIPTOR));\n  if (files == NULL)\n  {\n    log_text(LOG_FATAL, \"Memory allocation failure.\");\n    return 1;\n  }\n\n#ifdef HAVE_LIBAIO\n  if (file_async_init())\n    return 1;\n#endif\n\n  init_vars();\n\n  return 0;\n}\n\n\nint file_prepare(void)\n{\n  unsigned int  i;\n  char          file_name[512];\n\n  for (i=0; i < num_files; i++)\n  {\n    snprintf(file_name, sizeof(file_name), \"test_file.%d\",i);\n    /* remove test files for creation test if they exist */\n    if (test_mode == MODE_WRITE)\n    {\n      unlink(file_name);\n      if (sb_create(file_name))\n      {\n        log_errno(LOG_FATAL, \"Cannot create file '%s'\", file_name);\n        return 1;\n      }\n    }\n\n    log_text(LOG_DEBUG, \"Opening file: %s\", file_name);\n    files[i] = sb_open(file_name);\n    if (!VALID_FILE(files[i]))\n    {\n      log_errno(LOG_FATAL, \"Cannot open file '%s'\", file_name);\n      log_text(LOG_WARNING, \"Did you forget to run the prepare step?\");\n      return 1;\n    }\n\n    if (test_mode == MODE_WRITE)\n      continue;\n\n    /* Validate file size */\n    struct stat buf;\n    if (fstat(files[i], &buf))\n    {\n      log_errno(LOG_FATAL, \"fstat() failed on file '%s'\", file_name);\n      return 1;\n    }\n    if (buf.st_size < file_size)\n    {\n      char ss1[16], ss2[16];\n      log_text(LOG_FATAL,\n               \"Size of file '%s' is %sB, but at least %sB is expected.\",\n               file_name,\n               sb_print_value_size(ss1, sizeof(ss1), buf.st_size),\n               sb_print_value_size(ss2, sizeof(ss2), file_size));\n      log_text(LOG_WARNING,\n               \"Did you run 'prepare' with different --file-total-size or \"\n               \"--file-num values?\");\n      return 1;\n    }\n  }\n\n#ifdef HAVE_MMAP\n  if (file_mmap_prepare())\n    return 1;\n#endif\n\n  return 0; \n}\n\n\nint file_done(void)\n{\n  unsigned int  i;\n  \n  for (i = 0; i < num_files; i++)\n    close(files[i]);\n\n#ifdef HAVE_LIBAIO\n  if (file_async_done())\n    return 1;\n#endif\n\n#ifdef HAVE_MMAP\n  if (file_mmap_done())\n    return 1;\n#endif\n\n  for (i = 0; i < sb_globals.threads; i++)\n  {\n    if (per_thread[i].buffer != NULL)\n      sb_free_memaligned(per_thread[i].buffer);\n  }\n\n  free(per_thread);\n\n  return 0;\n}\n\nsb_event_t file_next_event(int thread_id)\n{\n  if (test_mode == MODE_WRITE || test_mode == MODE_REWRITE ||\n      test_mode == MODE_READ)\n    return file_get_seq_request();\n  \n  \n  return file_get_rnd_request(thread_id);\n}\n\n\n/* Get sequential read or write request */\n\n\nsb_event_t file_get_seq_request(void)\n{\n  sb_event_t           sb_req;\n  sb_file_request_t    *file_req = &sb_req.u.file_request;\n\n  sb_req.type = SB_REQ_TYPE_FILE;\n  SB_THREAD_MUTEX_LOCK();\n  \n  /* assume function is called with correct mode always */\n  if (test_mode == MODE_WRITE || test_mode == MODE_REWRITE)\n    file_req->operation = FILE_OP_TYPE_WRITE;\n  else     \n    file_req->operation = FILE_OP_TYPE_READ;\n\n  /* See whether it's time to fsync file(s) */\n  if (file_fsync_freq != 0 && file_req->operation == FILE_OP_TYPE_WRITE &&\n      is_dirty && req_performed % file_fsync_freq == 0)\n  {\n    file_req->operation = FILE_OP_TYPE_FSYNC;\n    file_req->file_id = fsynced_file;\n    file_req->pos = 0;\n    file_req->size = 0;\n    fsynced_file++;\n    if (fsynced_file == num_files)\n    {\n      fsynced_file = 0;\n      is_dirty = 0;\n    }\n\n    SB_THREAD_MUTEX_UNLOCK();\n    return sb_req;\n  }\n\n  req_performed++;\n\n  if (file_req->operation == FILE_OP_TYPE_WRITE)\n    is_dirty = 1;\n\n  /* Rewind to the first file if all files are processed */\n  if (current_file == num_files)\n  {\n    position= 0;\n    current_file= 0;\n  }\n\n  file_req->file_id = current_file;\n  file_req->pos = position;\n  file_req->size = SB_MIN(file_request_size, file_size - position);\n\n  position += file_req->size;\n\n  /* scroll to the next file if not already out of bound */\n  if (position == file_size)\n  {\n    current_file++;\n    position=0;\n  }      \n  \n  if (sb_globals.validate)\n  {\n    check_seq_req(&prev_req, file_req);\n    prev_req = *file_req;\n  }\n  \n  SB_THREAD_MUTEX_UNLOCK(); \n\n  return sb_req;    \n}\n\n\n/* Request generatior for random tests */\n\n\nsb_event_t file_get_rnd_request(int thread_id)\n{\n  sb_event_t           sb_req;\n  sb_file_request_t    *file_req = &sb_req.u.file_request;\n  unsigned long long   tmppos;\n  int                  mode = test_mode;\n  unsigned int         i;\n\n  sb_req.type = SB_REQ_TYPE_FILE;\n\n  if (test_mode == MODE_RND_RW)\n  {\n    mode = (sb_counter_val(thread_id, SB_CNT_READ) + 1.0) /\n        (sb_counter_val(thread_id, SB_CNT_WRITE) + 1.0) < file_rw_ratio ?\n      MODE_RND_READ : MODE_RND_WRITE;\n  }\n\n  /*\n    is_dirty is only set if writes are done and cleared after all files\n    are synced\n  */\n  if (file_fsync_freq != 0 && is_dirty)\n  {\n    if (req_performed % file_fsync_freq == 0)\n    {\n      file_req->operation = FILE_OP_TYPE_FSYNC;  \n      file_req->file_id = fsynced_file;\n      file_req->pos = 0;\n      file_req->size = 0;\n      fsynced_file++;\n      if (fsynced_file == num_files)\n      {\n        fsynced_file = 0;\n        is_dirty = 0;\n      }\n\n      SB_THREAD_MUTEX_UNLOCK();\n      return sb_req;\n    }\n  }\n\n  if (mode==MODE_RND_WRITE) /* mode shall be WRITE or RND_WRITE only */\n    file_req->operation = FILE_OP_TYPE_WRITE;\n  else\n    file_req->operation = FILE_OP_TYPE_READ;\n\nretry:\n  tmppos = (long long) (sb_rand_uniform_double() * total_size);\n  tmppos = tmppos - (tmppos % (long long) file_block_size);\n  file_req->file_id = (int) (tmppos / (long long) file_size);\n  file_req->pos = (long long) (tmppos % (long long) file_size);\n  file_req->size = SB_MIN(file_block_size, file_size - file_req->pos);\n\n  if (sb_globals.validate)\n  {\n    /*\n       For the multi-threaded validation test we have to make sure the block is\n       not being used by another thread\n    */\n    for (i = 0; i < sb_globals.threads; i++)\n    {\n      if (i != (unsigned) thread_id && per_thread[i].buffer_file_id == file_req->file_id &&\n          per_thread[i].buffer_pos == file_req->pos)\n        goto retry;\n    }\n  }\n\n  per_thread[thread_id].buffer_file_id = file_req->file_id;\n  per_thread[thread_id].buffer_pos = file_req->pos;\n\n  req_performed++;\n  if (file_req->operation == FILE_OP_TYPE_WRITE) \n    is_dirty = 1;\n\n  SB_THREAD_MUTEX_UNLOCK();        \n  return sb_req;\n}\n\n\nint file_execute_event(sb_event_t *sb_req, int thread_id)\n{\n  FILE_DESCRIPTOR    fd;\n  sb_file_request_t *file_req = &sb_req->u.file_request;\n\n  if (sb_globals.debug)\n  {\n    log_text(LOG_DEBUG,\n             \"Executing request, operation: %d, file_id: %d, pos: %d, \"\n             \"size: %d\",\n             file_req->operation,\n             file_req->file_id,\n             (int)file_req->pos,\n             (int)file_req->size);\n  }\n  \n  /* Check request parameters */\n  if (file_req->file_id > num_files)\n  {\n    log_text(LOG_FATAL, \"Incorrect file id in request: %u\", file_req->file_id);\n    return 1;\n  }\n  if (file_req->pos + file_req->size > file_size)\n  {\n    log_text(LOG_FATAL, \"I/O request exceeds file size. \"\n             \"file id: %d file size: %lld req offset: %lld req size: %lld\",\n             file_req->file_id, (long long) file_size,\n             (long long) file_req->pos, (long long) file_req->size);\n    return 1;\n  }\n  fd = files[file_req->file_id];\n\n  switch (file_req->operation) {\n    case FILE_OP_TYPE_NULL:\n      log_text(LOG_FATAL, \"Execute of NULL request called !, aborting\");\n      return 1;\n    case FILE_OP_TYPE_WRITE:\n\n      /* Store checksum and offset in a buffer when in validation mode */\n      if (sb_globals.validate)\n        file_fill_buffer(per_thread[thread_id].buffer, file_req->size, file_req->pos);\n                         \n      if(file_pwrite(file_req->file_id, per_thread[thread_id].buffer,\n                     file_req->size, file_req->pos, thread_id)\n         != (ssize_t)file_req->size)\n      {\n        log_errno(LOG_FATAL, \"Failed to write file! file: \" FD_FMT \" pos: %lld\", \n                  fd, (long long)file_req->pos);\n        return 1;\n      }\n\n      /* Check if we have to fsync each write operation */\n      if (file_fsync_all && file_fsync(file_req->file_id, thread_id))\n          return 1;\n\n      /* In async mode stats will me updated on AIO requests completion */\n      if (file_io_mode != FILE_IO_MODE_ASYNC)\n      {\n        sb_counter_inc(thread_id, SB_CNT_WRITE);\n        sb_counter_add(thread_id, SB_CNT_BYTES_WRITTEN, file_req->size);\n      }\n\n      break;\n    case FILE_OP_TYPE_READ:\n      if(file_pread(file_req->file_id, per_thread[thread_id].buffer,\n                    file_req->size, file_req->pos, thread_id)\n         != (ssize_t)file_req->size)\n      {\n        log_errno(LOG_FATAL, \"Failed to read file! file: \" FD_FMT \" pos: %lld\",\n                  fd, (long long)file_req->pos);\n        return 1;\n      }\n\n      /* Validate block if run with validation enabled */\n      if (sb_globals.validate &&\n          file_validate_buffer(per_thread[thread_id].buffer, file_req->size, file_req->pos))\n      {\n        log_text(LOG_FATAL,\n          \"Validation failed on file \" FD_FMT \", block offset %lld, exiting...\",\n                 file_req->file_id, (long long) file_req->pos);\n        return 1;\n      }\n\n      /* In async mode stats will me updated on AIO requests completion */\n      if(file_io_mode != FILE_IO_MODE_ASYNC)\n      {\n        sb_counter_inc(thread_id, SB_CNT_READ);\n        sb_counter_add(thread_id, SB_CNT_BYTES_READ, file_req->size);\n      }\n\n      break;\n    case FILE_OP_TYPE_FSYNC:\n      /* Ignore fsync requests if we are already fsync'ing each operation */\n      if (file_fsync_all)\n        break;\n      if(file_fsync(file_req->file_id, thread_id))\n        return 1;\n\n      break;\n    default:\n      log_text(LOG_FATAL, \"Execute of UNKNOWN file request type called (%d)!, \"\n               \"aborting\", file_req->operation);\n      return 1;\n  }\n  return 0;\n\n}\n\nstatic void print_file_extra_flags(void)\n{\n  log_text(LOG_NOTICE, \"Extra file open flags: %s%s%s%s\",\n           file_extra_flags == 0 ? \"(none)\" : \"\",\n           file_extra_flags & SB_FILE_FLAG_SYNC ? \"sync \" : \"\",\n           file_extra_flags & SB_FILE_FLAG_DSYNC ? \"dsync \": \"\",\n           file_extra_flags & SB_FILE_FLAG_DIRECTIO ? \"directio\" : \"\"\n           );\n}\n\nvoid file_print_mode(void)\n{\n  char sizestr[16];\n\n  print_file_extra_flags();\n  log_text(LOG_NOTICE, \"%d files, %sB each\", num_files,\n           sb_print_value_size(sizestr, sizeof(sizestr), file_size));\n  log_text(LOG_NOTICE, \"%sB total file size\",\n           sb_print_value_size(sizestr, sizeof(sizestr),\n                               file_size * num_files));\n  log_text(LOG_NOTICE, \"Block size %sB\",\n           sb_print_value_size(sizestr, sizeof(sizestr), file_block_size));\n  if (file_merged_requests > 0)\n    log_text(LOG_NOTICE, \"Merging requests up to %sB for sequential IO.\",\n             sb_print_value_size(sizestr, sizeof(sizestr),\n                                 file_request_size));\n\n  switch (test_mode)\n  {\n    case MODE_RND_WRITE:\n    case MODE_RND_READ:\n    case MODE_RND_RW:\n      log_text(LOG_NOTICE, \"Number of IO requests: %\" PRIu64,\n               sb_globals.max_events);\n      log_text(LOG_NOTICE,\n               \"Read/Write ratio for combined random IO test: %2.2f\",\n               file_rw_ratio);\n      break;\n    default:\n      break;\n  }\n\n  if (file_fsync_freq > 0)\n    log_text(LOG_NOTICE,\n             \"Periodic FSYNC enabled, calling fsync() each %d requests.\",\n             file_fsync_freq);\n\n  if (file_fsync_end)\n    log_text(LOG_NOTICE, \"Calling fsync() at the end of test, Enabled.\");\n\n  if (file_fsync_all)\n    log_text(LOG_NOTICE, \"Calling fsync() after each write operation.\");\n\n  log_text(LOG_NOTICE, \"Using %s I/O mode\", get_io_mode_str(file_io_mode));\n\n  if (sb_globals.validate)\n    log_text(LOG_NOTICE, \"Using checksums validation.\");\n  \n  log_text(LOG_NOTICE, \"Doing %s test\", get_test_mode_str(test_mode));\n}\n\n/* Print intermediate test statistics. */\n\nvoid file_report_intermediate(sb_stat_t *stat)\n{\n  const double seconds = stat->time_interval;\n\n  log_timestamp(LOG_NOTICE, stat->time_total,\n                \"reads: %4.2f MiB/s writes: %4.2f MiB/s fsyncs: %4.2f/s \"\n                \"latency (ms,%u%%): %4.3f\",\n                stat->bytes_read / mebibyte / seconds,\n                stat->bytes_written / mebibyte / seconds,\n                stat->other / seconds,\n                sb_globals.percentile,\n                SEC2MS(stat->latency_pct));\n}\n\n/* Print cumulative test statistics. */\n\nvoid file_report_cumulative(sb_stat_t *stat)\n{\n  const double seconds = stat->time_interval;\n\n  log_text(LOG_NOTICE, \"\\n\"\n           \"Throughput:\\n\"\n           \"         read:  IOPS=%4.2f %4.2f MiB/s (%4.2f MB/s)\\n\"\n           \"         write: IOPS=%4.2f %4.2f MiB/s (%4.2f MB/s)\\n\"\n           \"         fsync: IOPS=%4.2f\",\n           stat->reads / seconds,\n           stat->bytes_read / mebibyte / seconds,\n           stat->bytes_read / megabyte / seconds,\n           stat->writes / seconds,\n           stat->bytes_written / mebibyte / seconds,\n           stat->bytes_written / megabyte / seconds,\n           stat->other / seconds\n           );\n\n  log_text(LOG_NOTICE, \"\");\n\n  log_text(LOG_NOTICE, \"Latency (ms):\");\n  log_text(LOG_NOTICE, \"         min:                            %10.2f\",\n           SEC2MS(stat->latency_min));\n  log_text(LOG_NOTICE, \"         avg:                            %10.2f\",\n           SEC2MS(stat->latency_avg));\n  log_text(LOG_NOTICE, \"         max:                            %10.2f\",\n           SEC2MS(stat->latency_max));\n\n  if (sb_globals.percentile > 0)\n    log_text(LOG_NOTICE, \"        %3dth percentile:                %10.2f\",\n             sb_globals.percentile, SEC2MS(stat->latency_pct));\n  else\n    log_text(LOG_NOTICE, \"         percentile stats:               disabled\");\n\n  log_text(LOG_NOTICE, \"         sum:                            %10.2f\",\n           SEC2MS(stat->latency_sum));\n  log_text(LOG_NOTICE, \"\");\n}\n\n/* Return name for I/O mode */\n\nconst char *get_io_mode_str(file_io_mode_t mode)\n{\n  switch (mode) {\n    case FILE_IO_MODE_SYNC:\n      return \"synchronous\";\n    case FILE_IO_MODE_ASYNC:\n      return \"asynchronous\";\n    case FILE_IO_MODE_MMAP:\n#if SIZEOF_SIZE_T == 4\n      return \"slow mmaped\";\n#else\n      return \"fast mmaped\";\n#endif\n    default:\n      break;\n  }\n\n  return \"(unknown)\";\n}\n\n\n/* Return name for test mode */\n\n\nconst char *get_test_mode_str(file_test_mode_t mode)\n{\n  switch (mode) {\n    case MODE_WRITE:\n      return \"sequential write (creation)\";\n    case MODE_REWRITE:\n      return \"sequential rewrite\";\n    case MODE_READ:\n      return \"sequential read\";\n    case MODE_RND_READ:\n      return \"random read\"; \n    case MODE_RND_WRITE:\n      return \"random write\";\n    case MODE_RND_RW:\n      return \"random r/w\";\n    case MODE_MIXED:\n      return \"mixed\";\n    default:\n      break;\n  }\n  \n  return \"(unknown)\";\n}\n\n\n/*\n  Converts the argument of --file-extra-flags to platform-specific open() flags.\n  Returns 1 on error, 0 on success.\n*/\n\nstatic int convert_extra_flags(file_flags_t extra_flags, int *open_flags)\n{\n  if (extra_flags)\n  {\n    *open_flags = 0;\n\n    if (extra_flags & SB_FILE_FLAG_SYNC)\n    {\n      *open_flags |= O_SYNC;\n    }\n\n    if (extra_flags & SB_FILE_FLAG_DSYNC)\n    {\n#ifdef O_DSYNC\n      *open_flags |= O_DSYNC;\n#else\n      log_text(LOG_FATAL,\n               \"--file-extra-flags=dsync is not supported on this platform.\");\n      return 1;\n#endif\n    }\n\n    if (extra_flags & SB_FILE_FLAG_DIRECTIO)\n    {\n#ifdef HAVE_DIRECTIO\n      /* Will call directio(3) later */\n#elif defined(O_DIRECT)\n      *open_flags |= O_DIRECT;\n#else\n      log_text(LOG_FATAL,\n               \"--file-extra-flags=direct is not supported on this platform.\");\n      return 1;\n#endif\n    }\n\n    if (extra_flags > SB_FILE_FLAG_DIRECTIO)\n    {\n      log_text(LOG_FATAL, \"Unknown extra flags value: %d\", (int) extra_flags);\n      return 1;\n    }\n  }\n\n  return 0;\n}\n\n/* Create files of necessary size for test */\n\nint create_files(void)\n{\n  unsigned int       i;\n  int                fd;\n  char               file_name[512];\n  long long          offset;\n  long long          written = 0;\n  sb_timer_t         t;\n  double             seconds;\n  int                flags = 0;\n\n  log_text(LOG_NOTICE, \"%d files, %ldKb each, %ldMb total\", num_files,\n           (long)(file_size / 1024),\n           (long)((file_size * num_files) / (1024 * 1024)));\n  log_text(LOG_NOTICE, \"Creating files for the test...\");\n  print_file_extra_flags();\n\n  if (convert_extra_flags(file_extra_flags, &flags))\n    return 1;\n\n  sb_timer_init(&t);\n  sb_timer_start(&t);\n\n  for (i=0; i < num_files; i++)\n  {\n    snprintf(file_name, sizeof(file_name), \"test_file.%d\",i);\n\n    fd = open(file_name, O_CREAT | O_WRONLY | flags, S_IRUSR | S_IWUSR);\n    if (fd < 0)\n    {\n      log_errno(LOG_FATAL, \"Can't open file\");\n      return 1; \n    }\n\n    offset = (long long) lseek(fd, 0, SEEK_END);\n\n    if (offset >= file_size)\n      log_text(LOG_NOTICE, \"Reusing existing file %s\", file_name);\n    else if (offset > 0)\n      log_text(LOG_NOTICE, \"Extending existing file %s\", file_name);\n    else\n      log_text(LOG_NOTICE, \"Creating file %s\", file_name);\n\n    for (; offset < file_size;\n         written += file_block_size, offset += file_block_size)\n    {\n      /*\n        If in validation mode, fill buffer with random values\n        and write checksum. Not called in parallel, so use per_thread[0].\n      */\n      if (sb_globals.validate)\n        file_fill_buffer(per_thread[0].buffer, file_block_size, offset);\n                         \n      if (write(fd, per_thread[0].buffer, file_block_size) < 0)\n        goto error;\n    }\n    \n    /* fsync files to prevent cache flush from affecting test results */\n    fsync(fd);\n    close(fd);\n  }\n\n  seconds = NS2SEC(sb_timer_stop(&t));\n\n  if (written > 0)\n    log_text(LOG_NOTICE, \"%llu bytes written in %.2f seconds (%.2f MiB/sec).\",\n             written, seconds,\n             (double) (written / mebibyte) / seconds);\n  else\n    log_text(LOG_NOTICE, \"No bytes written.\");\n\n  return 0;\n\n error:\n  log_errno(LOG_FATAL, \"Failed to write file!\");\n  close(fd);\n  return 1;\n}\n\n\n/* Remove test files */\n\n\nint remove_files(void)\n{\n  unsigned int i;\n  char         file_name[512];\n  \n  log_text(LOG_NOTICE, \"Removing test files...\");\n  \n  for (i = 0; i < num_files; i++)\n  {\n    snprintf(file_name, sizeof(file_name), \"test_file.%d\",i);\n    unlink(file_name);\n  }\n\n  return 0;\n}\n\n\n/* 'prepare' command for fileio test */\n\n\nint file_cmd_prepare(void)\n{\n  if (parse_arguments())\n    return 1;\n\n  /*\n    Make sure that files do not exist for 'sequential write' test mode,\n    create test files for other test modes\n  */\n  if (test_mode == MODE_WRITE)\n    return remove_files();\n\n  return create_files();\n}\n\n\n/* 'cleanup' command for fileio test */\n\n\nint file_cmd_cleanup(void)\n{\n  if (parse_arguments())\n    return 1;\n\n  return remove_files();\n}\n\nvoid init_vars(void)\n{\n  position = 0; /* position in file */\n  current_file = 0;\n  fsynced_file = 0; /* for counting file to be fsynced */\n  req_performed = 0;\n  is_dirty = 0;\n  if (sb_globals.validate)\n  {\n    prev_req.size = 0;\n    prev_req.operation = FILE_OP_TYPE_NULL;\n    prev_req.file_id = 0;\n    prev_req.pos = 0;\n  }\n}\n\n/*\n  Before the benchmark is stopped, issue fsync() if --file-fsync-end is used,\n  and wait for all async operations to complete.\n*/\n\nint file_thread_done(int thread_id)\n{\n  if (file_fsync_end && test_mode != MODE_READ && test_mode != MODE_RND_READ)\n  {\n    for (unsigned i = 0; i < num_files; i++)\n    {\n      if(file_fsync(i, thread_id))\n        return 1;\n    }\n  }\n\n#ifdef HAVE_LIBAIO\n  if (file_io_mode == FILE_IO_MODE_ASYNC && aio_ctxts[thread_id].nrequests > 0)\n    return file_wait(thread_id, aio_ctxts[thread_id].nrequests);\n#endif\n\n  return 0;\n}\n\n#ifdef HAVE_LIBAIO\n/* Allocate async contexts pool */\n\n\nint file_async_init(void)\n{\n  unsigned int i;\n\n  if (file_io_mode != FILE_IO_MODE_ASYNC)\n    return 0;\n  \n  file_async_backlog = sb_get_value_int(\"file-async-backlog\");\n  if (file_async_backlog <= 0) {\n    log_text(LOG_FATAL, \"Invalid value of file-async-backlog: %d\",\n             file_async_backlog);\n    return 1;\n  }\n\n  aio_ctxts = (sb_aio_context_t *)calloc(sb_globals.threads,\n                                         sizeof(sb_aio_context_t));\n  for (i = 0; i < sb_globals.threads; i++)\n  {\n    if (io_queue_init(file_async_backlog, &aio_ctxts[i].io_ctxt))\n    {\n      log_errno(LOG_FATAL, \"io_queue_init() failed!\");\n      return 1;\n    }\n      \n    aio_ctxts[i].events = (struct io_event *)malloc(file_async_backlog *\n                                                    sizeof(struct io_event));\n    if (aio_ctxts[i].events == NULL)\n    {\n      log_errno(LOG_FATAL, \"Failed to allocate async I/O context!\");\n      return 1;\n    }\n  }\n\n  return 0;\n}\n\n\n/* Destroy async contexts pool */\n\n\nint file_async_done(void)\n{\n  unsigned int i;\n  \n  if (file_io_mode != FILE_IO_MODE_ASYNC)\n    return 0;\n\n  for (i = 0; i < sb_globals.threads; i++)\n  {\n    io_queue_release(aio_ctxts[i].io_ctxt);\n    free(aio_ctxts[i].events);\n  }\n  \n  free(aio_ctxts);\n\n  return 0;\n}  \n\n/*\n  Submit async I/O requests until the length of request queue exceeds\n  the limit. Then wait for at least one request to complete and proceed.\n*/\n\n\nint file_submit_or_wait(struct iocb *iocb, sb_file_op_t type, ssize_t len,\n                        int thread_id)\n{\n  sb_aio_oper_t   *oper;\n  struct iocb     *iocbp;\n\n  oper = (sb_aio_oper_t *)malloc(sizeof(sb_aio_oper_t));\n  if (oper == NULL)\n  {\n    log_text(LOG_FATAL, \"Failed to allocate AIO operation!\");\n    return 1;\n  }\n\n  memcpy(&oper->iocb, iocb, sizeof(*iocb));\n  oper->type = type;\n  oper->len = len;\n  iocbp = &oper->iocb;\n\n  if (io_submit(aio_ctxts[thread_id].io_ctxt, 1, &iocbp) < 1)\n  {\n    log_errno(LOG_FATAL, \"io_submit() failed!\");\n    return 1;\n  }\n  \n  aio_ctxts[thread_id].nrequests++;\n  if (aio_ctxts[thread_id].nrequests < file_async_backlog)\n    return 0;\n  \n  return file_wait(thread_id, 1);\n}\n\n\n/*\n  Wait for at least nreq I/O requests to complete\n*/\n\n\nint file_wait(int thread_id, long nreq)\n{ \n  long            i;\n  long            nr;\n  struct io_event *event;\n  sb_aio_oper_t   *oper;\n  struct iocb     *iocbp;\n\n  /* Try to read some events */\n#ifdef HAVE_OLD_GETEVENTS\n  (void)nreq; /* unused */\n  nr = io_getevents(aio_ctxts[thread_id].io_ctxt, file_async_backlog,\n                    aio_ctxts[thread_id].events, NULL);\n#else\n  nr = io_getevents(aio_ctxts[thread_id].io_ctxt, nreq, file_async_backlog,\n                    aio_ctxts[thread_id].events, NULL);\n#endif\n  if (nr < 1)\n  {\n    log_errno(LOG_FATAL, \"io_getevents() failed!\");\n    return 1;\n  }\n\n  /* Verify results */\n  for (i = 0; i < nr; i++)\n  {\n    event = (struct io_event *)aio_ctxts[thread_id].events + i;\n    iocbp = (struct iocb *)(unsigned long)event->obj;\n    oper = (sb_aio_oper_t *)iocbp;\n    switch (oper->type) {\n    case FILE_OP_TYPE_FSYNC:\n        if (event->res != 0)\n        {\n          log_text(LOG_FATAL, \"Asynchronous fsync failed!\\n\");\n          return 1;\n        }\n\n        sb_counter_inc(thread_id, SB_CNT_OTHER);\n\n        break;\n\n    case FILE_OP_TYPE_READ:\n        if ((ssize_t)event->res != oper->len)\n        {\n          log_text(LOG_FATAL, \"Asynchronous read failed!\\n\");\n          return 1;\n        }\n\n        sb_counter_inc(thread_id, SB_CNT_READ);\n        sb_counter_add(thread_id, SB_CNT_BYTES_READ, oper->len);\n\n        break;\n\n    case FILE_OP_TYPE_WRITE:\n        if ((ssize_t)event->res != oper->len)\n        {\n          log_text(LOG_FATAL, \"Asynchronous write failed!\\n\");\n          return 1;\n        }\n\n        sb_counter_inc(thread_id, SB_CNT_WRITE);\n        sb_counter_add(thread_id, SB_CNT_BYTES_WRITTEN, oper->len);\n\n        break;\n\n    default:\n        break;\n    }\n    free(oper);\n    aio_ctxts[thread_id].nrequests--;\n  }\n  \n  return 0;\n}\n#endif /* HAVE_LIBAIO */\n\n                        \n#ifdef HAVE_MMAP\n/* Initialize data structures required for mmap'ed I/O operations */\n\n\nint file_mmap_prepare(void)\n{\n  unsigned int i;\n  \n  if (file_io_mode != FILE_IO_MODE_MMAP)\n    return 0;\n\n  file_page_mask = ~(sb_get_allocation_granularity() - 1);\n  \n  /* Extend file sizes for sequential write test */\n  if (test_mode == MODE_WRITE)\n    for (i = 0; i < num_files; i++)\n    {\n      if (ftruncate(files[i], file_size))\n      {\n        log_errno(LOG_FATAL, \"ftruncate() failed on file %d\", i);\n        return 1;\n      }\n    }\n\n#if SIZEOF_SIZE_T > 4\n  mmaps = (void **)malloc(num_files * sizeof(void *));\n  for (i = 0; i < num_files; i++)\n  {\n    mmaps[i] = mmap(NULL, file_size, PROT_READ | PROT_WRITE, MAP_SHARED,\n                    files[i], 0);\n    if (mmaps[i] == MAP_FAILED)\n    {\n      log_errno(LOG_FATAL, \"mmap() failed on file %d\", i);\n      return 1;\n    }\n  }\n#else\n  (void)i; /* unused */\n#endif\n  \n  return 0;\n}\n\n\n/* Destroy data structure used by mmap'ed I/O operations */\n\n\nint file_mmap_done(void)\n{\n  unsigned int i;\n\n  if (file_io_mode != FILE_IO_MODE_MMAP)\n    return 0;\n\n#if SIZEOF_SIZE_T > 4\n  for (i = 0; i < num_files; i++)\n    munmap(mmaps[i], file_size);\n\n  free(mmaps);\n#else\n   (void)i; /* unused */\n#endif\n  \n  return 0;\n}\n#endif /* HAVE_MMAP */\n\nint file_do_fsync(unsigned int id, int thread_id)\n{\n  FILE_DESCRIPTOR fd = files[id];\n#ifdef HAVE_LIBAIO\n  struct iocb iocb;\n#else\n  (void)thread_id; /* unused */\n#endif\n\n  /*\n    FIXME: asynchronous fsync support is missing\n    in Linux kernel at the moment\n  */\n  if (file_io_mode == FILE_IO_MODE_SYNC\n      || file_io_mode == FILE_IO_MODE_ASYNC\n#if defined(HAVE_MMAP) && SIZEOF_SIZE_T == 4\n      /* Use fsync in mmaped mode on 32-bit architectures */\n      || file_io_mode == FILE_IO_MODE_MMAP\n#endif\n      )\n  {\n    if (file_fsync_mode == FSYNC_ALL)\n      return fsync(fd);\n\n#ifdef F_FULLFSYNC\n      return fcntl(fd, F_FULLFSYNC) != -1;\n#elif defined(HAVE_FDATASYNC)\n    return fdatasync(fd);\n#else\n    log_text(LOG_ALERT, \"Unknown fsync mode: %d\", file_fsync_mode);\n    return -1;\n#endif\n\n  }\n#ifdef HAVE_LIBAIO\n  else if (file_io_mode == FILE_IO_MODE_ASYNC)\n  {\n    /* Use asynchronous fsync */\n    if (file_fsync_mode == FSYNC_ALL)\n      io_prep_fsync(&iocb, fd);\n    else\n      io_prep_fdsync(&iocb, fd);\n\n    return file_submit_or_wait(&iocb, FILE_OP_TYPE_FSYNC, 0, thread_id);\n  }\n#endif\n#ifdef HAVE_MMAP\n  /* Use msync on file on 64-bit architectures */\n  else if (file_io_mode == FILE_IO_MODE_MMAP)\n  {\n    return msync(mmaps[id], file_size, MS_SYNC | MS_INVALIDATE);\n  }\n#endif\n\n  return 1; /* Unknown I/O mode */\n}\n\n\nint file_fsync(unsigned int id, int thread_id)\n{\n  if (file_do_fsync(id, thread_id))\n  {\n    log_errno(LOG_FATAL, \"Failed to fsync file! file: \" FD_FMT, files[id]);\n    return 1;\n  }\n\n  sb_counter_inc(thread_id, SB_CNT_OTHER);\n\n  return 0;\n}\n\n\nssize_t file_pread(unsigned int file_id, void *buf, ssize_t count,\n                   long long offset, int thread_id)\n{\n  FILE_DESCRIPTOR fd = files[file_id];\n#ifdef HAVE_MMAP\n  void        *start;\n  long long    page_addr;\n  long long    page_offset;\n#endif\n#ifdef HAVE_LIBAIO\n  struct iocb iocb;\n#else\n  (void)thread_id; /* unused */\n#endif\n    \n  if (file_io_mode == FILE_IO_MODE_SYNC)\n    return pread(fd, buf, count, offset);\n#ifdef HAVE_LIBAIO\n  else if (file_io_mode == FILE_IO_MODE_ASYNC)\n  {\n    /* Use asynchronous read */\n    io_prep_pread(&iocb, fd, buf, count, offset);\n\n    if (file_submit_or_wait(&iocb, FILE_OP_TYPE_READ, count, thread_id))\n      return 0;\n\n    return count;\n  }\n#endif\n#ifdef HAVE_MMAP\n  else if (file_io_mode == FILE_IO_MODE_MMAP)\n  {\n# if SIZEOF_SIZE_T == 4\n    /* Create file mapping for each I/O operation on 32-bit platforms */\n    page_addr = offset & file_page_mask;\n    page_offset = offset - page_addr;\n    start = mmap(NULL, count + page_offset, PROT_READ, MAP_SHARED,\n                 fd, page_addr);\n    if (start == MAP_FAILED)\n      return 0;\n    memcpy(buf, (char *)start + page_offset, count);\n    munmap(start, count + page_offset);\n    return count;\n# else\n    (void)start; /* unused */\n    (void)page_addr; /* unused */\n    (void)page_offset; /* unused */\n    \n    /* We already have all files mapped on 64-bit platforms */\n    memcpy(buf, (char *)mmaps[file_id] + offset, count);\n\n    return count;\n# endif\n  }\n#endif /* HAVE_MMAP */\n  \n  return 1; /* Unknown I/O mode */\n}\n\n\nssize_t file_pwrite(unsigned int file_id, void *buf, ssize_t count,\n                    long long offset, int thread_id)\n{\n  FILE_DESCRIPTOR fd = files[file_id];\n#ifdef HAVE_MMAP\n  void        *start;\n  size_t       page_addr;\n  size_t       page_offset;\n#endif  \n#ifdef HAVE_LIBAIO\n  struct iocb iocb;\n#else  \n  (void)thread_id; /* unused */\n#endif\n  \n  if (file_io_mode == FILE_IO_MODE_SYNC)\n    return pwrite(fd, buf, count, offset);\n#ifdef HAVE_LIBAIO\n  else if (file_io_mode == FILE_IO_MODE_ASYNC)\n  {\n    /* Use asynchronous write */\n    io_prep_pwrite(&iocb, fd, buf, count, offset);\n\n    if (file_submit_or_wait(&iocb, FILE_OP_TYPE_WRITE, count, thread_id))\n      return 0;\n\n    return count;\n  }\n#endif\n#ifdef HAVE_MMAP\n  else if (file_io_mode == FILE_IO_MODE_MMAP)\n  {\n# if SIZEOF_SIZE_T == 4\n    /* Create file mapping for each I/O operation on 32-bit platforms */\n    page_addr = offset & file_page_mask;\n    page_offset = offset - page_addr;\n    start = mmap(NULL, count + page_offset, PROT_READ | PROT_WRITE, MAP_SHARED,\n                 fd, page_addr);\n\n    if (start == MAP_FAILED)\n      return 0;\n    memcpy((char *)start + page_offset, buf, count);\n    munmap(start, count + page_offset);\n\n    return count;\n# else\n    (void)start; /* unused */\n    (void)page_addr; /* unused */\n    (void)page_offset; /* unused */\n\n    /* We already have all files mapped on 64-bit platforms */\n    memcpy((char *)mmaps[file_id] + offset, buf, count);\n\n    return count;\n# endif    \n  }\n#endif /* HAVE_MMAP */\n\n  return 0; /* Unknown I/O mode */\n}\n\n\n/* Parse the command line arguments */\n\n\nint parse_arguments(void)\n{\n  char         *mode;\n  unsigned int  i;\n  \n  num_files = sb_get_value_int(\"file-num\");\n\n  if (num_files <= 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for file-num: %d\", num_files);\n    return 1;\n  }\n  total_size = sb_get_value_size(\"file-total-size\");\n  if (total_size <= 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for file-total-size: %lld\",\n             (long long)total_size);\n    return 1;\n  }\n  file_size = total_size / num_files;\n  \n  mode = sb_get_value_string(\"file-test-mode\");\n\n  /* File test mode is necessary only for 'run' command */\n  if (!strcmp(sb_globals.cmdname, \"run\"))\n  {\n    if (mode == NULL)\n    {\n      log_text(LOG_FATAL, \"Missing required argument: --file-test-mode\\n\");\n\n      log_text(LOG_NOTICE, \"fileio options:\");\n      sb_print_options(fileio_args);\n\n      return 1;\n    }\n    if (!strcmp(mode, \"seqwr\"))\n      test_mode = MODE_WRITE;\n    else if (!strcmp(mode, \"seqrewr\"))\n      test_mode = MODE_REWRITE;\n    else if (!strcmp(mode, \"seqrd\"))\n      test_mode = MODE_READ;\n    else if (!strcmp(mode, \"rndrd\"))\n      test_mode = MODE_RND_READ;\n    else if (!strcmp(mode, \"rndwr\"))\n      test_mode = MODE_RND_WRITE;\n    else if (!strcmp(mode, \"rndrw\"))\n      test_mode = MODE_RND_RW;\n    else\n    {\n      log_text(LOG_FATAL, \"Invalid IO operations mode: %s.\", mode);\n      return 1;\n    }\n  }\n  \n  mode  = sb_get_value_string(\"file-io-mode\");\n  if (mode == NULL)\n    mode = \"sync\";\n  if (!strcmp(mode, \"sync\"))\n    file_io_mode = FILE_IO_MODE_SYNC;\n  else if (!strcmp(mode, \"async\"))\n  {\n#ifdef HAVE_LIBAIO\n    file_io_mode = FILE_IO_MODE_ASYNC;\n#else\n    log_text(LOG_FATAL,\n             \"asynchronous I/O mode is unsupported on this platform.\");\n    return 1;\n#endif\n  }\n  else if (!strcmp(mode, \"mmap\"))\n  {\n#ifdef HAVE_MMAP\n    file_io_mode = FILE_IO_MODE_MMAP;\n#else\n    log_text(LOG_FATAL,\n             \"mmap'ed I/O mode is unsupported on this platform.\");\n    return 1;\n#endif\n  }\n  else\n  {\n    log_text(LOG_FATAL, \"unknown I/O mode: %s\", mode);\n    return 1;\n  }\n  \n  file_merged_requests = sb_get_value_int(\"file-merged-requests\");\n  if (file_merged_requests < 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for file-merged-requests: %d.\",\n             file_merged_requests);\n    return 1;\n  }\n  \n  file_block_size = sb_get_value_size(\"file-block-size\");\n  if (file_block_size <= 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for file-block-size: %d.\",\n             file_block_size);\n    return 1;\n  }\n\n  if (file_merged_requests > 0)\n    file_request_size = file_block_size * file_merged_requests;\n  else\n    file_request_size = file_block_size;\n\n  mode = sb_get_value_string(\"file-extra-flags\");\n\n  sb_list_item_t *pos;\n  SB_LIST_FOR_EACH(pos, sb_get_value_list(\"file-extra-flags\"))\n  {\n    const char *val = SB_LIST_ENTRY(pos, value_t, listitem)->data;\n\n    if (!strcmp(val, \"sync\"))\n      file_extra_flags |= SB_FILE_FLAG_SYNC;\n    else if (!strcmp(val, \"dsync\"))\n      file_extra_flags |= SB_FILE_FLAG_DSYNC;\n    else if (!strcmp(val, \"direct\"))\n      file_extra_flags |= SB_FILE_FLAG_DIRECTIO;\n    else\n    {\n      log_text(LOG_FATAL, \"Invalid value for file-extra-flags: %s\", mode);\n      return 1;\n    }\n  }\n\n  file_fsync_freq = sb_get_value_int(\"file-fsync-freq\");\n  if (file_fsync_freq < 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for file-fsync-freq: %d.\",\n             file_fsync_freq);\n    return 1;\n  }\n\n  file_fsync_end = sb_get_value_flag(\"file-fsync-end\");\n  file_fsync_all = sb_get_value_flag(\"file-fsync-all\");\n  /* file-fsync-all overrides file-fsync-end and file-fsync-freq */\n  if (file_fsync_all) {\n    file_fsync_end = 0;\n    file_fsync_freq = 0;\n  }\n  \n  mode = sb_get_value_string(\"file-fsync-mode\");\n  if (!strcmp(mode, \"fsync\"))\n    file_fsync_mode = FSYNC_ALL;\n  else if (!strcmp(mode, \"fdatasync\"))\n  {\n#ifdef HAVE_FDATASYNC\n    file_fsync_mode = FSYNC_DATA;\n#else\n    log_text(LOG_FATAL, \"fdatasync() is unavailable on this platform\");\n    return 1;\n#endif\n  }\n  else\n  {\n    log_text(LOG_FATAL, \"Invalid fsync mode: %s.\", mode);\n    return 1;\n  }\n\n  file_rw_ratio = sb_get_value_double(\"file-rw-ratio\");\n  if (file_rw_ratio < 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for --file-rw-ratio: %f.\", file_rw_ratio);\n    return 1;\n  }\n\n  per_thread = malloc(sizeof(*per_thread) * sb_globals.threads);\n  for (i = 0; i < sb_globals.threads; i++)\n  {\n    per_thread[i].buffer = sb_memalign(file_request_size, sb_getpagesize());\n    if (per_thread[i].buffer == NULL)\n    {\n      log_text(LOG_FATAL, \"Failed to allocate a memory buffer\");\n      return 1;\n    }\n    memset(per_thread[i].buffer, 0, file_request_size);\n  }\n\n  return 0;\n}\n\n\n/* check if two requests are sequential */\n\n\nvoid check_seq_req(sb_file_request_t *prev_req, sb_file_request_t *r)\n{\n  /* Do not check fsync operation at the moment */\n  if (r->operation == FILE_OP_TYPE_FSYNC || r->operation == FILE_OP_TYPE_NULL)\n    return; \n  /* if old request is NULL do not check against it */\n  if (prev_req->operation == FILE_OP_TYPE_NULL)\n    return;\n  /* check files */\n  if (r->file_id - prev_req->file_id>1 &&\n      !(r->file_id == 0 && prev_req->file_id == num_files-1))\n  {\n    log_text(LOG_WARNING,\n             \"Discovered too large file difference in seq requests!\");\n    return;\n  }\n  if (r->file_id == prev_req->file_id)\n  {\n    if(r->pos - prev_req->pos != prev_req->size)\n    {\n      log_text(LOG_WARNING,\n               \"Discovered too large position difference in seq request!\");\n      return;\n    }\n  }    \n  else /* if file changed last request has to complete file and new start */\n  {\n    if ((prev_req->pos + prev_req->size != file_size) || (r->pos != 0))\n    {\n      log_text(LOG_WARNING, \"Invalid file switch found!\");  \n      log_text(LOG_WARNING, \"Old: file_id: %d, pos: %d  size: %d\",\n               prev_req->file_id, (int)prev_req->pos, (int)prev_req->size);\n      log_text(LOG_WARNING, \"New: file_id: %d, pos: %d  size: %d\",\n               r->file_id, (int)r->pos, (int)r->size);\n      \n      return;\n    }  \n  }    \n} \n\n\n/*\n  Alignment requirement for mmap(). The same as page size, except on Windows\n  (on Windows it has to be 64KB, even if pagesize is only 4 or 8KB)\n*/\nsize_t sb_get_allocation_granularity(void)\n{\n  return sb_getpagesize();\n}\n\nstatic void sb_free_memaligned(void *buf)\n{\n  free(buf);\n}\n\nstatic FILE_DESCRIPTOR sb_open(const char *name)\n{\n  FILE_DESCRIPTOR file;\n  int flags = 0;\n\n  if (convert_extra_flags(file_extra_flags, &flags))\n    return SB_INVALID_FILE;\n\n  file = open(name, O_RDWR | flags, S_IRUSR | S_IWUSR);\n\n#ifdef HAVE_DIRECTIO\n  if (VALID_FILE(file) && file_extra_flags & SB_FILE_FLAG_DIRECTIO &&\n      directio(file, DIRECTIO_ON))\n  {\n    log_errno(LOG_FATAL, \"directio() failed\");\n    return SB_INVALID_FILE;\n  }\n#endif\n\n  return file;\n}\n\n/*\n  Create a file with a given path. Signal an error if the file already\n  exists. Return a non-zero value on error.\n*/\n\nstatic int sb_create(const char *path)\n{\n  FILE_DESCRIPTOR file;\n  int res;\n\n  file = open(path, O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);\n  res = !VALID_FILE(file);\n  close(file);\n\n  return res;\n}\n\n\n/* Fill buffer with random values and write checksum */\n\n\nvoid file_fill_buffer(unsigned char *buf, unsigned int len,\n                      size_t offset)\n{\n  unsigned int i;\n\n  for (i = 0; i < len - (FILE_CHECKSUM_LENGTH + FILE_OFFSET_LENGTH); i++)\n    buf[i] = sb_rand_uniform_uint64() & 0xFF;\n\n  /* Store the checksum */\n  *(int *)(void *)(buf + i) = (int)crc32(0, (unsigned char *)buf, len -\n                                 (FILE_CHECKSUM_LENGTH + FILE_OFFSET_LENGTH));\n  /* Store the offset */\n  *(long *)(void *)(buf + i + FILE_CHECKSUM_LENGTH) = offset;\n}\n\n\n/* Validate checksum and offset of block read from disk */\n\n\nint file_validate_buffer(unsigned char  *buf, unsigned int len, size_t offset)\n{\n  unsigned int checksum;\n  unsigned int cs_offset;\n\n  cs_offset = len - (FILE_CHECKSUM_LENGTH + FILE_OFFSET_LENGTH);\n  \n  checksum = (unsigned int)crc32(0, (unsigned char *)buf, cs_offset);\n\n  if (checksum != *(unsigned int *)(void *)(buf + cs_offset))\n  {\n    log_text(LOG_FATAL, \"Checksum mismatch in block with offset: %lld\",\n             (long long) offset);\n    log_text(LOG_FATAL, \"    Calculated value: 0x%x    Stored value: 0x%x\",\n             checksum, *(unsigned int *)(void *)(buf + cs_offset));\n    return 1;\n  }\n\n  if (offset != *(size_t *)(void *)(buf + cs_offset + FILE_CHECKSUM_LENGTH))\n  {\n    log_text(LOG_FATAL, \"Offset mismatch in block:\");\n    log_text(LOG_FATAL, \"   Actual offset: %zu    Stored offset: %zu\",\n             offset, *(size_t *)(void *)(buf + cs_offset + FILE_CHECKSUM_LENGTH));\n    return 1;\n  }\n\n  return 0;\n}\n"
  },
  {
    "path": "src/tests/memory/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbmemory.a\n\nlibsbmemory_a_SOURCES = sb_memory.c ../sb_memory.h\n\nlibsbmemory_a_CPPFLAGS = $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/tests/memory/sb_memory.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#include \"sysbench.h\"\n#include \"sb_rand.h\"\n\n#ifdef HAVE_SYS_IPC_H\n# include <sys/ipc.h>\n#endif\n\n#ifdef HAVE_SYS_SHM_H\n# include <sys/shm.h>\n#endif\n\n#include <inttypes.h>\n\n#define LARGE_PAGE_SIZE (4UL * 1024 * 1024)\n\n/* Memory test arguments */\nstatic sb_arg_t memory_args[] =\n{\n  SB_OPT(\"memory-block-size\", \"size of memory block for test\", \"1K\", SIZE),\n  SB_OPT(\"memory-total-size\", \"total size of data to transfer\", \"100G\", SIZE),\n  SB_OPT(\"memory-scope\", \"memory access scope {global,local}\", \"global\",\n         STRING),\n#ifdef HAVE_LARGE_PAGES\n  SB_OPT(\"memory-hugetlb\", \"allocate memory from HugeTLB pool\", \"off\", BOOL),\n#endif\n  SB_OPT(\"memory-oper\", \"type of memory operations {read, write, none}\",\n         \"write\", STRING),\n  SB_OPT(\"memory-access-mode\", \"memory access mode {seq,rnd}\", \"seq\", STRING),\n\n  SB_OPT_END\n};\n\n/* Memory test operations */\nstatic int memory_init(void);\nstatic void memory_print_mode(void);\nstatic sb_event_t memory_next_event(int);\nstatic int event_rnd_none(sb_event_t *, int);\nstatic int event_rnd_read(sb_event_t *, int);\nstatic int event_rnd_write(sb_event_t *, int);\nstatic int event_seq_none(sb_event_t *, int);\nstatic int event_seq_read(sb_event_t *, int);\nstatic int event_seq_write(sb_event_t *, int);\nstatic void memory_report_intermediate(sb_stat_t *);\nstatic void memory_report_cumulative(sb_stat_t *);\n\nstatic sb_test_t memory_test =\n{\n  .sname = \"memory\",\n  .lname = \"Memory functions speed test\",\n  .ops = {\n    .init = memory_init,\n    .print_mode = memory_print_mode,\n    .next_event = memory_next_event,\n    .report_intermediate = memory_report_intermediate,\n    .report_cumulative = memory_report_cumulative\n  },\n  .args = memory_args\n};\n\n/* Test arguments */\n\nstatic ssize_t memory_block_size;\nstatic long long    memory_total_size;\nstatic unsigned int memory_scope;\nstatic unsigned int memory_oper;\nstatic unsigned int memory_access_rnd;\n#ifdef HAVE_LARGE_PAGES\nstatic unsigned int memory_hugetlb;\n#endif\n\nstatic ssize_t max_offset;\n\n/* Arrays of per-thread buffers and event counters */\nstatic size_t **buffers;\nstatic uint64_t *thread_counters;\n\n#ifdef HAVE_LARGE_PAGES\nstatic void * hugetlb_alloc(size_t size);\n#endif\n\nint register_test_memory(sb_list_t *tests)\n{\n  SB_LIST_ADD_TAIL(&memory_test.listitem, tests);\n\n  return 0;\n}\n\n\nint memory_init(void)\n{\n  unsigned int i;\n  char         *s;\n  size_t       *buffer;\n\n  memory_block_size = sb_get_value_size(\"memory-block-size\");\n  if (memory_block_size < SIZEOF_SIZE_T ||\n      /* Must be a power of 2 */\n      (memory_block_size & (memory_block_size - 1)) != 0)\n  {\n    log_text(LOG_FATAL, \"Invalid value for memory-block-size: %s\",\n             sb_get_value_string(\"memory-block-size\"));\n    return 1;\n  }\n\n  max_offset = memory_block_size / SIZEOF_SIZE_T - 1;\n\n  memory_total_size = sb_get_value_size(\"memory-total-size\");\n\n  s = sb_get_value_string(\"memory-scope\");\n  if (!strcmp(s, \"global\"))\n    memory_scope = SB_MEM_SCOPE_GLOBAL;\n  else if (!strcmp(s, \"local\"))\n    memory_scope = SB_MEM_SCOPE_LOCAL;\n  else\n  {\n    log_text(LOG_FATAL, \"Invalid value for memory-scope: %s\", s);\n    return 1;\n  }\n\n#ifdef HAVE_LARGE_PAGES\n    memory_hugetlb = sb_get_value_flag(\"memory-hugetlb\");\n#endif  \n\n  s = sb_get_value_string(\"memory-oper\");\n  if (!strcmp(s, \"write\"))\n    memory_oper = SB_MEM_OP_WRITE;\n  else if (!strcmp(s, \"read\"))\n    memory_oper = SB_MEM_OP_READ;\n  else if (!strcmp(s, \"none\"))\n    memory_oper = SB_MEM_OP_NONE;\n  else\n  {\n    log_text(LOG_FATAL, \"Invalid value for memory-oper: %s\", s);\n    return 1;\n  }\n\n  s = sb_get_value_string(\"memory-access-mode\");\n  if (!strcmp(s, \"seq\"))\n    memory_access_rnd = 0;\n  else if (!strcmp(s, \"rnd\"))\n    memory_access_rnd = 1;\n  else\n  {\n    log_text(LOG_FATAL, \"Invalid value for memory-access-mode: %s\", s);\n    return 1;\n  }\n\n  if (memory_scope == SB_MEM_SCOPE_GLOBAL)\n  {\n#ifdef HAVE_LARGE_PAGES\n    if (memory_hugetlb)\n      buffer = hugetlb_alloc(memory_block_size);\n    else\n#endif\n      buffer = sb_memalign(memory_block_size, sb_getpagesize());\n\n    if (buffer == NULL)\n    {\n      log_text(LOG_FATAL, \"Failed to allocate buffer!\");\n      return 1;\n    }\n\n    memset(buffer, 0, memory_block_size);\n  }\n\n  thread_counters = malloc(sb_globals.threads * sizeof(uint64_t));\n  buffers = malloc(sb_globals.threads * sizeof(void *));\n  if (thread_counters == NULL || buffers == NULL)\n  {\n    log_text(LOG_FATAL, \"Failed to allocate thread-local memory!\");\n    return 1;\n  }\n\n  for (i = 0; i < sb_globals.threads; i++)\n  {\n    if (memory_scope == SB_MEM_SCOPE_GLOBAL)\n      buffers[i] = buffer;\n    else\n    {\n#ifdef HAVE_LARGE_PAGES\n      if (memory_hugetlb)\n        buffers[i] = hugetlb_alloc(memory_block_size);\n      else\n#endif\n        buffers[i] = sb_memalign(memory_block_size, sb_getpagesize());\n\n      if (buffers[i] == NULL)\n      {\n        log_text(LOG_FATAL, \"Failed to allocate buffer for thread #%d!\", i);\n        return 1;\n      }\n\n      memset(buffers[i], 0, memory_block_size);\n    }\n\n    thread_counters[i] =\n      memory_total_size / memory_block_size / sb_globals.threads;\n  }\n\n  switch (memory_oper) {\n  case SB_MEM_OP_NONE:\n    memory_test.ops.execute_event =\n      memory_access_rnd ? event_rnd_none : event_seq_none;\n    break;\n\n  case SB_MEM_OP_READ:\n    memory_test.ops.execute_event =\n      memory_access_rnd ? event_rnd_read : event_seq_read;\n    break;\n\n  case SB_MEM_OP_WRITE:\n    memory_test.ops.execute_event =\n      memory_access_rnd ? event_rnd_write : event_seq_write;\n    break;\n\n  default:\n    log_text(LOG_FATAL, \"Unknown memory request type: %d\\n\", memory_oper);\n    return 1;\n  }\n\n  /* Use our own limit on the number of events */\n  sb_globals.max_events = 0;\n\n\n  return 0;\n}\n\n\nsb_event_t memory_next_event(int tid)\n{\n  sb_event_t      req;\n\n  if (memory_total_size > 0 && thread_counters[tid]-- == 0)\n  {\n    req.type = SB_REQ_TYPE_NULL;\n    return req;\n  }\n\n  req.type = SB_REQ_TYPE_MEMORY;\n\n  return req;\n}\n\n/*\n  Use either 32- or 64-bit primitives depending on the native word\n  size. ConcurrencyKit ensures the corresponding loads/stores are not optimized\n  away by the compiler.\n*/\n#if SIZEOF_SIZE_T == 4\n# define SIZE_T_LOAD(ptr) ck_pr_load_32((uint32_t *)(ptr))\n# define SIZE_T_STORE(ptr,val) ck_pr_store_32((uint32_t *)(ptr),(uint32_t)(val))\n#elif SIZEOF_SIZE_T == 8\n# define SIZE_T_LOAD(ptr) ck_pr_load_64((uint64_t *)(ptr))\n# define SIZE_T_STORE(ptr,val) ck_pr_store_64((uint64_t *)(ptr),(uint64_t)(val))\n#else\n# error Unsupported platform.\n#endif\n\nint event_rnd_none(sb_event_t *req, int tid)\n{\n  (void) req; /* unused */\n  (void) tid; /* unused */\n\n  for (ssize_t i = 0; i <= max_offset; i++)\n  {\n    size_t offset = (volatile size_t) sb_rand_default(0, max_offset);\n    (void) offset; /* unused */\n  }\n\n  return 0;\n}\n\n\nint event_rnd_read(sb_event_t *req, int tid)\n{\n  (void) req; /* unused */\n\n  for (ssize_t i = 0; i <= max_offset; i++)\n  {\n    size_t offset = (size_t) sb_rand_default(0, max_offset);\n    size_t val = SIZE_T_LOAD(buffers[tid] + offset);\n    (void) val; /* unused */\n  }\n\n  return 0;\n}\n\n\nint event_rnd_write(sb_event_t *req, int tid)\n{\n  (void) req; /* unused */\n\n  for (ssize_t i = 0; i <= max_offset; i++)\n  {\n    size_t offset = (size_t) sb_rand_default(0, max_offset);\n    SIZE_T_STORE(buffers[tid] + offset, i);\n  }\n\n  return 0;\n}\n\n\nint event_seq_none(sb_event_t *req, int tid)\n{\n  (void) req; /* unused */\n\n  for (size_t *buf = buffers[tid], *end = buf + max_offset; buf <= end; buf++)\n  {\n    ck_pr_barrier();\n    /* nop */\n  }\n\n  return 0;\n}\n\n\nint event_seq_read(sb_event_t *req, int tid)\n{\n  (void) req; /* unused */\n\n  for (size_t *buf = buffers[tid], *end = buf + max_offset; buf < end; buf++)\n  {\n    size_t val = SIZE_T_LOAD(buf);\n    (void) val; /* unused */\n  }\n\n  return 0;\n}\n\n\nint event_seq_write(sb_event_t *req, int tid)\n{\n  (void) req; /* unused */\n\n  for (size_t *buf = buffers[tid], *end = buf + max_offset; buf < end; buf++)\n  {\n    SIZE_T_STORE(buf, (size_t) tid);\n  }\n\n  return 0;\n}\n\n\nvoid memory_print_mode(void)\n{\n  char *str;\n\n  log_text(LOG_NOTICE, \"Running memory speed test with the following options:\");\n  log_text(LOG_NOTICE, \"  block size: %ldKiB\",\n           (long)(memory_block_size / 1024));\n  log_text(LOG_NOTICE, \"  total size: %ldMiB\",\n           (long)(memory_total_size / 1024 / 1024));\n\n  switch (memory_oper) {\n    case SB_MEM_OP_READ:\n      str = \"read\";\n      break;\n    case SB_MEM_OP_WRITE:\n      str = \"write\";\n      break;\n    case SB_MEM_OP_NONE:\n      str = \"none\";\n      break;\n    default:\n      str = \"(unknown)\";\n      break;\n  }\n  log_text(LOG_NOTICE, \"  operation: %s\", str);\n\n  switch (memory_scope) {\n    case SB_MEM_SCOPE_GLOBAL:\n      str = \"global\";\n      break;\n    case SB_MEM_SCOPE_LOCAL:\n      str = \"local\";\n      break;\n    default:\n      str = \"(unknown)\";\n      break;\n  }\n  log_text(LOG_NOTICE, \"  scope: %s\", str);\n\n  log_text(LOG_NOTICE, \"\");\n}\n\n/*\n  Print intermediate test statistics.\n*/\n\nvoid memory_report_intermediate(sb_stat_t *stat)\n{\n  const double megabyte = 1024.0 * 1024.0;\n\n  log_timestamp(LOG_NOTICE, stat->time_total, \"%4.2f MiB/sec\",\n                stat->events * memory_block_size / megabyte /\n                stat->time_interval);\n}\n\n/*\n  Print cumulative test statistics.\n*/\n\nvoid memory_report_cumulative(sb_stat_t *stat)\n{\n  const double megabyte = 1024.0 * 1024.0;\n\n  log_text(LOG_NOTICE, \"Total operations: %\" PRIu64 \" (%8.2f per second)\\n\",\n           stat->events, stat->events / stat->time_interval);\n\n  if (memory_oper != SB_MEM_OP_NONE)\n  {\n    const double mb = stat->events * memory_block_size / megabyte;\n    log_text(LOG_NOTICE, \"%4.2f MiB transferred (%4.2f MiB/sec)\\n\",\n             mb, mb / stat->time_interval);\n  }\n\n  sb_report_cumulative(stat);\n}\n\n#ifdef HAVE_LARGE_PAGES\n\n/* Allocate memory from HugeTLB pool */\n\nvoid * hugetlb_alloc(size_t size)\n{\n  int shmid;\n  void *ptr;\n  struct shmid_ds buf;\n\n  /* Align block size to my_large_page_size */\n  size = ((size - 1) & ~LARGE_PAGE_SIZE) + LARGE_PAGE_SIZE;\n\n  shmid = shmget(IPC_PRIVATE, size, SHM_HUGETLB | SHM_R | SHM_W);\n  if (shmid < 0)\n  {\n      log_errno(LOG_FATAL,\n                \"Failed to allocate %zd bytes from HugeTLB memory.\", size);\n\n      return NULL;\n  }\n\n  ptr = shmat(shmid, NULL, 0);\n  if (ptr == (void *)-1)\n  {\n    log_errno(LOG_FATAL, \"Failed to attach shared memory segment,\");\n    shmctl(shmid, IPC_RMID, &buf);\n\n    return NULL;\n  }\n\n  /*\n        Remove the shared memory segment so that it will be automatically freed\n            after memory is detached or process exits\n  */\n  shmctl(shmid, IPC_RMID, &buf);\n\n  return ptr;\n}\n\n#endif\n"
  },
  {
    "path": "src/tests/mutex/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbmutex.a\n\nlibsbmutex_a_SOURCES = sb_mutex.c ../sb_mutex.h\n\nlibsbmutex_a_CPPFLAGS = $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/tests/mutex/sb_mutex.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n#include \"sysbench.h\"\n#include \"sb_ck_pr.h\"\n#include \"sb_rand.h\"\n\ntypedef struct\n{\n  pthread_mutex_t mutex;\n  char            pad[256];\n} thread_lock;\n\n\n/* Mutex test arguments */\nstatic sb_arg_t mutex_args[] =\n{\n  SB_OPT(\"mutex-num\", \"total size of mutex array\", \"4096\", INT),\n  SB_OPT(\"mutex-locks\", \"number of mutex locks to do per thread\", \"50000\", INT),\n  SB_OPT(\"mutex-loops\", \"number of empty loops to do outside mutex lock\",\n         \"10000\", INT),\n\n  SB_OPT_END\n};\n\n/* Mutex test operations */\nstatic int mutex_init(void);\nstatic void mutex_print_mode(void);\nstatic sb_event_t mutex_next_event(int);\nstatic int mutex_execute_event(sb_event_t *, int);\nstatic int mutex_done(void);\n\nstatic sb_test_t mutex_test =\n{\n  .sname = \"mutex\",\n  .lname = \"Mutex performance test\",\n  .ops = {\n     .init = mutex_init,\n     .print_mode = mutex_print_mode,\n     .next_event = mutex_next_event,\n     .execute_event = mutex_execute_event,\n     .done = mutex_done\n  },\n  .args = mutex_args\n};\n\n\nstatic thread_lock *thread_locks;\nstatic unsigned int mutex_num;\nstatic unsigned int mutex_loops;\nstatic unsigned int mutex_locks;\nstatic unsigned int global_var;\n\nstatic TLS int tls_counter;\n\nint register_test_mutex(sb_list_t *tests)\n{\n  SB_LIST_ADD_TAIL(&mutex_test.listitem, tests);\n\n  return 0;\n}\n\n\nint mutex_init(void)\n{\n  unsigned int i;\n  \n  mutex_num = sb_get_value_int(\"mutex-num\");\n  mutex_loops = sb_get_value_int(\"mutex-loops\");\n  mutex_locks = sb_get_value_int(\"mutex-locks\");\n\n  thread_locks = (thread_lock *)malloc(mutex_num * sizeof(thread_lock));\n  if (thread_locks == NULL)\n  {\n    log_text(LOG_FATAL, \"Memory allocation failure!\");\n    return 1;\n  }\n\n  for (i = 0; i < mutex_num; i++)\n    pthread_mutex_init(&thread_locks[i].mutex, NULL);\n  \n  return 0;\n}\n\n\nint mutex_done(void)\n{\n  unsigned int i;\n\n  for(i=0; i < mutex_num; i++)\n    pthread_mutex_destroy(&thread_locks[i].mutex);\n  free(thread_locks);\n  \n  return 0;\n}\n\n\nsb_event_t mutex_next_event(int thread_id)\n{\n  sb_event_t         sb_req;\n  sb_mutex_request_t   *mutex_req = &sb_req.u.mutex_request;\n\n  (void) thread_id; /* unused */\n\n  /* Perform only one request per thread */\n  if (tls_counter++ > 0)\n    sb_req.type = SB_REQ_TYPE_NULL;\n  else\n  {\n    sb_req.type = SB_REQ_TYPE_MUTEX;\n    mutex_req->nlocks = mutex_locks;\n    mutex_req->nloops = mutex_loops;\n  }\n\n  return sb_req;\n}\n\n\nint mutex_execute_event(sb_event_t *sb_req, int thread_id)\n{\n  unsigned int         i;\n  unsigned int         current_lock;\n  sb_mutex_request_t   *mutex_req = &sb_req->u.mutex_request;\n\n  (void) thread_id; /* unused */\n\n  do\n  {\n    current_lock = sb_rand_uniform(0, mutex_num - 1);\n\n    for (i = 0; i < mutex_req->nloops; i++)\n      ck_pr_barrier();\n\n    pthread_mutex_lock(&thread_locks[current_lock].mutex);\n    global_var++;\n    pthread_mutex_unlock(&thread_locks[current_lock].mutex);\n    mutex_req->nlocks--;\n  }\n  while (mutex_req->nlocks > 0);\n\n  return 0;\n}\n\n\nvoid mutex_print_mode(void)\n{\n  log_text(LOG_INFO, \"Doing mutex performance test\");\n}\n\n"
  },
  {
    "path": "src/tests/sb_cpu.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_CPU_H\n#define SB_CPU_H\n\nint register_test_cpu(sb_list_t *tests);\n\n#endif\n"
  },
  {
    "path": "src/tests/sb_fileio.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_FILEIO_H\n#define SB_FILEIO_H\n\n/* File operation types */\ntypedef enum\n{\n  FILE_OP_TYPE_NULL,\n  FILE_OP_TYPE_READ,\n  FILE_OP_TYPE_WRITE,\n  FILE_OP_TYPE_FSYNC\n} sb_file_op_t;\n\n/* File IO request definition */\n\ntypedef struct\n{\n  unsigned int    file_id;\n  long long       pos;\n  ssize_t         size;\n  sb_file_op_t    operation; \n} sb_file_request_t;\n\nint register_test_fileio(sb_list_t *tests);\n\n#endif\n"
  },
  {
    "path": "src/tests/sb_memory.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_MEMORY_H\n#define SB_MEMORY_H\n\n/* Memory request type definition */\ntypedef enum\n{\n  SB_MEM_OP_NONE,\n  SB_MEM_OP_READ,\n  SB_MEM_OP_WRITE\n} sb_mem_op_t;\n\n\n/* Memory scope type definition */\ntypedef enum\n{\n  SB_MEM_SCOPE_GLOBAL,\n  SB_MEM_SCOPE_LOCAL\n} sb_mem_scope_t;\n\n\nint register_test_memory(sb_list_t *tests);\n\n#endif\n"
  },
  {
    "path": "src/tests/sb_mutex.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_MUTEX_H\n#define SB_MUTEX_H\n\n/* Threads request definition */\n\ntypedef struct\n{\n  unsigned int nlocks;\n  unsigned int nloops;\n} sb_mutex_request_t;\n\nint register_test_mutex(sb_list_t *tests);\n\n#endif\n\n"
  },
  {
    "path": "src/tests/sb_threads.h",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifndef SB_THREADS_H\n#define SB_THREADS_H\n\n/* Threads request definition */\n\ntypedef struct\n{\n  unsigned int lock_num;\n} sb_threads_request_t;\n\nint register_test_threads(sb_list_t *tests);\n\n#endif\n\n"
  },
  {
    "path": "src/tests/threads/Makefile.am",
    "content": "# Copyright (C) 2004 MySQL AB\n# Copyright (C) 2004-2008 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n# \n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n# \n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nnoinst_LIBRARIES = libsbthreads.a\n\nlibsbthreads_a_SOURCES = sb_threads.c ../sb_threads.h\n\nlibsbthreads_a_CPPFLAGS = $(AM_CPPFLAGS)\n"
  },
  {
    "path": "src/tests/threads/sb_threads.c",
    "content": "/* Copyright (C) 2004 MySQL AB\n   Copyright (C) 2004-2018 Alexey Kopytov <akopytov@gmail.com>\n\n   This program is free software; you can redistribute it and/or modify\n   it under the terms of the GNU General Public License as published by\n   the Free Software Foundation; either version 2 of the License, or\n   (at your option) any later version.\n\n   This program is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n   GNU General Public License for more details.\n\n   You should have received a copy of the GNU General Public License\n   along with this program; if not, write to the Free Software\n   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n*/\n\n#ifdef HAVE_CONFIG_H\n# include \"config.h\"\n#endif\n\n#ifdef HAVE_PTHREAD_H\n# include <pthread.h>\n#endif\n\n#include \"sysbench.h\"\n#include \"sb_ck_pr.h\"\n\n/* How to test scheduler pthread_yield or sched_yield */\n#ifdef HAVE_PTHREAD_YIELD\n#define YIELD pthread_yield \n#else\n#define YIELD sched_yield\n#endif\n\n/* Threads test arguments */\nstatic sb_arg_t threads_args[] =\n{\n  SB_OPT(\"thread-yields\", \"number of yields to do per request\", \"1000\", INT),\n  SB_OPT(\"thread-locks\", \"number of locks per thread\", \"8\", INT),\n\n  SB_OPT_END\n};\n\n/* Threads test operations */\nstatic int threads_init(void);\nstatic int threads_prepare(void);\nstatic void threads_print_mode(void);\nstatic sb_event_t threads_next_event(int);\nstatic int threads_execute_event(sb_event_t *, int);\nstatic int threads_cleanup(void);\n\nstatic sb_test_t threads_test =\n{\n  .sname = \"threads\",\n  .lname = \"Threads subsystem performance test\",\n  .ops = {\n    .init = threads_init,\n    .prepare = threads_prepare,\n    .print_mode = threads_print_mode,\n    .next_event = threads_next_event,\n    .execute_event = threads_execute_event,\n    .cleanup = threads_cleanup\n  },\n  .args = threads_args\n};\n\nstatic unsigned int thread_yields;\nstatic unsigned int thread_locks;\nstatic pthread_mutex_t *test_mutexes;\nstatic unsigned int req_performed;\n\n\nint register_test_threads(sb_list_t *tests)\n{\n  SB_LIST_ADD_TAIL(&threads_test.listitem, tests);\n\n  return 0;\n}\n\n\nint threads_init(void)\n{\n  thread_yields = sb_get_value_int(\"thread-yields\");\n  thread_locks = sb_get_value_int(\"thread-locks\");\n  req_performed = 0;\n\n  return 0;\n}\n\n\nint threads_prepare(void)\n{\n  unsigned int i;\n\n  test_mutexes = (pthread_mutex_t *)malloc(thread_locks *\n                                           sizeof(pthread_mutex_t));\n  if (test_mutexes == NULL)\n  {\n    log_text(LOG_FATAL, \"Memory allocation failure!\");\n    return 1;\n  }\n  \n  for(i = 0; i < thread_locks; i++)\n    pthread_mutex_init(test_mutexes + i, NULL);\n\n  return 0;\n}\n\n\nint threads_cleanup(void)\n{\n  unsigned int i;\n\n  for(i=0; i < thread_locks; i++)\n    pthread_mutex_destroy(test_mutexes + i);\n  free(test_mutexes);\n  \n  return 0;\n}\n\n\nsb_event_t threads_next_event(int thread_id)\n{\n  sb_event_t         sb_req;\n  sb_threads_request_t *threads_req = &sb_req.u.threads_request;\n\n  (void) thread_id; /* unused */\n\n  sb_req.type = SB_REQ_TYPE_THREADS;\n  threads_req->lock_num = ck_pr_faa_uint(&req_performed, 1) % thread_locks;\n\n  return sb_req;\n}\n\n\nint threads_execute_event(sb_event_t *sb_req, int thread_id)\n{\n  unsigned int         i;\n  sb_threads_request_t *threads_req = &sb_req->u.threads_request;\n\n  (void) thread_id; /* unused */\n\n  for(i = 0; i < thread_yields; i++)\n  {\n    pthread_mutex_lock(&test_mutexes[threads_req->lock_num]);\n    YIELD();\n    pthread_mutex_unlock(&test_mutexes[threads_req->lock_num]);\n  }\n\n  return 0;\n}\n\n\nvoid threads_print_mode(void)\n{\n  log_text(LOG_INFO, \"Doing thread subsystem performance test\");\n  log_text(LOG_INFO, \"Thread yields per test: %d Locks used: %d\",\n         thread_yields, thread_locks);\n}\n\n"
  },
  {
    "path": "src/xoroshiro128plus.h",
    "content": "/*\n  Code below is based on the original work with the following copyright notice:\n*/\n\n/*  Written in 2016 by David Blackman and Sebastiano Vigna (vigna@acm.org)\n\nTo the extent possible under law, the author has dedicated all copyright\nand related and neighboring rights to this software to the public domain\nworldwide. This software is distributed without any warranty.\n\nSee <http://creativecommons.org/publicdomain/zero/1.0/>. */\n\n#include <stdint.h>\n\n/* This is the successor to xorshift128+. It is the fastest full-period\n   generator passing BigCrush without systematic failures, but due to the\n   relatively short period it is acceptable only for applications with a\n   mild amount of parallelism; otherwise, use a xorshift1024* generator.\n\n   Beside passing BigCrush, this generator passes the PractRand test suite\n   up to (and included) 16TB, with the exception of binary rank tests,\n   which fail due to the lowest bit being an LFSR; all other bits pass all\n   tests. We suggest to use a sign test to extract a random Boolean value.\n\n   Note that the generator uses a simulated rotate operation, which most C\n   compilers will turn into a single instruction. In Java, you can use\n   Long.rotateLeft(). In languages that do not make low-level rotation\n   instructions accessible xorshift128+ could be faster.\n\n   The state must be seeded so that it is not everywhere zero. If you have\n   a 64-bit seed, we suggest to seed a splitmix64 generator and use its\n   output to fill s. */\n\ninline uint64_t xoroshiro_rotl(const uint64_t x, int k) {\n        return (x << k) | (x >> (64 - k));\n}\n\ninline uint64_t xoroshiro_next(uint64_t s[2]) {\n        const uint64_t s0 = s[0];\n        uint64_t s1 = s[1];\n        const uint64_t result = s0 + s1;\n\n        s1 ^= s0;\n        s[0] = xoroshiro_rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b\n        s[1] = xoroshiro_rotl(s1, 36); // c\n\n        return result;\n}\n\n\n/* This is the jump function for the generator. It is equivalent\n   to 2^64 calls to next(); it can be used to generate 2^64\n   non-overlapping subsequences for parallel computations. */\n\nstatic inline void xoroshiro_jump(uint64_t s[2]) {\n        static const uint64_t JUMP[] = { 0xbeac0467eba5facb, 0xd86b048b86aa9922 };\n\n        uint64_t s0 = 0;\n        uint64_t s1 = 0;\n        int i, b;\n        for(i = 0; i < (int) (sizeof JUMP / sizeof *JUMP); i++)\n                for(b = 0; b < 64; b++) {\n                        if (JUMP[i] & 1ULL << b) {\n                                s0 ^= s[0];\n                                s1 ^= s[1];\n                        }\n                        xoroshiro_next(s);\n                }\n\n        s[0] = s0;\n        s[1] = s1;\n}\n"
  },
  {
    "path": "tests/Makefile.am",
    "content": "# Copyright (C) 2016-2018 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nAM_TESTS_ENVIRONMENT = \\\n\tPATH=\"$(top_srcdir)/third_party/cram/scripts:$$PATH\" \\\n\tPYTHONPATH=\"$(top_srcdir)/third_party/cram:$$PYTHONPATH\"\n\nTESTS = test_run.sh\n\ntest_SCRIPTS = test_run.sh\n\nEXTRA_DIST = $(test_SCRIPTS) \\\n             README.md\n\ntestroot = \t$(datadir)\ntestdir = \t$(testroot)/sysbench/tests\ntest_dirs= \tt include\n\n# Used by dist-hook and install-data-local to copy all\n# test files into either dist or install directory\ninstall_test_files:\n\t@if test -z \"$(INSTALL_TO_DIR)\"; then \\\n\t  echo \"Set INSTALL_TO_DIR!\" && exit 1; \\\n\tfi\n\t@for dir in $(test_dirs); do \\\n\t  from_dir=\"$(srcdir)/$$dir\"; \\\n\t  to_dir=\"$(INSTALL_TO_DIR)/$$dir\"; \\\n\t  $(mkinstalldirs) \"$$to_dir\"; \\\n\t  for f in `(cd $$from_dir && ls *.t *.sh *.lua) 2>/dev/null`; do \\\n\t    if test -f \"$$from_dir/$$f\"; then \\\n\t      $(INSTALL_DATA) \"$$from_dir/$$f\" \"$$to_dir/$$f\" ; \\\n\t    fi; \\\n\t  done \\\n\tdone\n\ndist-hook:\n\t$(MAKE)\tINSTALL_TO_DIR=\"$(distdir)\" install_test_files\n\ninstall-data-local:\n\t$(MAKE)\tINSTALL_TO_DIR=\"$(DESTDIR)$(testdir)\" install_test_files\n\nuninstall-local:\n\trm -f -r $(DESTDIR)$(testdir)\n\ntest:\n\t./test_run.sh\n"
  },
  {
    "path": "tests/README.md",
    "content": "sysbench Test Suite\n===================\n\nsysbench uses the [Cram](https://bitheap.org/cram/) framework for\nfunctional and regression testing. If your system has Python 2.7.9 or\nlater, or Python 3.4 or later, installing Cram is as simple as executing\n`pip install cram`.\n\nIf you use an older Python version, you may need to [install\npip](https://pip.pypa.io/en/latest/installing/) first:\n\n``` {.example}\ncurl https://bootstrap.pypa.io/get-pip.py | python\n```\n\nTo run the sysbench test suite, invoke the `test_run.sh` script in the\n`tests` directory as follows:\n\n``` {.example}\n./test_run.sh [test_name]...\n```\n\nEach `test_name` argument is a name of a test case file. Functional and\nregression tests are located in the `t` subdirectory in files with the\n`.t` suffix.\n\nIf no tests are named on the `test_run.sh` command line, it will execute\nall files with the `.t` suffix in the `t` subdirectory.\n\nSome tests require external servers (MySQL, PostgreSQL, etc). One should\nuse environment variables to specify connection related arguments that\nsysbench can use to connect to such external server(s). The currently\nrecognized variables are:\n\n- `SBTEST_MYSQL_ARGS` -- MySQL connection options: `--mysql-host`,\n  `--mysql-port`, `--mysql-socket` `--mysql-user`, `--mysql-password`\n  and `--mysql-db`;\n\n- `SBTEST_PGSQL_ARGS` -- PostgreSQL connection options: `--pgsql-host`,\n  `--pgsql-port`, `--pgsql-user`, `--pgsql-password` and `--pgsql-db`.\n\nFor example:\n``` {.example}\nexport SBTEST_MYSQL_ARGS=\"--mysql-host=localhost --mysql-user=sbtest --mysql-password=secret --mysql-db=sbtest\"\nexport SBTEST_PGSQL_ARGS=\"--pgsql-host=localhost --pgsql-user=postgres --pgsql-password=secret --pgsql-db=sbtest\"\n./test_run.sh\n```\n\nsysbench assumes that server(s) are pre-configured so that the specified\ndatabase exists and the user connecting with the specified credentials\nhas all privileges on the database. In particular, sysbench must have\nenough privileges to create/drop/read/modify tables in that database.\n"
  },
  {
    "path": "tests/include/api_sql_common.sh",
    "content": "########################################################################\n# Common code for SQL API tests\n#\n# Expects the following variables and callback functions to be defined by the\n# caller:\n#\n#   DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench\n#\n########################################################################\n\nset -eu\n\nSB_ARGS=\"--verbosity=1 --events=1 $DB_DRIVER_ARGS $CRAMTMP/api_sql.lua\"\ncat >$CRAMTMP/api_sql.lua <<EOF\nfunction thread_init()\n  drv = sysbench.sql.driver()\n  con = drv:connect()\nend\n\nfunction event()\n  local e, m\n  local inspect = require(\"inspect\")\n\n  print(\"drv:name() = \" .. drv:name())\n  print(\"SQL types:\")\n  print(inspect(sysbench.sql.type))\n  print('--')\n\n  print(\"SQL error codes:\")\n  print(inspect(sysbench.sql.error))\n  print('--')\n\n  e, m = pcall(sysbench.sql.driver, \"non-existing\")\n  print(m)\n\n  con:query(\"DROP TABLE IF EXISTS t\")\n  con:query(\"CREATE TABLE t(a INT)\")\n  con:bulk_insert_init(\"INSERT INTO t VALUES\")\n  for i = 1,100 do\n    con:bulk_insert_next(string.format(\"(%d)\", i))\n  end\n  con:bulk_insert_done()\n  print(con:query_row(\"SELECT COUNT(DISTINCT a) FROM t\"))\n  print('--')\n  con:query(\"DROP TABLE IF EXISTS t2\")\n  con:query(\"CREATE TABLE t2(a INT, b VARCHAR(120), c FLOAT)\")\n  con:query(\"INSERT INTO t2 VALUES (1, 'foo', 0.4)\")\n  con:query(\"INSERT INTO t2 VALUES (NULL, 'bar', 0.2)\")\n  con:query(\"INSERT INTO t2 VALUES (2, NULL, 0.3)\")\n  con:query(\"INSERT INTO t2 VALUES (NULL, NULL, 0.1)\")\n\n  print('--')\n  local rs = con:query(\"SELECT * FROM t2 ORDER BY a\")\n  for i = 1, rs.nrows do\n     print(string.format(\"%s %s %s\", unpack(rs:fetch_row(), 1, rs.nfields)))\n  end\n  print('--')\n\n  print(string.format(\"%s %s\", con:query_row(\"SELECT b, a FROM t2 ORDER BY b\")))\n  print('--')\n  con:query(\"DROP TABLE t2\")\n  con:query(\"ALTER TABLE t ADD COLUMN b CHAR(10), ADD COLUMN c FLOAT\")\n\n  e, m = pcall(con.prepare, con, \"SELECT * FROM nonexisting\")\n  print(m)\n  print('--')\n\n  local stmt = con:prepare(\"UPDATE t SET a = a + ?, b = ?, c = ?\")\n  local a = stmt:bind_create(sysbench.sql.type.INT)\n  local b = stmt:bind_create(sysbench.sql.type.CHAR, 10)\n  local c = stmt:bind_create(sysbench.sql.type.FLOAT)\n\n  print(a)\n  print(b)\n  print(c)\n\n  e, m = pcall(stmt.bind_create, stmt, sysbench.sql.type.DATE)\n  print(m)\n\n  print(stmt:bind_param())\n\n  stmt:bind_param(a, b, c)\n  a:set(100)\n  rs1 = stmt:execute()\n  print(rs1)\n  a:set(200)\n  b:set(\"01234567890\")\n  rs2 = stmt:execute()\n  print(rs2)\n  a:set(300)\n  b:set(\"09876543210\")\n  c:set(0.9)\n  rs3 = stmt:execute()\n  print(rs3)\n\n  e, m = pcall(rs3.free, rs)\n  print(m)\n\n  e, m = pcall(rs2.free, rs)\n  print(m)\n\n  e, m = pcall(rs1.free, rs)\n  print(m)\n\n  rs = con:query(\"SELECT a, b, c FROM t\")\n  print(unpack(rs:fetch_row(), 1, rs.nfields))\n\n  stmt:close()\n\n  print('--')\n  con:disconnect()\n  e, m = pcall(con.query, con, \"SELECT 1\")\n  print(m)\n\n  con:disconnect()\n\n  print('--')\n  con = drv:connect()\n  rs = con:query(\"SELECT MIN(a), MAX(a), MIN(b), MAX(b) FROM t\")\n  print(rs.nfields)\n  for i = 1, rs.nrows do\n     print(string.format(\"%s %s %s %s\", unpack(rs:fetch_row(), 1, rs.nfields)))\n  end\n  con:query(\"DROP TABLE t\")\n  print('--')\nend\nEOF\nsysbench $SB_ARGS run\n\n# Reconnect\ncat >$CRAMTMP/api_sql.lua <<EOF\nfunction sysbench.hooks.report_cumulative(stat)\n  print(\"reconnects = \" .. stat.reconnects)\nend\nfunction thread_init()\n  drv = sysbench.sql.driver()\n  con = drv:connect()\nend\nfunction event()\n  print(con:query_row(\"SELECT 1\"))\n  con:reconnect()\n  print(con:query_row(\"SELECT 2\"))\n  print('--')\nend\nEOF\nsysbench $SB_ARGS run\n\n# Failed connection handling\n\ncat >$CRAMTMP/api_sql.lua <<EOF\nfunction event()\n  local drv = sysbench.sql.driver()\n  local e,m = pcall(drv.connect, drv)\n  print(m)\nend\nEOF\n# Reset --mysql-socket if it's specified on the command line, otherwise sysbench\n# will assume --mysql-host=localhost\nsysbench $SB_ARGS --mysql-host=\"non-existing\" --pgsql-host=\"non-existing\" \\\n         --mysql-socket= \\\n         run\n\n# Error hooks\ncat >$CRAMTMP/api_sql.lua <<EOF\nfunction sysbench.hooks.sql_error_ignorable(e)\n  print(\"Got an error descriptor:\")\n  local inspect = require(\"inspect\")\n  print(inspect(e))\nend\n\nfunction event()\n  local drv = sysbench.sql.driver()\n  local con = drv:connect()\n  local queries = {\n    \"CREATE TABLE t(a CHAR(1) NOT NULL)\",\n    \"INSERT INTO t VALUES (1)\",\n    \"INSERT INTO t VALUES (NULL)\",\n    [[INSERT INTO t VALUES ('test')]],\n    \"DROP TABLE t\",\n    \"DROP TABLE t\"\n  }\n  print('--')\n  con:query(\"DROP TABLE IF EXISTS t\")\n  if (drv:name() == 'mysql') then\n    con:query(\"SET sql_mode='STRICT_TRANS_TABLES'\")\n  end\n  for i = 1, #queries do\n    local e, m = pcall(function () con:query(queries[i]) end)\n    if not e then print(m) end\n  end\n  print('--')\nend\nEOF\nsysbench $SB_ARGS run\n\n\ncat <<EOF\n########################################################################\n# Multiple connections test\n########################################################################\nEOF\ncat >$CRAMTMP/api_sql.lua <<EOF\nfunction thread_init()\n  drv = sysbench.sql.driver()\n  con = {}\n  for i=1,10 do\n    con[i] = drv:connect()\n  end\nend\n\nfunction event()\n  con[1]:query(\"DROP TABLE IF EXISTS t\")\n  con[2]:query(\"CREATE TABLE t(a INT)\")\n  for i=1,10 do\n    con[i]:query(\"INSERT INTO t VALUES (\" .. i .. \")\")\n  end\n  rs = con[1]:query(\"SELECT * FROM t\")\n  for i = 1, rs.nrows do\n     print(string.format(\"%s\", unpack(rs:fetch_row(), 1, rs.nfields)))\n  end\n  con[1]:query(\"DROP TABLE t\")\nend\nEOF\n\nsysbench $SB_ARGS run\n\ncat <<EOF\n########################################################################\n# Incorrect bulk API usage\n########################################################################\nEOF\ncat >$CRAMTMP/api_sql.lua <<EOF\nc = sysbench.sql.driver():connect()\nc:query(\"CREATE TABLE t1(a INT)\")\nc:bulk_insert_init(\"INSERT INTO t1 VALUES\")\nc:bulk_insert_next(\"(1)\")\nc:bulk_insert_done()\ne,m = pcall(function () c:bulk_insert_next(\"(2)\") end)\nprint(m)\nc:bulk_insert_done()\nc:query(\"DROP TABLE t1\")\nEOF\n\nsysbench $SB_ARGS\n\ncat <<EOF\n########################################################################\n# query_row() with an empty result set\n########################################################################\nEOF\ncat >$CRAMTMP/api_sql.lua <<EOF\nc = sysbench.sql.driver():connect()\nc:query(\"CREATE TABLE t1(a INT)\")\nprint(c:query_row(\"SELECT * FROM t1\"))\nc:query(\"DROP TABLE t1\")\nEOF\n\nsysbench $SB_ARGS\n\ncat <<EOF\n########################################################################\n# GH-282: Mysql's fetch_row() is broken\n########################################################################\nEOF\ncat >$CRAMTMP/api_sql.lua <<EOF\nconnection = sysbench.sql.driver():connect()\nrows = connection:query(\"select 1 union select 2\")\n\nr = rows:fetch_row();\nwhile ( r ) do\n  print( r[ 1 ] )\n  r = rows:fetch_row()\nend\nEOF\n\nsysbench $SB_ARGS\n"
  },
  {
    "path": "tests/include/config.sh.in",
    "content": "#!/usr/bin/env bash\n\n# Configuration file used by the sysbench test suite.\n\n# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nexport SBTEST_VERSION_STRING=\"sysbench @PACKAGE_VERSION@@SB_GIT_SHA@\"\nexport SBTEST_VERSION=\"@PACKAGE_VERSION@\"\nexport SBTEST_HAS_MYSQL=@USE_MYSQL@\nexport SBTEST_HAS_PGSQL=@USE_PGSQL@\n"
  },
  {
    "path": "tests/include/drv_common.sh",
    "content": "#!/usr/bin/env bash\n#\n#########################################################################\n# Common code for DB driver tests\n# Variables:\n#   DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench\n#########################################################################\n\nset -eu\n\ncat >test.lua <<EOF\nfunction event()\n  c = c or sysbench.sql.driver():connect()\n  c:query(\"SELECT 1\")\nend\nEOF\n\nsysbench test.lua \\\n         --events=10 \\\n         --threads=2 \\\n         $DB_DRIVER_ARGS \\\n         run\n"
  },
  {
    "path": "tests/include/inspect.lua",
    "content": "local inspect ={\n  _VERSION = 'inspect.lua 3.1.0',\n  _URL     = 'http://github.com/kikito/inspect.lua',\n  _DESCRIPTION = 'human-readable representations of tables',\n  _LICENSE = [[\n    MIT LICENSE\n    Copyright (c) 2013 Enrique García Cota\n    Permission is hereby granted, free of charge, to any person obtaining a\n    copy of this software and associated documentation files (the\n    \"Software\"), to deal in the Software without restriction, including\n    without limitation the rights to use, copy, modify, merge, publish,\n    distribute, sublicense, and/or sell copies of the Software, and to\n    permit persons to whom the Software is furnished to do so, subject to\n    the following conditions:\n    The above copyright notice and this permission notice shall be included\n    in all copies or substantial portions of the Software.\n    THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n    OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\n    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\n    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\n    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\n    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n  ]]\n}\n\nlocal tostring = tostring\n\ninspect.KEY       = setmetatable({}, {__tostring = function() return 'inspect.KEY' end})\ninspect.METATABLE = setmetatable({}, {__tostring = function() return 'inspect.METATABLE' end})\n\n-- Apostrophizes the string if it has quotes, but not aphostrophes\n-- Otherwise, it returns a regular quoted string\nlocal function smartQuote(str)\n  if str:match('\"') and not str:match(\"'\") then\n    return \"'\" .. str .. \"'\"\n  end\n  return '\"' .. str:gsub('\"', '\\\\\"') .. '\"'\nend\n\n-- \\a => '\\\\a', \\0 => '\\\\0', 31 => '\\31'\nlocal shortControlCharEscapes = {\n  [\"\\a\"] = \"\\\\a\",  [\"\\b\"] = \"\\\\b\", [\"\\f\"] = \"\\\\f\", [\"\\n\"] = \"\\\\n\",\n  [\"\\r\"] = \"\\\\r\",  [\"\\t\"] = \"\\\\t\", [\"\\v\"] = \"\\\\v\"\n}\nlocal longControlCharEscapes = {} -- \\a => nil, \\0 => \\000, 31 => \\031\nfor i=0, 31 do\n  local ch = string.char(i)\n  if not shortControlCharEscapes[ch] then\n    shortControlCharEscapes[ch] = \"\\\\\"..i\n    longControlCharEscapes[ch]  = string.format(\"\\\\%03d\", i)\n  end\nend\n\nlocal function escape(str)\n  return (str:gsub(\"\\\\\", \"\\\\\\\\\")\n             :gsub(\"(%c)%f[0-9]\", longControlCharEscapes)\n             :gsub(\"%c\", shortControlCharEscapes))\nend\n\nlocal function isIdentifier(str)\n  return type(str) == 'string' and str:match( \"^[_%a][_%a%d]*$\" )\nend\n\nlocal function isSequenceKey(k, sequenceLength)\n  return type(k) == 'number'\n     and 1 <= k\n     and k <= sequenceLength\n     and math.floor(k) == k\nend\n\nlocal defaultTypeOrders = {\n  ['number']   = 1, ['boolean']  = 2, ['string'] = 3, ['table'] = 4,\n  ['function'] = 5, ['userdata'] = 6, ['thread'] = 7\n}\n\nlocal function sortKeys(a, b)\n  local ta, tb = type(a), type(b)\n\n  -- strings and numbers are sorted numerically/alphabetically\n  if ta == tb and (ta == 'string' or ta == 'number') then return a < b end\n\n  local dta, dtb = defaultTypeOrders[ta], defaultTypeOrders[tb]\n  -- Two default types are compared according to the defaultTypeOrders table\n  if dta and dtb then return defaultTypeOrders[ta] < defaultTypeOrders[tb]\n  elseif dta     then return true  -- default types before custom ones\n  elseif dtb     then return false -- custom types after default ones\n  end\n\n  -- custom types are sorted out alphabetically\n  return ta < tb\nend\n\n-- For implementation reasons, the behavior of rawlen & # is \"undefined\" when\n-- tables aren't pure sequences. So we implement our own # operator.\nlocal function getSequenceLength(t)\n  local len = 1\n  local v = rawget(t,len)\n  while v ~= nil do\n    len = len + 1\n    v = rawget(t,len)\n  end\n  return len - 1\nend\n\nlocal function getNonSequentialKeys(t)\n  local keys = {}\n  local sequenceLength = getSequenceLength(t)\n  for k,_ in pairs(t) do\n    if not isSequenceKey(k, sequenceLength) then table.insert(keys, k) end\n  end\n  table.sort(keys, sortKeys)\n  return keys, sequenceLength\nend\n\nlocal function getToStringResultSafely(t, mt)\n  local __tostring = type(mt) == 'table' and rawget(mt, '__tostring')\n  local str, ok\n  if type(__tostring) == 'function' then\n    ok, str = pcall(__tostring, t)\n    str = ok and str or 'error: ' .. tostring(str)\n  end\n  if type(str) == 'string' and #str > 0 then return str end\nend\n\nlocal function countTableAppearances(t, tableAppearances)\n  tableAppearances = tableAppearances or {}\n\n  if type(t) == 'table' then\n    if not tableAppearances[t] then\n      tableAppearances[t] = 1\n      for k,v in pairs(t) do\n        countTableAppearances(k, tableAppearances)\n        countTableAppearances(v, tableAppearances)\n      end\n      countTableAppearances(getmetatable(t), tableAppearances)\n    else\n      tableAppearances[t] = tableAppearances[t] + 1\n    end\n  end\n\n  return tableAppearances\nend\n\nlocal copySequence = function(s)\n  local copy, len = {}, #s\n  for i=1, len do copy[i] = s[i] end\n  return copy, len\nend\n\nlocal function makePath(path, ...)\n  local keys = {...}\n  local newPath, len = copySequence(path)\n  for i=1, #keys do\n    newPath[len + i] = keys[i]\n  end\n  return newPath\nend\n\nlocal function processRecursive(process, item, path, visited)\n\n    if item == nil then return nil end\n    if visited[item] then return visited[item] end\n\n    local processed = process(item, path)\n    if type(processed) == 'table' then\n      local processedCopy = {}\n      visited[item] = processedCopy\n      local processedKey\n\n      for k,v in pairs(processed) do\n        processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited)\n        if processedKey ~= nil then\n          processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited)\n        end\n      end\n\n      local mt  = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited)\n      setmetatable(processedCopy, mt)\n      processed = processedCopy\n    end\n    return processed\nend\n\n\n\n-------------------------------------------------------------------\n\nlocal Inspector = {}\nlocal Inspector_mt = {__index = Inspector}\n\nfunction Inspector:puts(...)\n  local args   = {...}\n  local buffer = self.buffer\n  local len    = #buffer\n  for i=1, #args do\n    len = len + 1\n    buffer[len] = args[i]\n  end\nend\n\nfunction Inspector:down(f)\n  self.level = self.level + 1\n  f()\n  self.level = self.level - 1\nend\n\nfunction Inspector:tabify()\n  self:puts(self.newline, string.rep(self.indent, self.level))\nend\n\nfunction Inspector:alreadyVisited(v)\n  return self.ids[v] ~= nil\nend\n\nfunction Inspector:getId(v)\n  local id = self.ids[v]\n  if not id then\n    local tv = type(v)\n    id              = (self.maxIds[tv] or 0) + 1\n    self.maxIds[tv] = id\n    self.ids[v]     = id\n  end\n  return tostring(id)\nend\n\nfunction Inspector:putKey(k)\n  if isIdentifier(k) then return self:puts(k) end\n  self:puts(\"[\")\n  self:putValue(k)\n  self:puts(\"]\")\nend\n\nfunction Inspector:putTable(t)\n  if t == inspect.KEY or t == inspect.METATABLE then\n    self:puts(tostring(t))\n  elseif self:alreadyVisited(t) then\n    self:puts('<table ', self:getId(t), '>')\n  elseif self.level >= self.depth then\n    self:puts('{...}')\n  else\n    if self.tableAppearances[t] > 1 then self:puts('<', self:getId(t), '>') end\n\n    local nonSequentialKeys, sequenceLength = getNonSequentialKeys(t)\n    local mt                = getmetatable(t)\n    local toStringResult    = getToStringResultSafely(t, mt)\n\n    self:puts('{')\n    self:down(function()\n      if toStringResult then\n        self:puts(' -- ', escape(toStringResult))\n        if sequenceLength >= 1 then self:tabify() end\n      end\n\n      local count = 0\n      for i=1, sequenceLength do\n        if count > 0 then self:puts(',') end\n        self:puts(' ')\n        self:putValue(t[i])\n        count = count + 1\n      end\n\n      for _,k in ipairs(nonSequentialKeys) do\n        if count > 0 then self:puts(',') end\n        self:tabify()\n        self:putKey(k)\n        self:puts(' = ')\n        self:putValue(t[k])\n        count = count + 1\n      end\n\n      if mt then\n        if count > 0 then self:puts(',') end\n        self:tabify()\n        self:puts('<metatable> = ')\n        self:putValue(mt)\n      end\n    end)\n\n    if #nonSequentialKeys > 0 or mt then -- result is multi-lined. Justify closing }\n      self:tabify()\n    elseif sequenceLength > 0 then -- array tables have one extra space before closing }\n      self:puts(' ')\n    end\n\n    self:puts('}')\n  end\nend\n\nfunction Inspector:putValue(v)\n  local tv = type(v)\n\n  if tv == 'string' then\n    self:puts(smartQuote(escape(v)))\n  elseif tv == 'number' or tv == 'boolean' or tv == 'nil' or\n         tv == 'cdata' or tv == 'ctype' then\n    self:puts(tostring(v))\n  elseif tv == 'table' then\n    self:putTable(v)\n  else\n    self:puts('<',tv,' ',self:getId(v),'>')\n  end\nend\n\n-------------------------------------------------------------------\n\nfunction inspect.inspect(root, options)\n  options       = options or {}\n\n  local depth   = options.depth   or math.huge\n  local newline = options.newline or '\\n'\n  local indent  = options.indent  or '  '\n  local process = options.process\n\n  if process then\n    root = processRecursive(process, root, {}, {})\n  end\n\n  local inspector = setmetatable({\n    depth            = depth,\n    level            = 0,\n    buffer           = {},\n    ids              = {},\n    maxIds           = {},\n    newline          = newline,\n    indent           = indent,\n    tableAppearances = countTableAppearances(root)\n  }, Inspector_mt)\n\n  inspector:putValue(root)\n\n  return table.concat(inspector.buffer)\nend\n\nsetmetatable(inspect, { __call = function(_, ...) return inspect.inspect(...) end })\n\nreturn inspect\n"
  },
  {
    "path": "tests/include/mysql_common.sh",
    "content": "########################################################################\n# Common code for MySQL-specific tests\n########################################################################\nset -eu\n\nif [ -z \"${SBTEST_MYSQL_ARGS:-}\" ]\nthen\n  exit 80\nfi\n\nfunction db_show_table() {\n  mysql -uroot sbtest -Nse \"SHOW CREATE TABLE $1\\G\"\n}\n\nDB_DRIVER_ARGS=\"--db-driver=mysql $SBTEST_MYSQL_ARGS\"\n"
  },
  {
    "path": "tests/include/pgsql_common.sh",
    "content": "########################################################################\n# Common code for PostgreSQL-specific tests\n########################################################################\nset -eu\n\nif [ -z \"${SBTEST_PGSQL_ARGS:-}\" ]\nthen\n  exit 80\nfi\n\n# Emulate \"\\d+\" output since it is not portable across PostgreSQL major versions\nfunction db_show_table() {\n  if ! psql -c \"\\d+ $1\" sbtest > /dev/null\n  then\n      return\n  fi\n\n  echo \"                            Table \\\"public.$1\\\"\"\n  psql -q sbtest <<EOF\n\\pset footer off\n SELECT\n    f.attname AS \"Column\",\n    pg_catalog.format_type(f.atttypid,f.atttypmod) AS \"Type\",\n    CASE\n        WHEN f.attnotnull = 't' OR p.contype = 'p' THEN 'not null '\n        ELSE ''\n    END ||\n    CASE\n        WHEN f.atthasdef = 't' THEN 'default ' ||\n             pg_catalog.pg_get_expr(d.adbin, d.adrelid, true)\n        ELSE ''\n    END AS \"Modifiers\",\n    CASE\n        WHEN f.attstorage = 'p' THEN 'plain'\n        ELSE 'extended'\n    END as \"Storage\",\n    CASE\n        WHEN f.attstattarget < 0 THEN ''\n        ELSE f.attstattarget::text\n    END as \"Stats target\",\n    pg_catalog.col_description(f.attrelid, f.attnum) as \"Description\"\nFROM pg_attribute f\n    JOIN pg_class c ON c.oid = f.attrelid\n    JOIN pg_type t ON t.oid = f.atttypid\n    LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum\n    LEFT JOIN pg_namespace n ON n.oid = c.relnamespace\n    LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey)\n    LEFT JOIN pg_class AS g ON p.confrelid = g.oid\nWHERE c.relkind = 'r'::char\n    AND n.nspname = 'public'\n    AND c.relname = '$1'\n    AND f.attnum > 0\nEOF\n  echo \"Indexes:\"\n  psql -qt sbtest <<EOF\n SELECT REPLACE(indexdef, 'public.', '')\nFROM pg_catalog.pg_indexes\nWHERE schemaname = 'public'\n    AND tablename = '$1'\nORDER BY 1\nEOF\n}\n\nDB_DRIVER_ARGS=\"--db-driver=pgsql $SBTEST_PGSQL_ARGS\"\n"
  },
  {
    "path": "tests/include/script_bulk_insert_common.sh",
    "content": "#!/usr/bin/env bash\n#\n################################################################################\n# Common code for select_bulk_insert* tests\n#\n# Expects the following variables and callback functions to be defined by the\n# caller:\n#\n#   DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench\n#\n#   db_show_table() -- called with a single argument to dump a specified table\n#                      schema\n################################################################################\n\nset -eu\n\nARGS=\"${SBTEST_SCRIPTDIR}/bulk_insert.lua $DB_DRIVER_ARGS --threads=2 --verbosity=1\"\n\nsysbench $ARGS prepare\n\nfor i in $(seq 1 3)\ndo\n    db_show_table sbtest${i} || true # Error on non-existing table\ndone\n\nsysbench $ARGS --events=100 --verbosity=3 run\n\nsysbench $ARGS cleanup\n\nfor i in $(seq 1 3)\ndo\n    db_show_table sbtest${i} || true # Error on non-existing table\ndone\n"
  },
  {
    "path": "tests/include/script_oltp_common.sh",
    "content": "#!/usr/bin/env bash\n#\n################################################################################\n# Common code for OLTP tests\n#\n# Expects the following variables and callback functions to be defined by the\n# caller:\n#\n#   DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench\n#   OLTP_SCRIPT_PATH -- path to the script file to execute\n#   SB_EXTRA_ARGS -- optional variable to specify extra sysbench arguments\n#\n#   db_show_table() -- called with a single argument to dump a specified table\n#                      schema\n################################################################################\n\nset -eu\n\nSB_EXTRA_ARGS=${SB_EXTRA_ARGS:-}\n\n# Test single-threaded prepare/prewarm/cleanup output\n\nARGS=\"${OLTP_SCRIPT_PATH} ${DB_DRIVER_ARGS} --tables=8 --threads=1 ${SB_EXTRA_ARGS}\"\nsysbench $ARGS prepare\n\ndb_show_table sbtest1\ndb_show_table sbtest2\ndb_show_table sbtest3\ndb_show_table sbtest4\ndb_show_table sbtest5\ndb_show_table sbtest6\ndb_show_table sbtest7\ndb_show_table sbtest8\ndb_show_table sbtest9 || true # Error on non-existing table\n\nsysbench $ARGS warmup || true # MySQL only\nsysbench $ARGS cleanup\n\n# Test parallel prepare/prewarm/cleanup. Parallelism may result in\n# non-deterministic output, so we redirect it to /dev/null\n\nARGS=\"${OLTP_SCRIPT_PATH} ${DB_DRIVER_ARGS} --tables=8 --threads=2 ${SB_EXTRA_ARGS}\"\n\nsysbench $ARGS prepare >/dev/null\n\ndb_show_table sbtest1\ndb_show_table sbtest2\ndb_show_table sbtest3\ndb_show_table sbtest4\ndb_show_table sbtest5\ndb_show_table sbtest6\ndb_show_table sbtest7\ndb_show_table sbtest8\ndb_show_table sbtest9 || true # Error on non-existing table\n\nsysbench $ARGS prewarm >/dev/null || true # MySQL only\n\nsysbench --events=100 $ARGS run\n\nsysbench $ARGS cleanup >/dev/null\n\ndb_show_table sbtest1 || true # Error on non-existing table\ndb_show_table sbtest2 || true # Error on non-existing table\ndb_show_table sbtest3 || true # Error on non-existing table\ndb_show_table sbtest4 || true # Error on non-existing table\ndb_show_table sbtest5 || true # Error on non-existing table\ndb_show_table sbtest6 || true # Error on non-existing table\ndb_show_table sbtest7 || true # Error on non-existing table\ndb_show_table sbtest8 || true # Error on non-existing table\n\necho \"# Test --create-secondary=off\"\nARGS=\"${OLTP_SCRIPT_PATH} ${DB_DRIVER_ARGS} ${SB_EXTRA_ARGS} --tables=1\"\n\nsysbench --create-secondary=off $ARGS prepare\n\ndb_show_table sbtest1\n\nsysbench $ARGS cleanup\n\necho \"# Test --auto-inc=off\"\n\nARGS=\"$ARGS --auto-inc=off --verbosity=1\"\n\nsysbench $ARGS prepare\nsysbench $ARGS run\nsysbench $ARGS cleanup\n\necho \"# Test --reconnect\"\n\nARGS=\"${OLTP_SCRIPT_PATH} ${DB_DRIVER_ARGS} ${SB_EXTRA_ARGS} --events=100 \\\n--reconnect=5\"\n\nsysbench $ARGS prepare >/dev/null || true\nsysbench $ARGS run | grep reconnects:\nsysbench $ARGS cleanup >/dev/null || true\n"
  },
  {
    "path": "tests/include/script_select_random_common.sh",
    "content": "#!/usr/bin/env bash\n#\n################################################################################\n# Common code for select_random_* tests\n#\n# Expects the following variables and callback functions to be defined by the\n# caller:\n#\n#   DB_DRIVER_ARGS -- extra driver-specific arguments to pass to sysbench\n#\n#   db_show_table() -- called with a single argument to dump a specified table\n#                      schema\n################################################################################\n\nset -eu\n\nfor test in select_random_points select_random_ranges\ndo\n    ARGS=\"${SBTEST_SCRIPTDIR}/${test}.lua $DB_DRIVER_ARGS --tables=1\"\n\n    sysbench $ARGS prepare\n\n    db_show_table sbtest1\n\n    for i in $(seq 2 8)\n    do\n        db_show_table sbtest${i} || true # Error on non-existing table\n    done\n\n    sysbench $ARGS --events=100 run\n\n    sysbench $ARGS cleanup\n\n    for i in $(seq 1 8)\n    do\n        db_show_table sbtest${i} || true # Error on non-existing table\n    done\n\n    ARGS=\"${SBTEST_SCRIPTDIR}/select_random_points.lua $DB_DRIVER_ARGS --tables=8\"\ndone\n"
  },
  {
    "path": "tests/t/1st.t",
    "content": "# Ensure the sysbench binary exists in PATH and is executable\n\n  $ sysbench --help >/dev/null 2>&1\n"
  },
  {
    "path": "tests/t/api_basic.t",
    "content": "########################################################################\nBasic Lua API tests\n########################################################################\n\n  $ SB_ARGS=\"--verbosity=0 --events=2 --db-driver=mysql $SBTEST_MYSQL_ARGS $CRAMTMP/api_basic.lua\"\n\n  $ cat >$CRAMTMP/api_basic.lua <<EOF\n  > function init(thread_id)\n  >   print(\"tid:\" .. (thread_id or \"(nil)\") .. \" init()\")\n  > end\n  > \n  > function prepare(thread_id)\n  >   print(\"tid:\" .. (thread_id or \"(nil)\") .. \" prepare()\")\n  > end\n  > \n  > function run(thread_id)\n  >   print(\"tid:\" .. (thread_id or \"(nil)\") .. \" run()\")\n  > end\n  > \n  > function cleanup(thread_id)\n  >   print(\"tid:\" .. (thread_id or \"(nil)\") .. \" cleanup()\")\n  > end\n  > \n  > function help(thread_id)\n  >   print(\"tid:\" .. (thread_id or \"(nil)\") .. \" help()\")\n  > end\n  > \n  > function thread_init(thread_id)\n  >   print(string.format(\"tid:%d thread_init()\", thread_id))\n  > end\n  > \n  > function event(thread_id)\n  >   print(string.format(\"tid:%d event()\", thread_id))\n  > end\n  > \n  > function thread_done(thread_id)\n  >   print(string.format(\"tid:%d thread_done()\", thread_id))\n  > end\n  > \n  > function done(thread_id)\n  >   print(\"tid:\" .. (thread_id or \"(nil)\") .. \" done()\")\n  > end\n  > \n  > EOF\n\n  $ sysbench $SB_ARGS prepare\n  tid:(nil) prepare()\n\n  $ sysbench $SB_ARGS run\n  tid:(nil) init()\n  tid:0 thread_init()\n  tid:0 event()\n  tid:0 event()\n  tid:0 thread_done()\n  tid:(nil) done()\n\n  $ sysbench $SB_ARGS cleanup\n  tid:(nil) cleanup()\n\n  $ sysbench $SB_ARGS help\n  tid:(nil) help()\n \n  $ cat >$CRAMTMP/api_basic.lua <<EOF\n  > function event()\n  >   print(sysbench.version)\n  >   print(sysbench.version_string)\n  > end\n  > EOF\n\n  $ sysbench $SB_ARGS --events=1 run |\n  > sed -e \"s/$SBTEST_VERSION_STRING/VERSION_STRING/\" \\\n  >     -e \"s/$SBTEST_VERSION/VERSION/\"\n  VERSION\n  VERSION_STRING\n\n  $ cat >$CRAMTMP/api_basic.lua <<EOF\n  > function event()\n  >     print(string.format(\"sysbench.cmdline.script_path = %s\", sysbench.cmdline.script_path))\n  > end\n  > EOF\n  $ sysbench $SB_ARGS --events=1 run\n  sysbench.cmdline.script_path = */api_basic.lua (glob)\n\n########################################################################\nError handling\n########################################################################\n\n# Syntax errors in the script\n  $ cat >$CRAMTMP/api_basic.lua <<EOF\n  > foo\n  > EOF\n  $ sysbench $SB_ARGS run\n  FATAL: */api_basic.lua:2: '=' expected near '<eof>' (glob)\n  [1]\n\n# Missing event function\n  $ cat >$CRAMTMP/api_basic.lua <<EOF\n  > function foo()\n  > end\n  > EOF\n  $ sysbench $SB_ARGS run\n  FATAL: cannot find the event() function in *api_basic.lua (glob)\n  [1]\n\n########################################################################\nevent() return values\n########################################################################\n\n  $ cat >$CRAMTMP/api_basic.lua <<EOF\n  > sysbench.cmdline.options = { param = {\"param\", 0} }\n  > function event()\n  >   i = (i or 0) + 1\n  >   local param = sysbench.opt.param\n  >   print(i)\n  >   if param == 1 then\n  >     return 0\n  >   elseif param == 2 then\n  >     return 1\n  >   elseif param == 3 then\n  >     return true\n  >   elseif param == 4 then\n  >     return {}\n  >   elseif param == 5 then\n  >     return false\n  >   elseif param == 6 then\n  >     return nil\n  >   else\n  >     error(\"Unknown param value\")\n  >   end\n  > end\n  > EOF\n  $ sysbench $SB_ARGS run --param=1\n  1\n  $ sysbench $SB_ARGS run --param=2\n  1\n  $ sysbench $SB_ARGS run --param=3\n  1\n  $ sysbench $SB_ARGS run --param=4\n  1\n  $ sysbench $SB_ARGS run --param=5\n  1\n  2\n  $ sysbench $SB_ARGS run --param=6\n  1\n  2\n"
  },
  {
    "path": "tests/t/api_histogram.t",
    "content": "########################################################################\nTests for histogram API\n########################################################################\n\n  $ sysbench <<EOF\n  >   h = sysbench.histogram.new(1000, 1, 10)\n  >   h:update(1)\n  >   h:update(2)\n  >   h:update(0)\n  >   h:update(10)\n  >   h:update(100)\n  >   h:update(5.001)\n  >   h:print()\n  > EOF\n  sysbench * (glob)\n  \n         value  ------------- distribution ------------- count\n         1.000 |**************************************** 2\n         2.001 |********************                     1\n         4.997 |********************                     1\n        10.000 |**************************************** 2\n"
  },
  {
    "path": "tests/t/api_rand.t",
    "content": "########################################################################\nPRNG Lua API tests\n########################################################################\n\n  $ SB_ARGS=\"--verbosity=0 --events=1\"\n\n  $ cat >$CRAMTMP/api_rand.lua <<EOF\n  > ffi.cdef[[int printf(const char *fmt, ...);]]\n  > function init()\n  >   -- Ensure a consistent sort order...\n  >   mod_funcs = {}\n  >   for f in pairs(sysbench.rand) do\n  >     table.insert(mod_funcs, f)\n  >   end\n  >   table.sort(mod_funcs)\n  >   for i, f in ipairs(mod_funcs) do\n  >     print(string.format(\"sysbench.rand.%s\", f))\n  >   end\n  > end\n  > function event()\n  >   print(\"sysbench.rand.default(0, 99) = \" .. sysbench.rand.default(0, 99))\n  >   print(\"sysbench.rand.unique(0, 4294967295) = \" .. sysbench.rand.unique(0, 4294967295))\n  >   ffi.C.printf(\"sysbench.rand.uniform_uint64() = %llu\\n\", sysbench.rand.uniform_uint64())\n  >   print([[sysbench.rand.string(\"abc-###-@@@-xyz\") = ]] .. sysbench.rand.string(\"abc-###-@@@-xyz\"))\n  >   print([[sysbench.rand.varstring(1, 23) = ]] .. sysbench.rand.varstring(1, 23))\n  >   print(\"sysbench.rand.uniform(0, 99) = \" .. sysbench.rand.uniform(0, 99))\n  >   print(\"sysbench.rand.gaussian(0, 99) = \" .. sysbench.rand.gaussian(0, 99))\n  >   print(\"sysbench.rand.pareto(0, 99) = \" .. sysbench.rand.pareto(0, 99))\n  >   print(\"sysbench.rand.zipfian(0, 99) = \" .. sysbench.rand.zipfian(0, 99))\n  > end\n  > EOF\n\n  $ sysbench $SB_ARGS $CRAMTMP/api_rand.lua run\n  sysbench.rand.default\n  sysbench.rand.gaussian\n  sysbench.rand.pareto\n  sysbench.rand.string\n  sysbench.rand.uniform\n  sysbench.rand.uniform_double\n  sysbench.rand.uniform_uint64\n  sysbench.rand.unique\n  sysbench.rand.varstring\n  sysbench.rand.zipfian\n  sysbench.rand.default\\(0, 99\\) = [0-9]{1,2} (re)\n  sysbench.rand.unique\\(0, 4294967295\\) = [0-9]{1,10} (re)\n  sysbench.rand.uniform_uint64\\(\\) = [0-9]+ (re)\n  sysbench.rand.string\\(\".*\"\\) = abc-[0-9]{3}-[a-z]{3}-xyz (re)\n  sysbench.rand.varstring\\(1, 23\\) = [0-z]{1,23} (re)\n  sysbench.rand.uniform\\(0, 99\\) = [0-9]{1,2} (re)\n  sysbench.rand.gaussian\\(0, 99\\) = [0-9]{1,2} (re)\n  sysbench.rand.pareto\\(0, 99\\) = [0-9]{1,2} (re)\n  sysbench.rand.zipfian\\(0, 99\\) = [0-9]{1,2} (re)\n\n########################################################################\nGH-96: sb_rand_uniq(1, oltp_table_size) generate duplicate value\n########################################################################\n  $ cat >$CRAMTMP/api_rand_uniq.lua <<EOF\n  > function event()\n  >   print(sysbench.rand.unique())\n  > end\n  > EOF\n\n  $ sysbench $SB_ARGS --events=100000 $CRAMTMP/api_rand_uniq.lua run |\n  >   sort -n | uniq | wc -l | sed -e 's/ //g'\n  100000\n"
  },
  {
    "path": "tests/t/api_reports.t",
    "content": "########################################################################\nTests for custom report hooks\n########################################################################\n\n# Trigger one intermediate and one cumulative report\n  $ SB_ARGS=\"api_reports.lua --time=5 --report-interval=2 --verbosity=1\"\n\n########################################################################\n# Default human-readable format via a custom hook\n########################################################################\n\n  $ cat >api_reports.lua <<EOF\n  > ffi.cdef[[int usleep(unsigned int);]]\n  > \n  > function event()\n  >   ffi.C.usleep(1000)\n  > end\n  > \n  > sysbench.hooks.report_intermediate = sysbench.report_default\n  > sysbench.hooks.report_cumulative = sysbench.report_default\n  > EOF\n\n  $ sysbench $SB_ARGS run\n  \\[ 2s \\] thds: 1 tps: [0-9]*\\.[0-9]* qps: 0\\.00 \\(r\\/w\\/o: 0\\.00\\/0\\.00\\/0\\.00\\) lat \\(ms,95%\\): [1-9][0-9]*\\.[0-9]* err\\/s 0\\.00 reconn\\/s: 0\\.00 (re)\n  \\[ 4s \\] thds: 1 tps: [0-9]*\\.[0-9]* qps: 0\\.00 \\(r\\/w\\/o: 0\\.00\\/0\\.00\\/0\\.00\\) lat \\(ms,95%\\): [1-9][0-9]*\\.[0-9]* err\\/s 0\\.00 reconn\\/s: 0\\.00 (re)\n  \\[ 5s \\] thds: 0 tps: [0-9]*\\.[0-9]* qps: 0\\.00 \\(r\\/w\\/o: 0\\.00\\/0\\.00\\/0\\.00\\) lat \\(ms,95%\\): [1-9][0-9]*\\.[0-9]* err\\/s 0\\.00 reconn\\/s: 0\\.00 (re)\n\n########################################################################\n# CSV format via a custom hook\n########################################################################\n\n  $ cat >api_reports.lua <<EOF\n  > ffi.cdef[[int usleep(unsigned int);]]\n  > \n  > function event()\n  >   ffi.C.usleep(1000)\n  > end\n  > \n  > sysbench.hooks.report_intermediate = sysbench.report_csv\n  > sysbench.hooks.report_cumulative = sysbench.report_csv\n  > EOF\n\n  $ sysbench $SB_ARGS run\n  2,1,[0-9]*\\.[0-9]*,0\\.00,0\\.00,0\\.00,0\\.00,[1-9][0-9]*\\.[0-9]*,0\\.00,0\\.00 (re)\n  4,1,[0-9]*\\.[0-9]*,0\\.00,0\\.00,0\\.00,0\\.00,[1-9][0-9]*\\.[0-9]*,0\\.00,0\\.00 (re)\n  5,0,[0-9]*\\.[0-9]*,0\\.00,0\\.00,0\\.00,0\\.00,[1-9][0-9]*\\.[0-9]*,0\\.00,0\\.00 (re)\n\n########################################################################\n# JSON format via a custom hook\n########################################################################\n\n  $ cat >api_reports.lua <<EOF\n  > ffi.cdef[[int usleep(unsigned int);]]\n  > \n  > function event()\n  >   ffi.C.usleep(1000)\n  > end\n  > \n  > sysbench.hooks.report_intermediate = sysbench.report_json\n  > sysbench.hooks.report_cumulative = sysbench.report_json\n  > EOF\n\n  $ sysbench $SB_ARGS run\n  [\n    {\n      \"time\":    2,\n      \"threads\": 1,\n      \"tps\": *.*, (glob)\n      \"qps\": {\n        \"total\": 0.00,\n        \"reads\": 0.00,\n        \"writes\": 0.00,\n        \"other\": 0.00\n      },\n      \"latency\": [1-9][0-9]*\\.[0-9]*, (re)\n      \"errors\": 0.00,\n      \"reconnects\": 0.00\n    },\n    {\n      \"time\":    4,\n      \"threads\": 1,\n      \"tps\": *.*, (glob)\n      \"qps\": {\n        \"total\": 0.00,\n        \"reads\": 0.00,\n        \"writes\": 0.00,\n        \"other\": 0.00\n      },\n      \"latency\": [1-9][0-9]*\\.[0-9]*, (re)\n      \"errors\": 0.00,\n      \"reconnects\": 0.00\n    }\n  ]\n  [\n    {\n      \"time\":    5,\n      \"threads\": 0,\n      \"tps\": *.*, (glob)\n      \"qps\": {\n        \"total\": 0.00,\n        \"reads\": 0.00,\n        \"writes\": 0.00,\n        \"other\": 0.00\n      },\n      \"latency\": [1-9][0-9]*\\.[0-9]*, (re)\n      \"errors\": 0.00,\n      \"reconnects\": 0.00\n    }\n  ]\n"
  },
  {
    "path": "tests/t/api_sql_mysql.t",
    "content": "########################################################################\nSQL Lua API + MySQL tests\n########################################################################\n\n  $ . ${SBTEST_INCDIR}/mysql_common.sh\n  $ . ${SBTEST_INCDIR}/api_sql_common.sh\n  drv:name() = mysql\n  SQL types:\n  {\n    BIGINT = 4,\n    CHAR = 11,\n    DATE = 8,\n    DATETIME = 9,\n    DOUBLE = 6,\n    FLOAT = 5,\n    INT = 3,\n    NONE = 0,\n    SMALLINT = 2,\n    TIME = 7,\n    TIMESTAMP = 10,\n    TINYINT = 1,\n    VARCHAR = 12\n  }\n  --\n  SQL error codes:\n  {\n    FATAL = 2,\n    IGNORABLE = 1,\n    NONE = 0\n  }\n  --\n  FATAL: invalid database driver name: 'non-existing'\n  failed to initialize the DB driver\n  100\n  --\n  --\n  nil bar 0.2\n  nil nil 0.1\n  1 foo 0.4\n  2 nil 0.3\n  --\n  nil 2\n  --\n  FATAL: mysql_stmt_prepare() failed\n  FATAL: MySQL error: 1146 \"Table 'sbtest.nonexisting' doesn't exist\"\n  SQL API error\n  --\n  <sql_param>\n  <sql_param>\n  <sql_param>\n  Unsupported argument type: 8\n  nil\n  <sql_result>\n  <sql_result>\n  <sql_result>\n  ALERT: attempt to free an invalid result set\n  db_free_results() failed\n  db_free_results() failed\n  db_free_results() failed\n  601\\t0987654321\\t0.9 (esc)\n  --\n  (last message repeated 2 times)\n  ALERT: attempt to use an already closed connection\n  */api_sql.lua:*: SQL API error (glob)\n  ALERT: attempt to close an already closed connection\n  --\n  4\n  601 700 0987654321 0987654321\n  --\n  1\n  2\n  --\n  reconnects = 1\n  FATAL: unable to connect to MySQL server on host 'non-existing', port 3306, aborting...\n  FATAL: error 2005: Unknown MySQL server host 'non-existing' (0)\n  connection creation failed\n  --\n  FATAL: mysql_drv_query() returned error 1048 (Column 'a' cannot be null) for query 'INSERT INTO t VALUES (NULL)'\n  Got an error descriptor:\n  {\n    connection = <sql_connection>,\n    query = \"INSERT INTO t VALUES (NULL)\",\n    sql_errmsg = \"Column 'a' cannot be null\",\n    sql_errno = 1048,\n    sql_state = \"23000\"\n  }\n  */api_sql.lua:*: SQL error, errno = 1048, state = '23000': Column 'a' cannot be null (glob)\n  FATAL: mysql_drv_query() returned error 1406 (Data too long for column 'a' at row 1) for query 'INSERT INTO t VALUES ('test')'\n  Got an error descriptor:\n  {\n    connection = <sql_connection>,\n    query = \"INSERT INTO t VALUES ('test')\",\n    sql_errmsg = \"Data too long for column 'a' at row 1\",\n    sql_errno = 1406,\n    sql_state = \"22001\"\n  }\n  */api_sql.lua:*: SQL error, errno = 1406, state = '22001': Data too long for column 'a' at row 1 (glob)\n  FATAL: mysql_drv_query() returned error 1051 (Unknown table '*t') for query 'DROP TABLE t' (glob)\n  Got an error descriptor:\n  {\n    connection = <sql_connection>,\n    query = \"DROP TABLE t\",\n    sql_errmsg = \"Unknown table 'sbtest.t'\",\n    sql_errno = 1051,\n    sql_state = \"42S02\"\n  }\n  */api_sql.lua:*: SQL error, errno = 1051, state = '42S02': Unknown table '*t' (glob)\n  --\n  ########################################################################\n  # Multiple connections test\n  ########################################################################\n  1\n  2\n  3\n  4\n  5\n  6\n  7\n  8\n  9\n  10\n  ########################################################################\n  # Incorrect bulk API usage\n  ########################################################################\n  ALERT: attempt to call bulk_insert_next() before bulk_insert_init()\n  */api_sql.lua:*: db_bulk_insert_next() failed (glob)\n  ########################################################################\n  # query_row() with an empty result set\n  ########################################################################\n  nil\n  ########################################################################\n  # GH-282: Mysql's fetch_row() is broken\n  ########################################################################\n  1\n  2\n########################################################################\n# GH-304: Benchmark Stored Procedure with sysbench\n########################################################################\n  $ cat >api_sql.lua <<EOF\n  >   con = sysbench.sql.driver():connect()\n  >  \n  >   con:query([[\n  > CREATE PROCEDURE p1 (IN txt VARCHAR(255))\n  > BEGIN\n  >   SELECT 'begin:', txt;\n  >   INSERT INTO t1 VALUES(1);\n  >   SELECT * FROM t1;\n  >   DELETE FROM t1 WHERE a = 1;\n  >   SELECT 'done';\n  > END\n  >   ]])\n  >  \n  >   con:query(\"CREATE TABLE t1(a INT)\")\n  >  \n  >   stmt = con:prepare(\"CALL p1(?)\")\n  >   param = stmt:bind_create(sysbench.sql.type.CHAR, 10)\n  >   stmt:bind_param(param)\n  >  \n  >   function print_rs(rs)\n  >      if rs == nil then return end\n  >      print(rs.nrows)\n  >      print(rs.nfields)\n  >      for i = 1, rs.nrows do\n  >         print(unpack(rs:fetch_row(), 1, rs.nfields))\n  >      end\n  >   end\n  >  \n  >   local rs = con:query([[CALL p1(\"foo\")]])\n  >   while rs ~= nil do\n  >      print_rs(rs)\n  >      rs = con:next_result()\n  >   end\n  >  \n  >   param:set(\"bar\")\n  >   rs = stmt:execute()\n  >   while rs ~= nil do\n  >      rs = stmt:next_result()\n  >   end\n  >  \n  >   con:query(\"DROP PROCEDURE IF EXISTS p1\");\n  >   con:query(\"DROP TABLE IF EXISTS t1\");\n  > EOF\n\n  $ sysbench $DB_DRIVER_ARGS --verbosity=1 api_sql.lua\n  1\n  2\n  begin:\\tfoo (esc)\n  1\n  1\n  1\n  1\n  1\n  done\n"
  },
  {
    "path": "tests/t/api_sql_pgsql.t",
    "content": "########################################################################\nSQL Lua API + PostgreSQL tests\n########################################################################\n\n  $ . ${SBTEST_INCDIR}/pgsql_common.sh\n  $ . ${SBTEST_INCDIR}/api_sql_common.sh\n  drv:name() = pgsql\n  SQL types:\n  {\n    BIGINT = 4,\n    CHAR = 11,\n    DATE = 8,\n    DATETIME = 9,\n    DOUBLE = 6,\n    FLOAT = 5,\n    INT = 3,\n    NONE = 0,\n    SMALLINT = 2,\n    TIME = 7,\n    TIMESTAMP = 10,\n    TINYINT = 1,\n    VARCHAR = 12\n  }\n  --\n  SQL error codes:\n  {\n    FATAL = 2,\n    IGNORABLE = 1,\n    NONE = 0\n  }\n  --\n  FATAL: invalid database driver name: 'non-existing'\n  failed to initialize the DB driver\n  100\n  --\n  --\n  1 foo 0.4\n  2 nil 0.3\n  nil bar 0.2\n  nil nil 0.1\n  --\n  bar nil\n  --\n  FATAL: PQprepare() failed: ERROR:  relation \"nonexisting\" does not exist\n  LINE 1: SELECT * FROM nonexisting\n                        ^\n  \n  SQL API error\n  --\n  <sql_param>\n  <sql_param>\n  <sql_param>\n  Unsupported argument type: 8\n  nil\n  <sql_result>\n  <sql_result>\n  <sql_result>\n  ALERT: attempt to free an invalid result set\n  db_free_results() failed\n  db_free_results() failed\n  db_free_results() failed\n  601\\t0987654321\\t0.9 (esc)\n  --\n  (last message repeated 2 times)\n  ALERT: attempt to use an already closed connection\n  */api_sql.lua:*: SQL API error (glob)\n  ALERT: attempt to close an already closed connection\n  --\n  4\n  601 700 0987654321 0987654321\n  --\n  1\n  2\n  --\n  reconnects = 1\n  FATAL: Connection to database failed: could not translate host name \"non-existing\" to address: * (glob)\n  \n  connection creation failed\n  --\n  FATAL: PQexec() failed: 7 null value in column \"a\" *violates not-null constraint (glob)\n  FATAL: failed query was: INSERT INTO t VALUES (NULL)\n  Got an error descriptor:\n  {\n    connection = <sql_connection>,\n    query = \"INSERT INTO t VALUES (NULL)\",\n    sql_errmsg = 'null value in column \"a\" *violates not-null constraint', (glob)\n    sql_errno = 0,\n    sql_state = \"23502\"\n  }\n  */api_sql.lua:*: SQL error, errno = 0, state = '23502': null value in column \"a\" *violates not-null constraint (glob)\n  FATAL: PQexec() failed: 7 value too long for type character(1)\n  FATAL: failed query was: INSERT INTO t VALUES ('test')\n  Got an error descriptor:\n  {\n    connection = <sql_connection>,\n    query = \"INSERT INTO t VALUES ('test')\",\n    sql_errmsg = \"value too long for type character(1)\",\n    sql_errno = 0,\n    sql_state = \"22001\"\n  }\n  */api_sql.lua:*: SQL error, errno = 0, state = '22001': value too long for type character(1) (glob)\n  FATAL: PQexec() failed: 7 table \"t\" does not exist\n  FATAL: failed query was: DROP TABLE t\n  Got an error descriptor:\n  {\n    connection = <sql_connection>,\n    query = \"DROP TABLE t\",\n    sql_errmsg = 'table \"t\" does not exist',\n    sql_errno = 0,\n    sql_state = \"42P01\"\n  }\n  */api_sql.lua:*: SQL error, errno = 0, state = '42P01': table \"t\" does not exist (glob)\n  --\n  ########################################################################\n  # Multiple connections test\n  ########################################################################\n  1\n  2\n  3\n  4\n  5\n  6\n  7\n  8\n  9\n  10\n  ########################################################################\n  # Incorrect bulk API usage\n  ########################################################################\n  ALERT: attempt to call bulk_insert_next() before bulk_insert_init()\n  */api_sql.lua:*: db_bulk_insert_next() failed (glob)\n  ########################################################################\n  # query_row() with an empty result set\n  ########################################################################\n  nil\n  ########################################################################\n  # GH-282: Mysql's fetch_row() is broken\n  ########################################################################\n  1\n  2\n"
  },
  {
    "path": "tests/t/cmd_cleanup.t",
    "content": "  $ sysbench cleanup\n  sysbench * (glob)\n  \n  FATAL: Cannot find benchmark 'cleanup': no such built-in test, file or module\n  [1]\n\n  $ cat >cmd_cleanup.lua <<EOF\n  > function cleanup()\n  >   print('function cleanup()')\n  > end\n  > EOF\n  $ sysbench cmd_cleanup.lua cleanup\n  sysbench * (glob)\n  \n  function cleanup()\n"
  },
  {
    "path": "tests/t/cmd_help.t",
    "content": "  $ sysbench help\n  sysbench * (glob)\n  \n  FATAL: Cannot find benchmark 'help': no such built-in test, file or module\n  [1]\n\n  $ cat >cmd_help.lua <<EOF\n  > function help()\n  >   print('function help()')\n  > end\n  > EOF\n  $ sysbench cmd_help.lua help\n  sysbench * (glob)\n  \n  function help()\n"
  },
  {
    "path": "tests/t/cmd_prepare.t",
    "content": "  $ sysbench prepare\n  sysbench * (glob)\n  \n  FATAL: Cannot find benchmark 'prepare': no such built-in test, file or module\n  [1]\n\n  $ cat >cmd_prepare.lua <<EOF\n  > function prepare()\n  >   print('function prepare()')\n  > end\n  > EOF\n  $ sysbench cmd_prepare.lua prepare\n  sysbench * (glob)\n  \n  function prepare()\n"
  },
  {
    "path": "tests/t/cmd_run.t",
    "content": "  $ sysbench run\n  sysbench * (glob)\n  \n  FATAL: Cannot find benchmark 'run': no such built-in test, file or module\n  [1]\n\n  $ cat >cmd_run.lua <<EOF\n  > function thread_run()\n  >   print('function thread_run()')\n  > end\n  > function event()\n  > end\n  > EOF\n  $ sysbench --verbosity=0 cmd_run.lua run\n  function thread_run()\n"
  },
  {
    "path": "tests/t/cmdline.t",
    "content": "########################################################################\n# Command line syntax tests\n########################################################################\n\n  $ sysbench foo bar\n  sysbench * (glob)\n  \n  FATAL: Cannot find benchmark 'foo': no such built-in test, file or module\n  [1]\n\n  $ sysbench foo bar baz\n  Unrecognized command line argument: baz\n  [1]\n\n  $ sysbench --unknown <<EOF\n  > EOF\n  sysbench * (glob)\n  \n\n  $ sysbench fileio\n  sysbench * (glob)\n  \n  The 'fileio' test requires a command argument. See 'sysbench fileio help'\n  [1]\n\n  $ sysbench --help foo | grep Usage:\n  Usage:\n\n  $ sysbench <<EOF\n  > print('test')\n  > EOF\n  sysbench * (glob)\n  \n  test\n\n  $ sysbench run <<EOF\n  > print('script body')\n  > function event()\n  >   print('event function')\n  > end\n  > EOF\n  sysbench * (glob)\n  \n  FATAL: Cannot find benchmark 'run': no such built-in test, file or module\n  [1]\n\n  $ cat >$CRAMTMP/cmdline.lua <<EOF\n  > #!/usr/bin/env sysbench\n  > print('script body')\n  > function event()\n  >   print('event function')\n  > end\n  > EOF\n  $ sysbench --events=1 $CRAMTMP/cmdline.lua\n  sysbench * (glob)\n  \n  script body\n\n  $ sysbench --events=1 $CRAMTMP/cmdline.lua run\n  sysbench * (glob)\n  \n  script body\n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  script body\n  Threads started!\n  \n  event function\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:*s (glob)\n      total number of events:              1\n  \n  Latency (ms):\n           min: *.* (glob)\n           avg: *.* (glob)\n           max: *.* (glob)\n           95th percentile: *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           1.0000/0.00\n      execution time (avg/stddev):   *.*/0.00 (glob)\n  \n########################################################################\nCommand line options tests\n########################################################################\n\n  $ cat >cmdline.lua <<EOF\n  > sysbench.cmdline.options = {\n  >   str_opt1 = {\"str_opt1 description\"},\n  >   str_opt2 = {\"str_opt2 description\", \"opt2\"},\n  >   str_opt3 = {\"str_opt3 description\", \"opt3\", sysbench.cmdline.ARG_STRING},\n  >   bool_opt1 = {\"bool_opt1 description\", false},\n  >   bool_opt2 = {\"bool_opt2 description\", true},\n  >   bool_opt3 = {\"bool_opt3 description\", nil, sysbench.cmdline.ARG_BOOL},\n  >   int_opt1 = {\"int_opt1 description\", 10},\n  >   int_opt2 = {\"int_opt2 description\", nil, sysbench.cmdline.ARG_INT},\n  >   int_opt3 = {\"int_opt3 description\", 20, sysbench.cmdline.ARG_INT},\n  >   float_opt1 = {\"float_opt1 description\", 3.14, sysbench.cmdline.ARG_DOUBLE},\n  >   float_opt2 = {\"float_opt2 description\", 0.2},\n  >   list_opt1 = {\"list_opt1 description\", {\"foo\", \"bar\"}},\n  >   list_opt2 = {\"list_opt2 description\", nil, sysbench.cmdline.ARG_LIST},\n  >   [\"dash-opt\"] = {\"dash-opt desc\", \"dash-opt val\"}\n  > }\n  > \n  > function print_opt_table()\n  >    local o = sysbench.opt\n  >    print(o.str_opt1)\n  >    print(o.str_opt2)\n  >    print(o.str_opt3)\n  >    print(o.bool_opt1)\n  >    print(o.bool_opt2)\n  >    print(o.bool_opt3)\n  >    print(o.int_opt1)\n  >    print(o.int_opt2)\n  >    print(o.float_opt1)\n  >    print(o.float_opt2)\n  >    print(o.list_opt1)\n  >    print(o.list_opt2)\n  >    print(o.dash_opt)\n  >    print()\n  > end\n  > \n  > function help()\n  >    print(\"function help()\")\n  >    print(\"Available options:\")\n  >    sysbench.cmdline.print_test_options()\n  >    print_opt_table()\n  > end\n  > \n  > function init()\n  >   print(\"function init()\")\n  >   print_opt_table()\n  > end\n  > \n  > function thread_init()\n  >   print(\"function thread_init()\")\n  >   print_opt_table()\n  > end\n  > \n  > function event()\n  >   print(\"function event()\")\n  >   print_opt_table()\n  > end\n  > \n  > function thread_done()\n  >   print(\"function thread_done()\")\n  >   print_opt_table()\n  > end\n  > \n  > function done()\n  >   print(\"function done()\")\n  >   print_opt_table()\n  > end\n  > EOF\n\n  $ sysbench cmdline.lua\n  sysbench * (glob)\n  \n  $ sysbench cmdline.lua help\n  sysbench * (glob)\n  \n  function help()\n  Available options:\n    --bool_opt1[=on|off]   bool_opt1 description [off]\n    --bool_opt2[=on|off]   bool_opt2 description [on]\n    --bool_opt3[=on|off]   bool_opt3 description\n    --dash-opt=STRING      dash-opt desc [dash-opt val]\n    --float_opt1=N         float_opt1 description [3.14]\n    --float_opt2=N         float_opt2 description [0.2]\n    --int_opt1=N           int_opt1 description [10]\n    --int_opt2=N           int_opt2 description\n    --int_opt3=N           int_opt3 description [20]\n    --list_opt1=[LIST,...] list_opt1 description [foo,bar]\n    --list_opt2=[LIST,...] list_opt2 description\n    --str_opt1=STRING      str_opt1 description\n    --str_opt2=STRING      str_opt2 description [opt2]\n    --str_opt3=STRING      str_opt3 description [opt3]\n  \n  \n  opt2\n  opt3\n  false\n  true\n  true\n  10\n  0\n  3.14\n  0.2\n  table: 0x* (glob)\n  table: 0x* (glob)\n  dash-opt val\n  \n  $ sysbench cmdline.lua prepare\n  sysbench * (glob)\n  \n  'cmdline.lua' test does not implement the 'prepare' command.\n  [1]\n\n  $ sysbench --non-existing-option=3 cmdline.lua prepare\n  sysbench * (glob)\n  \n  invalid option: --non-existing-option=3\n  [1]\n\n  $ sysbench cmdline.lua --events=1 run\n  sysbench * (glob)\n  \n  function init()\n  \n  opt2\n  opt3\n  false\n  true\n  true\n  10\n  0\n  3.14\n  0.2\n  table: 0x* (glob)\n  table: 0x* (glob)\n  dash-opt val\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  function thread_init()\n  \n  opt2\n  opt3\n  false\n  true\n  true\n  10\n  0\n  3.14\n  0.2\n  table: 0x* (glob)\n  table: 0x* (glob)\n  dash-opt val\n  \n  Threads started!\n  \n  function event()\n  \n  opt2\n  opt3\n  false\n  true\n  true\n  10\n  0\n  3.14\n  0.2\n  table: 0x* (glob)\n  table: 0x* (glob)\n  dash-opt val\n  \n  function thread_done()\n  \n  opt2\n  opt3\n  false\n  true\n  true\n  10\n  0\n  3.14\n  0.2\n  table: 0x* (glob)\n  table: 0x* (glob)\n  dash-opt val\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              1\n  \n  Latency (ms):\n           min:                                  * (glob)\n           avg:                                  * (glob)\n           max:                                  * (glob)\n           95th percentile:                      * (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           1.0000/0.00\n      execution time (avg/stddev):   */0.00 (glob)\n  \n  function done()\n  \n  opt2\n  opt3\n  false\n  true\n  true\n  10\n  0\n  3.14\n  0.2\n  table: 0x* (glob)\n  table: 0x* (glob)\n  dash-opt val\n  \n\n  $ sysbench cmdline.lua cleanup\n  sysbench * (glob)\n  \n  'cmdline.lua' test does not implement the 'cleanup' command.\n  [1]\n\n  $ cat >cmdline.lua <<EOF\n  > \n  > EOF\n\n  $ sysbench cmdline.lua help\n  sysbench * (glob)\n  \n  'cmdline.lua' test does not implement the 'help' command.\n  [1]\n\n  $ cat >cmdline.lua <<EOF\n  > sysbench.cmdline.options = {\n  >   {}, \n  > }\n  > \n  > function help()\n  > end\n  > EOF\n  $ sysbench cmdline.lua help\n  sysbench * (glob)\n  \n  FATAL: `sysbench.cmdline.read_cmdline_options' function failed: [string \"sysbench.cmdline.lua\"]:*: wrong table structure in sysbench.cmdline.options (glob)\n  [1]\n\n  $ sysbench fileio --invalid-option prepare\n  sysbench * (glob)\n  \n  invalid option: --invalid-option\n  [1]\n\n# Custom commands\n\n  $ sysbench <<EOF\n  > sysbench.cmdline.commands = {\n  >   cmd1 = \"wrong structure\"\n  > }\n  > EOF\n  sysbench * (glob)\n  \n  $ sysbench <<EOF\n  > sysbench.cmdline.commands = {\n  >   cmd1 = { non_existing_func }\n  > }\n  > EOF\n  sysbench * (glob)\n  \n  $ cat >cmdline.lua <<EOF\n  > ffi.cdef \"unsigned int sleep(unsigned int);\"\n  > function cmd1_func()\n  >  print(\"cmd1, sysbench.tid = \" .. sysbench.tid)\n  > end\n  > function cmd2_func()\n  >   ffi.C.sleep(sysbench.tid % 2)\n  >   print(\"cmd2, sysbench.tid = \" .. sysbench.tid)\n  > end\n  > function prepare_func()\n  >   ffi.C.sleep(sysbench.tid % 2)\n  >   print(\"prepare_func, sysbench.tid = \" .. sysbench.tid)\n  > end\n  > sysbench.cmdline.commands = {\n  >  cmd1 = { cmd1_func },\n  >  cmd2 = { cmd2_func, sysbench.cmdline.PARALLEL_COMMAND },\n  >  prepare = { prepare_func, sysbench.cmdline.PARALLEL_COMMAND }\n  > }\n  > EOF\n\n  $ sysbench --threads=2 cmdline.lua cmd1\n  sysbench * (glob)\n  \n  cmd1, sysbench.tid = 0\n  $ sysbench --threads=2 cmdline.lua cmd2\n  sysbench * (glob)\n  \n  Initializing worker threads...\n  \n  cmd2, sysbench.tid = [01] (re)\n  cmd2, sysbench.tid = [01] (re)\n\n  $ sysbench --threads=2 cmdline.lua prepare\n  sysbench * (glob)\n  \n  Initializing worker threads...\n  \n  prepare_func, sysbench.tid = [01] (re)\n  prepare_func, sysbench.tid = [01] (re)\n\n  $ sysbench --threads=2 cmdline.lua cmd3\n  sysbench * (glob)\n  \n  Unknown command: cmd3\n  [1]\n\n  $ cat >cmdline.lua <<EOF\n  > sysbench.cmdline.options = { opt1 = {\"opt1\"}, opt2 = {\"opt2\"} }\n  > function print_cmd()\n  >   print(\"argv = \" .. require(\"inspect\")(sysbench.cmdline.argv))\n  >   print(string.format(\"sysbench.cmdline.command = %s\",sysbench.cmdline.command))\n  > end\n  > function prepare()\n  >  print_cmd()\n  > end\n  > print_cmd()\n  > EOF\n  $ sysbench --opt1 --opt2=val cmdline.lua\n  sysbench * (glob)\n  \n  argv = { \"--opt1\", \"--opt2=val\", \"cmdline.lua\",\n    [0] = \"sysbench\"\n  }\n  sysbench.cmdline.command = nil\n  $ sysbench --opt1 --opt2=val cmdline.lua prepare\n  sysbench * (glob)\n  \n  argv = { \"--opt1\", \"--opt2=val\", \"cmdline.lua\", \"prepare\",\n    [0] = \"sysbench\"\n  }\n  sysbench.cmdline.command = prepare\n  argv = { \"--opt1\", \"--opt2=val\", \"cmdline.lua\", \"prepare\",\n    [0] = \"sysbench\"\n  }\n  sysbench.cmdline.command = prepare\n\n  $ sysbench - <<EOF\n  > print(\"hello\")\n  > EOF\n  sysbench * (glob)\n  \n  hello\n\n  $ sysbench - prepare <<EOF\n  > function prepare()\n  >   print(\"prepare\")\n  > end\n  > print(\"global\")\n  > EOF\n  sysbench * (glob)\n  \n  global\n\n# Test benchmark specification as a module\n\n  $ cat > cmdline_module.lua <<EOF\n  > print(\"cmdline_module loaded\")\n  > function event()\n  >   print(\"cmdline_module event\")\n  > end\n  > EOF\n\n  $ LUA_PATH=\"$PWD/?.lua;$LUA_PATH\" sysbench cmdline_module --verbosity=0\n  cmdline_module loaded\n\n  $ LUA_PATH=\"$PWD/?.lua;$LUA_PATH\" sysbench cmdline_module --events=1 --verbosity=0 run\n  cmdline_module loaded\n  cmdline_module loaded\n  cmdline_module event\n\n# Test that errors thrown by the script itself are reported properly\n\n  $ cat >> cmdline_module.lua <<EOF\n  >   error(\"test error\")\n  > EOF\n\n  $ LUA_PATH=\"$PWD/?.lua;$LUA_PATH\" sysbench cmdline_module --verbosity=0\n  cmdline_module loaded\n  FATAL: */cmdline_module.lua:5: test error (glob)\n  [1]\n  $ LUA_PATH=\"$PWD/?.lua;$LUA_PATH\" sysbench cmdline_module --events=1 --verbosity=0 run\n  cmdline_module loaded\n  FATAL: */cmdline_module.lua:5: test error (glob)\n  [1]\n\n##########################################################################\n# Test boolean option validation\n##########################################################################\n  $ cat > cmdline.lua <<EOF\n  > sysbench.cmdline.options = {\n  >  bool_opt = {\"Flag\", false}\n  > }\n  > \n  > function prepare()\n  >   print(\"bool_opt = \" .. tostring(sysbench.opt.bool_opt))\n  > end\n  > EOF\n\n  $ SB_ARGS=--verbosity=0\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=on prepare\n  bool_opt = true\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=off prepare\n  bool_opt = false\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=true prepare\n  bool_opt = true\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=false prepare\n  bool_opt = false\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=1 prepare\n  bool_opt = true\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=0 prepare\n  bool_opt = false\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=5 prepare\n  invalid option: --bool-opt=5\n  [1]\n  $ sysbench $SB_ARGS cmdline.lua --bool-opt=foo prepare\n  invalid option: --bool-opt=foo\n  [1]\n"
  },
  {
    "path": "tests/t/commands.t",
    "content": "  $ commands=$(sysbench --help | grep 'Commands' | cut -d ' ' -f 6-)\n  $ for cmd in $commands; do\n  > if [ ! -r ${SBTEST_SUITEDIR}/cmd_${cmd}.t ]\n  > then\n  >   echo \"Cannot find test(s) for 'sysbench $cmd'!\"\n  >   exit 1\n  > fi\n  > done\n"
  },
  {
    "path": "tests/t/drivers.t",
    "content": "########################################################################\nMake sure all available DB drivers are covered\n########################################################################\n\n  $ drivers=$(sysbench --help | sed -n '/Compiled-in database drivers:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3)\n  $ for drv in $drivers\n  > do\n  >   if [ ! -r ${SBTEST_SUITEDIR}/drv_${drv}.t ]\n  >   then\n  >     echo \"Cannot find test(s) for the $drv driver!\"\n  >     exit 1\n  >   fi\n  > done\n\n# Try using a non-existing driver\n  $ sysbench --db-driver=nonexisting ${SBTEST_SCRIPTDIR}/oltp_read_write.lua cleanup\n  sysbench * (glob)\n  \n  (FATAL: invalid database driver name: 'nonexisting'|FATAL: No DB drivers available) (re)\n  FATAL: `cleanup' function failed: * failed to initialize the DB driver (glob)\n  [1]\n"
  },
  {
    "path": "tests/t/drv_mysql.t",
    "content": "########################################################################\nMySQL driver tests\n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ . $SBTEST_INCDIR/drv_common.sh\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            10\n          write:                           0\n          other:                           0\n          total:                           10\n      transactions:                        10     (*.* per sec.) (glob)\n      queries:                             10     (*.* per sec.) (glob)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *.*s (glob)\n      total number of events:              10\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           *.*/*.* (glob)\n      execution time (avg/stddev):   *.*/*.* (glob)\n  \n"
  },
  {
    "path": "tests/t/drv_pgsql.t",
    "content": "########################################################################\nPostgreSQL driver tests\n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ . $SBTEST_INCDIR/drv_common.sh\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            10\n          write:                           0\n          other:                           0\n          total:                           10\n      transactions:                        10     (*.* per sec.) (glob)\n      queries:                             10     (*.* per sec.) (glob)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *.*s (glob)\n      total number of events:              10\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           *.*/*.* (glob)\n      execution time (avg/stddev):   *.*/*.* (glob)\n  \n"
  },
  {
    "path": "tests/t/help_drv_mysql.t",
    "content": "Skip test if the MySQL driver is not available.\n\n  $ if [ -z \"$SBTEST_HAS_MYSQL\" ]\n  > then\n  >   exit 80\n  > fi\n\n  $ sysbench --help | grep -- '--db-driver'\n    --db-driver=STRING  specifies database driver to use ('help' to get list of available drivers) [mysql]\n\n  $ sysbench --help | sed -n '/mysql options:/,/^$/p' | grep -v 'mysql-ssl[=\\[]'\n  mysql options:\n    --mysql-host=[LIST,...]               MySQL server host [localhost]\n    --mysql-port=[LIST,...]               MySQL server port [3306]\n    --mysql-socket=[LIST,...]             MySQL socket\n    --mysql-user=STRING                   MySQL user [sbtest]\n    --mysql-password=STRING               MySQL password []\n    --mysql-db=STRING                     MySQL database name [sbtest]\n    --mysql-ssl-key=STRING                path name of the client private key file\n    --mysql-ssl-ca=STRING                 path name of the CA file\n    --mysql-ssl-cert=STRING               path name of the client public key certificate file\n    --mysql-ssl-cipher=STRING             use specific cipher for SSL connections []\n    --mysql-compression[=on|off]          use compression, if available in the client library [off]\n    --mysql-compression-algorithms=STRING compression algorithms to use [zlib]\n    --mysql-debug[=on|off]                trace all client library calls [off]\n    --mysql-ignore-errors=[LIST,...]      list of errors to ignore, or \"all\" [1213,1020,1205]\n    --mysql-dry-run[=on|off]              Dry run, pretend that all MySQL client API calls are successful without executing them [off]\n  \n"
  },
  {
    "path": "tests/t/help_drv_pgsql.t",
    "content": "Skip test if the PostgreSQL driver is not available.\n\n  $ if [ -z \"$SBTEST_HAS_PGSQL\" ]\n  > then\n  >   exit 80\n  > fi\n\n  $ sysbench --help | sed -n '/pgsql options:/,/^$/p'\n  pgsql options:\n    --pgsql-host=STRING     PostgreSQL server host [localhost]\n    --pgsql-port=N          PostgreSQL server port [5432]\n    --pgsql-user=STRING     PostgreSQL user [sbtest]\n    --pgsql-password=STRING PostgreSQL password []\n    --pgsql-db=STRING       PostgreSQL database name [sbtest]\n    --pgsql-sslmode=STRING  PostgreSQL SSL mode (disable, allow, prefer, require, verify-ca, verify-full) [prefer]\n  \n"
  },
  {
    "path": "tests/t/opt_help.t",
    "content": "########################################################################\nSkip everything between \"Compiled-in database drivers:\" and\n\"Compiled-in tests:\" as that part depends on available database\ndrivers and thus, build options. Driver-specific options are tested\nseparately.\n########################################################################\n\n  $ sysbench --help | sed '/Compiled-in database drivers:/,/Compiled-in tests:/d' \n  Usage:\n    sysbench [options]... [testname] [command]\n  \n  Commands implemented by most tests: prepare run cleanup help\n  \n  General options:\n    --threads=N                     number of threads to use [1]\n    --events=N                      limit for total number of events [0]\n    --time=N                        limit for total execution time in seconds [10]\n    --warmup-time=N                 execute events for this many seconds with statistics disabled before the actual benchmark run with statistics enabled [0]\n    --forced-shutdown=STRING        number of seconds to wait after the --time limit before forcing shutdown, or 'off' to disable [off]\n    --thread-stack-size=SIZE        size of stack per thread [64K]\n    --thread-init-timeout=N         wait time in seconds for worker threads to initialize [30]\n    --rate=N                        average transactions rate. 0 for unlimited rate [0]\n    --report-interval=N             periodically report intermediate statistics with a specified interval in seconds. 0 disables intermediate reports [0]\n    --report-checkpoints=[LIST,...] dump full statistics and reset all counters at specified points in time. The argument is a list of comma-separated values representing the amount of time in seconds elapsed from start of test when report checkpoint(s) must be performed. Report checkpoints are off by default. []\n    --debug[=on|off]                print more debugging info [off]\n    --validate[=on|off]             perform validation checks where possible [off]\n    --help[=on|off]                 print help and exit [off]\n    --version[=on|off]              print version and exit [off]\n    --config-file=FILENAME          File containing command line options\n    --luajit-cmd=STRING             perform LuaJIT control command. This option is equivalent to 'luajit -j'. See LuaJIT documentation for more information\n  \n  Pseudo-Random Numbers Generator options:\n    --rand-type=STRING   random numbers distribution {uniform, gaussian, pareto, zipfian} to use by default [uniform]\n    --rand-seed=N        seed for random number generator. When 0, the current time is used as an RNG seed. [0]\n    --rand-pareto-h=N    shape parameter for the Pareto distribution [0.2]\n    --rand-zipfian-exp=N shape parameter (exponent, theta) for the Zipfian distribution [0.8]\n  \n  Log options:\n    --verbosity=N verbosity level {5 - debug, 0 - only critical messages} [3]\n  \n    --percentile=N       percentile to calculate in latency statistics (1-100). Use the special value of 0 to disable percentile calculations [95]\n    --histogram[=on|off] print latency histogram in report [off]\n  \n  General database options:\n  \n    --db-driver=STRING  specifies database driver to use \\('help' to get list of available drivers\\)( \\[mysql\\])? (re)\n    --db-ps-mode=STRING prepared statements usage mode {auto, disable} [auto]\n    --db-debug[=on|off] print database-specific debug information [off]\n  \n  \n    fileio - File I/O test\n    cpu - CPU performance test\n    memory - Memory functions speed test\n    threads - Threads subsystem performance test\n    mutex - Mutex performance test\n  \n  See 'sysbench <testname> help' for a list of options for each test.\n  \n########################################################################\nTest driver-specific options\n########################################################################\n  $ drivers=$(sysbench --help | sed -n '/Compiled-in database drivers:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3)\n  $ for drv in $drivers\n  > do\n  >   if [ ! -r ${SBTEST_SUITEDIR}/help_drv_${drv}.t ]\n  >   then\n  >     echo \"Cannot find test(s) for $drv driver options!\"\n  >     exit 1\n  >   fi\n  > done\n"
  },
  {
    "path": "tests/t/opt_histogram.t",
    "content": "########################################################################\n--histogram tests\n########################################################################\n\n  $ cat >$CRAMTMP/histogram.lua <<EOF\n  > local ffi = require(\"ffi\")\n  > ffi.cdef[[\n  >   int usleep(unsigned int);\n  > ]]\n  > function event()\n  >   if (sysbench.tid == 0) then\n  >     ffi.C.usleep(1000000)\n  >   else\n  >     ffi.C.usleep(2000000)\n  >   end\n  > end\n  > EOF\n  $ sysbench --histogram $CRAMTMP/histogram.lua --events=2 --threads=2 run\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Latency histogram (values are in milliseconds)\n         value  ------------- distribution ------------- count\n     * |\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1 (glob)\n     * |\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\*\\* 1 (glob)\n   \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                     *s (glob)\n      total number of events:              2\n  \n  Latency (ms):\n           min: *.* (glob)\n           avg: *.* (glob)\n           max: *.* (glob)\n           95th percentile: *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           1.0000/0.00\n      execution time (avg/stddev):   */* (glob)\n  \n"
  },
  {
    "path": "tests/t/opt_luajit_cmd.t",
    "content": "########################################################################\n--luajit-cmd tests\n########################################################################\n\n  $ cat >opt_luajit_cmd.lua <<EOF\n  > print(\"JIT status: \" .. (jit.status() and \"on\" or \"off\"))\n  > EOF\n  $ sysbench --luajit-cmd opt_luajit_cmd.lua\n  sysbench * (glob)\n  \n  JIT status: on\n\n  $ sysbench --luajit-cmd=off opt_luajit_cmd.lua\n  sysbench * (glob)\n  \n  JIT status: off\n\n  $ sysbench --luajit-cmd=on opt_luajit_cmd.lua\n  sysbench * (glob)\n  \n  JIT status: on\n"
  },
  {
    "path": "tests/t/opt_rate.t",
    "content": "########################################################################\nTests for the --rate option (aka the limited rate mode)\n########################################################################\n\n# Failing to deliver the requested rate should result in a non-zero exit code\n  $ sysbench --rate=2000000000 cpu run --verbosity=1\n  FATAL: The event queue is full. This means the worker threads are unable to keep up with the specified event generation rate\n  [1]\n"
  },
  {
    "path": "tests/t/opt_report_checkpoints.t",
    "content": "########################################################################\n# --report-checkpoints tests\n########################################################################\n\n  $ if [ -z \"$SBTEST_HAS_MYSQL\" ]\n  > then\n  >   exit 80\n  > fi\n\n  $ sysbench ${SBTEST_SCRIPTDIR}/oltp_read_write.lua --db-driver=mysql --mysql-dry-run --time=3 --events=0 --report-checkpoints=1,2 run | grep -E '(Checkpoint report|SQL statistics)'\n  [ 1s ] Checkpoint report:\n  SQL statistics:\n  [ 2s ] Checkpoint report:\n  SQL statistics:\n  SQL statistics:\n\n# Run a test that does not support checkpoint reports\n\n  $ sysbench cpu --report-checkpoints=1 --time=2 run | grep 'Checkpoint report'\n  [ 1s ] Checkpoint report:\n"
  },
  {
    "path": "tests/t/opt_report_interval.t",
    "content": "########################################################################\n# --report-interval tests\n########################################################################\n\n  $ if [ -z \"$SBTEST_HAS_MYSQL\" ]\n  > then\n  >   exit 80\n  > fi\n\n  $ sysbench ${SBTEST_SCRIPTDIR}/oltp_read_write.lua --db-driver=mysql --mysql-dry-run --time=3 --events=0 --report-interval=1 run | grep '\\[ 2s \\]'\n  [ 2s ] thds: 1 tps: * qps: * (r/w/o: */*/*) lat (ms,95%): *.* err/s: 0.00 reconn/s: 0.00 (glob)\n\n# Run a test that does not support intermediate reports\n\n  $ sysbench cpu --report-interval=1 --time=2 run | grep '\\[ 1s \\]'\n  [ 1s ] thds: 1 eps: * lat (ms,95%): * (glob)\n"
  },
  {
    "path": "tests/t/opt_version.t",
    "content": "########################################################################\nTest for the --version option\n########################################################################\n\n  $ sysbench --version\n  sysbench [.0-9]+(-[a-f0-9]+)? (re)\n\n  $ version=$(sysbench --version | cut -d ' ' -f 1,2)\n  $ test \"$version\" = \"$SBTEST_VERSION_STRING\"\n"
  },
  {
    "path": "tests/t/opt_warmup_time.t",
    "content": "########################################################################\n--warmup-time tests\n########################################################################\n\n  $ cat >$CRAMTMP/warmup_time.lua <<EOF\n  > local ffi = require(\"ffi\")\n  > ffi.cdef[[\n  >   int usleep(unsigned int);\n  > ]]\n  > function event()\n  >   if (sysbench.tid == 0) then\n  >     ffi.C.usleep(2000000)\n  >   else\n  >     ffi.C.usleep(3000000)\n  >   end\n  > end\n  > EOF\n\n  $ sysbench --warmup-time=-1 $CRAMTMP/warmup_time.lua --threads=2 run\n  FATAL: Invalid value for --warmup-time: -1.\n  \n  [1]\n\n  $ sysbench --warmup-time=1 $CRAMTMP/warmup_time.lua --threads=2 --time=1 run\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Warmup time: 1s\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Warming up for 1 seconds...\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        2.*s (glob)\n      total number of events:              2\n  \n  Latency (ms):\n           min: * (glob)\n           avg: * (glob)\n           max: * (glob)\n           95th percentile: * (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  $ sysbench --warmup-time=1 $CRAMTMP/warmup_time.lua --threads=2 --time=0 --events=3 run\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Warmup time: 1s\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Warming up for 1 seconds...\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        5.*s (glob)\n      total number of events:              5\n  \n  Latency (ms):\n           min: * (glob)\n           avg: * (glob)\n           max: * (glob)\n           95th percentile: * (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n"
  },
  {
    "path": "tests/t/script_bulk_insert_mysql.t",
    "content": "########################################################################\nbulk_insert.lua + MySQL tests\n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ . $SBTEST_INCDIR/script_bulk_insert_common.sh\n  Creating table 'sbtest1'...\n  Creating table 'sbtest2'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=InnoDB * (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=InnoDB * (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            0\n          write:                           [12] (re)\n          other:                           0\n          total:                           [12] (re)\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             [12]      \\(.* per sec.\\) (re)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):* (glob)\n      execution time (avg/stddev):* (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n"
  },
  {
    "path": "tests/t/script_bulk_insert_pgsql.t",
    "content": "########################################################################\nbulk_insert.lua + PostgreSQL tests\n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ . $SBTEST_INCDIR/script_bulk_insert_common.sh\n  Creating table 'sbtest1'...\n  Creating table 'sbtest2'...\n                              Table \"public.sbtest1\"\n   Column |  Type   |     Modifiers      | Storage | Stats target | Description \n  --------+---------+--------------------+---------+--------------+-------------\n   id     | integer | not null           | plain   |              | \n   k      | integer | not null default 0 | plain   |              | \n  \n  Indexes:\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |  Type   |     Modifiers      | Storage | Stats target | Description \n  --------+---------+--------------------+---------+--------------+-------------\n   id     | integer | not null           | plain   |              | \n   k      | integer | not null default 0 | plain   |              | \n  \n  Indexes:\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n  Did not find any relation named \"sbtest3\".\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            0\n          write:                           [12] (re)\n          other:                           0\n          total:                           [12] (re)\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             [12]      \\(.* per sec.\\) (re)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):* (glob)\n      execution time (avg/stddev):* (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n"
  },
  {
    "path": "tests/t/script_oltp_delete_mysql.t",
    "content": "########################################################################\noltp_delete.lua + MySQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_delete.lua\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench * (glob)\n  \n  Preloading table sbtest1\n  Preloading table sbtest2\n  Preloading table sbtest3\n  Preloading table sbtest4\n  Preloading table sbtest5\n  Preloading table sbtest6\n  Preloading table sbtest7\n  Preloading table sbtest8\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            0\n          write:                           * (glob)\n          other:                           * (glob)\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_delete_pgsql.t",
    "content": "########################################################################\noltp_delete.lua + PostgreSQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_delete.lua\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  FATAL: *: warmup is currently MySQL only (glob)\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            0\n          write:                           * (glob)\n          other:                           * (glob)\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_general_mysql.t",
    "content": "  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ SB_EXTRA_ARGS=${SB_EXTRA_ARGS:-}\n  $ ARGS=\"oltp_read_write ${DB_DRIVER_ARGS} --verbosity=1 ${SB_EXTRA_ARGS}\"\n\n  $ sysbench $ARGS --create-table-options=\"COMMENT='foo'\" prepare\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n\n  $ db_show_table sbtest1\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB * COMMENT='foo' (glob)\n\n  $ sysbench $ARGS cleanup\n  Dropping table 'sbtest1'...\n"
  },
  {
    "path": "tests/t/script_oltp_help.t",
    "content": "########################################################################\nOLTP usage information test\n########################################################################\n\n  $ sysbench $SBTEST_SCRIPTDIR/oltp_read_write.lua help\n  sysbench * (glob)\n  \n  oltp_read_write.lua options:\n    --auto_inc[=on|off]           Use AUTO_INCREMENT column as Primary Key (for MySQL), or its alternatives in other DBMS. When disabled, use client-generated IDs [on]\n    --create_secondary[=on|off]   Create a secondary index in addition to the PRIMARY KEY [on]\n    --create_table_options=STRING Extra CREATE TABLE options []\n    --delete_inserts=N            Number of DELETE/INSERT combinations per transaction [1]\n    --distinct_ranges=N           Number of SELECT DISTINCT queries per transaction [1]\n    --index_updates=N             Number of UPDATE index queries per transaction [1]\n    --mysql_storage_engine=STRING Storage engine, if MySQL is used [innodb]\n    --non_index_updates=N         Number of UPDATE non-index queries per transaction [1]\n    --order_ranges=N              Number of SELECT ORDER BY queries per transaction [1]\n    --pgsql_variant=STRING        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\n    --point_selects=N             Number of point SELECT queries per transaction [10]\n    --range_selects[=on|off]      Enable/disable all range SELECT queries [on]\n    --range_size=N                Range size for range SELECT queries [100]\n    --reconnect=N                 Reconnect after every N events. The default (0) is to not reconnect [0]\n    --secondary[=on|off]          Use a secondary index in place of the PRIMARY KEY [off]\n    --simple_ranges=N             Number of simple range SELECT queries per transaction [1]\n    --skip_trx[=on|off]           Don't start explicit transactions and execute all queries in the AUTOCOMMIT mode [off]\n    --sum_ranges=N                Number of SELECT SUM() queries per transaction [1]\n    --table_size=N                Number of rows per table [10000]\n    --tables=N                    Number of tables [1]\n  \n"
  },
  {
    "path": "tests/t/script_oltp_insert_mysql.t",
    "content": "########################################################################\noltp_insert.lua + MySQL tests\n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_insert.lua\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench * (glob)\n  \n  Preloading table sbtest1\n  Preloading table sbtest2\n  Preloading table sbtest3\n  Preloading table sbtest4\n  Preloading table sbtest5\n  Preloading table sbtest6\n  Preloading table sbtest7\n  Preloading table sbtest8\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            0\n          write:                           100\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_insert_pgsql.t",
    "content": "########################################################################\noltp_insert.lua + PostgreSQL tests\n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_insert.lua\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  FATAL: *: warmup is currently MySQL only (glob)\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            0\n          write:                           100\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_point_select_mysql.t",
    "content": "########################################################################\noltp_point_select.lua + MySQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_point_select.lua\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench * (glob)\n  \n  Preloading table sbtest1\n  Preloading table sbtest2\n  Preloading table sbtest3\n  Preloading table sbtest4\n  Preloading table sbtest5\n  Preloading table sbtest6\n  Preloading table sbtest7\n  Preloading table sbtest8\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            100\n          write:                           0\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_point_select_pgsql.t",
    "content": "########################################################################\noltp_point_select.lua + PostgreSQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_point_select.lua\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  FATAL: *: warmup is currently MySQL only (glob)\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            100\n          write:                           0\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_read_write_mysql.t",
    "content": "########################################################################\noltp_read_write.lua + MySQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ DB_DRIVER_ARGS=\"--db-driver=mysql --mysql-storage-engine=myisam $SBTEST_MYSQL_ARGS\"\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_read_write.lua\n# Override --threads to run read/write tests with a single thread for\n# deterministic results\n  $ SB_EXTRA_ARGS=\"--threads=1\"\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench * (glob)\n  \n  Preloading table sbtest1\n  Preloading table sbtest2\n  Preloading table sbtest3\n  Preloading table sbtest4\n  Preloading table sbtest5\n  Preloading table sbtest6\n  Preloading table sbtest7\n  Preloading table sbtest8\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            1400\n          write:                           400\n          other:                           200\n          total:                           2000\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             2000   (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=MyISAM AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n\n\n  $ DB_DRIVER_ARGS=\"--db-driver=mysql --mysql-storage-engine=innodb $SBTEST_MYSQL_ARGS\"\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench * (glob)\n  \n  Preloading table sbtest1\n  Preloading table sbtest2\n  Preloading table sbtest3\n  Preloading table sbtest4\n  Preloading table sbtest5\n  Preloading table sbtest6\n  Preloading table sbtest7\n  Preloading table sbtest8\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest2\n  CREATE TABLE `sbtest2` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_2` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest3\n  CREATE TABLE `sbtest3` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_3` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest4\n  CREATE TABLE `sbtest4` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_4` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest5\n  CREATE TABLE `sbtest5` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_5` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest6\n  CREATE TABLE `sbtest6` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_6` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest7\n  CREATE TABLE `sbtest7` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_7` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  *************************** 1. row ***************************\n  sbtest8\n  CREATE TABLE `sbtest8` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_8` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest9' doesn't exist\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            1400\n          write:                           400\n          other:                           200\n          total:                           2000\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             2000   (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_oltp_read_write_pgsql.t",
    "content": "########################################################################\noltp_read_write.lua + PostgreSQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ OLTP_SCRIPT_PATH=${SBTEST_SCRIPTDIR}/oltp_read_write.lua\n# Override --threads to run read/write tests with a single thread for\n# deterministic results\n  $ SB_EXTRA_ARGS=\"--threads=1\"\n  $ . $SBTEST_INCDIR/script_oltp_common.sh\n  sysbench *.* * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Creating table 'sbtest2'...\n  Inserting 10000 records into 'sbtest2'\n  Creating a secondary index on 'sbtest2'...\n  Creating table 'sbtest3'...\n  Inserting 10000 records into 'sbtest3'\n  Creating a secondary index on 'sbtest3'...\n  Creating table 'sbtest4'...\n  Inserting 10000 records into 'sbtest4'\n  Creating a secondary index on 'sbtest4'...\n  Creating table 'sbtest5'...\n  Inserting 10000 records into 'sbtest5'\n  Creating a secondary index on 'sbtest5'...\n  Creating table 'sbtest6'...\n  Inserting 10000 records into 'sbtest6'\n  Creating a secondary index on 'sbtest6'...\n  Creating table 'sbtest7'...\n  Inserting 10000 records into 'sbtest7'\n  Creating a secondary index on 'sbtest7'...\n  Creating table 'sbtest8'...\n  Inserting 10000 records into 'sbtest8'\n  Creating a secondary index on 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  FATAL: *: warmup is currently MySQL only (glob)\n  sysbench *.* * (glob)\n  \n  Dropping table 'sbtest1'...\n  Dropping table 'sbtest2'...\n  Dropping table 'sbtest3'...\n  Dropping table 'sbtest4'...\n  Dropping table 'sbtest5'...\n  Dropping table 'sbtest6'...\n  Dropping table 'sbtest7'...\n  Dropping table 'sbtest8'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n                              Table \"public.sbtest2\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest2_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_2 ON sbtest2 USING btree (k)\n   CREATE UNIQUE INDEX sbtest2_pkey ON sbtest2 USING btree (id)\n  \n                              Table \"public.sbtest3\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest3_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_3 ON sbtest3 USING btree (k)\n   CREATE UNIQUE INDEX sbtest3_pkey ON sbtest3 USING btree (id)\n  \n                              Table \"public.sbtest4\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest4_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_4 ON sbtest4 USING btree (k)\n   CREATE UNIQUE INDEX sbtest4_pkey ON sbtest4 USING btree (id)\n  \n                              Table \"public.sbtest5\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest5_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_5 ON sbtest5 USING btree (k)\n   CREATE UNIQUE INDEX sbtest5_pkey ON sbtest5 USING btree (id)\n  \n                              Table \"public.sbtest6\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest6_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_6 ON sbtest6 USING btree (k)\n   CREATE UNIQUE INDEX sbtest6_pkey ON sbtest6 USING btree (id)\n  \n                              Table \"public.sbtest7\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest7_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_7 ON sbtest7 USING btree (k)\n   CREATE UNIQUE INDEX sbtest7_pkey ON sbtest7 USING btree (id)\n  \n                              Table \"public.sbtest8\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest8_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_8 ON sbtest8 USING btree (k)\n   CREATE UNIQUE INDEX sbtest8_pkey ON sbtest8 USING btree (id)\n  \n  Did not find any relation named \"sbtest9\".\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            1400\n          write:                           400\n          other:                           200\n          total:                           2000\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             2000   (* per sec.) (glob)\n      ignored errors:                      0      (* per sec.) (glob)\n      reconnects:                          0      (* per sec.) (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  # Test --create-secondary=off\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  # Test --auto-inc=off\n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  Dropping table 'sbtest1'...\n  # Test --reconnect\n      reconnects:                          20     (* per sec.) (glob)\n"
  },
  {
    "path": "tests/t/script_select_random_mysql.t",
    "content": "########################################################################\nselect_random_*.lua + MySQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/mysql_common.sh\n  $ . $SBTEST_INCDIR/script_select_random_common.sh\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            100\n          write:                           0\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):* (glob)\n      execution time (avg/stddev):* (glob)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n  *************************** 1. row ***************************\n  sbtest1\n  CREATE TABLE `sbtest1` (\n    `id` int* NOT NULL AUTO_INCREMENT, (glob)\n    `k` int* NOT NULL DEFAULT '0', (glob)\n    `c` char(120)* NOT NULL DEFAULT '', (glob)\n    `pad` char(60)* NOT NULL DEFAULT '', (glob)\n    PRIMARY KEY (`id`),\n    KEY `k_1` (`k`)\n  ) ENGINE=InnoDB AUTO_INCREMENT=10001 DEFAULT CHARSET=* (glob)\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            100\n          write:                           0\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):* (glob)\n      execution time (avg/stddev):* (glob)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest1' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest2' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest3' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest4' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest5' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest6' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest7' doesn't exist\n  ERROR 1146 (42S02) at line 1: Table 'sbtest.sbtest8' doesn't exist\n"
  },
  {
    "path": "tests/t/script_select_random_pgsql.t",
    "content": "########################################################################\nselect_random_*.lua + PostgreSQL tests \n########################################################################\n\n  $ . $SBTEST_INCDIR/pgsql_common.sh\n  $ . $SBTEST_INCDIR/script_select_random_common.sh\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            100\n          write:                           0\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):* (glob)\n      execution time (avg/stddev):* (glob)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  sysbench * (glob)\n  \n  Creating table 'sbtest1'...\n  Inserting 10000 records into 'sbtest1'\n  Creating a secondary index on 'sbtest1'...\n                              Table \"public.sbtest1\"\n   Column |      Type      |                      Modifiers                       | Storage  | Stats target | Description \n  --------+----------------+------------------------------------------------------+----------+--------------+-------------\n   id     | integer        | not null default nextval('sbtest1_id_seq'::regclass) | plain    |              | \n   k      | integer        | not null default 0                                   | plain    |              | \n   c      | character(120) | not null default ''::bpchar                          | extended |              | \n   pad    | character(60)  | not null default ''::bpchar                          | extended |              | \n  \n  Indexes:\n   CREATE INDEX k_1 ON sbtest1 USING btree (k)\n   CREATE UNIQUE INDEX sbtest1_pkey ON sbtest1 USING btree (id)\n  \n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  SQL statistics:\n      queries performed:\n          read:                            100\n          write:                           0\n          other:                           0\n          total:                           100\n      transactions:                        100    (* per sec.) (glob)\n      queries:                             100    (* per sec.) (glob)\n      ignored errors:                      0      (0.00 per sec.)\n      reconnects:                          0      (0.00 per sec.)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):* (glob)\n      execution time (avg/stddev):* (glob)\n  \n  sysbench * (glob)\n  \n  Dropping table 'sbtest1'...\n  Did not find any relation named \"sbtest1\".\n  Did not find any relation named \"sbtest2\".\n  Did not find any relation named \"sbtest3\".\n  Did not find any relation named \"sbtest4\".\n  Did not find any relation named \"sbtest5\".\n  Did not find any relation named \"sbtest6\".\n  Did not find any relation named \"sbtest7\".\n  Did not find any relation named \"sbtest8\".\n"
  },
  {
    "path": "tests/t/test_cpu.t",
    "content": "########################################################################\ncpu benchmark tests\n########################################################################\n  $ args=\"cpu --cpu-max-prime=1000 --events=100 --threads=2\"\n  $ sysbench $args help\n  sysbench *.* * (glob)\n  \n  cpu options:\n    --cpu-max-prime=N upper limit for primes generator [10000]\n  \n  $ sysbench $args prepare\n  sysbench *.* * (glob)\n  \n  'cpu' test does not implement the 'prepare' command.\n  [1]\n  $ sysbench $args run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Prime numbers limit: 1000\n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  CPU speed:\n      events per second: *.* (glob)\n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           50.0000/* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  $ sysbench $args cleanup\n  sysbench *.* * (glob)\n  \n  'cpu' test does not implement the 'cleanup' command.\n  [1]\n"
  },
  {
    "path": "tests/t/test_fileio.t",
    "content": "########################################################################\nfileio benchmark tests\n########################################################################\n\n  $ fileio_args=\"fileio --file-num=4 --file-total-size=32M\"\n\n  $ sysbench $fileio_args prepare\n  sysbench *.* * (glob)\n  \n  4 files, 8192Kb each, 32Mb total\n  Creating files for the test...\n  Extra file open flags: (none)\n  Creating file test_file.0\n  Creating file test_file.1\n  Creating file test_file.2\n  Creating file test_file.3\n  33554432 bytes written in * seconds (*.* MiB/sec). (glob)\n\n  $ ls test_file.*\n  test_file.0\n  test_file.1\n  test_file.2\n  test_file.3\n  $ for i in $(seq 0 3)\n  > do\n  >   echo -n \"test_file.$i: \"\n  >   echo $(wc -c < test_file.$i)\n  > done\n  test_file.0: 8388608\n  test_file.1: 8388608\n  test_file.2: 8388608\n  test_file.3: 8388608\n\n  $ sysbench $fileio_args run | grep FATAL\n  FATAL: Missing required argument: --file-test-mode\n\n  $ sysbench $fileio_args --events=150 --file-test-mode=rndrw run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Extra file open flags: (none)\n  4 files, 8MiB each\n  32MiB total file size\n  Block size 16KiB\n  Number of IO requests: 150\n  Read/Write ratio for combined random IO test: 1.50\n  Periodic FSYNC enabled, calling fsync() each 100 requests.\n  Calling fsync() at the end of test, Enabled.\n  Using synchronous I/O mode\n  Doing random r/w test\n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n           read:  IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           write: IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           fsync: IOPS=*.* (glob)\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  $ sysbench $fileio_args --events=150 --file-test-mode=rndrd run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Extra file open flags: (none)\n  4 files, 8MiB each\n  32MiB total file size\n  Block size 16KiB\n  Number of IO requests: 150\n  Read/Write ratio for combined random IO test: 1.50\n  Periodic FSYNC enabled, calling fsync() each 100 requests.\n  Calling fsync() at the end of test, Enabled.\n  Using synchronous I/O mode\n  Doing random read test\n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n           read:  IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           write: IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           fsync: IOPS=*.* (glob)\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n\n  $ sysbench $fileio_args --events=150 --file-test-mode=seqrd run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Extra file open flags: (none)\n  4 files, 8MiB each\n  32MiB total file size\n  Block size 16KiB\n  Periodic FSYNC enabled, calling fsync() each 100 requests.\n  Calling fsync() at the end of test, Enabled.\n  Using synchronous I/O mode\n  Doing sequential read test\n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n           read:  IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           write: IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           fsync: IOPS=*.* (glob)\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n\n  $ sysbench $fileio_args --events=150 --file-test-mode=rndwr run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Extra file open flags: (none)\n  4 files, 8MiB each\n  32MiB total file size\n  Block size 16KiB\n  Number of IO requests: 150\n  Read/Write ratio for combined random IO test: 1.50\n  Periodic FSYNC enabled, calling fsync() each 100 requests.\n  Calling fsync() at the end of test, Enabled.\n  Using synchronous I/O mode\n  Doing random write test\n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n           read:  IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           write: IOPS=*.* *.* MiB/s (*.* MB/s) (glob)\n           fsync: IOPS=*.* (glob)\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n\n  $ sysbench $fileio_args --events=150 --file-test-mode=rndwr --validate run | grep Validation\n  Validation checks: on.\n\n  $ sysbench $fileio_args --events=150 --file-test-mode=foo run\n  sysbench *.* * (glob)\n  \n  FATAL: Invalid IO operations mode: foo.\n  [1]\n  $ sysbench $fileio_args cleanup\n  sysbench *.* * (glob)\n  \n  Removing test files...\n  $ ls\n\n  $ sysbench $fileio_args --file-test-mode=rndrw --verbosity=2 run\n  FATAL: Cannot open file 'test_file.0' errno = 2 (No such file or directory)\n  WARNING: Did you forget to run the prepare step?\n  [1]\n\n########################################################################\nGH-196:  fileio: validate file sizes on startup\n########################################################################\n  $ args=\"$fileio_args --verbosity=2\"\n  $ sysbench $args --file-total-size=1M prepare\n  $ sysbench $args --file-test-mode=rndwr --events=1 run\n  FATAL: Size of file 'test_file.0' is 256KiB, but at least 8MiB is expected.\n  WARNING: Did you run 'prepare' with different --file-total-size or --file-num values?\n  [1]\n  $ sysbench $args cleanup\n  $ sysbench $args --file-num=8 prepare\n  $ sysbench $args --file-test-mode=rndwr --events=1 run\n  FATAL: Size of file 'test_file.0' is 4MiB, but at least 8MiB is expected.\n  WARNING: Did you run 'prepare' with different --file-total-size or --file-num values?\n  [1]\n  $ sysbench $args --file-num=8 cleanup\n  $ sysbench $args --file-total-size=1M prepare\n  $ sysbench $args --file-test-mode=seqwr --events=1 run\n  $ sysbench $args cleanup\n  $ unset args\n\n########################################################################\nGH-198: Tolerate misaligned test_files.\n########################################################################\n  $ args=\"$fileio_args --verbosity=2 --file-total-size=1M --file-num=128 --file-block-size=4097 --events=2\"\n  $ sysbench $args --file-total-size=1M prepare\n  $ sysbench $args --file-test-mode=seqrd run\n  $ sysbench $args --file-test-mode=rndrd run\n  $ sysbench $args cleanup\n  $ unset args\n\n########################################################################\nExtra file flags. Not testing 'direct' as that is not supported on all\ntested platforms\n########################################################################\n  $ args=\"$fileio_args --file-total-size=16K --file-num=1\"\n  $ sysbench $args --file-extra-flags= prepare\n  sysbench * (glob)\n  \n  1 files, 16Kb each, 0Mb total\n  Creating files for the test...\n  Extra file open flags: (none)\n  Creating file test_file.0\n  16384 bytes written in * seconds (* MiB/sec). (glob)\n\n  $ sysbench $args --file-extra-flags=sync prepare\n  sysbench * (glob)\n  \n  1 files, 16Kb each, 0Mb total\n  Creating files for the test...\n  Extra file open flags: sync \n  Reusing existing file test_file.0\n  No bytes written.\n\n  $ sysbench $args --file-extra-flags=dsync prepare\n  sysbench * (glob)\n  \n  1 files, 16Kb each, 0Mb total\n  Creating files for the test...\n  Extra file open flags: dsync \n  Reusing existing file test_file.0\n  No bytes written.\n\n  $ sysbench $args --file-extra-flags=dsync,sync prepare\n  sysbench * (glob)\n  \n  1 files, 16Kb each, 0Mb total\n  Creating files for the test...\n  Extra file open flags: sync dsync \n  Reusing existing file test_file.0\n  No bytes written.\n\n  $ sysbench $args --file-extra-flags= cleanup\n  sysbench * (glob)\n  \n  Removing test files...\n\n########################################################################\nGH-229: \"--file-fsync-freq=0\" seems to prevent fsync() at end of test\n########################################################################\n  $ args=\"fileio --file-total-size=160K --file-num=10 --file-test-mode=seqwr\"\n  $ args=\"$args --file-fsync-freq=0 --file-fsync-end=1\"\n  $ args=\"$args --events=0 --time=1\"\n  $ sysbench $args prepare\n  sysbench * (glob)\n  \n  10 files, 16Kb each, 0Mb total\n  Creating files for the test...\n  Extra file open flags: (none)\n  Creating file test_file.0\n  Creating file test_file.1\n  Creating file test_file.2\n  Creating file test_file.3\n  Creating file test_file.4\n  Creating file test_file.5\n  Creating file test_file.6\n  Creating file test_file.7\n  Creating file test_file.8\n  Creating file test_file.9\n  163840 bytes written in * seconds (* MiB/sec). (glob)\n  $ sysbench $args run\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Extra file open flags: (none)\n  10 files, 16KiB each\n  160KiB total file size\n  Block size 16KiB\n  Calling fsync() at the end of test, Enabled.\n  Using synchronous I/O mode\n  Doing sequential write (creation) test\n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n           read:  IOPS=0.00 0.00 MiB/s (0.00 MB/s)\n           write: IOPS=[^0].* [^0].* MiB/s \\([^0].* MB/s\\) (re)\n           fsync: IOPS=[^0].* (re)\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  $ sysbench $args --file-fsync-end=off run\n  sysbench * (glob)\n  \n  Running the test with following options:\n  Number of threads: 1\n  Initializing random number generator from current time\n  \n  \n  Extra file open flags: (none)\n  10 files, 16KiB each\n  160KiB total file size\n  Block size 16KiB\n  Using synchronous I/O mode\n  Doing sequential write (creation) test\n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n           read:  IOPS=0.00 0.00 MiB/s (0.00 MB/s)\n           write: IOPS=[^0].* [^0].* MiB/s \\([^0].* MB/s\\) (re)\n           fsync: IOPS=0.00\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n"
  },
  {
    "path": "tests/t/test_memory.t",
    "content": "########################################################################\nmemory benchmark tests\n########################################################################\n\n  $ args=\"memory --memory-block-size=4K --memory-total-size=1G --events=1 --time=0 --threads=2\"\n\nThe --memory-hugetlb option is supported and printed by 'sysbench\nhelp' only on Linux.\n\n  $ if [ \"$(uname -s)\" = \"Linux\" ]\n  > then\n  >   sysbench $args help | grep hugetlb\n  > else\n  >   echo \"  --memory-hugetlb[=on|off]   allocate memory from HugeTLB pool [off]\"\n  > fi\n    --memory-hugetlb[=on|off]   allocate memory from HugeTLB pool [off]\n\n  $ sysbench $args help | grep -v hugetlb\n  sysbench * (glob)\n  \n  memory options:\n    --memory-block-size=SIZE    size of memory block for test [1K]\n    --memory-total-size=SIZE    total size of data to transfer [100G]\n    --memory-scope=STRING       memory access scope {global,local} [global]\n    --memory-oper=STRING        type of memory operations {read, write, none} [write]\n    --memory-access-mode=STRING memory access mode {seq,rnd} [seq]\n  \n  $ sysbench $args prepare\n  sysbench *.* * (glob)\n  \n  'memory' test does not implement the 'prepare' command.\n  [1]\n\n  $ sysbench $args --memory-block-size=-1 run\n  sysbench * (glob)\n  \n  FATAL: Invalid value for memory-block-size: -1\n  [1]\n\n  $ sysbench $args --memory-block-size=0 run\n  sysbench * (glob)\n  \n  FATAL: Invalid value for memory-block-size: 0\n  [1]\n\n  $ sysbench $args --memory-block-size=3 run\n  sysbench * (glob)\n  \n  FATAL: Invalid value for memory-block-size: 3\n  [1]\n\n  $ sysbench $args --memory-block-size=9 run\n  sysbench * (glob)\n  \n  FATAL: Invalid value for memory-block-size: 9\n  [1]\n\n########################################################################\n# Global reads\n########################################################################\n\n  $ sysbench $args --memory-oper=read run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Running memory speed test with the following options:\n    block size: 4KiB\n    total size: 1024MiB\n    operation: read\n    scope: global\n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Total operations: 262144 (* per second) (glob)\n  \n  1024.00 MiB transferred (* MiB/sec) (glob)\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              262144\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n########################################################################\n# Global writes\n########################################################################\n\n  $ sysbench $args --memory-oper=write run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Running memory speed test with the following options:\n    block size: 4KiB\n    total size: 1024MiB\n    operation: write\n    scope: global\n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Total operations: 262144 (* per second) (glob)\n  \n  1024.00 MiB transferred (* MiB/sec) (glob)\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              262144\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n########################################################################\n# Local reads\n########################################################################\n\n  $ sysbench $args --memory-scope=local --memory-oper=read run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Running memory speed test with the following options:\n    block size: 4KiB\n    total size: 1024MiB\n    operation: read\n    scope: local\n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Total operations: 262144 (* per second) (glob)\n  \n  1024.00 MiB transferred (* MiB/sec) (glob)\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              262144\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n########################################################################\n# Local writes\n########################################################################\n\n  $ sysbench $args --memory-scope=local --memory-oper=write run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Running memory speed test with the following options:\n    block size: 4KiB\n    total size: 1024MiB\n    operation: write\n    scope: local\n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  Total operations: 262144 (* per second) (glob)\n  \n  1024.00 MiB transferred (* MiB/sec) (glob)\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              262144\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  $ sysbench $args cleanup\n  sysbench *.* * (glob)\n  \n  'memory' test does not implement the 'cleanup' command.\n  [1]\n"
  },
  {
    "path": "tests/t/test_mutex.t",
    "content": "########################################################################\nmutex benchmark tests\n########################################################################\n  $ args=\"mutex --events=10 --threads=2\"\n  $ sysbench $args help\n  sysbench *.* * (glob)\n  \n  mutex options:\n    --mutex-num=N   total size of mutex array [4096]\n    --mutex-locks=N number of mutex locks to do per thread [50000]\n    --mutex-loops=N number of empty loops to do outside mutex lock [10000]\n  \n  $ sysbench $args prepare\n  sysbench *.* * (glob)\n  \n  'mutex' test does not implement the 'prepare' command.\n  [1]\n  $ sysbench $args run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              2\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  $ sysbench $args cleanup\n  sysbench *.* * (glob)\n  \n  'mutex' test does not implement the 'cleanup' command.\n  [1]\n"
  },
  {
    "path": "tests/t/test_threads.t",
    "content": "########################################################################\nthreads benchmark tests\n########################################################################\n\n  $ args=\"threads --events=100 --threads=2\"\n  $ sysbench $args help\n  sysbench *.* * (glob)\n  \n  threads options:\n    --thread-yields=N number of yields to do per request [1000]\n    --thread-locks=N  number of locks per thread [8]\n  \n  $ sysbench $args prepare\n  sysbench *.* * (glob)\n  \n  'threads' test does not implement the 'prepare' command.\n  [1]\n  $ sysbench $args run\n  sysbench *.* * (glob)\n  \n  Running the test with following options:\n  Number of threads: 2\n  Initializing random number generator from current time\n  \n  \n  Initializing worker threads...\n  \n  Threads started!\n  \n  \n  Throughput:\n      events/s (eps): *.* (glob)\n      time elapsed:                        *s (glob)\n      total number of events:              100\n  \n  Latency (ms):\n           min:                              *.* (glob)\n           avg:                              *.* (glob)\n           max:                              *.* (glob)\n           95th percentile:         *.* (glob)\n           sum: *.* (glob)\n  \n  Threads fairness:\n      events (avg/stddev):           */* (glob)\n      execution time (avg/stddev):   */* (glob)\n  \n  $ sysbench $args cleanup\n  sysbench *.* * (glob)\n  \n  'threads' test does not implement the 'cleanup' command.\n  [1]\n"
  },
  {
    "path": "tests/t/tests.t",
    "content": "########################################################################\nMake sure all built-in tests are covered\n########################################################################\n\n  $ tests=$(sysbench --help | sed -n '/Compiled-in tests:/,/^$/p' | tail -n +2 | cut -d ' ' -f 3)\n  $ for t in $tests\n  > do\n  >   if [ ! -r ${SBTEST_SUITEDIR}/test_${t}.t ]\n  >   then\n  >     echo \"Cannot find regression test(s) for 'sysbench $t'!\"\n  >     exit 1\n  >   fi\n  > done\n"
  },
  {
    "path": "tests/test_run.sh",
    "content": "#!/usr/bin/env bash\n\n# Copyright (C) 2016-2017 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nset -eu\n\ntestroot=$(cd $(dirname \"$0\"); echo $PWD)\n\n# Find the sysbench binary to use\ndirlist=( \"$testroot/../src\"       # source directory\n          \"$testroot/../bin\"       # standalone install root directory\n          \"$testroot/../../../bin\" # system-wide install (e.g. /usr/local/share/sysbench/tests)\n          \"$PWD/../src\" )          # build directory by 'make distcheck'\n\nfor dir in ${dirlist[@]}\ndo\n    if [ -x \"$dir/sysbench\" ]\n    then\n        sysbench_dir=\"$dir\"\n        break\n    fi\ndone\n\nif [ -z ${sysbench_dir+x} ]\nthen\n    echo \"Cannot find sysbench in the following list of directories: \\\n${dirlist[@]}\"\n    exit 1\nfi\n\nif [ -z ${srcdir+x} ]\nthen\n    SBTEST_INCDIR=\"$PWD/include\"\n    SBTEST_CONFIG=\"$SBTEST_INCDIR/config.sh\"\n    if [ $# -lt 1 ]\n    then\n        tests=\"t/*.t\"\n    fi\nelse\n    # SBTEST_INCDIR must be an absolute path, because cram changes CWD to a\n    # temporary directory when executing tests. That's why we can just use\n    # $srcdir here\n    SBTEST_INCDIR=\"$(cd $srcdir; echo $PWD)/include\"\n    SBTEST_CONFIG=\"$PWD/include/config.sh\"\n    if [ $# -lt 1 ]\n    then\n        tests=\"$srcdir/t/*.t\"\n    fi\nfi\nif [ -z ${tests+x} ]\nthen\n   tests=\"$*\"\nfi\n\nexport SBTEST_ROOTDIR=\"$testroot\"\nexport SBTEST_SCRIPTDIR=\"$testroot/../src/lua\"\nexport SBTEST_SUITEDIR=\"$testroot/t\"\nexport SBTEST_CONFIG\nexport SBTEST_INCDIR\n\n# Add directories containing sysbench and cram to PATH\nexport PATH=\"${sysbench_dir}:${SBTEST_ROOTDIR}/../third_party/cram/scripts:$PATH\"\n\nexport PYTHONPATH=\"${SBTEST_ROOTDIR}/../third_party/cram:${PYTHONPATH:-}\"\n\nLUA_PATH=\"$SBTEST_SCRIPTDIR/?;$SBTEST_SCRIPTDIR/?.lua\"\nLUA_PATH=\"$LUA_PATH;$SBTEST_INCDIR/?;$SBTEST_INCDIR/?.lua\"\nexport LUA_PATH\n\n. $SBTEST_CONFIG\n\nif $(command -v python >/dev/null 2>&1)\nthen\n    PYTHON=python\nelif $(command -v python3 >/dev/null 2>&1)\nthen\n    PYTHON=python3\nelif $(command -v python2 >/dev/null 2>&1)\nthen\n    PYTHON=python2\nelse\n    echo \"Cannot find python interpreter in PATH\"\n    exit 1\nfi\n\n$PYTHON $(command -v cram) --shell=/bin/bash --verbose $tests\n"
  },
  {
    "path": "third_party/concurrency_kit/Makefile.am",
    "content": "# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nEXTRA_DIST = ck\n\nall-local: $(builddir)/lib/libck.a\n\n# Concurrency Kit does not support VPATH builds\n$(builddir)/lib/libck.a:\n\trm -rf tmp\n\tmkdir tmp\n\ttar -C $(srcdir) -cf - ck | tar -xf - -C tmp/\n\tchmod -R u+w tmp\n\tcd tmp/ck &&                        \\\n\tCC=\"$(CC)\"                          \\\n\tCFLAGS=\"$(CFLAGS) $(CPPFLAGS)\"      \\\n\tLDFLAGS=\"$(LDFLAGS)\"                \\\n\t  ./configure ${CK_CONFIGURE_FLAGS} \\\n\t  --prefix=$(abs_top_builddir)/third_party/concurrency_kit && \\\n\t$(MAKE) && \\\n\t$(MAKE) install\n\nclean-local:\n\trm -rf tmp include lib share\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/.gitignore",
    "content": "/Makefile\nbuild/ck.build\nbuild/ck.pc\nbuild/regressions.build\nbuild/ck.spec\ninclude/ck_md.h\nsrc/Makefile\ndoc/Makefile\ndoc/*.3\nbuild/Makefile\n.DS_Store\nLOG\n*.log\n*.html\n*.gz\n*.o\n*.a\n*.so\n*.dSYM\n.*.sw[op]\nGPATH\nGRTAGS\nGTAGS\nID\nregressions/ck_array/validate/serial\nregressions/ck_backoff/validate/validate\nregressions/ck_bag/validate/order\nregressions/ck_barrier/benchmark/throughput\nregressions/ck_barrier/validate/barrier_centralized\nregressions/ck_barrier/validate/barrier_combining\nregressions/ck_barrier/validate/barrier_dissemination\nregressions/ck_barrier/validate/barrier_mcs\nregressions/ck_barrier/validate/barrier_tournament\nregressions/ck_bitmap/validate/serial\nregressions/ck_brlock/benchmark/latency\nregressions/ck_brlock/benchmark/throughput\nregressions/ck_brlock/validate/validate\nregressions/ck_bytelock/benchmark/latency\nregressions/ck_bytelock/validate/validate\nregressions/ck_cohort/benchmark/ck_cohort.LATENCY\nregressions/ck_cohort/benchmark/ck_cohort.THROUGHPUT\nregressions/ck_cohort/validate/validate\nregressions/ck_epoch/validate/ck_epoch_call\nregressions/ck_epoch/validate/ck_epoch_poll\nregressions/ck_epoch/validate/ck_epoch_section\nregressions/ck_epoch/validate/ck_epoch_section_2\nregressions/ck_epoch/validate/torture\nregressions/ck_epoch/validate/ck_epoch_synchronize\nregressions/ck_epoch/validate/ck_stack\nregressions/ck_epoch/validate/ck_stack_read\nregressions/ck_fifo/benchmark/latency\nregressions/ck_fifo/validate/ck_fifo_mpmc\nregressions/ck_fifo/validate/ck_fifo_mpmc_iterator\nregressions/ck_fifo/validate/ck_fifo_spsc\nregressions/ck_fifo/validate/ck_fifo_spsc_iterator\nregressions/ck_hp/benchmark/fifo_latency\nregressions/ck_hp/benchmark/stack_latency\nregressions/ck_hp/validate/ck_hp_fifo\nregressions/ck_hp/validate/ck_hp_fifo_donner\nregressions/ck_hp/validate/ck_hp_stack\nregressions/ck_hp/validate/nbds_haz_test\nregressions/ck_hp/validate/serial\nregressions/ck_hs/benchmark/apply\nregressions/ck_hs/benchmark/parallel_bytestring\nregressions/ck_hs/benchmark/parallel_bytestring.delete\nregressions/ck_hs/benchmark/serial\nregressions/ck_hs/validate/serial\nregressions/ck_ht/benchmark/parallel_bytestring\nregressions/ck_ht/benchmark/parallel_bytestring.delete\nregressions/ck_ht/benchmark/parallel_direct\nregressions/ck_ht/benchmark/serial\nregressions/ck_ht/benchmark/serial.delete\nregressions/ck_ht/validate/serial\nregressions/ck_ht/validate/serial.delete\nregressions/ck_pflock/benchmark/latency\nregressions/ck_pflock/benchmark/throughput\nregressions/ck_pflock/validate/validate\nregressions/ck_pr/benchmark/ck_pr_cas_64\nregressions/ck_pr/benchmark/ck_pr_cas_64_2\nregressions/ck_pr/benchmark/ck_pr_fas_64\nregressions/ck_pr/benchmark/fp\nregressions/ck_pr/validate/ck_pr_add\nregressions/ck_pr/validate/ck_pr_and\nregressions/ck_pr/validate/ck_pr_bin\nregressions/ck_pr/validate/ck_pr_btc\nregressions/ck_pr/validate/ck_pr_btr\nregressions/ck_pr/validate/ck_pr_bts\nregressions/ck_pr/validate/ck_pr_btx\nregressions/ck_pr/validate/ck_pr_cas\nregressions/ck_pr/validate/ck_pr_dec\nregressions/ck_pr/validate/ck_pr_faa\nregressions/ck_pr/validate/ck_pr_fas\nregressions/ck_pr/validate/ck_pr_fax\nregressions/ck_pr/validate/ck_pr_inc\nregressions/ck_pr/validate/ck_pr_load\nregressions/ck_pr/validate/ck_pr_n\nregressions/ck_pr/validate/ck_pr_or\nregressions/ck_pr/validate/ck_pr_store\nregressions/ck_pr/validate/ck_pr_sub\nregressions/ck_pr/validate/ck_pr_unary\nregressions/ck_pr/validate/ck_pr_xor\nregressions/ck_queue/validate/ck_list\nregressions/ck_queue/validate/ck_slist\nregressions/ck_queue/validate/ck_stailq\nregressions/ck_rhs/benchmark/parallel_bytestring\nregressions/ck_rhs/benchmark/serial\nregressions/ck_rhs/validate/serial\nregressions/ck_ring/benchmark/latency\nregressions/ck_ring/validate/ck_ring_spmc\nregressions/ck_ring/validate/ck_ring_spmc_template\nregressions/ck_ring/validate/ck_ring_spsc\nregressions/ck_ring/validate/ck_ring_spsc_template\nregressions/ck_ring/validate/ck_ring_mpmc\nregressions/ck_ring/validate/ck_ring_mpmc_template\nregressions/ck_rwcohort/benchmark/ck_neutral.LATENCY\nregressions/ck_rwcohort/benchmark/ck_neutral.THROUGHPUT\nregressions/ck_rwcohort/benchmark/ck_rp.LATENCY\nregressions/ck_rwcohort/benchmark/ck_rp.THROUGHPUT\nregressions/ck_rwcohort/benchmark/ck_wp.LATENCY\nregressions/ck_rwcohort/benchmark/ck_wp.THROUGHPUT\nregressions/ck_rwcohort/validate/ck_neutral\nregressions/ck_rwcohort/validate/ck_rp\nregressions/ck_rwcohort/validate/ck_wp\nregressions/ck_rwlock/benchmark/latency\nregressions/ck_rwlock/benchmark/throughput\nregressions/ck_rwlock/validate/validate\nregressions/ck_sequence/benchmark/ck_sequence\nregressions/ck_sequence/validate/ck_sequence\nregressions/ck_spinlock/benchmark/ck_anderson.LATENCY\nregressions/ck_spinlock/benchmark/ck_anderson.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_cas.LATENCY\nregressions/ck_spinlock/benchmark/ck_cas.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_clh.LATENCY\nregressions/ck_spinlock/benchmark/ck_clh.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_dec.LATENCY\nregressions/ck_spinlock/benchmark/ck_dec.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_fas.LATENCY\nregressions/ck_spinlock/benchmark/ck_fas.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_hclh.LATENCY\nregressions/ck_spinlock/benchmark/ck_hclh.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_mcs.LATENCY\nregressions/ck_spinlock/benchmark/ck_mcs.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_spinlock.LATENCY\nregressions/ck_spinlock/benchmark/ck_spinlock.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_ticket.LATENCY\nregressions/ck_spinlock/benchmark/ck_ticket.THROUGHPUT\nregressions/ck_spinlock/benchmark/ck_ticket_pb.LATENCY\nregressions/ck_spinlock/benchmark/ck_ticket_pb.THROUGHPUT\nregressions/ck_spinlock/benchmark/linux_spinlock.LATENCY\nregressions/ck_spinlock/benchmark/linux_spinlock.THROUGHPUT\nregressions/ck_spinlock/validate/ck_anderson\nregressions/ck_spinlock/validate/ck_cas\nregressions/ck_spinlock/validate/ck_clh\nregressions/ck_spinlock/validate/ck_dec\nregressions/ck_spinlock/validate/ck_fas\nregressions/ck_spinlock/validate/ck_hclh\nregressions/ck_spinlock/validate/ck_mcs\nregressions/ck_spinlock/validate/ck_spinlock\nregressions/ck_spinlock/validate/ck_ticket\nregressions/ck_spinlock/validate/ck_ticket_pb\nregressions/ck_spinlock/validate/linux_spinlock\nregressions/ck_stack/benchmark/latency\nregressions/ck_stack/validate/mpmc_pair\nregressions/ck_stack/validate/mpmc_pop\nregressions/ck_stack/validate/mpmc_push\nregressions/ck_stack/validate/mpmc_trypair\nregressions/ck_stack/validate/mpmc_trypop\nregressions/ck_stack/validate/mpmc_trypush\nregressions/ck_stack/validate/mpnc_push\nregressions/ck_stack/validate/pthreads_pair\nregressions/ck_stack/validate/serial\nregressions/ck_stack/validate/spinlock_eb_pair\nregressions/ck_stack/validate/spinlock_eb_pop\nregressions/ck_stack/validate/spinlock_eb_push\nregressions/ck_stack/validate/spinlock_pair\nregressions/ck_stack/validate/spinlock_pop\nregressions/ck_stack/validate/spinlock_push\nregressions/ck_stack/validate/upmc_pop\nregressions/ck_stack/validate/upmc_push\nregressions/ck_stack/validate/upmc_trypop\nregressions/ck_stack/validate/upmc_trypush\nregressions/ck_swlock/benchmark/latency\nregressions/ck_swlock/benchmark/throughput\nregressions/ck_swlock/validate/validate\nregressions/ck_tflock/benchmark/latency\nregressions/ck_tflock/benchmark/throughput\nregressions/ck_tflock/validate/validate\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/LICENSE",
    "content": "Copyright 2010-2014 Samy Al Bahra.\nCopyright 2011-2013 AppNexus, Inc.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions\nare met:\n1. Redistributions of source code must retain the above copyright\n   notice, this list of conditions and the following disclaimer.\n2. Redistributions in binary form must reproduce the above copyright\n   notice, this list of conditions and the following disclaimer in the\n   documentation and/or other materials provided with the distribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\nARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\nFOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\nDAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\nOR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\nHOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\nOUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\nSUCH DAMAGE.\n\nHazard Pointers (src/ck_hp.c) also includes this license:\n\n(c) Copyright 2008, IBM Corporation.\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\nhttp://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nck_pr_rtm leverages work from Andi Kleen:\nCopyright (c) 2012,2013 Intel Corporation\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that: (1) source code distributions\nretain the above copyright notice and this paragraph in its entirety, (2)\ndistributions including binary code include the above copyright notice and\nthis paragraph in its entirety in the documentation or other materials\nprovided with the distribution\n\nTHIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\nWARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/README",
    "content": "  ____                                                        _  ___ _\n / ___|___  _ __   ___ _   _ _ __ _ __ ___ _ __   ___ _   _  | |/ (_) |_\n| |   / _ \\| '_ \\ / __| | | | '__| '__/ _ \\ '_ \\ / __| | | | | ' /| | __|\n| |__| (_) | | | | (__| |_| | |  | | |  __/ | | | (__| |_| | | . \\| | |_\n \\____\\___/|_| |_|\\___|\\__,_|_|  |_|  \\___|_| |_|\\___|\\__, | |_|\\_\\_|\\__|\n                                                      |___/\n\nStep 1.\n\t./configure\n\tFor additional options try ./configure --help\n\nStep 2.\n\tIn order to compile regressions (requires POSIX threads) use\n        \"make regressions\". In order to compile libck use \"make all\" or \"make\".\n\nStep 3.\n\tIn order to install use \"make install\"\n\tTo uninstall use \"make uninstall\".\n\nSee http://concurrencykit.org/ for more information.\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.aarch64",
    "content": "\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.arm",
    "content": "CFLAGS+=-D__arm__\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.in",
    "content": "CC=@CC@\nMAKE=make\nSRC_DIR=@SRC_DIR@\nBUILD_DIR=@BUILD_DIR@\nCFLAGS+=@CFLAGS@ -I$(SRC_DIR)/include -I$(BUILD_DIR)/include\nLDFLAGS+=@LDFLAGS@\nALL_LIBS=@ALL_LIBS@\nLD=@LD@\n\ninclude $(BUILD_DIR)/build/ck.build.@PROFILE@\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.ppc",
    "content": "CFLAGS+=-m32 -D__ppc__\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.ppc64",
    "content": "CFLAGS+=-m64 -D__ppc64__\nLDFLAGS+=-m64\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.s390x",
    "content": "CFLAGS+=-O2 -D__s390x__\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.sparcv9",
    "content": "CFLAGS+=-m64 -D__sparcv9__\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.x86",
    "content": "CFLAGS+=-m32 -D__x86__ -msse -msse2\nLDFLAGS+=-m32\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.build.x86_64",
    "content": "CFLAGS+=-m64 -D__x86_64__\nLDFLAGS+=-m64\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.pc.in",
    "content": "prefix=@PREFIX@\nincludedir=@HEADERS@\nlibdir=@LIBRARY@\n\nName: Concurrency Kit\nDescription: Toolkit for well-specified design and implementation of concurrent systems\nURL: http://concurrencykit.org/\nVersion: @VERSION@\nLibs: -L${libdir} -lck\nCflags: -D__@PROFILE@__ -I${includedir} @PC_CFLAGS@\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/ck.spec.in",
    "content": "Name: ck\nVersion: @VERSION@\nRelease: 1%{?dist}\nGroup: Development/Libraries\nSummary: Concurrency Kit\nLicense: Simplified BSD License\nURL: http://concurrencykit.org\nBuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)\n\nSource: http://concurrencykit.org/releases/ck-%{version}.tar.gz\n\n%description\nConcurrency Kit provides a plethora of concurrency primitives, safe memory\nreclamation mechanisms and lock-less and lock-free data structures designed to\naid in the design and implementation of high performance concurrent systems. It\nis designed to minimize dependencies on operating system-specific interfaces\nand most of the interface relies only on a strict subset of the standard\nlibrary and more popular compiler extensions.\n\n%package devel\nGroup: Development/Libraries\nSummary: Header files and libraries for CK development\nRequires: %{name} = %{version}-%{release}\n\n%description devel\nConcurrency Kit provides a plethora of concurrency primitives, safe memory\nreclamation mechanisms and lock-less and lock-free data structures designed to\naid in the design and implementation of high performance concurrent systems. It\nis designed to minimize dependencies on operating system-specific interfaces\nand most of the interface relies only on a strict subset of the standard\nlibrary and more popular compiler extensions.\n\nThis package provides the libraries, include files, and other\nresources needed for developing Concurrency Kit applications.\n\n%prep\n%setup -q\n\n%build\nCFLAGS=$RPM_OPT_FLAGS ./configure \t\t\\\n\t--libdir=%{_libdir} \t\t\t\\\n\t--includedir=%{_includedir}/%{name}\t\\\n\t--mandir=%{_mandir}\t\t\t\\\n\t--prefix=%{_prefix}\nmake %{?_smp_mflags}\n\n%install\nrm -rf $RPM_BUILD_ROOT\nmake DESTDIR=$RPM_BUILD_ROOT install\n\n%clean\nrm -rf $RPM_BUILD_ROOT\n\n%files\n%defattr(-,root,root,-)\n%{_libdir}/libck.so.@VERSION@\n%{_libdir}/libck.so.@VERSION_MAJOR@\n\n%files devel\n%defattr(-,root,root)\n%{_libdir}/libck.so\n%{_includedir}/%{name}/*.h\n%{_includedir}/%{name}/*/*.h\n%{_includedir}/%{name}/*/*/*.h\n%{_libdir}/libck.a\n%{_libdir}/pkgconfig/%{name}.pc\n%{_mandir}/man3/*.3.gz\n\n%post\n/sbin/ldconfig\n\n%postun\n/sbin/ldconfig\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/build/regressions.build.in",
    "content": "CC=@CC@\nMAKE=make\nCORES=@CORES@\nCFLAGS=@CFLAGS@ -I../../../include -DCORES=@CORES@\nLD=@LD@\nLDFLAGS=@LDFLAGS@\nPTHREAD_CFLAGS=@PTHREAD_CFLAGS@\nBUILD_DIR=@BUILD_DIR@\n\ninclude $(BUILD_DIR)/build/ck.build.@PROFILE@\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/configure",
    "content": "#!/bin/sh\n#\n# Copyright © 2009-2013 Samy Al Bahra.\n# Copyright © 2011 Devon H. O'Dell <devon.odell@gmail.com>\n# All rights reserved.\n#\n# Redistribution and use in source and binary forms, with or without\n# modification, are permitted provided that the following conditions\n# are met:\n# 1. Redistributions of source code must retain the above copyright\n#    notice, this list of conditions and the following disclaimer.\n# 2. Redistributions in binary form must reproduce the above copyright\n#    notice, this list of conditions and the following disclaimer in the\n#    documentation and/or other materials provided with the distribution.\n#\n# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n# SUCH DAMAGE.\n#\n\nREQUIRE_HEADER=\"stdbool.h stddef.h stdint.h string.h\"\n\nEXIT_SUCCESS=0\nEXIT_FAILURE=1\nWANT_PIC=yes\n\nP_PWD=`pwd`\nMAINTAINER='sbahra@repnop.org'\nVERSION=${VERSION:-'1.0.0'}\nVERSION_MAJOR='0'\nBUILD=\"$PWD/build/ck.build\"\nPREFIX=${PREFIX:-\"/usr/local\"}\nLDNAME=\"libck.so\"\nLDNAME_VERSION=\"libck.so.$VERSION\"\nLDNAME_MAJOR=\"libck.so.$VERSION_MAJOR\"\n\nOPTION_CHECKING=1\n\nexport CFLAGS\nexport PREFIX\nLC_ALL=C\nexport LC_ALL\n\nif test -n \"${BASH_VERSION+set}\" && (set -o posix) >/dev/null 2>&1; then\n \tset -o posix\nfi\n\ntrap epilog 1 2 3 6\n\nepilog()\n{\n\trm -f .1.c .1\n}\n\nassert()\n{\n\n\tif test \"$#\" -eq 2; then\n\t\tfail=$2\n\t\tprint=true\n\telif test \"$#\" -eq 3; then\n\t\tfail=$3\n\t\tprint=echo\n\telse\n\t\techo \"Usage: assert <test> <fail string> or assert <test> <success string> <fail string>\" 1>&2\n\t\texit $EXIT_FAILURE\n\tfi\n\n\tif test -z \"$1\"; then\n\t\techo \"failed  [$fail]\"\n\t\texit $EXIT_FAILURE\n\telse\n\t\t${print} \"success [$1]\"\n\tfi\n}\n\nget_git_sha()\n{\n    # return a short SHA for the current HEAD\n    GIT_SHA=\"\"\n    GIT_MSG=\"success\"\n    gitcmd=`which git`\n    if test -n \"$gitcmd\"; then\n\tGIT_SHA=`git rev-parse --short HEAD  2>/dev/null`\n\tif ! test -n \"$GIT_SHA\"; then\n\t    GIT_MSG=\"not within a git repo\"\n\tfi\n    else\n\tGIT_MSG=\"git not installed or executable\"\n    fi\n}\n\ngenerate()\n{\n\tsed -e \"s#@PROFILE@#$PROFILE#g\"\t\t\t\t\\\n\t    -e \"s#@VERSION@#$VERSION#g\"\t\t\t\t\\\n\t    -e \"s#@VERSION_MAJOR@#$VERSION_MAJOR#g\"\t\t\\\n\t    -e \"s#@CC@#$CC#g\"\t\t\t\t\t\\\n \t    -e \"s#@CFLAGS@#$CFLAGS#g\"\t\t\t\t\\\n \t    -e \"s#@HEADERS@#$HEADERS#g\"\t\t\t\t\\\n\t    -e \"s#@LIBRARY@#$LIBRARY#g\"\t\t\t\t\\\n\t    -e \"s#@PREFIX@#$PREFIX#g\"\t\t\t\t\\\n\t    -e \"s#@CORES@#$CORES#g\"\t\t\t\t\\\n\t    -e \"s#@ALL_LIBS@#$ALL_LIBS#g\"\t\t\t\\\n\t    -e \"s#@INSTALL_LIBS@#$INSTALL_LIBS#g\"\t\t\\\n\t    -e \"s#@LD@#$LD#g\"\t\t\t\t\t\\\n\t    -e \"s#@LDFLAGS@#$LDFLAGS#g\"\t\t\t\t\\\n\t    -e \"s#@PTHREAD_CFLAGS@#$PTHREAD_CFLAGS#g\"\t\t\\\n\t    -e \"s#@MANDIR@#$MANDIR#g\"\t\t\t\t\\\n\t    -e \"s#@GZIP@#$GZIP#g\"\t\t\t\t\\\n\t    -e \"s#@GZIP_SUFFIX@#$GZIP_SUFFIX#g\"\t\t\t\\\n\t    -e \"s#@POINTER_PACK_ENABLE@#$POINTER_PACK_ENABLE#g\"\t\\\n\t    -e \"s#@DISABLE_DOUBLE@#$DISABLE_DOUBLE#g\"\t\t\\\n\t    -e \"s#@RTM_ENABLE@#$RTM_ENABLE#g\"\t\t\t\\\n\t    -e \"s#@LSE_ENABLE@#$LSE_ENABLE#g\"\t\t\t\\\n\t    -e \"s#@VMA_BITS@#$VMA_BITS_R#g\"\t\t\t\\\n\t    -e \"s#@VMA_BITS_VALUE@#$VMA_BITS_VALUE_R#g\"\t\t\\\n\t    -e \"s#@MM@#$MM#g\"\t\t\t\t\t\\\n\t    -e \"s#@BUILD_DIR@#$P_PWD#g\"\t\t\t\t\\\n\t    -e \"s#@SRC_DIR@#$BUILD_DIR#g\"\t\t\t\\\n\t    -e \"s#@LDNAME@#$LDNAME#g\"\t\t\t\t\\\n\t    -e \"s#@LDNAME_MAJOR@#$LDNAME_MAJOR#g\"\t\t\\\n\t    -e \"s#@LDNAME_VERSION@#$LDNAME_VERSION#g\"\t\t\\\n\t    -e \"s#@PC_CFLAGS@#$PC_CFLAGS#g\"\t\t\t\\\n\t    -e \"s#@GIT_SHA@#$GIT_SHA#g\"\t\t\t        \\\n\t\t$1 > $2\n}\n\ngenerate_stdout()\n{\n\n\techo\n\techo \"           VERSION = $VERSION\"\n\techo \"           GIT_SHA = $GIT_SHA\"\n\techo \"         BUILD_DIR = $P_PWD\"\n\techo \"           SRC_DIR = $BUILD_DIR\"\n\techo \"            SYSTEM = $SYSTEM\"\n\techo \"           PROFILE = $PROFILE\"\n\techo \"                CC = $CC\"\n\techo \"          COMPILER = $COMPILER\"\n\techo \"            CFLAGS = $CFLAGS\"\n\techo \"    PTHREAD_CFLAGS = $PTHREAD_CFLAGS\"\n\techo \"                LD = $LD\"\n\techo \"            LDNAME = $LDNAME\"\n\techo \"    LDNAME_VERSION = $LDNAME_VERSION\"\n\techo \"      LDNAME_MAJOR = $LDNAME_MAJOR\"\n\techo \"           LDFLAGS = $LDFLAGS\"\n\techo \"              GZIP = $GZIP\"\n\techo \"             CORES = $CORES\"\n\techo \"      POINTER_PACK = $POINTER_PACK_ENABLE\"\n\techo \"          VMA_BITS = $VMA_BITS\"\n\techo \"      MEMORY_MODEL = $MM\"\n\techo \"               RTM = $RTM_ENABLE\"\n\techo \"               LSE = $LSE_ENABLE\"\n\techo\n\techo \"Headers will be installed in $HEADERS\"\n\techo \"Libraries will be installed in $LIBRARY\"\n\techo \"Documentation will be installed in $MANDIR\"\n}\n\nfor option; do\n\tcase \"$option\" in\n\t*=?*)\n\t\toptname=`echo $option|cut -c 3-`\n\t\tvalue=`expr \"$optname\" : '[^=]*=\\(.*\\)'`\n\t\t;;\n\t*=)\n\t\tvalue=\n\t\t;;\n\t*)\n\t\tvalue=yes\n\t\t;;\n\tesac\n\n\tcase \"$option\" in\n\t--help)\n\t\techo \"Usage: $0 [OPTIONS]\"\n\t\techo\n\t\techo \"The following options may be used for cross-building.\"\n\t\techo \"  --profile=N              Use custom build profile (use in conjunction with \\$CC)\"\n\t\techo\n\t\techo \"The following options may be used to modify installation behavior.\"\n\t\techo \"  --includedir=N           Headers directory (default is ${PREFIX}/include)\"\n\t\techo \"  --libdir=N               Libraries directory (default is ${PREFIX}/lib)\"\n\t\techo \"  --mandir=N               Manual pages directory (default is ${PREFIX}/man)\"\n\t\techo \"  --prefix=N               Installs library files in N (default is $PREFIX)\"\n\t\techo\n\t\techo \"The following options will affect generated code.\"\n\t\techo \"  --enable-pointer-packing Assumes address encoding is subset of pointer range\"\n\t\techo \"  --enable-rtm             Enable restricted transactional memory (power, x86_64)\"\n\t\techo \"  --enable-lse             Enable large system extensions (arm64)\"\n\t\techo \"  --memory-model=N         Specify memory model (currently tso, pso or rmo)\"\n\t\techo \"  --vma-bits=N             Specify valid number of VMA bits\"\n\t\techo \"  --platform=N             Force the platform type, instead of relying on autodetection\"\n\t\techo \"  --use-cc-builtins        Use the compiler atomic bultin functions, instead of the CK implementation\"\n\t\techo \"  --disable-double         Don't generate any of the functions using the \\\"double\\\" type\"\n\t\techo\n\t\techo \"The following options affect regression testing.\"\n\t\techo \"  --cores=N                Specify number of cores available on target machine\"\n\t\techo\n\t\techo \"The following environment variables may be used:\"\n\t\techo \"   CC       C compiler command\"\n\t\techo \"   CFLAGS   C compiler flags\"\n\t\techo \"   LDFLAGS  Linker flags\"\n\t\techo \"   GZIP     GZIP compression tool\"\n\t\techo\n\t\techo \"Report bugs to ${MAINTAINER}.\"\n\t\texit $EXIT_SUCCESS\n\t\t;;\n\t--memory-model=*)\n\t\tcase \"$value\" in\n\t\t\"tso\")\n\t\t\tMM=\"CK_MD_TSO\"\n\t\t\t;;\n\t\t\"rmo\")\n\t\t\tMM=\"CK_MD_RMO\"\n\t\t\t;;\n\t\t\"pso\")\n\t\t\tMM=\"CK_MD_PSO\"\n\t\t\t;;\n\t\t*)\n\t\t\techo \"./configure [--help]\"\n\t\t\texit $EXIT_FAILURE\n\t\t\t;;\n\t\tesac\n\t\t;;\n\t--vma-bits=*)\n\t\tVMA_BITS=$value\n\t\t;;\n\t--enable-pointer-packing)\n\t\tPOINTER_PACK_ENABLE=\"CK_MD_POINTER_PACK_ENABLE\"\n\t\t;;\n\t--enable-rtm)\n\t\tRTM_ENABLE_SET=\"CK_MD_RTM_ENABLE\"\n\t\t;;\n\t--enable-lse)\n\t\tLSE_ENABLE_SET=\"CK_MD_LSE_ENABLE\"\n\t\t;;\n\t--cores=*)\n\t\tCORES=$value\n\t\t;;\n\t--profile=*)\n\t\tPROFILE=$value\n\t\t;;\n\t--prefix=*)\n\t\tPREFIX=$value\n\t\t;;\n\t--includedir=*)\n\t\tHEADERS=$value\n\t\t;;\n\t--libdir=*)\n\t\tLIBRARY=$value\n\t\t;;\n\t--mandir=*)\n\t\tMANDIR=$value\n\t\t;;\n\t--with-pic)\n\t\tWANT_PIC=yes\n\t\t;;\n\t--without-pic)\n\t\tWANT_PIC=no\n\t\t;;\n\t--disable-option-checking)\n\t\tOPTION_CHECKING=0\n\t\t;;\n\t--use-cc-builtins)\n\t\tUSE_CC_BUILTINS=1\n\t\t;;\n\t--disable-double)\n\t\tDISABLE_DOUBLE=\"CK_PR_DISABLE_DOUBLE\"\n\t\t;;\n\t--platform=*)\n\t\tPLATFORM=$value\n\t\t;;\n\t--build=*|--host=*|--target=*|--exec-prefix=*|--bindir=*|--sbindir=*|\\\n\t--sysconfdir=*|--datadir=*|--libexecdir=*|--localstatedir=*|\\\n\t--enable-static|\\\n\t--sharedstatedir=*|--infodir=*|--enable-shared|--disable-shared|\\\n\t--cache-file=*|--srcdir=*)\n\t\t# ignore for compat with regular configure\n\t\t;;\n\t--*)\n\t\tif test \"$OPTION_CHECKING\" -eq 1; then\n\t\t\techo \"$0 [--help]\"\n\t\t\techo \"Unknown option $option\"\n\t\t\texit $EXIT_FAILURE\n\t\tfi\n\t\t;;\n\t*=*)\n\t\toptname=`echo $option|cut -c 3-`\n\t\tNAME=`expr \"$optname\" : '\\([^=]*\\)='`\n\t\teval \"$NAME='$value'\"\n\t\texport $NAME\n\t\t;;\n\t*)\n\t\techo \"$0 [--help]\"\n\t\techo \"Unknown option $option\"\n\t\texit $EXIT_FAILURE\n\t\t;;\n\tesac\ndone\n\nHEADERS=${HEADERS:-\"${PREFIX}/include\"}\nLIBRARY=${LIBRARY:-\"${PREFIX}/lib\"}\nMANDIR=${MANDIR:-\"${PREFIX}/share/man\"}\nGZIP=${GZIP:-\"gzip -c\"}\nPOINTER_PACK_ENABLE=${POINTER_PACK_ENABLE:-\"CK_MD_POINTER_PACK_DISABLE\"}\nDISABLE_DOUBLE=${DISABLE_DOUBLE:-\"CK_PR_ENABLE_DOUBLE\"}\nRTM_ENABLE=${RTM_ENABLE_SET:-\"CK_MD_RTM_DISABLE\"}\nLSE_ENABLE=${LSE_ENABLE_SET:-\"CK_MD_LSE_DISABLE\"}\nVMA_BITS=${VMA_BITS:-\"unknown\"}\n\nDCORES=2\nprintf \"Detecting operating system.......\"\nSYSTEM=`uname -s 2> /dev/null`\ncase \"$SYSTEM\" in\n\t\"SunOS\")\n\t\tSYSTEM=solaris\n\t\t;;\n\t\"Linux\"|\"uClinux\")\n\t\tDCORES=`egrep '(^CPU[0-9]+|^processor.*:.*)' /proc/cpuinfo|wc -l`\n\t\tSYSTEM=linux\n\t\t;;\n\t\"FreeBSD\"|\"GNU/kFreeBSD\")\n\t\tDCORES=`sysctl -n hw.ncpu`\n\t\tSYSTEM=freebsd\n\t\t;;\n\t\"NetBSD\")\n\t\tDCORES=`sysctl -n hw.ncpu`\n\t\tSYSTEM=netbsd\n\t\t;;\n\t\"OpenBSD\")\n\t\tDCORES=`sysctl -n hw.ncpu`\n\t\tSYSTEM=openbsd\n\t\t;;\n\t\"DragonFly\")\n\t\tDCORES=`sysctl -n hw.ncpu`\n\t\tSYSTEM=dragonflybsd\n\t\t;;\n\t\"Darwin\")\n\t\tDCORES=`sysctl -n hw.ncpu`\n\t\tSYSTEM=darwin\n\t\t;;\n\tMINGW32*|MSYS_NT*)\n\t\tSYSTEM=mingw32\n\t\tLDFLAGS=\"-mthreads $LDFLAGS\"\n\t\t;;\n  CYGWIN_NT*)\n    SYSTEM=cygwin\n    LDFLAGS=\"-mthreads $LDFLAGS\"\n    ;;\n\t*)\n\t\tSYSTEM=\n\t\t;;\nesac\n\nassert \"$SYSTEM\" \"$SYSTEM\" \"unsupported\"\n\nCORES=${CORES:-${DCORES}}\nprintf \"Detecting machine architecture...\"\nif test \"x$PLATFORM\" = \"x\"; then\n\tPLATFORM=`uname -m 2> /dev/null`\nfi\n\ncase $PLATFORM in\n\t\"macppc\"|\"Power Macintosh\"|\"powerpc\")\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_RMO\"}\"\n\t\tPLATFORM=ppc\n\t\tENVIRONMENT=32\n\t\tLDFLAGS=\"-m32 $LDFLAGS\"\n\t\t;;\n\t\"sun4u\"|\"sun4v\"|\"sparc64\")\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_TSO\"}\"\n\t\tPLATFORM=sparcv9\n\t\tENVIRONMENT=64\n\t\tLDFLAGS=\"-m64 $LDFLAGS\"\n\t\t;;\n\ti386|i486|i586|i686|i586_i686|pentium*|athlon*|k5|k6|k6_2|k6_3)\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_TSO\"}\"\n\t\tcase $SYSTEM in\n\t\t\tdarwin)\n\t\t\t\tENVIRONMENT=64\n\t\t\t\tPLATFORM=x86_64\n\t\t\t\t;;\n\t\t\tfreebsd)\n\t\t\t\tPLATFORM=x86\n\t\t\t\tENVIRONMENT=32\n\n\t\t\t\t# FreeBSD doesn't give us a nice way to determine the CPU\n\t\t\t\t# class of the running system, reporting any 32-bit x86\n\t\t\t\t# architecture as i386. 486 is its minimum supported CPU\n\t\t\t\t# class and cmpxchg8b was implemented first in i586.\n\t\t\t\tdmesg | grep -q \"486-class\"\n\t\t\t\tif test \"$?\" -eq 0; then\n\t\t\t\t\tassert \"\" \"\" \"Must have an i586 class or higher CPU\"\n\t\t\t\tfi\n\n\t\t\t\t# FreeBSD still generates code for 486-class CPUs as its\n\t\t\t\t# default 32-bit target, but we need 586 at the least.\n\t\t\t\techo \"$CFLAGS\" | grep -q 'march='\n\t\t\t\tif test \"$?\" -ne 0; then\n\t\t\t\t\t# Needed for cmpxchg8b\n\t\t\t\t\tCFLAGS=\"$CFLAGS -march=i586\"\n\t\t\t\tfi\n\t\t\t\t;;\n\t\t\tlinux)\n\t\t\t\tcase $PLATFORM in\n\t\t\t\t\ti386|i486)\n\t\t\t\t\t\tassert \"\" \"\" \"Must have an i586 class or higher CPU\"\n\t\t\t\t\t\t;;\n\t\t\t\tesac\n\n\t\t\t\tPLATFORM=x86\n\t\t\t\tENVIRONMENT=32\n\t\t\t\t;;\n\n\t\t\t*)\n\t\t\t\tPLATFORM=x86\n\t\t\t\tENVIRONMENT=32\n\t\t\t\tassert \"$PLATFORM $ENVIRONMENT\" \"$PLATFORM $ENVIRONMENT\" \"unsupported\"\n\t\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"amd64\"|\"x86_64\")\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tPLATFORM=x86_64\n\t\tENVIRONMENT=64\n\t\tLDFLAGS=\"-m64 $LDFLAGS\"\n\t\tMM=\"${MM:-\"CK_MD_TSO\"}\"\n\t\t;;\n\t\"i86pc\")\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_TSO\"}\"\n\t\tif test -z \"$ISA\"; then ISA=`isainfo -n 2> /dev/null || echo i386` ; fi\n\t\tcase \"$ISA\" in\n\t\t\t\"amd64\")\n\t\t\t\tRTM_ENABLE=${RTM_ENABLE_SET:-\"CK_MD_RTM_DISABLE\"}\n\t\t\t\tPLATFORM=x86_64\n\t\t\t\tENVIRONMENT=64\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\tPLATFORM=x86\n\t\t\t\tENVIRONMENT=32\n\t\t\t\tassert \"$PLATFORM $ENVIRONMENT\" \"$PLATFORM $ENVIRONMENT\" \"unsupported\"\n\t\t\t\t;;\n\t\tesac\n\t\t;;\n\t\"ppc64\"|\"ppc64le\")\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_RMO\"}\"\n\t\tPLATFORM=ppc64\n\t\tENVIRONMENT=64\n\t\t;;\n\tarm|armv6l|armv7l)\n\t\tif test \"$PLATFORM\" = \"armv6l\"; then\n\t\t\tCFLAGS=\"$CFLAGS -march=armv6k\";\n\t\telif test \"$PLATFORM\" = \"armv7l\"; then\n\t\t\tCFLAGS=\"$CFLAGS -march=armv7-a\";\n\t\tfi\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_RMO\"}\"\n\t\tPLATFORM=arm\n\t\tENVIRONMENT=32\n\t\t;;\n\t\"arm64\"|\"aarch64\")\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_RMO\"}\"\n\t\tPLATFORM=aarch64\n\t\tENVIRONMENT=64\n\t\t;;\n\t\"s390x\")\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tMM=\"${MM:-\"CK_MD_RMO\"}\"\n\t\tPLATFORM=s390x\n\t\tENVIRONMENT=64\n\t\t;;\n\t*)\n\t\tRTM_ENABLE=\"CK_MD_RTM_DISABLE\"\n\t\tLSE_ENABLE=\"CK_MD_LSE_DISABLE\"\n\t\tPLATFORM=\n\t\tMM=\"${MM:-\"CK_MD_RMO\"}\"\n\t\t;;\nesac\n\nassert \"$PLATFORM\" \"$PLATFORM\" \"unsupported\"\n\nif test \"$VMA\" = \"unknown\"; then\n\tVMA_BITS_R=\"CK_MD_VMA_BITS_UNKNOWN\"\n\tVMA_BITS_VALUE_R=\"\"\n\tPOINTER_PACK_ENABLE=\"CK_MD_POINTER_PACK_DISABLE\"\nelse\n\tVMA_BITS_R=\"CK_MD_VMA_BITS\"\n\tVMA_BITS_VALUE_R=\"${VMA_BITS}ULL\"\nfi\n\nif test \"$USE_CC_BUILTINS\"; then\n\tCFLAGS=\"$CFLAGS -DCK_CC_BUILTINS\"\n\tPC_CFLAGS=\"-DCK_CC_BULITINS\"\nfi\n\n# `which` on Solaris sucks\npathsearch()\n{\n\twhat=$1\n\toldFS=\"$IFS\"\n\tIFS=\":\"\n\tfor d in $PATH ; do\n\t\tif test -x \"$d/$what\" ; then\n\t\t\techo \"$d/$what\";\n\t\t\tIFS=\"$oldFS\"\n\t\t\treturn\n\t\tfi\n\tdone\n\tIFS=\"$oldFS\"\n}\n\nprintf \"Finding dirname command..........\"\nDIRNAME=`pathsearch \"${DIRNAME:-dirname}\"`\nif test -z \"$DIRNAME\" -o ! -x \"$DIRNAME\"; then\n\tDIRNAME=`pathsearch \"${DIRNAME:-dirname}\"`\n\tDIRNAME=\"$DIRNAME\"\nelse\n\techo \"success [$DIRNAME]\"\nfi\n\nif test -z \"$DIRNAME\"; then\n\techo \"not found (out of source build unsupported)\"\nelse\n\tprintf \"Determining build directory......\"\n\n\tBUILD_DIR=`$DIRNAME $0`\n\tcd `$DIRNAME $0`\n\tBUILD_DIR=`pwd`\n\n\techo \"success [$BUILD_DIR]\"\nfi\n\nprintf \"Finding gzip tool................\"\nGZIP=`pathsearch \"${GZIP:-gzip}\"`\nif test -z \"$GZIP\" -o ! -x \"$GZIP\"; then\n\tGZIP=`pathsearch \"${GZIP:-gzip}\"`\n\tGZIP=\"$GZIP\"\nfi\n\nif test -z \"$GZIP\"; then\n\techo \"not found\"\n\tGZIP=cat\n\tGZIP_SUFFIX=\"\"\nelse\n\techo \"success [$GZIP]\"\n\tGZIP=\"$GZIP -c\"\n\tGZIP_SUFFIX=\".gz\"\nfi\n\nprintf \"Finding suitable compiler........\"\nif test ! -x \"${CC}\"; then\n\tCC=`pathsearch \"${CC:-cc}\"`\n\tif test -z \"$CC\" -o ! -x \"$CC\"; then\n\t\tCC=`pathsearch \"${CC:-gcc}\"`\n\tfi\nfi\nassert \"$CC\" \"not found\"\n\ncat << EOF > .1.c\n#include <stdio.h>\nint main(void) {\n#if defined(_WIN32)\n#if defined(__MINGW64__)\n\tputs(\"mingw64\");\n\treturn (0);\n#elif defined(__MINGW32__) && (__MINGW32_MAJOR_VERSION >= 3)\n\tputs(\"mingw32\");\n\treturn (0);\n#else\n\treturn (1);\n#endif /* __MINGW32__ && __MINGW32_MAJOR_VERSION >= 3 */\n#elif defined(__clang__) && (__clang_major__ >= 3)\n\tputs(\"clang\");\n\treturn (0);\n#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x5110)\n\tputs(\"suncc\");\n\treturn (0);\n#elif defined(__GNUC__) && (__GNUC__ >= 4)\n\tputs(\"gcc\");\n\treturn (0);\n#else\n\treturn (1);\n#endif\n}\nEOF\n\n$CC -o .1 .1.c\nCOMPILER=`./.1 2> /dev/null`\nr=$?\nrm -f .1.c .1\n\nif test \"$r\" -ne 0; then\n\tassert \"\" \"update compiler\"\nelse\n\techo \"success [$CC]\"\nfi\n\nif test \"$COMPILER\" = \"suncc\"; then\n\tLD=/bin/ld\n\tLDFLAGS=\"-G -z text -h libck.so.$VERSION_MAJOR $LDFLAGS\"\n\tCFLAGS=\"-xO5 $CFLAGS\"\n\tPTHREAD_CFLAGS=\"-mt -lpthread\"\nelif test \"$COMPILER\" = \"gcc\" || test \"$COMPILER\" = \"clang\" || test \"$COMPILER\" = \"mingw32\" || test \"$COMPILER\" = \"mingw64\"; then\n\tLD=$CC\n\tSONAME=\"$LDNAME_MAJOR\"\n\tif test \"$SYSTEM\" = \"darwin\"; then\n\t\tCC_WL_OPT=\"-install_name\"\n\t\tLDNAME=\"libck.dylib\"\n\t\tLDNAME_VERSION=\"libck.$VERSION.dylib\"\n\t\tLDNAME_MAJOR=\"libck.$VERSION_MAJOR.dylib\"\n\t\tSONAME=\"$LIBRARY/$LDNAME_MAJOR\"\n\telse\n\t\tCC_WL_OPT=\"-soname\"\n\tfi\n\n\tLDFLAGS=\"-Wl,$CC_WL_OPT,$SONAME $LDFLAGS\"\n\tif test \"$WANT_PIC\" = \"yes\"; then\n\t\tLDFLAGS=\"$LDFLAGS -shared -fPIC\"\n\t\tCFLAGS=\"$CFLAGS -fPIC\"\n\t\tALL_LIBS=\"libck.so libck.a\"\n\t\tINSTALL_LIBS=\"install-so install-lib\"\n\telse\n\t\tLDFLAGS=\"$LDFLAGS -fno-PIC\"\n\t\tCFLAGS=\"$CFLAGS -fno-PIC\"\n\t\tALL_LIBS=\"libck.a\"\n\t\tINSTALL_LIBS=\"install-lib\"\n\tfi\n\n\tCFLAGS=\"-D_XOPEN_SOURCE=600 -D_BSD_SOURCE -D_DEFAULT_SOURCE -std=gnu99 -pedantic -Wall -W -Wundef -Wendif-labels -Wshadow -Wpointer-arith -Wcast-align -Wcast-qual -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wdisabled-optimization -fstrict-aliasing -O2 -pipe -Wno-parentheses $CFLAGS\"\n\tPTHREAD_CFLAGS=\"-pthread\"\n\tif test \"$COMPILER\" = \"mingw64\"; then\n\t\tENVIRONMENT=64\n\t\tPLATFORM=x86_64\n\tfi\nelse\n\tassert \"\" \"unknown compiler\"\nfi\n\nprintf \"Detecting VMA bits...............\"\nVMA=\"unknown\"\nif test \"$VMA_BITS\" = \"unknown\"; then\n\tif test \"$PLATFORM\" = \"x86\" || test $PLATFORM = \"x86_64\"; then\n\t\tcase $SYSTEM in\n\t\t\tdarwin)\n\t\t\t\tVMA=`sysctl -n machdep.cpu.address_bits.virtual`\n\t\t\t\t;;\n\t\t\tlinux)\n\t\t\t\tVMA=`awk '/address sizes/ {print $7;exit}' /proc/cpuinfo`\n\t\t\t\t;;\n\t\t\t*)\n\t\t\t\tif test \"$PLATFORM\" = \"x86\"; then\n\t\t\t\t\tVMA=\"32\"\n\t\t\t\telse\n\t\t\t\t\tcat << EOF > .1.c\n\t\t\t\t\t#include <stdio.h>\n\n\t\t\t\t\tint main(int argc, char *argv[])\n\t\t\t\t\t{\n\t\t\t\t\t\tunsigned long ret = 0x80000000;\n\n\t\t\t\t\t\t__asm __volatile(\"cpuid\\n\"\n\t\t\t\t\t\t\t\t : \"+a\" (ret));\n\t\t\t\t\t\tif (ret >= 0x80000008) {\n\t\t\t\t\t\t\t\tret = 0x80000008;\n\t\t\t\t\t\t\t\t__asm __volatile(\"cpuid\\n\"\n\t\t\t\t\t\t\t\t : \"+a\" (ret));\n\t\t\t\t\t\t\t\tprintf(\"%lu\\n\", (ret >> 8) & 0xff);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn (1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn (0);\n\t\t\t\t\t}\nEOF\n\n\t\t\t\t\t$CC -o .1 .1.c 2>/dev/null\n\t\t\t\t\tVMA=`./.1 2>/dev/null`\n\t\t\t\t\tif test $? -ne 0; then\n\t\t\t\t\t\tVMA=\"unknown\"\n\t\t\t\t\tfi\n\t\t\t\t\trm -f .1.c .1\n\t\t\t\tfi\n\t\tesac\n\tfi\n\n\tVMA_BITS=$VMA\nelse\n\tVMA=$VMA_BITS\nfi\n\nif test \"$VMA\" = \"unknown\"; then\n\techo \"unknown\"\n\tVMA_BITS_R=\"CK_MD_VMA_BITS_UNKNOWN\"\n\tVMA_BITS_VALUE_R=\"\"\n\tPOINTER_PACK_ENABLE=\"CK_MD_POINTER_PACK_DISABLE\"\nelse\n\techo \"success [$VMA]\"\n\tVMA_BITS_R=\"CK_MD_VMA_BITS\"\n\tVMA_BITS_VALUE_R=\"${VMA_BITS}ULL\"\nfi\n\nfor i in $REQUIRE_HEADER; do\n\tprintf \"Checking header file usability...\"\n\n\tcat << EOF > .1.c\n#include <$i>\nint main(void){return(0);}\nEOF\n\t$CC -o .1 .1.c 2> /dev/null\n\thf_s=$?\n\n\trm -f .1 .1.c\n\tif test $hf_s -eq 0; then\n\t\techo \"success [$i]\"\n\telse\n\t\techo \"failed  [$i]\"\n\t\texit $EXIT_FAILURE\n\tfi\ndone\n\nprintf \"Detecting git SHA................\"\nget_git_sha\necho \"$GIT_MSG [$GIT_SHA]\"\n\nif test \"$PROFILE\"; then\n    printf \"Using user-specified profile.....\"\n\n\tif test -z \"$CC\"; then\n\t\techo \"failed [specify compiler]\"\n\t\texit $EXIT_FAILURE\n\tfi\n\n\tif test ! -f build/ck.build.$PROFILE; then\n\t\techo \"failed [$PROFILE]\"\n\t\texit $EXIT_FAILURE\n\tfi\n\n\techo \"success [$PROFILE]\"\n\tprintf \"Generating header files..........\"\n\tgenerate include/ck_md.h.in include/ck_md.h\n\techo \"success\"\n\tprintf \"Generating build files...........\"\n\tgenerate src/Makefile.in src/Makefile\n\tgenerate doc/Makefile.in doc/Makefile\n\tgenerate build/ck.build.in build/ck.build\n\tgenerate build/regressions.build.in build/regressions.build\n\tgenerate build/ck.pc.in build/ck.pc\n\tgenerate build/ck.spec.in build/ck.spec\n\tgenerate Makefile.in Makefile\n\techo \"success\"\n\tgenerate_stdout\n\texit $EXIT_SUCCESS\nfi\n\n# Platform will be used as a macro.\nPROFILE=\"${PROFILE:-$PLATFORM}\"\nPLATFORM=\"__${PLATFORM}__\"\n\nprintf \"Generating header files..........\"\ngenerate include/ck_md.h.in include/ck_md.h\necho \"success\"\n\nprintf \"Generating build files...........\"\n\nmkdir -p $P_PWD/doc\nmkdir -p $P_PWD/build\nmkdir -p $P_PWD/include\nmkdir -p $P_PWD/src\n\nif test \"$P_PWD\" '!=' \"$BUILD_DIR\"; then\n\tmkdir -p $P_PWD/regressions\n\tcp $BUILD_DIR/regressions/Makefile.unsupported $P_PWD/regressions/Makefile &> /dev/null\n\tcp $BUILD_DIR/build/ck.build.$PROFILE $P_PWD/build/ck.build.$PROFILE &> /dev/null\n\tcp $BUILD_DIR/include/ck_md.h $P_PWD/include/ck_md.h &> /dev/null\nfi\n\ngenerate src/Makefile.in $P_PWD/src/Makefile\ngenerate doc/Makefile.in $P_PWD/doc/Makefile\ngenerate build/ck.build.in $P_PWD/build/ck.build\ngenerate build/regressions.build.in $P_PWD/build/regressions.build\ngenerate build/ck.pc.in $P_PWD/build/ck.pc\ngenerate build/ck.spec.in $P_PWD/build/ck.spec\ngenerate Makefile.in $P_PWD/Makefile\ntouch src/*.c\necho \"success\"\ngenerate_stdout\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_ARRAY_FOREACH",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_FOREACH 3\n.Sh NAME\n.Nm CK_ARRAY_FOREACH\n.Nd iterate through an array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft bool\n.Fn CK_ARRAY_FOREACH \"ck_array_t *array\" \"ck_array_iterator_t *iterator\" \"void **b\"\n.Sh DESCRIPTION\nThe\n.Fn CK_ARRAY_FOREACH 3\nmacro iterates through the array pointed to by\n.Fa array .\nA pointer to an iterator object must be specified by\n.Fa iterator\nand\n.Fa b\nmust point to a void pointer.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_array.h>\n\n/* Assume this was already previously initialized. */\nck_array_t array;\n\nvoid\nexample(void)\n{\n\tck_array_iterator_t iterator;\n\tvoid *pointer;\n\n\tCK_ARRAY_FOREACH(&array, &iterator, &pointer) {\n\t\tdo_something(pointer);\n\t}\n}\n.Ed\n.Sh RETURN VALUES\nThis macro has no return value.\n.Sh SEE ALSO\n.Xr ck_array_init 3 ,\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_deinit 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_INIT",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_COHORT_INIT 3\n.Sh NAME\n.Nm CK_COHORT_INIT\n.Nd initialize instance of a cohort type\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_INIT \"COHORT_NAME cohort_name\" \"COHORT *cohort\" \"void *global_lock\" \\\n\"void *local_lock\" \"unsigned int pass_limit\"\n.Sh DESCRIPTION\nUntil a cohort instance is initialized using the CK_COHORT_INIT macro, any operations\ninvolving it will have undefined behavior.  After this macro has been called, the cohort\npointed to by the\n.Fa cohort\nargument will use the lock pointed to by\n.Fa global_lock\nas its global lock and the lock pointed to by\n.Fa local_lock\nas its local lock.\n.Pp\nThe cohort will relinquish its global lock after\n.Fa pass_limit\nconsecutive acquisitions of its local lock, even if there are other threads waiting.\nIf you are unsure of a value to use for the\n.Fa pass_limit\nargument, you should use CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_INSTANCE",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_COHORT_INSTANCE 3\n.Sh NAME\n.Nm CK_COHORT_INSTANCE\n.Nd declare an instance of a cohort type\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_INSTANCE \"COHORT_NAME cohort_name\"\n.Sh DESCRIPTION\nThe user must use this macro to declare instances of cohort types that they have\ndefined.  For instance, if they have used the CK_COHORT_PROTOTYPE macro to define\na cohort type with name foo, they would create an instance of this type as follows:\n.br\nCK_COHORT_INSTANCE(foo) cohort;\n.Pp\nThis macro should also be used when allocating memory for cohorts.  For instance,\nto allocate a block of 4 cohorts:\n.br\nCK_COHORT_INSTANCE(foo) *cohorts = malloc(4 * sizeof(CK_COHORT_INSTANCE(foo)));\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_LOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_COHORT_LOCK 3\n.Sh NAME\n.Nm CK_COHORT_LOCK\n.Nd acquire cohort lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_LOCK \"COHORT_NAME cohort_name\" \"COHORT *cohort\" \"void *global_context\" \\\n\"void *local_context\"\n.Sh DESCRIPTION\nThis call attempts to acquire both the local and global (if necessary) locks from\n.Fa cohort .\nThe call will block until both locks have been acquired.\n.Fa global_context\nwill be passed as the second argument to the function that was provided as the\n.Fa global_lock_method\nargument to CK_COHORT_PROTOTYPE if that method is called, and\n.Fa local_context\nwill be passed to the function specified by\n.Fa local_lock_method\n.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_PROTOTYPE",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_COHORT_PROTOTYPE 3\n.Sh NAME\n.Nm CK_COHORT_PROTOTYPE\n.Nd define cohort type with specified lock types\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_PROTOTYPE \"COHORT_NAME cohort_name\" \"TYPE global_lock_method\" \\\n\"LOCK_FXN global_unlock_method\" \"LOCK_FXN local_lock_method\" \"LOCK_FXN local_unlock_method\"\n.Sh DESCRIPTION\nThe ck_cohort.h header file does not define any cohort types.  Instead, the user must use\nthe CK_COHORT_PROTOTYPE or\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3\nmacros to define any types they want to use.  They must use CK_COHORT_TRYLOCK_PROTOTYPE\nif they want their cohort type to support trylock operations.\nThe CK_COHORT_PROTOTYPE macro takes the following arguments:\n.Pp\n.Fa cohort_name\n: An identifier used for this cohort type.  This will have to be passed to each\nof the other CK_COHORT macros.\n.br\n.Fa global_lock_method\n: The method that should be called to acquire the global lock\n.br\n.Fa global_unlock_method\n: The method that should be called to relinquish the global lock\n.br\n.Fa local_lock_method\n: The method that should be called to acquire the local lock\n.br\n.Fa local_unlock_method\n: The method that should be called to relinquish the local lock\n.Pp\nInstances of the defined cohort type can be declared as:\n.br\n    CK_COHORT_INSTANCE(cohort_name) cohort;\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_TRYLOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 9, 2013.\n.Dt CK_COHORT_TRYLOCK 3\n.Sh NAME\n.Nm CK_COHORT_TRYLOCK\n.Nd try to acquire cohort lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_TRYLOCK \"COHORT_NAME cohort_name\" \"COHORT *cohort\" \"void *global_trylock_context\" \\\n\"void *local_trylock_context\" \"void *lock_unlock_context\"\n.Sh DESCRIPTION\nThis call attempts to acquire both the local and global (if necessary) locks from\n.Fa cohort .\nIt can only be used with cohort types that were defined using the\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3\nmacro.  The call will not block and will return a bool that will evaluate to true iff\nthe cohort was successfully acquired.\n.Fa global_trylock_context\nwill be passed as the second argument to the function that was provided as the\n.Fa global_trylock_method\nargument to CK_COHORT_TRYLOCK_PROTOTYPE if that method is called, and\n.Fa local_trylock_context\nwill be passed to the function specified by\n.Fa local_trylock_method .\nIf the global lock acquisition fails, then the cohort will immediately release its\nlocal lock as well, and\n.Fa local_unlock_context\nwill be passed to the function specified by\n.Fa local_unlock_method\nwhen this call is made.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_TRYLOCK_PROTOTYPE",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 9, 2013.\n.Dt CK_COHORT_TRYLOCK_PROTOTYPE 3\n.Sh NAME\n.Nm CK_COHORT_TRYLOCK_PROTOTYPE\n.Nd define cohort type with specified lock types\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_TRYLOCK_PROTOTYPE \"COHORT_NAME cohort_name\" \"LOCK_FXN global_lock_method\" \\\n\"LOCK_FXN global_unlock_method\" \"BOOL_LOCK_FXN global_locked_method\" \\\n\"BOOL_LOCK_FXN global_trylock_method\" \"LOCK_FXN local_lock_method\" \\\n\"LOCK_FXN local_unlock_method\" \"BOOL_LOCK_FXN local_locked_method\" \"BOOL_LOCK_FXN local_trylock_method\"\n.Sh DESCRIPTION\nThe ck_cohort.h header file does not define any cohort types.  Instead, the user must use\nthe CK_COHORT_PROTOTYPE or CK_COHORT_TRYLOCK_PROTOTYPE macros to define any types\nthey want to use.  They must use CK_COHORT_TRYLOCK_PROTOTYPE if they want their cohort type to have support\nfor trylock operations.  The CK_COHORT_TRYLOCK_PROTOTYPE macro takes the following arguments:\n.Pp\n.Fa cohort_name\n: An identifier used for this cohort type.  This will have to be passed to each\nof the other CK_COHORT macros.\n.br\n.Fa global_lock_method\n: The method that should be called to acquire the global lock\n.br\n.Fa global_unlock_method\n: The method that should be called to relinquish the global lock\n.br\n.Fa global_locked_method\n: This method should return true iff the global lock is acquired by a thread.\n.br\n.Fa global_trylock_method\n: The method that should be called to try to acquire the global lock.\nIt should not block and return true iff the lock was successfully acquired.\n.br\n.Fa local_lock_method\n: The method that should be called to acquire the local lock\n.br\n.Fa local_unlock_method\n: The method that should be called to relinquish the local lock\n.br\n.Fa global_locked_method\n: This method should return true iff the global lock is acquired by a thread.\n.br\n.Fa local_trylock_method\n: The method that should be called to try to acquire the local lock.\nIt should not block and return true iff the lock was successfully acquired.\n.Pp\nInstances of the defined cohort type can be declared as:\n.br\n    CK_COHORT_INSTANCE(cohort_name) cohort;\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_COHORT_UNLOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_COHORT_UNLOCK 3\n.Sh NAME\n.Nm CK_COHORT_UNLOCK\n.Nd release cohort lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_UNLOCK \"COHORT_NAME cohort_name\" \"COHORT *cohort\" \"void *global_context\" \\\n\"void *local_context\"\n.Sh DESCRIPTION\nThis call instructs\n.Fa cohort\nto relinquish its local lock and potentially its global lock as well.\n.Fa global_context\nwill be passed as the second argument to the function that was provided as the\n.Fa global_lock_method\nargument to CK_COHORT_PROTOTYPE if that method is called, and\n.Fa local_context\nwill be passed to the function specified by\n.Fa local_lock_method\n.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_HS_HASH",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 28, 2012\n.Dt CK_HS_HASH 3\n.Sh NAME\n.Nm CK_HS_HASH\n.Nd invoke hash function with hash set seed\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft unsigned long\n.Fn CK_HS_HASH \"ck_hs_t *hs\" \"ck_hs_hash_cb_t *hf\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn CK_HS_HASH 3\nmacro will invoke the hash function pointed to by the\n.Fa hf\nargument with the seed value associated with\n.Fa hs\nand the key pointer specified by the\n.Fa key\nargument.\n.Sh RETURN VALUES\nThis function will return the value returned by the\n.Fa hf\nfunction.\n.Sh ERRORS\nIt is expected\n.Fa hs\nwas previously initialized via\n.Fn ck_hs_init 3 .\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RHS_HASH",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 28, 2012\n.Dt CK_RHS_HASH 3\n.Sh NAME\n.Nm CK_RHS_HASH\n.Nd invoke hash function with hash set seed\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft unsigned long\n.Fn CK_RHS_HASH \"ck_rhs_t *hs\" \"ck_rhs_hash_cb_t *hf\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn CK_RHS_HASH 3\nmacro will invoke the hash function pointed to by the\n.Fa hf\nargument with the seed value associated with\n.Fa hs\nand the key pointer specified by the\n.Fa key\nargument.\n.Sh RETURN VALUES\nThis function will return the value returned by the\n.Fa hf\nfunction.\n.Sh ERRORS\nIt is expected\n.Fa hs\nwas previously initialized via\n.Fn ck_rhs_init 3 .\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_INIT",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_INIT 3\n.Sh NAME\n.Nm CK_RWCOHORT_INIT\n.Nd initialize instance of a cohort-based reader-writer lock type\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rwcohort.h\n.Fn CK_RWCOHORT_NEUTRAL_INIT \"COHORT_NAME cohort_name\" \"LOCK *lock\"\n.Fn CK_RWCOHORT_RP_INIT \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"unsigned int wait_limit\"\n.Fn CK_RWCOHORT_WP_INIT \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"unsigned int wait_limit\"\n.Sh DESCRIPTION\nThis macro initializes the lock instance pointed to by the\n.Fa lock\nargument.  Until a lock instance is initialized using the CK_RWCOHORT_INIT macro, any operations\ninvolving it will have undefined behavior.  Note that the\n.Fa wait_limit\nargument should only be used with reader-preference or writer-preference locks.  For neutral\nlocks, this argument should be excluded.\nIf you are unsure of a value to use for the\n.Fa wait_limit\nargument, you should use CK_RWCOHORT_STRATEGY_DEFAULT_LOCAL_WAIT_LIMIT.\n.Sh SEE ALSO\n.Xr ck_rwcohort 3 ,\n.Xr CK_RWCOHORT_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_LOCK 3 ,\n.Xr CK_RWCOHORT_UNLOCK 3 ,\n.Xr CK_RWCOHORT_LOCKED 3 ,\n.Xr CK_RWCOHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_INSTANCE",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_INSTANCE 3\n.Sh NAME\n.Nm CK_RWCOHORT_INSTANCE\n.Nd declare an instance of a cohort-based reader-writer lock type\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_RWCOHORT_NEUTRAL_INSTANCE \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_RP_INSTANCE \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_WP_INSTANCE \"COHORT_NAME cohort_name\"\n.Sh DESCRIPTION\nThe user must use this macro to declare instances of lock types that they have\ndefined using the\n.Xr CK_RWCOHORT_PROTOTYPE 3\nmacro.  The cohort_name must be the same as the one used in the prototype macro.\nFor instance, if CK_RWCOHORT_PROTOTYPE was called with the name \"foo\", the\nCK_RWCOHORT_INSTANCE macro should be called as\n.br\nCK_RWCOHORT_INSTANCE(foo) cohort;\n.Pp\nThis macro should also be used when allocating memory for cohorts.  For instance,\nto allocate a block of 4 cohorts:\n.br\nCK_RWCOHORT_WP_INSTANCE(foo) *cohorts = malloc(4 * sizeof(CK_RWCOHORT_WP_INSTANCE(foo)));\n.Sh SEE ALSO\n.Xr ck_rwcohort 3 ,\n.Xr CK_RWCOHORT_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_LOCK 3 ,\n.Xr CK_RWCOHORT_UNLOCK 3 ,\n.Xr CK_RWCOHORT_LOCKED 3 ,\n.Xr CK_RWCOHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_PROTOTYPE",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_PROTOTYPE 3\n.Sh NAME\n.Nm CK_RWCOHORT_PROTOTYPE\n.Nd define reader-writer cohort-based lock using the specified cohort type\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rwcohort.h\n.Fn CK_RWCOHORT_NEUTRAL_PROTOTYPE \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_RP_PROTOTYPE \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_WP_PROTOTYPE \"COHORT_NAME cohort_name\"\n.Sh DESCRIPTION\nThe ck_rwcohort.h header file does not define any cohort types.  Instead, the user must use\nthe CK_RWCOHORT_PROTOTYPE macro to define any types they want to use.\nThis macro takes a single argument which corresponds to the type of the cohort lock that\nthe reader-writer lock should use.  A cohort type must have already been defined with that name\nusing the\n.Xr CK_COHORT_PROTOTYPE 3\nor\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3\nmacros.\n.Pp\nInstances of the defined lock type can be declared as:\n.br\n    CK_RWCOHORT_INSTANCE(cohort_name) lock;\n.Sh SEE ALSO\n.Xr ck_rwcohort 3 ,\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_INIT 3 ,\n.Xr CK_RWCOHORT_READ_LOCK 3 ,\n.Xr CK_RWCOHORT_READ_UNLOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_LOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_UNLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_READ_LOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_READ_LOCK 3\n.Sh NAME\n.Nm CK_RWCOHORT_READ_LOCK\n.Nd acquire read-only permission for cohort-based reader-writer lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_RWCOHORT_NEUTRAL_READ_LOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_RP_READ_LOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_WP_READ_LOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Sh DESCRIPTION\nThis call will acquire read-only permission from\n.Fa lock .\nThe call will block until this permission has been acquired.\n.Fa cohort\nmust point to a cohort whose global lock is the same as all other cohorts used with\n.Fa lock .\nThe\n.Fa global_context\nand\n.Fa local_context\narguments will be passed along as the context arguments to any calls to\n.Fa cohort .\n.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_RWCOHORT_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_INIT 3 ,\n.Xr CK_RWCOHORT_READ_UNLOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_LOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_UNLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_READ_UNLOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_READ_UNLOCK 3\n.Sh NAME\n.Nm CK_RWCOHORT_READ_UNLOCK\n.Nd relinquish read-only access to cohort-based reader-writer lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_RWCOHORT_NEUTRAL_READ_UNLOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_RP_READ_UNLOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_WP_READ_UNLOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Sh DESCRIPTION\nThis call will relinquish read-only permission to\n.Fa lock .\n.Fa cohort\nmust point to a cohort whose global lock is the same as all other cohorts used with\n.Fa lock .\nThe\n.Fa global_context\nand\n.Fa local_context\narguments will be passed along as the context arguments to any calls to\n.Fa cohort .\n.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_RWCOHORT_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_INIT 3 ,\n.Xr CK_RWCOHORT_READ_LOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_LOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_UNLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_WRITE_LOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_WRITE_LOCK 3\n.Sh NAME\n.Nm CK_RWCOHORT_WRITE_LOCK\n.Nd acquite write access for a cohort-based reader-writer lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_RWCOHORT_NEUTRAL_WRITE_LOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_RP_WRITE_LOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_WP_WRITE_LOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Sh DESCRIPTION\nThis call will acquire write permission for\n.Fa lock .\nThe call will block until this permission has been acquired.\n.Fa cohort\nmust point to a cohort whose global lock is the same as all other cohorts used with\n.Fa lock .\nThe\n.Fa global_context\nand\n.Fa local_context\narguments will be passed along as the context arguments to any calls to\n.Fa cohort .\n.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_RWCOHORT_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_INIT 3 ,\n.Xr CK_RWCOHORT_READ_LOCK 3 ,\n.Xr CK_RWCOHORT_READ_UNLOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_UNLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/CK_RWCOHORT_WRITE_UNLOCK",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt CK_RWCOHORT_WRITE_UNLOCK 3\n.Sh NAME\n.Nm CK_RWCOHORT_WRITE_UNLOCK\n.Nd relinquish write access for cohort-based reader-writer lock\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_RWCOHORT_NEUTRAL_WRITE_UNLOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_RP_WRITE_UNLOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_WP_WRITE_UNLOCK \"COHORT_NAME cohort_name\" \"LOCK *lock\" \"COHORT *cohort\"\\\n\"void *global_context\" \"void *local_context\"\n.Sh DESCRIPTION\nThis call will relinquish write permission for\n.Fa lock .\n.Fa cohort\nmust point to a cohort whose global lock is the same as all other cohorts used with\n.Fa lock .\nThe\n.Fa global_context\nand\n.Fa local_context\narguments will be passed along as the context arguments to any calls to\n.Fa cohort .\n.\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr CK_RWCOHORT_PROTOTYPE 3 ,\n.Xr CK_RWCOHORT_INSTANCE 3 ,\n.Xr CK_RWCOHORT_INITIALIZER 3 ,\n.Xr CK_RWCOHORT_INIT 3 ,\n.Xr CK_RWCOHORT_READ_LOCK 3 ,\n.Xr CK_RWCOHORT_READ_UNLOCK 3 ,\n.Xr CK_RWCOHORT_WRITE_LOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_buffer",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_BUFFER 3\n.Sh NAME\n.Nm ck_array_buffer\n.Nd return length and pointer to array of reader-visible pointers\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft void *\n.Fn ck_array_buffer \"ck_array_t *array\" \"unsigned int *length\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_buffer 3\nreturns a pointer to the array of pointers currently visible\nto readers after the last commit operation in\n.Fa array .\nThe unsigned integer pointed to by\n.Fa length\nis updated to reflect the length of the array.\n.Sh RETURN VALUES\nThis function returns a pointer to an array of pointers.\n.Sh SEE ALSO\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_init 3\n.Xr ck_array_deinit 3 ,\n.Xr ck_array_length 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_commit",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_COMMIT 3\n.Sh NAME\n.Nm ck_array_commit\n.Nd linearization point for mutations before commit call\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft bool\n.Fn ck_array_commit \"ck_array_t *array\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_commit 3\nfunction will commit any pending put or remove operations associated\nwith the array. The function may end up requesting the safe reclamation\nof memory actively being iterated upon by other threads.\n.Sh RETURN VALUES\nThis function returns true if the commit operation succeeded. It will\nreturn false otherwise, and pending operations will not be applied.\n.Sh SEE ALSO\n.Xr ck_array_init 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_deinit 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_deinit",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_DEINIT 3\n.Sh NAME\n.Nm ck_array_deinit\n.Nd destroy and deinitialize a pointer array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft void\n.Fn ck_array_deinit \"ck_array_t *array\" \"bool defer\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_deinit 3\ndestroys the memory associated with the array pointed\nto by\n.Fa array .\nThe\n.Fa defer\nargument is true if the allocator must destroy\nthe memory using safe memory reclamation or false\nif the allocator can destroy this memory immediately.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_init 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_INIT 3\n.Sh NAME\n.Nm ck_array_init\n.Nd initialize a pointer array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft bool\n.Fn ck_array_init \"ck_array_t *array\" \"unsigned int mode\" \"struct ck_malloc *allocator\" \"unsigned int initial_length\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_init 3\nfunction initializes the array pointed to by the argument\n.Fa array .\nThe mode value must be\n.Dv CK_ARRAY_MODE_SPMC .\nThe\n.Fa allocator\nargument must point to a ck_malloc data structure with valid non-NULL function pointers\ninitialized for malloc, free and realloc. The\n.Fa initial_length\nspecifies the initial length of the array. The value of\n.Fa initial_length\nmust be greater than or equal to 2. An array allows for one concurrent put or remove operations\nin the presence of any number of concurrent CK_ARRAY_FOREACH operations.\n.Sh RETURN VALUES\nThis function returns true if the array was successfully created. It returns\nfalse if the creation failed. Failure may occur due to internal memory allocation\nfailures or invalid arguments.\n.Sh SEE ALSO\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_deinit 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_initialized",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_INITIALIZED 3\n.Sh NAME\n.Nm ck_array_initialized\n.Nd indicates whether an array was recently initialized or deinitialized\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft bool\n.Fn ck_array_initialized \"ck_array_t *array\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_initialized 3\ncan be used to determine whether an array was recently initialized\nwith\n.Fn ck_array_init 3\nor deinitialized with\n.Fn ck_array_deinit 3 .\nBehavior is undefined if a user allocates internal allocator data\nin through other means.\n.Sh RETURN VALUES\nThis function returns true if the array is initialized, and false\notherwise.\n.Sh SEE ALSO\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_init 3\n.Xr ck_array_deinit 3 ,\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_length",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_LENGTH 3\n.Sh NAME\n.Nm ck_array_length\n.Nd returns the number of pointers committed to an array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft unsigned int\n.Fn ck_array_length \"ck_array_t *array\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_length 3\nfunction returns the number of items a concurrent\ntraversal operation would encounter at completion\ntime.\n.Sh RETURN VALUES\nThe number of traversal-visible pointers is returned.\n.Sh SEE ALSO\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_init 3\n.Xr ck_array_deinit 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_put",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_PUT 3\n.Sh NAME\n.Nm ck_array_put\n.Nd attempt immediate or deferred insertion of a pointer into array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft bool\n.Fn ck_array_put \"ck_array_t *array\" \"void *pointer\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_put 3\nfunction will attempt to insert the value of\n.Fa pointer\ninto the array pointed to by\n.Fa array .\nThis function may incur additional memory allocations\nif not enough memory has been allocated in the array\nfor a new entry. The operation is also free to apply\nthe operation immediately if there is an opportunity\nfor elimination with a pending (uncommitted) remove\noperation.\n.Sh RETURN VALUES\nThis function returns true if the put operation succeeded. It will\nreturn false otherwise due to internal allocation failures.\n.Sh SEE ALSO\n.Xr ck_array_init 3 ,\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_deinit 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_put_unique",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_PUT_UNIQUE 3\n.Sh NAME\n.Nm ck_array_put_unique\n.Nd attempt immediate or deferred insertion of a unique pointer into array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft int\n.Fn ck_array_put_unique \"ck_array_t *array\" \"void *pointer\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_put_unique 3\nfunction will attempt to insert the value of\n.Fa pointer\ninto the array pointed to by\n.Fa array .\nThis function may incur additional memory allocations\nif not enough memory has been allocated in the array\nfor a new entry. The operation is also free to apply\nthe operation immediately if there is an opportunity\nfor elimination with a pending (uncommitted) remove\noperation. The function will not make any modifications\nif the pointer already exists in the array.\n.Sh RETURN VALUES\nThis function returns 1 if the pointer already exists in the array.\nIt returns 0 if the put operation succeeded. It returns -1 on\nerror due to internal memory allocation failures.\n.Sh SEE ALSO\n.Xr ck_array_init 3 ,\n.Xr ck_array_commit 3 ,\n.Xr ck_array_put 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_deinit 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_array_remove",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd October 18, 2013\n.Dt CK_ARRAY_REMOVE 3\n.Sh NAME\n.Nm ck_array_remove\n.Nd attempt immediate or deferred removal of a pointer from an array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_array.h\n.Ft bool\n.Fn ck_array_remove \"ck_array_t *array\" \"void *pointer\"\n.Sh DESCRIPTION\nThe\n.Fn ck_array_remove 3\nfunction will attempt to remove the value of\n.Fa pointer\ninto the array pointed to by\n.Fa array . The operation is also free to apply\nthe operation immediately if there is an opportunity\nfor elimination with a pending (uncommitted) put\noperation. If no elimination was possible, the function\nmay require to allocate more memory.\n.Sh RETURN VALUES\nThis function returns true if the remove operation succeeded. It will\nreturn false otherwise due to internal allocation failures or because\nthe value did not exist.\n.Sh SEE ALSO\n.Xr ck_array_init 3 ,\n.Xr ck_array_commit 3 ,\n.Xr ck_array_remove 3 ,\n.Xr ck_array_put_unique 3 ,\n.Xr ck_array_deinit 3\n.Xr ck_array_length 3 ,\n.Xr ck_array_buffer 3 ,\n.Xr ck_array_initialized 3 ,\n.Xr CK_ARRAY_FOREACH 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_base",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_BASE 3\n.Sh NAME\n.Nm ck_bitmap_base\n.Nd determine the size of a bit array in bytes\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft unsigned int\n.Fn ck_bitmap_base \"unsigned int n_bits\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_base\nfunction returns the number of bytes that would be used\nto store the number of bits specified by\n.Fa n_bits .\n.Sh RETURN VALUES\nThis function returns a non-zero value that is guaranteed to\nbe a multiple of\n.Dv sizeof(CK_BITMAP_WORD) .\n.Sh SEE ALSO\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_bits",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_BITS 3\n.Sh NAME\n.Nm ck_bitmap_bits\n.Nd return number of addressable bits in bitmap\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft unsigned int\n.Fn ck_bitmap_bits \"ck_bitmap_t *bitmap\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_bits\nfunction returns the maximum number of addressable bits in\nthe object pointed to by\n.Fa bitmap .\n.Sh RETURN VALUES\nThis function returns a non-zero value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_bts",
    "content": ".\\\"\n.\\\" Copyright 2014 David Joseph.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd August 22, 2014\n.Dt CK_BITMAP_BTS 3\n.Sh NAME\n.Nm ck_bitmap_bts\n.Nd set the bit at the specified index and fetch its original value\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft bool\n.Fn ck_bitmap_bts \"ck_bitmap_t *bitmap\" \"unsigned int n\"\n.Sh DESCRIPTION\n.Fn ck_bitmap_bts\nsets the bit at the offset specified by the argument\n.Fa n\nto\n.Dv 1\nand fetches its original value.\n.Sh RETURN VALUES\nThis function returns the original value of the bit at offset\n.Fa n\nin\n.Fa bitmap .\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_buffer",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_BUFFER 3\n.Sh NAME\n.Nm ck_bitmap_buffer\n.Nd returns pointer to bit array\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft void *\n.Fn ck_bitmap_buffer \"ck_bitmap_t *bitmap\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_buffer\nfunctions returns a pointer to the actual bit array.\nFor ck_bitmap pointers, the bit array is of type\nCK_BITMAP_WORD[] and consists of\nck_bitmap_base(bitmap) / sizeof(CK_BITMAP_WORD) elements.\nOn currently supported 64-bit platforms\n.Dv CK_BITMAP_WORD\nis\n.Dv uint64_t .\nOn currently supported 32-bit platforms\n.Dv CK_BITMAP_WORD\nis\n.Dv uint32_t .\n.Sh RETURN VALUES\nThis function returns a non-NULL value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_bits 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_clear",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_CLEAR 3\n.Sh NAME\n.Nm ck_bitmap_clear\n.Nd reset all bits\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft void\n.Fn ck_bitmap_clear \"ck_bitmap_t *bitmap\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_clear\nfunction sets all bits in the bitmap pointed to by\n.Fa bitmap\nto 0.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_INIT 3\n.Sh NAME\n.Nm ck_bitmap_init\n.Nd initialize a bitmap\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft void\n.Fn ck_bitmap_init \"ck_bitmap_t *bitmap\" \"unsigned int n_bits\" \"bool set\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_init\nfunction initializes the bitmap pointed to by the\n.Fa bitmap\npointer. The argument\n.Fa n_bits\nspecifies the number of bits that are to be stored in the bitmap.\nThe argument\n.Fa set\ndetermines whether the values of the bits in\n.Fa bitmap\nare to be initialized to\n.Dv 1\nor\n.Dv 0 .\n.Pp\nIt is expected that\n.Fa bitmap\npoints to a contiguous region of memory containing at least\nthe number of bytes specified by\n.Xr ck_bitmap_size 3 .\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\n.Bl -tag -width Er\n.Pp\nThe behavior of\n.Fn ck_bitmap_init\nis undefined if\n.Fa bitmap\nis not a pointer to a region of bytes\nof at least\n.Xr ck_bitmap_size 3\nlength.\n.El\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_iterator_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" Copyright 2012-2013 Shreyas Prasad.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 27, 2012\n.Dt CK_BITMAP_ITERATOR_INIT 3\n.Sh NAME\n.Nm ck_bitmap_iterator_init\n.Nd initialize bitmap iterator\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Pp\n.Ft void\n.Fn ck_bitmap_iterator_init \"ck_bitmap_iterator_t *iterator\" \"ck_bitmap_t *bitmap\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_iterator_init\nfunction will initialize the object pointed to by\nthe\n.Fa iterator\nargument for use with\n.Fa bitmap .\n.Pp\nAn iterator is used to iterate through set bitmap bits\nwith the\n.Xr ck_bitmap_next 3\nfunction.\n.Sh RETURN VALUES\nThe\n.Fn ck_bitmap_iterator_init\nfunction does not return a value.\n.Sh ERRORS\nThis function will not fail.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3 ,\n.Xr ck_bitmap_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_next",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" Copyright 2012-2013 Shreyas Prasad.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 27, 2012\n.Dt CK_BITMAP_TEST 3\n.Sh NAME\n.Nm ck_bitmap_next\n.Nd iterate to the next set bit in bitmap\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft bool\n.Fn ck_bitmap_next \"ck_bitmap_t *bitmap\" \"ck_bitmap_iterator_t iterator\" \"unsigned int *bit\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_next\nfunction will increment the iterator object pointed to by\n.Fa iterator\nto point to the next set bit in the bitmap. If\n.Fn ck_bitmap_next\nreturns\n.Dv true\nthen the pointer pointed to by\n.Fa bit\nis initialized to the number of the current set bit pointed to by the\n.Fa iterator\nobject.\n.Pp\nIt is expected that\n.Fa iterator\nhas been initialized using the\n.Xr ck_bitmap_iterator_init 3\nfunction.\n.Sh RETURN VALUES\nIf\n.Fn ck_bitmap_next\nreturns\n.Dv true\nthen the object pointed to by\n.Fa bit\ncontains a set bit. If\n.Fn ck_bitmap_next\nreturns\n.Dv false\nthen value of the object pointed to by\n.Fa bit\nis undefined.\n.Sh ERRORS\nBehavior is undefined if\n.Fa iterator\nor\n.Fa bitmap\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3 ,\n.Xr ck_bitmap_iterator_init 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_reset",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_RESET 3\n.Sh NAME\n.Nm ck_bitmap_reset\n.Nd resets the bit at the specified index\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft void\n.Fn ck_bitmap_reset \"ck_bitmap_t *bitmap\" \"unsigned int n\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_reset\nresets the bit at offset specified by the argument\n.Fa n\nto\n.Dv 0 .\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_set",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_SET 3\n.Sh NAME\n.Nm ck_bitmap_set\n.Nd set the bit at the specified index\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft void\n.Fn ck_bitmap_set \"ck_bitmap_t *bitmap\" \"unsigned int n\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_set\nsets the bit at offset specified by the argument\n.Fa n\nto\n.Dv 1 .\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_size",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_SIZE 3\n.Sh NAME\n.Nm ck_bitmap_size\n.Nd returns necessary number of bytes for bitmap\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft unsigned int\n.Fn ck_bitmap_size \"unsigned int n_bits\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_size\nfunction returns the number of bytes that are necessary\nto allocate for a bitmap that will contain the number\nof bits specified by\n.Fa n_bits .\n.Pp\nThis function is used to determine how many bytes to\nallocate for dynamically created bitmap objects. The\nallocated object must still be initialized using\n.Xr ck_bitmap_init 3 .\n.Sh RETURN VALUES\nThis function returns a non-zero value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set_mpmc 3 ,\n.Xr ck_bitmap_reset_mpmc 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_test",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2012\n.Dt CK_BITMAP_TEST 3\n.Sh NAME\n.Nm ck_bitmap_test\n.Nd determine if the bit at the specified index is set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft bool\n.Fn ck_bitmap_test \"ck_bitmap_t *bitmap\" \"unsigned int n\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_test\ndetermines if the bit at the offset specified by the argument\n.Fa n\nis set to\n.Dv 1 .\n.Sh RETURN VALUES\nThis function returns\n.Dv true\nif the bit at the specified offset is set to\n.Dv 1\nand otherwise returns\n.Dv false .\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_set_mpmc 3 ,\n.Xr ck_bitmap_reset_mpmc 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_bitmap_union",
    "content": ".\\\"\n.\\\" Copyright 2012-2014 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 23, 2013\n.Dt CK_BITMAP_UNION 3\n.Sh NAME\n.Nm ck_bitmap_union\n.Nd generates union of two bitmaps\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_bitmap.h\n.Ft void\n.Fn ck_bitmap_union \"ck_bitmap_t *dst\" \"ck_bitmap_t *src\"\n.Sh DESCRIPTION\nThe\n.Fn ck_bitmap_union\nfunction sets all bits in the bitmap pointed to by\n.Fa src\nin the bitmap pointed to by\n.Fa dst .\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_bitmap_base 3 ,\n.Xr ck_bitmap_size 3 ,\n.Xr ck_bitmap_init 3 ,\n.Xr ck_bitmap_reset 3 ,\n.Xr ck_bitmap_set 3 ,\n.Xr ck_bitmap_clear 3 ,\n.Xr ck_bitmap_test 3 ,\n.Xr ck_bitmap_bits 3 ,\n.Xr ck_bitmap_buffer 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_brlock",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 26, 2013.\n.Dt ck_brlock 3\n.Sh NAME\n.Nm ck_brlock_init ,\n.Nm ck_brlock_write_lock ,\n.Nm ck_brlock_write_unlock ,\n.Nm ck_brlock_write_trylock ,\n.Nm ck_brlock_read_register ,\n.Nm ck_brlock_read_unregister ,\n.Nm ck_brlock_read_lock ,\n.Nm ck_brlock_read_trylock ,\n.Nm ck_brlock_read_unlock\n.Nd big-reader locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_brlock.h\n.Pp\n.Dv ck_brlock_t brlock = CK_BRLOCK_INITIALIZER;\n.Pp\n.Dv ck_brlock_reader_t reader = CK_BRLOCK_READER_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_brlock_init \"ck_brlock_t *br\"\n.Ft void\n.Fn ck_brlock_write_lock \"ck_brlock_t *br\"\n.Ft void\n.Fn ck_brlock_write_unlock \"ck_brlock_t *br\"\n.Ft bool\n.Fn ck_brlock_write_trylock \"ck_brlock_t *br\" \"unsigned int factor\"\n.Ft void\n.Fn ck_brlock_read_register \"ck_brlock_t *br\" \"ck_brlock_reader_t *reader\"\n.Ft void\n.Fn ck_brlock_read_unregister \"ck_brlock_t *br\" \"ck_brlock_reader_t *reader\"\n.Ft void\n.Fn ck_brlock_read_lock \"ck_brlock_t *br\" \"ck_brlock_reader_t *reader\"\n.Ft bool\n.Fn ck_brlock_read_trylock \"ck_brlock_t *br\" \"ck_brlock_reader_t *reader\" \\\n\"unsigned int factor\"\n.Ft void\n.Fn ck_brlock_read_unlock \"ck_brlock_reader_t *reader\"\n.Sh DESCRIPTION\nBig reader locks are distributed reader-writer locks with low latency constant time\nreader acquisition (with respect to number of concurrent readers). On the other\nhand, writer acquisitions are a relatively expensive O(n) operation. This is a write-biased\nlock.\n.Sh EXAMPLE\n.Bd -literal -offset indent\nstatic ck_brlock_t lock = CK_BRLOCK_INITIALIZER;\nstatic __thread ck_brlock_reader_t reader;\n\nstatic void\nreader(void)\n{\n\n\t/* Add our thread as a lock participant. */\n\tck_brlock_read_register(&lock, &reader);\n\n\tfor (;;) {\n\t\tck_brlock_read_lock(&lock, &reader);\n\t\t/* Read-side critical section. */\n\t\tck_brlock_read_unlock(&reader);\n\n\t\tif (ck_brlock_read_trylock(&lock, &reader, 1) == true) {\n\t\t\t/* Read-side critical section. */\n\t\t\tck_brlock_read_unlock(&reader);\n\t\t}\n\t}\n\n\treturn;\n}\n\nstatic void\nwriter(void)\n{\n\n\tfor (;;) {\n\t\tck_brlock_write_lock(&lock);\n\t\t/* Write-side critical section. */\n\t\tck_brlock_write_unlock(&lock);\n\n\t\tif (ck_brlock_write_trylock(&lock, 1) == true) {\n\t\t\t/* Write-side critical section. */\n\t\t\tck_brlock_write_unlock(&lock);\n\t\t}\n\t}\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_bytelock 3 ,\n.Xr ck_rwlock 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_cohort",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd February 24, 2013.\n.Dt ck_cohort 3\n.Sh NAME\n.Nm ck_cohort\n.Nd generalized interface for lock cohorts\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_cohort.h\n.Fn CK_COHORT_PROTOTYPE \"COHORT_NAME cohort_name\" \"LOCK_FXN global_lock_method\" \\\n\"LOCK_FXN global_unlock_method\" \"LOCK_FXN local_lock_method\" \"LOCK_FXN local_unlock_method\"\n.Fn CK_COHORT_TRYLOCK_PROTOTYPE \"COHORT_NAME cohort_name\" \\\n\"LOCK_FXN global_lock_method\" \"LOCK_FXN global_unlock_method\" \\\n\"BOOL_LOCK_FXN global_locked_method\" \"BOOL_LOCK_FXN global_trylock_method\" \\\n\"LOCK_FXN local_lock_method\" \"LOCK_FXN local_unlock_method\" \\\n\"BOOL_LOCK_FXN local_locked_method\" \"BOOL_LOCK_FXN local_trylock_method\"\n.Fn CK_COHORT_INSTANCE \"COHORT_NAME cohort_name\"\n.Fn CK_COHORT_INIT \"COHORT_NAME cohort_name\" \"ck_cohort *cohort\" \\\n\"void *global_lock\" \"void *local_lock\" \"unsigned int pass_limit\"\n.Fn CK_COHORT_LOCK \"COHORT_NAME cohort_name\" \"ck_cohort *cohort\" \\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_COHORT_UNLOCK \"COHORT_NAME cohort_name\" \"ck_cohort *cohort\" \\\n\"void *global_context\" \"void *local_context\"\n.Pp\nWhere LOCK_FXN refers to a method with the signature\n.br\nvoid(void *lock, void *context)\n.br\nBOOL_LOCK_FXN refers to a method with the signature\n.br\nbool(void *lock, void *context)\n.Pp\nThe\n.Fa context\nargument in each signature is used to pass along any additional information that\nthe lock might need for its lock, unlock and trylock methods.  The values for this\nargument are provided to each call to\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\nand\n.Xr CK_COHORT_TRYLOCK 3\n.\n.Sh DESCRIPTION\nck_cohort.h provides an interface for defining lock cohorts with\narbitrary lock types.  Cohorts are a mechanism for coordinating\nthreads on NUMA architectures in order to reduce the frequency\nwith which a lock is passed between threads on different clusters.\n.Pp\nBefore using a cohort, the user must define a cohort type using\neither the\n.Fn CK_COHORT_PROTOTYPE\nor the\n.Fn CK_COHORT_TRYLOCK_PROTOTYPE\nmacros.  These macros allow the user to specify the lock methods that\nthey would like the cohort to use.  See the\n.Xr CK_COHORT_PROTOTYPE 3\nand\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3\nman pages for more details.\n.Pp\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <stdlib.h>\n#include <pthread.h>\n\n#include <ck_pr.h>\n#include <ck_cohort.h>\n#include <ck_spinlock.h>\n\n/*\n * Create cohort methods with signatures that match\n * the required signature\n */\nstatic void\nck_spinlock_lock_with_context(ck_spinlock_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_lock(lock);\n\treturn;\n}\n\nstatic void\nck_spinlock_unlock_with_context(ck_spinlock_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_unlock(lock);\n\treturn;\n}\n\nstatic bool\nck_spinlock_locked_with_context(ck_spinlock_t *lock, void *context)\n{\n\t(void)context;\n\treturn ck_spinlock_locked(lock);\n}\n\n/*\n * define a cohort type named \"test_cohort\" that will use\n * the above methods for both its global and local locks\n */\nCK_COHORT_PROTOTYPE(test_cohort,\n\tck_spinlock_lock_with_context, ck_spinlock_unlock_with_context, ck_spinlock_locked_with_context,\n\tck_spinlock_lock_with_context, ck_spinlock_unlock_with_context, ck_spinlock_locked_with_context)\n\nstatic ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;\nstatic unsigned int ready;\n\nstatic void *\nfunction(void *context)\n{\n\tCK_COHORT_INSTANCE(test_cohort) *cohort = context;\n\n\twhile (ready == 0);\n\n\twhile (ready > 0) {\n\t\t/*\n\t\t * acquire the cohort lock before performing critical section.\n\t\t * note that we pass NULL for both the global and local context\n\t\t * arguments because neither the lock nor unlock functions\n\t\t * will use them.\n\t\t */\n\t\tCK_COHORT_LOCK(test_cohort, cohort, NULL, NULL);\n\n\t\t/* perform critical section */\n\n\t\t/* relinquish cohort lock */\n\t\tCK_COHORT_UNLOCK(test_cohort, cohort, NULL, NULL);\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(void)\n{\n\tunsigned int nthr = 4;\n\tunsigned int n_cohorts = 2;\n\tunsigned int i;\n\n\t/* allocate 2 cohorts of the defined type */\n\tCK_COHORT_INSTANCE(test_cohort) *cohorts =\n\t    calloc(n_cohorts, sizeof(CK_COHORT_INSTANCE(test_cohort)));\n\n\t/* create local locks to use with each cohort */\n\tck_spinlock_t *local_locks =\n\t\tcalloc(n_cohorts, sizeof(ck_spinlock_t));\n\n\tpthread_t *threads =\n\t\tcalloc(nthr, sizeof(pthread_t));\n\n\t/* initialize each of the cohorts before using them */\n\tfor (i = 0 ; i < n_cohorts ; ++i) {\n\t\tCK_COHORT_INIT(test_cohort, cohorts + i, &global_lock, local_locks + i,\n\t\t\tCK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\t}\n\n\t/* start each thread and assign cohorts equally */\n\tfor (i = 0 ; i < nthr ; ++i) {\n\t\tpthread_create(threads + i, NULL, function, cohorts + (i % n_cohorts));\n\t}\n\n\tck_pr_store_uint(&ready, 1);\n\tsleep(10);\n\tck_pr_store_uint(&ready, 0);\n\n\tfor (i = 0 ; i < nthr ; ++i) {\n\t\tpthread_join(threads[i], NULL);\n\t}\n\n\treturn 0;\n}\n.Ed\n.Sh SEE ALSO\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_elide",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 13, 2013.\n.Dt ck_elide 3\n.Sh NAME\n.Nm CK_ELIDE_PROTOTYPE ,\n.Nm CK_ELIDE_LOCK_ADAPTIVE ,\n.Nm CK_ELIDE_UNLOCK_ADAPTIVE ,\n.Nm CK_ELIDE_LOCK ,\n.Nm CK_ELIDE_UNLOCK ,\n.Nm CK_ELIDE_TRYLOCK_PROTOTYPE ,\n.Nm CK_ELIDE_TRYLOCK\n.Nd lock elision wrappers\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_elide.h\n.Pp\n.Dv ck_elide_stat_t stat = CK_ELIDE_STAT_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_elide_stat_init \"ck_elide_stat_t *\"\n.Pp\n.Dv struct ck_elide_config config = CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;\n.Pp\n.Bd -literal -offset\nstruct ck_elide_config {\n\tunsigned short skip_busy;\n\tshort retry_busy;\n\tunsigned short skip_other;\n\tshort retry_other;\n\tunsigned short skip_conflict;\n\tshort retry_conflict;\n};\n.Ed\n.Pp\n.Fn CK_ELIDE_PROTOTYPE \"NAME\" \"TYPE\" \"LOCK_PREDICATE\" \"LOCK_FUNCTION\" \"UNLOCK_PREDICATE\" \"UNLOCK_FUNCTION\"\n.Fn CK_ELIDE_LOCK_ADAPTIVE \"NAME\" \"ck_elide_stat_t *\" \"struct ck_elide_config *\" \"TYPE *\"\n.Fn CK_ELIDE_UNLOCK_ADAPTIVE \"NAME\" \"ck_elide_stat_t *\" \"TYPE *\"\n.Fn CK_ELIDE_LOCK \"NAME\" \"TYPE *\"\n.Fn CK_ELIDE_UNLOCK \"NAME\" \"TYPE *\"\n.Fn CK_ELIDE_TRYLOCK_PROTOTYPE \"NAME\" \"TYPE\" \"LOCK_PREDICATE\" \"TRYLOCK_FUNCTION\"\n.Sh DESCRIPTION\nThese macros implement lock elision wrappers for a user-specified single-argument\nlock interface. The wrappers will attempt to elide lock acquisition, allowing\nconcurrent execution of critical sections that do not issue conflicting memory\noperations. If any threads have successfully elided a lock acquisition,\nconflicting memory operations will roll-back any side-effects of the critical\nsection and force every thread to retry the lock acquisition regularly.\n.Pp\n.Fn CK_ELIDE_LOCK ,\n.Fn CK_ELIDE_UNLOCK ,\n.Fn CK_ELIDE_LOCK_ADAPTIVE ,\nand\n.Fn CK_ELIDE_UNLOCK_ADAPTIVE\nmacros require\na previous\n.Fn CK_ELIDE_PROTOTYPE\nwith the same\n.Fa NAME .\nElision is attempted if the\n.Fa LOCK_PREDICATE\nfunction returns false. If\n.Fa LOCK_PREDICATE\nreturns true then elision is aborted and\n.Fa LOCK_FUNCTION\nis executed instead. If any threads are in an elided critical section,\n.Fa LOCK_FUNCTION\nmust force them to rollback through a conflicting memory operation.\nThe\n.Fa UNLOCK_PREDICATE\nfunction must return true if the lock is acquired by the caller, meaning\nthat the lock was not successfully elided. If\n.Fa UNLOCK_PREDICATE\nreturns true, then the\n.Fa UNLOCK_FUNCTION\nis executed. If RTM is unsupported (no CK_F_PR_RTM macro) then\n.Fn CK_ELIDE_LOCK\nand\n.Fn CK_ELIDE_LOCK_ADAPTIVE\nwill immediately call\n.Fn LOCK_FUNCTION .\n.Fn CK_ELIDE_UNLOCK\nand\n.Fn CK_ELIDE_UNLOCK_ADAPTIVE\nwill immediately call\n.Fn UNLOCK_FUNCTION .\n.Pp\n.Fn CK_ELIDE_TRYLOCK\nrequires a previous\n.Fn CK_ELIDE_TRYLOCK_PROTOTYPE\nwith the same name.\nElision is attempted if the\n.Fa LOCK_PREDICATE\nfunction returns false. If\n.Fa LOCK_PREDICATE\nreturns true or if elision fails then the\noperation is aborted. If RTM is unsupported\n(no CK_F_PR_RTM macro) then\n.Fn CK_ELIDE_TRYLOCK\nwill immediately call\n.Fn TRYLOCK_FUNCTION .\n.Pp\n.Fn CK_ELIDE_LOCK_ADAPTIVE\nand\n.Fn CK_ELIDE_UNLOCK_ADAPTIVE\nwill adapt the elision behavior associated with lock operations\naccording to the run-time behavior of the program. This behavior\nis defined by the ck_elide_config structure pointer passed to\n.Fn CK_ELIDE_LOCK_ADAPTIVE .\nA thread-local ck_elide_stat structure must be passed to both\n.Fn CK_ELIDE_LOCK_ADAPTIVE\nand\n.Fn CK_ELIDE_UNLOCK_ADAPTIVE .\nThis structure is expected to be unique for different workloads,\nmay not be re-used in recursive acquisitions and must match the\nlifetime of the lock it is associated with. It is safe to mix\nadaptive calls with best-effort calls.\n.Pp\nBoth ck_spinlock.h and ck_rwlock.h define ck_elide wrappers under\nthe ck_spinlock and ck_rwlock namespace, respectively.\n.Sh EXAMPLES\nThis example utilizes built-in lock elision facilities in ck_rwlock and ck_spinlock.\n.Bd -literal -offset indent\n#include <ck_rwlock.h>\n#include <ck_spinlock.h>\n\nstatic ck_rwlock_t rw = CK_RWLOCK_INITIALIZER;\nstatic struct ck_elide_config rw_config =\n    CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;\nstatic __thread ck_elide_stat_t rw_stat =\n    CK_ELIDE_STAT_INITIALIZER;\n\nstatic ck_spinlock_t spinlock = CK_SPINLOCK_INITIALIZER;\nstatic struct ck_elide_config spinlock_config =\n    CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;\nstatic __thread ck_elide_stat_t spinlock_stat =\n    CK_ELIDE_STAT_INITIALIZER;\n\nvoid\nfunction(void)\n{\n\n\t/* Lock-unlock write-side lock in weak best-effort manner. */\n\tCK_ELIDE_LOCK(ck_rwlock_write, &rw);\n\tCK_ELIDE_UNLOCK(ck_rwlock_write, &rw);\n\n\t/* Attempt to acquire the write-side lock. */\n\tif (CK_ELIDE_TRYLOCK(ck_rwlock_write, &rw) == true)\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_write, &rw);\n\n\t/* Lock-unlock read-side lock in weak best-effort manner. */\n\tCK_ELIDE_LOCK(ck_rwlock_read, &rw);\n\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw);\n\n\t/* Attempt to acquire the read-side lock. */\n\tif (CK_ELIDE_TRYLOCK(ck_rwlock_read, &rw) == true)\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw);\n\n\t/* Lock-unlock write-side lock in an adaptive manner. */\n\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &rw_stat,\n\t    &rw_config, &rw);\n\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &rw_stat,\n\t    &rw_config, &rw);\n\n\t/* Lock-unlock read-side lock in an adaptive manner. */\n\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_read, &rw_stat,\n\t    &rw_config, &rw);\n\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_read, &rw_stat,\n\t    &rw_config, &rw);\n\n\t/* Lock-unlock spinlock in weak best-effort manner. */\n\tCK_ELIDE_LOCK(ck_spinlock, &spinlock);\n\tCK_ELIDE_UNLOCK(ck_spinlock, &spinlock);\n\n\t/* Attempt to acquire the lock. */\n\tif (CK_ELIDE_TRYLOCK(ck_spinlock, &lock) == true)\n\t\tCK_ELIDE_UNLOCK(ck_spinlock, &spinlock);\n\n\t/* Lock-unlock spinlock in an adaptive manner. */\n\tCK_ELIDE_LOCK_ADAPTIVE(ck_spinlock, &spinlock_stat,\n\t    &spinlock_config, &spinlock);\n\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_spinlock, &spinlock_stat,\n\t    &spinlock_config, &spinlock);\n}\n.Ed\n.Pp\nIn this example, user-defined locking functions are provided an elision\nimplementation.\n.Bd -literal -offset indent\n/* Assume lock_t has been previously defined. */\n#include <ck_elide.h>\n\n/*\n * This function returns true if the lock is unavailable at the time\n * it was called or false if the lock is available.\n */\nbool is_locked(lock_t *);\n\n/*\n * This function acquires the supplied lock.\n */\nvoid lock(lock_t *);\n\n/*\n * This function releases the lock.\n */\nvoid unlock(lock_t *);\n\nCK_ELIDE_PROTOTYPE(my_lock, lock_t, is_locked, lock, is_locked, unlock)\n\nstatic lock_t lock;\n\nvoid\nfunction(void)\n{\n\n\tCK_ELIDE_LOCK(my_lock, &lock);\n\tCK_ELIDE_UNLOCK(my_lock, &lock);\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_rwlock 3 ,\n.Xr ck_spinlock 3\n.Pp\nRavi Rajwar and James R. Goodman. 2001. Speculative lock elision: enabling highly concurrent multithreaded execution. In Proceedings of the 34th annual ACM/IEEE international symposium on Microarchitecture (MICRO 34). IEEE Computer Society, Washington, DC, USA, 294-305.\n.Pp\nAdditional information available at http://en.wikipedia.org/wiki/Transactional_Synchronization_Extensions and http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_barrier",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_BARRIER 3\n.Sh NAME\n.Nm ck_epoch_barrier\n.Nd block until a grace period and all callbacks have been dispatched\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_barrier \"ck_epoch_record_t *record\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_barrier 3\nfunction will block the caller until a grace period has been\ndetected, according to the semantics of epoch reclamation.\nAny objects requiring safe memory reclamation which are logically\ndeleted are safe for physical deletion following a call to\n.Fn ck_epoch_barrier 3 . This function will also dispatch all callbacks\nassociated with\n.Fa epoch\nthat were previously scheduled via\n.Fn ck_epoch_call 3 .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_epoch.h>\n#include <ck_stack.h>\n#include <stdlib.h>\n\n/*\n * epoch was previously initialized with ck_epoch_init.\n * stack was previously initialized with ck_stack_init.\n */\nck_epoch_t *epoch;\nck_stack_t *stack;\n\nvoid\nfunction(void)\n{\n\tck_epoch_record_t *record;\n\tck_stack_entry_t *s;\n\n\trecord = malloc(sizeof *record);\n\tck_epoch_register(&epoch, record);\n\n\t/*\n\t * We are using an epoch section here to guarantee no\n\t * nodes in the stack are deleted while we are dereferencing\n\t * them. This is needed here because there are multiple writers.\n\t * If there was only one thread popping from the this stack,\n\t * then there is no need to ck_epoch_begin/ck_epoch_end.\n\t */\n\tck_epoch_begin(record);\n\n\t/* Logically delete an object. */\n\ts = ck_stack_pop_upmc(stack);\n\n\tck_epoch_end(record);\n\n\t/*\n\t * Wait until no threads could possibly have a reference to the\n\t * object we just popped (assume all threads are simply executing\n\t * ck_stack_pop_upmc).\n\t */\n\tck_epoch_barrier(record);\n\n\t/* It is now safe to physically delete the object. */\n\tfree(s);\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\nBehavior is undefined if the object pointed to by\n.Fa epoch\nis not a valid epoch object. The object pointed to by\n.Fa record\nmust have been previously registered via\n.Fn ck_epoch_register 3 .\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_begin",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_BEGIN 3\n.Sh NAME\n.Nm ck_epoch_begin\n.Nd begin epoch-protected segment of execution\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_begin \"ck_epoch_record_t *record\" \"ck_epoch_section_t *section\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_begin 3\nfunction will mark the beginning of an epoch-protected code section.\nAn epoch-protected code section is delimited by a call to the\n.Fn ck_epoch_end 3\nfunction. Though recursion is allowed for epoch-protected sections,\nrecursive calls will be associated with the\n.Fn ck_epoch_begin 3\nthat is at the top of the call stack. If a section is passed, then\nrecursion on a record will cause the epoch to be refreshed on entry\nof every protected section.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\nThe object pointed to by\n.Fa epoch\nmust have been previously initiated via\n.Fn ck_epoch_init 3 .\nThe object pointed to by\n.Fa record\nmust have been previously registered via\n.Fn ck_epoch_register 3 .\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_call",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_CALL 3\n.Sh NAME\n.Nm ck_epoch_call\n.Nd defer function execution until a grace period\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\ntypedef struct ck_epoch_entry ck_epoch_entry_t;\n.br\ntypedef void ck_epoch_cb_t(ck_epoch_entry_t *);\n.Ft void\n.Fn ck_epoch_call \"ck_epoch_record_t *record\" \"ck_epoch_entry_t *entry\" \"ck_epoch_cb_t *function\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_call 3\nfunction will defer the execution of the function pointed to by\n.Fa function\nuntil a grace-period has been detected in\n.Fa epoch .\nThe function will be provided\nthe pointer specified by\n.Fa entry .\nThe function will execute at some time in the future via calls to\n.Fn ck_epoch_reclaim 3 ,\n.Fn ck_epoch_barrier 3\nor\n.Fn ck_epoch_poll 3 .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_epoch.h>\n#include <ck_stack.h>\n#include <stdlib.h>\n\n/*\n * epoch was previously initialized with ck_epoch_init.\n */\nck_epoch_t *epoch;\n\nstruct object {\n\tint value;\n\tck_epoch_entry_t epoch_entry;\n};\nstatic struct object *global;\n\nCK_EPOCH_CONTAINER(struct object, epoch_entry, object_container)\n\nvoid\ndestroy_object(ck_epoch_entry_t *e)\n{\n\tstruct object *o = object_container(e);\n\n\tfree(o);\n\treturn;\n}\n\nvoid\nfunction(void)\n{\n\tck_epoch_record_t *record;\n\tstruct object *n;\n\n\trecord = malloc(sizeof *record);\n\tck_epoch_register(&epoch, record);\n\n\tn = malloc(sizeof *n);\n\tif (n == NULL)\n\t\treturn;\n\n\tn->value = 1;\n\n\t/*\n\t * We are using an epoch section here because there are multiple\n\t * writers. It is also an option to use other forms of blocking\n\t * write-side synchronization such as mutexes.\n\t */\n\tck_epoch_begin(record);\n\tn = ck_pr_fas_ptr(&global, n);\n\tck_epoch_end(record);\n\n\t/* Defer destruction of previous object. */\n\tck_epoch_call(record, &n->epoch_entry, destroy_object);\n\n\t/* Poll epoch sub-system in non-blocking manner. */\n\tck_epoch_poll(record);\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\nThe object pointed to by\n.Fa record\nmust have been previously registered via\n.Fn ck_epoch_register 3 .\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_end",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_END 3\n.Sh NAME\n.Nm ck_epoch_end\n.Nd end epoch-protected segment of execution\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_end \"ck_epoch_record_t *record\" \"ck_epoch_section_t *section\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_end 3\nfunction will mark the end of an epoch-protected code section.\n.Fa section\nmust point to a section object initialized previously with\n.Fn ck_epoch_begin 3 .\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\nThe object pointed to by\n.Fa record\nmust have been previously registered via\n.Fn ck_epoch_register 3 .\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_INIT 3\n.Sh NAME\n.Nm ck_epoch_init\n.Nd initialize epoch reclamation object\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_init \"ck_epoch_t *epoch\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_init\nfunction initializes the epoch object pointed to by the\n.Fa epoch\npointer.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\n.Bl -tag -width Er\n.Pp\nThe behavior of\n.Fn ck_epoch_init\nis undefined if\n.Fa epoch\nis not a pointer to a\n.Tn ck_epoch_t\nobject.\n.El\n.Sh SEE ALSO\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_poll",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_POLL 3\n.Sh NAME\n.Nm ck_epoch_poll\n.Nd non-blocking poll of epoch object for dispatch cycles\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft bool\n.Fn ck_epoch_poll \"ck_epoch_record_t *record\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_poll 3\nfunction will attempt to dispatch any functions associated with the\nobject pointed to by\n.Fa epoch\nvia\n.Fn ck_epoch_call 3\nif deemed safe. This function is meant to be used in cases epoch\nreclamation cost must be amortized over time in a manner that does\nnot affect caller progress.\n.Sh RETURN VALUES\nThis function will return true if at least one function was dispatched.\nThis function will return false if it has determined not all threads have\nobserved the latest generation of epoch-protected objects. Neither value\nindicates an error.\n.Sh ERRORS\nBehavior is undefined if the object pointed to by\n.Fa record\nhas not have been previously registered via\n.Fn ck_epoch_register 3 .\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_reclaim",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 2, 2013\n.Dt CK_EPOCH_RECLAIM 3\n.Sh NAME\n.Nm ck_epoch_reclaim\n.Nd immediately execute all deferred callbacks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_reclaim \"ck_epoch_record_t *record\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_reclaim 3\nfunction will unconditionally execute all callbacks\nthat have been deferred with\n.Fn ck_epoch_call 3 .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_epoch.h>\n#include <ck_stack.h>\n#include <stdlib.h>\n\n/*\n * epoch was previously initialized with ck_epoch_init.\n */\nck_epoch_t *epoch;\n\nvoid\nfunction(void)\n{\n\tck_epoch_record_t *record;\n\n\tlogically_delete(object);\n\tck_epoch_call(epoch, record, &object->epoch_entry, destructor);\n\n\t/*\n\t * Wait until no threads could possibly have a reference to the\n\t * object we just deleted.\n\t */\n\tck_epoch_synchronize(epoch, record);\n\n\t/*\n\t * Execute all deferred callbacks.\n\t */\n\tck_epoch_reclaim(record);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_recycle",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_RECYCLE 3\n.Sh NAME\n.Nm ck_epoch_recycle\n.Nd return an epoch record that may be used by caller\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft ck_epoch_record_t *\n.Fn ck_epoch_recycle \"ck_epoch_t *epoch\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_recycle 3\nfunction attempts to return an unused epoch record object for use by\nthe caller. These epoch records were associated with previous calls\nto the\n.Fn ck_epoch_unregister 3\nfunction.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_epoch.h>\n#include <stdlib.h>\n\n/*\n * epoch was previously initialized with ck_epoch_init.\n */\nck_epoch_t *epoch;\n\nvoid\nfunction(void)\n{\n\tck_epoch_record_t *record;\n\n\trecord = ck_epoch_recycle(&epoch);\n\tif (record == NULL) {\n\t\trecord = malloc(sizeof *record);\n\t\tif (record == NULL)\n\t\t\treturn;\n\n\t\tck_epoch_register(&epoch, record);\n\t}\n\n\t/*\n\t * After we are done, we will unregister the record so it\n\t * can be used by other new participants in the epoch system\n\t * provided by the object pointed to by \"epoch\".\n\t */\n\tck_epoch_unregister(&epoch, record);\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function returns a pointer to a\n.Dv ck_epoch_record_t\nobject. If no unused record was found to be associated with the\nobject pointed to by\n.Fa epoch ,\nthen the function will return NULL.\n.Sh ERRORS\nBehavior is undefined if the object pointed to by\n.Fa epoch\nis not a valid epoch object.\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_register",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_REGISTER 3\n.Sh NAME\n.Nm ck_epoch_register\n.Nd register a thread for epoch reclamation\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_register \"ck_epoch_t *epoch\" \"ck_epoch_record_t *record\" \"void *cl\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_register 3\nfunction associates a record object specified by the\n.Fa record\npointer with the epoch object pointed to by\n.Fa epoch .\nAny thread or processor that will require safe memory reclamation\nguarantees must register a unique record object. After registration, the\nobject pointed to by the\n.Fa record\nargument will have lifetime managed by the underlying epoch sub-system.\nThe record object must not be destroyed after it is associated with a\n.Fn ck_epoch_register 3\ncall. An optional context pointer\n.Fa cl\nmay be passed that is retrievable with the\n.Fn ck_epoch_record_ct 3\nfunction.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_synchronize",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_SYNCHRONIZE 3\n.Sh NAME\n.Nm ck_epoch_synchronize\n.Nd block until a grace period has been detected\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_synchronize \"ck_epoch_record_t *record\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_synchronize 3\nfunction will block the caller until a grace period has been\ndetected, according to the semantics of epoch reclamation.\nAny objects requiring safe memory reclamation which are logically\ndeleted are safe for physical deletion following a call to\n.Fn ck_epoch_synchronize 3 .\nIf you require that all callbacks be dispatched, then it is suggested\nthat you use\n.Fn ck_epoch_barrier 3\ninstead or follow a call of\n.Fn ck_epoch_synchronize 3\nwith\n.Fn ck_epoch_reclaim 3 .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_epoch.h>\n#include <ck_stack.h>\n#include <stdlib.h>\n\n/*\n * epoch was previously initialized with ck_epoch_init.\n * stack was previously initialized with ck_stack_init.\n */\nck_epoch_t *epoch;\nck_stack_t *stack;\n\nvoid\nfunction(void)\n{\n\tck_epoch_record_t *record;\n\tck_stack_entry_t *s;\n\n\trecord = malloc(sizeof *record);\n\tck_epoch_register(&epoch, record);\n\n\t/*\n\t * We are using an epoch section here to guarantee no\n\t * nodes in the stack are deleted while we are dereferencing\n\t * them. This is needed here because there are multiple writers.\n\t * If there was only one thread popping from the this stack,\n\t * then there is no need to ck_epoch_begin/ck_epoch_end.\n\t */\n\tck_epoch_begin(record);\n\n\t/* Logically delete an object. */\n\ts = ck_stack_pop_upmc(stack);\n\n\tck_epoch_end(record);\n\n\t/*\n\t * Wait until no threads could possibly have a reference to the\n\t * object we just popped (assume all threads are simply executing\n\t * ck_stack_pop_upmc).\n\t */\n\tck_epoch_synchronize(record);\n\n\t/* It is now safe to physically delete the object. */\n\tfree(s);\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh ERRORS\nThe object pointed to by .Fa record must have been previously registered via\n.Fn ck_epoch_register 3 .\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_unregister 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_epoch_unregister",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 2, 2012\n.Dt CK_EPOCH_UNREGISTER 3\n.Sh NAME\n.Nm ck_epoch_unregister\n.Nd unregister a thread for epoch reclamation\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_epoch.h\n.Ft void\n.Fn ck_epoch_unregister \"ck_epoch_record_t *record\"\n.Sh DESCRIPTION\nThe\n.Fn ck_epoch_unregister 3\nfunction allows for the record pointed by the\n.Fa record\npointer to be used as a return value by the\n.Fn ck_epoch_recycle 3\nfunction. This record can now be used by another thread\nof execution. Behavior is undefined if the object pointed by\n.Fa record\nis modified in any way, even after a call is made to the\n.Fn ck_epoch_unregister 3\nfunction.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_epoch_init 3 ,\n.Xr ck_epoch_register 3 ,\n.Xr ck_epoch_recycle 3 ,\n.Xr ck_epoch_poll 3 ,\n.Xr ck_epoch_synchronize 3 ,\n.Xr ck_epoch_reclaim 3 ,\n.Xr ck_epoch_barrier 3 ,\n.Xr ck_epoch_call 3 ,\n.Xr ck_epoch_begin 3 ,\n.Xr ck_epoch_end 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_apply",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" Copyright 2014 Backtrace I/O, Inc.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 1, 2014\n.Dt CK_HS_APPLY 3\n.Sh NAME\n.Nm ck_hs_apply\n.Nd apply a function to hash set value\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft void *\n.Fn ck_hs_apply_fn_t \"void *key\" \"void *closure\"\n.Ft bool\n.Fn ck_hs_apply \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\" \"ck_hs_apply_fn_t *function\" \"void *argument\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_apply 3\nfunction will lookup the hash set slot associated with\n.Fa key\nand pass it to function pointed to by\n.Fa function\nfor further action. This callback may remove or replace\nthe value by respectively returning NULL or a pointer to\nanother object with an identical key. The first argument\npassed to\n.Fa function\nis a pointer to the object found in the hash set and\nthe second argument is the\n.Fa argument\npointer passed to\n.Fn ck_hs_apply 3 .\nIf the pointer returned by\n.Fa function\nis equivalent to the first argument then no modification\nis made to the hash set.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_apply 3\nreturns true and otherwise returns false on failure.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_count",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_COUNT 3\n.Sh NAME\n.Nm ck_hs_count\n.Nd returns number of entries in hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft unsigned long\n.Fn ck_hs_count \"ck_hs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_count 3\nfunction returns the number of keys currently\nstored in\n.Fa hs .\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_destroy",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_DESTROY 3\n.Sh NAME\n.Nm ck_hs_destroy\n.Nd destroy hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft void\n.Fn ck_hs_destroy \"ck_hs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_destroy 3\nfunction will request that the underlying allocator, as specified by the\n.Xr ck_hs_init 3\nfunction, immediately destroy the object pointed to by the\n.Fa hs\nargument.\nThe user must guarantee that no threads are accessing the object pointed to\nby\n.Fa hs\nwhen\n.Fn ck_hs_destroy 3\nis called.\n.Sh RETURN VALUES\n.Fn ck_hs_destroy 3\nhas no return value.\n.Sh ERRORS\nThis function is guaranteed not to fail.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_fas",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd June 20, 2013\n.Dt CK_HS_FAS 3\n.Sh NAME\n.Nm ck_hs_fas\n.Nd fetch and store key in hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_fas \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\" \"void **previous\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_fas 3\nfunction will fetch and store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_HS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_hs_fas 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nThe key must already exist in the hash set, and is\nreplaced by\n.Fa key\nand the previous value is stored into the void pointer\npointed to by the\n.Fa previous\nargument. If the key does not exist in the hash set\nthen the function will return false and the hash set\nis unchanged. This function\nis guaranteed to be stable with respect to memory usage.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_fas 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_gc",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 17, 2013\n.Dt CK_HS_GC 3\n.Sh NAME\n.Nm ck_hs_gc\n.Nd perform maintenance on a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_gc \"ck_hs_t *hs\" \"unsigned long cycles\" \"unsigned long seed\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_gc 3\nfunction will perform various maintenance routines on the hash set\npointed to by\n.Fa hs ,\nincluding defragmentation of probe sequences with respect to tombstones\nand in the case that the delete workload hint has been passed, recalculation\nof probe sequence bounds. The\n.Fa cycles\nargument is used to indicate how many hash set entries should be subject\nto attempted maintenance. If\n.Fa cycles\nis 0, then maintenance is performed on the complete hash set. The\n.Fa seed\nargument determines the start location of the maintenance process. If\n.Fa cycles\nis non-zero, it is recommended that\n.Fa seed\nis some random value. If the delete hint has been passed, the function\nwill require an additional 12% of memory (with respect to existing\nmemory usage of the set), until operation completion.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_gc 3\nreturns true and otherwise returns false on failure due to memory allocation\nfailure.\n.Sh ERRORS\nThis function will only return false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_get",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_GET 3\n.Sh NAME\n.Nm ck_hs_get\n.Nd load a key from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft void *\n.Fn ck_hs_get \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_get 3\nfunction will return a pointer to a key in the hash set\n.Fa hs\nthat is of equivalent value to the object pointed to by\n.Fa key .\nThe key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which is to have been previously generated using the\n.Xr CK_HS_HASH 3\nmacro).\n.Sh RETURN VALUES\nIf the provided key is a member of\n.Fa hs\nthen a pointer to the key as stored in\n.Fa hs\nis returned. If the key was not found in\n.Fa hs\nthen a value of\n.Dv NULL\nis returned.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_grow",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_GROW 3\n.Sh NAME\n.Nm ck_hs_grow\n.Nd enlarge hash set capacity\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_grow \"ck_hs_t *hs\" \"unsigned long capacity\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_grow 3\nfunction will resize the hash set in order to be\nable to store at least the number of entries specified by\n.Fa capacity\nat a load factor of one. The default hash set load factor\nis 0.5. If you wish to minimize the likelihood of memory allocations\nfor a hash set meant to store n entries, then specify a\n.Fa capacity\nof 2n. The default behavior of ck_hs is to round\n.Fa capacity\nto the next power of two if it is not already a power of two.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_grow 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. This function will only\nreturn false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_INIT 3\n.Sh NAME\n.Nm ck_hs_init\n.Nd initialize a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft typedef unsigned long\n.Fn ck_hs_hash_cb_t \"const void *key\" \"unsigned long seed\"\n.Ft typedef bool\n.Fn ck_hs_compare_cb_t \"const void *c1\" \"const void *c2\"\n.Ft bool\n.Fn ck_hs_init \"ck_hs_t *hs\" \"unsigned int mode\" \"ck_hs_hash_cb_t *hash_function\" \"ck_hs_compare_cb_t *compare\" \"struct ck_malloc *allocator\" \"unsigned long capacity\" \"unsigned long seed\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_init\nfunction initializes the hash set pointed to by the\n.Fa hs\npointer.\n.Pp\nThe argument\n.Fa mode\nspecifies the type of key-value pairs to be stored in the\nhash set as well as the expected concurrent access model.\nThe value of\n.Fa mode\nconsists of a bitfield of one of the following:\n.Bl -tag -width indent\n.It CK_HS_MODE_OBJECT\nThe hash set is meant to store pointers to objects. This provides\na hint that only CK_MD_VMA_BITS are necessary to encode the key\nargument. Any unused pointer bits are leveraged for internal\noptimizations.\n.It CK_HS_MODE_DIRECT\nThe hash set is meant to directly store key values and that all\nbits of the key are used to encode values.\n.El\n.Pp\nThe concurrent access model is specified by:\n.Bl -tag -width indent\n.It CK_HS_MODE_SPMC\nThe hash set should allow for concurrent readers in the\npresence of a single writer.\n.It CK_HS_MODE_MPMC\nThe hash set should allow for concurrent readers in the\npresence of concurrent writers. This is currently unsupported.\n.El\n.Pp\nThe developer is free to specify additional workload hints.\nThese hints are one of:\n.Bl -tag -width indent\n.It CK_HS_MODE_DELETE\nThe hash set is expected to have a delete-heavy workload.\nAt the cost of approximately 13% increased memory usage,\nallow for stronger per-slot probe bounds to combat the\neffects of tombstone accumulation.\n.El\n.Pp\nThe argument\n.Fa hash_function\nis a mandatory pointer to a user-specified hash function.\nA user-specified hash function takes two arguments. The\n.Fa key\nargument is a pointer to a key. The\n.Fa seed\nargument is the initial seed associated with the hash set.\nThis initial seed is specified by the user in\n.Xr ck_hs_init 3 .\n.Pp\nThe\n.Fa compare\nargument is an optional pointer to a user-specified\nkey comparison function. If NULL is specified in this\nargument, then pointer equality will be used to determine\nkey equality. A user-specified comparison function takes\ntwo arguments representing pointers to the objects being\ncompared for equality. It is expected to return true\nif the keys are of equal value and false otherwise.\n.Pp\nThe\n.Fa allocator\nargument is a pointer to a structure containing\n.Fa malloc\nand\n.Fa free\nfunction pointers which respectively define the memory allocation and\ndestruction functions to be used by the hash set being initialized.\n.Pp\nThe argument\n.Fa capacity\nrepresents the initial number of keys the hash\nset is expected to contain. This argument is simply a hint\nand the underlying implementation is free to allocate more\nor less memory than necessary to contain the number of entries\n.Fa capacity\nspecifies.\n.Pp\nThe argument\n.Fa seed\nspecifies the initial seed used by the underlying hash function.\nThe user is free to choose a value of their choice.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_hs_init\nreturns a value of\n.Dv true\nand otherwise returns a value of\n.Dv false\nto indicate an error.\n.Sh ERRORS\n.Bl -tag -width Er\n.Pp\nThe behavior of\n.Fn ck_hs_init\nis undefined if\n.Fa hs\nis not a pointer to a\n.Tn ck_hs_t\nobject.\n.El\n.Sh SEE ALSO\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_iterator_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_ITERATOR_INIT 3\n.Sh NAME\n.Nm ck_hs_iterator_init\n.Nd initialize hash set iterator\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Pp\n.Dv ck_hs_iterator_t iterator = CK_HS_ITERATOR_INITIALIZER\n.Pp\n.Ft void\n.Fn ck_hs_iterator_init \"ck_hs_iterator_t *iterator\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_iterator_init 3\nfunction will initialize the object pointed to\nby the\n.Fa iterator\nargument. Alternatively, an iterator may be statically\ninitialized by assigning it to the CK_HS_ITERATOR_INITIALIZER value.\n.Pp\nAn iterator is used to iterate through hash set entries with the\n.Xr ck_hs_next 3\nfunction.\n.Sh RETURN VALUES\n.Fn ck_hs_iterator_init 3\nhas no return value.\n.Sh ERRORS\nThis function will not fail.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_move",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 18, 2013\n.Dt CK_HS_MOVE 3\n.Sh NAME\n.Nm ck_hs_move\n.Nd move one from hash set to another\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_move \"ck_hs_t *destination\" \"ck_hs_t *source\" \"ck_hs_hash_cb_t *hash_cb\" \"ck_hs_compare_cb_t *compare_cb\" \"struct ck_malloc *m\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_move 3\nfunction will initialize\n.Fa source\nfrom\n.Fa destination .\nThe hash function is set to\n.Fa hash_cb ,\ncomparison function to\n.Fa compare_cb\nand the allocator callbacks to\n.Fa m .\nFurther modifications to\n.Fa source\nwill result in undefined behavior. Concurrent\n.Xr ck_hs_get 3\nand\n.Xr ck_hs_fas 3\noperations to\n.Fa source\nare legal until the next write operation to\n.Fa destination .\n.Pp\nThis operation moves ownership from one hash set object\nto another and re-assigns callback functions to developer-specified\nvalues. This allows for dynamic configuration of allocation\ncallbacks and is necessary for use-cases involving executable code\nwhich may be unmapped underneath the hash set.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_hs_move 3\nreturns true and otherwise returns false to indicate an error.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_next",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_NEXT 3\n.Sh NAME\n.Nm ck_hs_next\n.Nd iterate to next entry in hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_next \"ck_hs_t *hs\" \"ck_hs_iterator_t *iterator\" \"void **entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_next 3\nfunction will increment the iterator object pointed to by\n.Fa iterator\nto point to the next non-empty hash set entry. If\n.Fn ck_hs_next 3\nreturns true then the pointer pointed to by\n.Fa entry\nis initialized to the current hash set key pointed to by the\n.Fa iterator\nobject.\n.Pp\nIt is expected that\n.Fa iterator\nhas been initialized using the\n.Xr ck_hs_iterator_init 3\nfunction or statically initialized using CK_HS_ITERATOR_INITIALIZER.\n.Sh RETURN VALUES\nIf\n.Fn ck_hs_next 3\nreturns true then the object pointed to by\n.Fa entry\npoints to a valid hash set key. If\n.Fn ck_hs_next 3\nreturns false then the value of the object pointed to by\n.Fa entry\nis undefined.\n.Sh ERRORS\nBehavior is undefined if\n.Fa iterator\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_put",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_PUT 3\n.Sh NAME\n.Nm ck_hs_put\n.Nd store unique key into a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_put \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_put 3\nfunction will store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_HS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_hs_put 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nThe function will fail if a key with an\nequivalent value to\n.Fa key\nis already present in the hash set. For replacement\nsemantics, please see the\n.Xr ck_hs_set 3\nfunction.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_put 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized. The function will also\nreturn false if the hash set could not be enlarged\nto accomodate key insertion.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_put_unique",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 7, 2013\n.Dt CK_HS_PUT_UNIQUE 3\n.Sh NAME\n.Nm ck_hs_put_unique\n.Nd unconditionally store unique key into a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_put_unique \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_put_unique 3\nfunction will store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_HS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_hs_put 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nThe function will cause undefined behavior if a key with an\nequivalent value is already present in the hash set. For replacement\nsemantics, please see the\n.Xr ck_hs_set 3\nfunction.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_put_unique 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized. The function will also\nreturn false if the hash set could not be enlarged\nto accomodate key insertion. The function will\nresult in undefined behavior if called for an\nalready inserted key value.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_rebuild",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 7, 2013\n.Dt CK_HS_REBUILD 3\n.Sh NAME\n.Nm ck_hs_rebuild\n.Nd rebuild a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_rebuild \"ck_hs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_rebuild 3\nfunction will regenerate the hash set pointed to by\n.Fa hs .\nThis has the side-effect of pruning degradatory side-effects\nof workloads that are delete heavy. The regenerated hash\nset should have shorter probe sequences on average. This\noperation will require a significant amount of memory\nand is free to allocate a duplicate hash set in the\nrebuild process.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_rebuild 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nThis function will only return false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_remove",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_REMOVE 3\n.Sh NAME\n.Nm ck_hs_remove\n.Nd remove key from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft void *\n.Fn ck_hs_remove \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_remove 3\nfunction will attempt to remove the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_HS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_hs_remove 3\nwas successful then the key contained in the hash\nset is returned. If the key was not a member of the hash\nset then\n.Dv  NULL\nis returned.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_remove 3\nreturns a pointer to a key and otherwise returns\n.Dv NULL\non failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_reset",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_RESET 3\n.Sh NAME\n.Nm ck_hs_reset\n.Nd remove all keys from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_reset \"ck_hs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_reset 3\nfunction will remove all keys stored in the hash\nset pointed to by the\n.Fa hs\nargument.\n.Sh RETURN VALUES\nIf successful,\n.Fn ck_hs_reset 3\nwill return true and will otherwise return false on failure. This\nfunction will only fail if a replacement hash set could not be\nallocated internally.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_reset_size",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 5, 2013\n.Dt CK_HS_RESET_SIZE 3\n.Sh NAME\n.Nm ck_hs_reset_size\n.Nd remove all keys from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_reset_size \"ck_hs_t *hs\" \"unsigned long size\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_reset_size 3\nfunction will remove all keys stored in the hash\nset pointed to by the\n.Fa hs\nargument and create a new generation of the hash set that\nis preallocated for\n.Fa size\nentries.\n.Sh RETURN VALUES\nIf successful,\n.Fn ck_hs_reset_size 3\nwill return true and will otherwise return false on failure. This\nfunction will only fail if a replacement hash set could not be\nallocated internally.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_set",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_SET 3\n.Sh NAME\n.Nm ck_hs_set\n.Nd store key into a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft bool\n.Fn ck_hs_set \"ck_hs_t *hs\" \"unsigned long hash\" \"const void *key\" \"void **previous\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_set 3\nfunction will store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_HS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_hs_set 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nIf the key already exists in the hash set, then it is\nreplaced by\n.Fa key\nand the previous value is stored into the void pointer\npointed to by the\n.Fa previous\nargument. If previous is set to\n.Dv NULL\nthen\n.Fa key\nwas not a replacement for an existing entry in the hash set.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_hs_set 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized. The function will also\nreturn false if the hash set could not be enlarged\nto accomodate key insertion.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3 ,\n.Xr ck_hs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_hs_stat",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HS_STAT 3\n.Sh NAME\n.Nm ck_hs_stat\n.Nd get hash set status\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_hs.h\n.Ft void\n.Fn ck_hs_stat \"ck_hs_t *hs\" \"struct ck_hs_stat *st\"\n.Sh DESCRIPTION\nThe\n.Fn ck_hs_stat 3\nfunction will store various hash set statistics in\nthe object pointed to by\n.Fa st .\nThe ck_hs_stat structure is defined as follows:\n.Bd -literal -offset indent\nstruct ck_hs_stat {\n\tunsigned long tombstones;   /* Current number of tombstones in hash set. */\n\tunsigned long n_entries;    /* Current number of keys in hash set. */\n\tunsigned int probe_maximum; /* Longest read-side probe sequence. */\n};\n.Ed\n.Sh RETURN VALUES\n.Fn ck_hs_stat 3\nhas no return value.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_hs_init 3 ,\n.Xr ck_hs_move 3 ,\n.Xr ck_hs_destroy 3 ,\n.Xr CK_HS_HASH 3 ,\n.Xr ck_hs_iterator_init 3 ,\n.Xr ck_hs_next 3 ,\n.Xr ck_hs_get 3 ,\n.Xr ck_hs_put 3 ,\n.Xr ck_hs_put_unique 3 ,\n.Xr ck_hs_set 3 ,\n.Xr ck_hs_fas 3 ,\n.Xr ck_hs_remove 3 ,\n.Xr ck_hs_grow 3 ,\n.Xr ck_hs_gc 3 ,\n.Xr ck_hs_rebuild 3 ,\n.Xr ck_hs_count 3 ,\n.Xr ck_hs_reset 3 ,\n.Xr ck_hs_reset_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_count",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_COUNT 3\n.Sh NAME\n.Nm ck_ht_count\n.Nd return count of key-value pairs in hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft uint64_t\n.Fn ck_ht_count \"ck_ht_t *ht\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_count\nfunction will return the number of entries in the hash table\npointed to be the\n.Fa ht\nargument. The function may only be called without the presence\nof concurrent write operations.\n.Sh ERRORS\nBehavior is undefined if\n.Fa ht\nhas not been initialized.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_destroy",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_DESTROY 3\n.Sh NAME\n.Nm ck_ht_destroy\n.Nd immediately destroy a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_destroy \"ck_ht_t *ht\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_destroy\nfunction will request that the underlying allocator, as specified by the\n.Xr ck_ht_init 3\nfunction, immediately destroy the object pointed to by the\n.Fa ht\nargument.\n.Pp\nThe user must guarantee that no threads are accessing the object pointed to\nby\n.Fa ht\nwhen\n.Fn ck_ht_destroy\nis called.\n.Sh RETURN VALUES\n.Fn ck_ht_destroy\nhas no return value.\n.Sh ERRORS\n.Bl -tag -width Er\nThis function is guaranteed not to fail.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_empty",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_ENTRY_EMPTY 3\n.Sh NAME\n.Nm ck_ht_entry_empty\n.Nd determine whether entry contains a key-value pair\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_entry_empty \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_empty\nfunction will return\n.Dv false\nif\n.Fa entry\npoints to a valid key-value pair. If\n.Fa entry\ndoes not point to a valid key-value pair it\nreturns\n.Dv true.\nIt is expected that the object pointed to by\n.Fa entry\nwas initialized by a preceding call to the\n.Xr ck_ht_entry_set\nfamily of functions, the\n.Xr ck_ht_get_spmc 3\nfunction or the\n.Xr ck_ht_set_spmc 3\nfunction.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nhas not been initialized.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_key",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_KEY 3\n.Sh NAME\n.Nm ck_ht_entry_key\n.Nd return pointer to key as specified in hash table entry\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void *\n.Fn ck_ht_entry_key \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_key\nfunction will return the key pointer as specified in the\nobject pointed to by the\n.Fa entry\nargument.\n.Pp\nIt is expected that the entry is\nassociated with a hash table initialized with\n.Dv CK_HT_MODE_BYTESTRING\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_key\nreturns\n.Dv NULL\nif the entry is empty.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nhas not been initialized.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_key_direct",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_KEY_DIRECT 3\n.Sh NAME\n.Nm ck_ht_entry_key_direct\n.Nd return key value as specified in hash table entry\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft uintptr_t\n.Fn ck_ht_entry_key_direct \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_key_direct\nfunction will return the key value as specified in the\nobject pointed to by the\n.Fa entry\nargument.\n.Pp\nIt is expected that the entry is\nassociated with a hash table initialized with\n.Dv CK_HT_MODE_DIRECT\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_key_direct\nreturns\n.Dv 0\nif the entry is empty. Otherwise, it returns the\nkey value stored in the object pointed to by the\n.Fa entry\nargument.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nhas not been initialized.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_key_length",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_KEY_LENGTH 3\n.Sh NAME\n.Nm ck_ht_entry_key_length\n.Nd returns the length of the key specified in the argument\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft uint16_t\n.Fn ck_ht_entry_key_length \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_key_length\nfunction will return the length of the key associated with the\nobject pointed to by the\n.Fa entry\nargument.\n.Pp\nIt is expected that the entry is\nassociated with a hash table initialized with\n.Dv CK_HT_MODE_BYTESTRING\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_key_length\nreturns\n.Dv 0\nif the entry is empty.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nhas not been initialized.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_key_set",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_KEY_SET 3\n.Sh NAME\n.Nm ck_ht_entry_key_set\n.Nd initialize pointer to key in hash table entry\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_entry_key_set \"ck_ht_entry_t *entry\" \"const void *key\" \"uint16_t key_length\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_key_set\nfunction will initialize the object pointed to by\n.Fa entry\nwith a key pointed to by the\n.Fa key\nargument. The length of the key is specified by\n.Fa key_length.\nThe maximum value of\n.Fa key_length\nis defined by the CK_HT_KEY_LENGTH macro.\nThis function is typically used to initialize an\nentry for\n.Xr ck_ht_get_spmc 3\nand\n.Xr ck_ht_remove_spmc 3\noperations. It is expected that the entry will\nbe associated with a hash table initialized with\n.Dv CK_HT_MODE_BYTESTRING\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_key_set\nhas no return value.\n.Sh ERRORS\nThis function will never fail.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_key_set_direct",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_KEY_SET_DIRECT 3\n.Sh NAME\n.Nm ck_ht_entry_key_set_direct\n.Nd initialize key value in hash table entry\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_entry_key_set_direct \"ck_ht_entry_t *entry\" \"uintptr_t key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_key_set_direct\nfunction will initialize the object pointed to by\n.Fa entry\nwith the key value specified in the\n.Fa key\nargument. This function is typically used to initialize an\nentry for\n.Xr ck_ht_get_spmc 3\nand\n.Xr ck_ht_remove_spmc 3\noperations. It is expected that the entry will\nbe associated with a hash table initialized with\n.Dv CK_HT_MODE_DIRECT\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_key_set_direct\nhas no return value.\n.Sh ERRORS\nThis function will never fail.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_set",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_SET 3\n.Sh NAME\n.Nm ck_ht_entry_set\n.Nd initialize a key-value pair\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_entry_set \"ck_ht_entry_t *entry\" \"ck_ht_hash_t h\" \"const void *key\" \"uint16_t key_length\" \"const void *value\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_set\nfunction will initialize the object pointed to by\n.Fa entry\nwith a key pointed to by the\n.Fa key\nargument and a value pointed to by the\n.Fa value\nargument. The length of the key is specified by\n.Fa key_length.\nThe maximum value of\n.Fa key_length\nis defined by the CK_HT_KEY_LENGTH macro.\nThis function is typically used to initialize an\nentry for\n.Xr ck_ht_set_spmc 3\nand\n.Xr ck_ht_put_spmc 3\noperations. It is expected that the entry will\nbe associated with a hash table initialized with\n.Dv CK_HT_MODE_BYTESTRING\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_set\nhas no return value.\n.Sh ERRORS\nThis function will never fail.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_set_direct",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_SET_DIRECT 3\n.Sh NAME\n.Nm ck_ht_entry_set_direct\n.Nd initialize a key-value pair\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_entry_set_direct \"ck_ht_entry_t *entry\" \"ck_ht_hash_t h\" \"uintptr_t key\" \"uintptr_t value\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_set\nfunction will initialize the object pointed to by\n.Fa entry\nwith the hash value specified by the\n.Fa h\nargument, the key value specified in the\n.Fa key\nargument and the value specified by the\n.Fa value\nargument.\n.Pp\nThis function is typically used to initialize an\nentry for\n.Xr ck_ht_set_spmc 3\nand\n.Xr ck_ht_put_spmc 3\noperations. It is expected that the entry will\nbe associated with a hash table initialized with\n.Dv CK_HT_MODE_DIRECT\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\n.Fn ck_ht_entry_set_direct\nhas no return value.\n.Sh ERRORS\nThis function will never fail.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_value",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_VALUE 3\n.Sh NAME\n.Nm ck_ht_entry_value\n.Nd return pointer to value as specified in hash table entry\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void *\n.Fn ck_ht_entry_value \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_value\nfunction will return the value pointer as specified in the\nobject pointed to by the\n.Fa entry\nargument.\n.Pp\nIt is expected that the entry is\nassociated with a hash table initialized with\n.Dv CK_HT_MODE_BYTESTRING\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\nThe\n.Fn ck_ht_entry_value\nfunction returns the value pointed to by\n.Dv entry.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nhas not been initialized or if the key is empty.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_entry_value_direct",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ENTRY_VALUE_DIRECT 3\n.Sh NAME\n.Nm ck_ht_entry_value_direct\n.Nd return value as specified in hash table entry\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft uintptr_t\n.Fn ck_ht_entry_value_direct \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_entry_value_direct\nfunction will return the value of the key-value pair as specified in the\nobject pointed to by the\n.Fa entry\nargument.\n.Pp\nIt is expected that the entry is\nassociated with a hash table initialized with\n.Dv CK_HT_MODE_DIRECT\n(see\n.Xr ck_ht_init 3\nfor more information).\n.Sh RETURN VALUES\nThe\n.Fn ck_ht_entry_value_direct\nfunction returns the value stored in the object pointed to by the\n.Fa entry\nargument.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nhas not been initialized or if the key is empty.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_gc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 18, 2013\n.Dt CK_HT_GC 3\n.Sh NAME\n.Nm ck_ht_gc\n.Nd perform maintenance on a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_gc \"ck_ht_t *ht\" \"unsigned long cycles\" \"unsigned long seed\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_gc\nfunction will perform various maintenance routines on the hash table\npointed to by\n.Fa ht ,\nincluding defragmentation of probe sequences with respect to tombstones\nand in the case that the delete workload hint has been passed, recalculation\nof probe sequence bounds. The\n.Fa cycles\nargument is used to indicate how many hash table entries should be subject\nto attempted maintenance.\nIf\n.Fa cycles\nis 0, then maintenance is performed on the complete hash table. The\n.Fa seed\nargument determines the start location of the maintenance process. If\n.Fa cycles\nis non-zero, it is recommended that\n.Fa seed\nis some random value. If the delete hint has been passed, the function\nwill require an additional 12% of memory (with respect to existing\nmemory usage of the set), until operation completion.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_ht_gc 3\nreturns true and otherwise returns false on failure due to memory allocation\nfailure.\n.Sh ERRORS\nThis function will only return false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_get_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_GET_SPMC 3\n.Sh NAME\n.Nm ck_ht_get_spmc\n.Nd load a key-value pair from a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_get_spmc \"ck_ht_t *ht\" \"ck_ht_hash_t h\" \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_get_spmc\nfunction will return the value associated with the key specified in the\n.Fa entry\nargument in the hash table pointed to by the\n.Fa ht\nargument. The key specified in\n.Fa entry\nis expected to have the hash value specified by the\n.Fa h\nargument.\n.Pp\nIf\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_set_key 3\nor\n.Xr ck_ht_entry_set 3\nfunctions. If\n.Fa ht\nwas created with CK_HT_MODE_DIRECT then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_key_set_direct 3\nor\n.Xr ck_ht_entry_set_direct 3\nfunctions.\n.Pp\nIt is expected that\n.Fa h\nwas initialized with\n.Xr ck_ht_hash 3\nif\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING. If\n.Fa ht\nwas initialized with CK_HT_MODE_DIRECT then it is\nexpected that\n.Fa h\nwas initialized with the\n.Xr ck_ht_hash_direct 3\nfunction.\n.Pp\nIf the call to\n.Fn ck_ht_get_spmc\nwas successful then the key-value pair in\n.Fa entry\nwas successfully found in the hash table pointed\nto by\n.Fa h\nand will fail if the key specified in\n.Fa entry\ndoes not exist in the hash table. If successful\n.Fa entry\nwill contain the key-value pair found in the hash table\npointed to by the\n.Fa ht\nargument.\n.Pp\nIf\n.Fa ht\nwas initialized with CK_HT_MODE_BYTESTRING then\nthe key/value pair in\n.Fa entry\nmay be extracted using the\n.Xr ck_ht_entry_key 3\nand\n.Xr ck_ht_entry_value 3\nfunctions. The length of the key may be extracted\nusing the\n.Xr ck_ht_entry_key_length 3\nfunction.\n.Pp\nIf\n.Fa ht\nwas initialized with CK_HT_MODE_DIRECT then the\nkey/value pair in\n.Fa entry\nmay be extracted using the\n.Xr ck_ht_entry_key_direct 3\nand\n.Xr ck_ht_entry_value_direct 3\nfunctions.\n.Pp\nThis function is safe to call in the presence of a concurrent writer.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_ht_get_spmc\nreturns\n.Dv true.\nIf successful,\n.Fa entry\nwill contain the key/value pair as found\nin the hash table.\nOtherwise the function returns\n.Dv false\non failure.\n.Sh ERRORS\n.Bl -tag -width Er\nBehavior is undefined if\n.Fa entry\nor\n.Fa ht\nare uninitialized. The function will return\n.Dv false\nif the key as specified in\n.Fa entry\nwas not found in the hash table.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_grow_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_GROW_SPMC 3\n.Sh NAME\n.Nm ck_ht_grow_spmc\n.Nd resize a hash table if necessary\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_grow_spmc \"ck_ht_t *ht\" \"uint64_t capacity\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_grow_spmc\nfunction will resize the hash table in order to be able to\nat least store the number of entries specified by\n.Fa capacity\nat a load factor of one. The default load hash table load factor is\n0.5. If you wish to minimize the likelihood of memory allocations\nfor a hash table meant to store n entries then specify a capacity\nof 2n. The default behavior of ck_ht is to round\n.Fa capacity\nto the next available power of two if it is not already a power\nof two.\n.Pp\nThis function is safe to call in the presence of concurrent\n.Xr ck_ht_get_spmc 3\noperations.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_ht_grow_spmc\nreturns\n.Dv true\nand otherwise returns a\n.Dv false\nvalue.\n.Sh ERRORS\n.Bl -tag -width Er\nBehavior is undefined if\n.Fa ht\nis uninitialized. The function will only return\n.Dv false\nif there are internal memory allocation failures.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_hash",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_HASH 3\n.Sh NAME\n.Nm ck_ht_hash\n.Nd generate a hash value for a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_hash \"ck_ht_hash_t *h\" \"ck_ht_t *ht\" \"const void *key\" \"uint16_t key_length\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_hash\nfunction will generate a hash value in the object pointed to by the\n.Fa h\nargument. The hash value is valid for use in the hash table pointed to by the\n.Fa ht\nargument for the key (of bytestring type) specified by the\n.Fa key\nargument. The length of the key is specified by the\n.Fa key_length\nargument.\n.Sh RETURN VALUES\n.Fn ck_ht_hash\nhas no return value.\n.Sh ERRORS\n.Bl -tag -width Er\nBehavior is undefined if\n.Fa key\nis\n.Dv NULL\nor if\n.Fa ht\nis uninitialized.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_hash_direct",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_HASH_DIRECT 3\n.Sh NAME\n.Nm ck_ht_hash_direct\n.Nd generate a hash value for a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_hash_direct \"ck_ht_hash_t *h\" \"ck_ht_t *ht\" \"uintptr_t key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_hash_direct\nfunction will generate a hash value in the object pointed to by the\n.Fa h\nargument. The hash value is valid for use in the hash table pointed to by the\n.Fa ht\nargument for the key (of direct type) specified by the\n.Fa key\nargument.\n.Sh RETURN VALUES\n.Fn ck_ht_hash_direct\nhas no return value.\n.Sh ERRORS\n.Bl -tag -width Er\nBehavior is undefined if\n.Fa key\nis a\n.Dv 0\nor\n.Dv UINTPTR_MAX\nvalue or if\n.Fa ht\nis uninitialized.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 28, 2012\n.Dt CK_HT_INIT 3\n.Sh NAME\n.Nm ck_ht_init\n.Nd initialize a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft typedef void\n.Fn ck_ht_hash_cb_t \"ck_ht_hash_t *h\" \"const void *key\" \"size_t key_length\" \"uint64_t seed\"\n.Ft bool\n.Fn ck_ht_init \"ck_ht_t *ht\" \"enum ck_ht_mode mode\" \"ck_ht_hash_cb_t *hash_function\" \"struct ck_malloc *allocator\" \"uint64_t capacity\" \"uint64_t seed\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_init\nfunction initializes the hash table pointed to by the\n.Fa ht\npointer.\n.Pp\nThe argument\n.Fa mode\nspecifies the type of key-value pairs to be stored in the\nhash table. The value of\n.Fa mode\nmay be one of:\n.Bl -tag -width indent\n.It CK_HT_MODE_BYTESTRING\nThe hash table is meant to store key-value pointers where\nkey is a region of memory that is up to 65536 bytes long.\nThis pointer will be dereferenced during hash table operations\nfor key comparison. Entries of this hash table are expected\nto be interacted with using the\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\nand\n.Xr ck_ht_entry_set 3\nfunctions. Attempting a hash table operation with a key of value\nNULL or (void *)UINTPTR_MAX will result in undefined behavior.\n.It CK_HT_MODE_DIRECT\nThe hash table is meant to store key-value pointers where\nthe key is of fixed width field compatible with the\n.Tn uintptr_t\ntype. The key will be directly compared with other keys for\nequality. Entries of this hash table are expected to be interacted\nwith using the\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3\nand\n.Xr ck_ht_entry_set_direct 3\nfunctions. Attempting a hash table operation with a key of value of 0 or\nUINTPTR_MAX will result in undefined behavior.\n.El\n.Pp\nIn addition to this, the user may bitwise OR the mode flag with\nCK_HT_WORKLOAD_DELETE to indicate that the hash table will\nhave to handle a delete heavy workload, in which case stronger\nbounds on latency can be provided at the cost of approximately\n13% higher memory usage.\nThe argument\n.Fa hash_function\nis a pointer to a user-specified hash function. It is optional,\nif\n.Dv NULL\nis specified, then the default hash function implementation will be\nused (\n.Xr ck_ht_hash 3 ).\nA user-specified hash function takes four arguments. The\n.Fa h\nargument is a pointer to a hash value object. The hash function\nis expected to update the\n.Fa value\nobject of type\n.Fa uint64_t\ncontained with-in the object pointed to by\n.Fa h .\nThe\n.Fa key\nargument is a pointer to a key, the\n.Fa key_length\nargument is the length of the key and the\n.Fa seed\nargument is the initial seed associated with the hash table.\nThis initial seed is specified by the user in\n.Xr ck_ht_init 3 .\n.Pp\nThe\n.Fa allocator\nargument is a pointer to a structure containing\n.Fa malloc\nand\n.Fa free\nfunction pointers which respectively define the memory allocation and\ndestruction functions to be used by the hash table being initialized.\n.Pp\nThe argument\n.Fa capacity\nrepresents the initial number of key-value pairs the hash\ntable is expected to contain. This argument is simply a hint\nand the underlying implementation is free to allocate more\nor less memory than necessary to contain the number of entries\n.Fa capacity\nspecifies.\n.Pp\nThe argument\n.Fa seed\nspecifies the initial seed used by the underlying hash function.\nThe user is free to choose a value of their choice.\n.Pp\nThe hash table is safe to access by multiple readers in the presence\nof one concurrent writer. Behavior is undefined in the presence of\nconcurrent writers.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_ht_init\nreturns a value of\n.Dv true\nand otherwise returns a value of\n.Dv false\nto indicate an error.\n.Sh ERRORS\n.Bl -tag -width Er\n.Pp\nThe behavior of\n.Fn ck_ht_init\nis undefined if\n.Fa ht\nis not a pointer to a\n.Tn ck_ht_t\nobject.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_iterator_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_ITERATOR_INIT 3\n.Sh NAME\n.Nm ck_ht_iterator_init\n.Nd initialize hash table iterator\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Pp\n.Dv ck_ht_iterator_t iterator = CK_HT_ITERATOR_INITIALIZER\n.Pp\n.Ft void\n.Fn ck_ht_iterator_init \"ck_ht_iterator_t *iterator\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_iterator_init\nfunction will initialize the object pointed to by\nthe\n.Fa iterator\nargument. Alternatively, an iterator may be statically initialized\nby assigning it the\n.Dv CK_HT_ITERATOR_INITIALIZER\nvalue.\n.Pp\nAn iterator is used to iterate through hash table entries\nwith the\n.Xr ck_ht_next 3\nfunction.\n.Sh RETURN VALUES\nThe\n.Fn ck_ht_iterator_init\nfunction does not return a value.\n.Sh ERRORS\nThis function will not fail.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_next",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 30, 2012\n.Dt CK_HT_NEXT 3\n.Sh NAME\n.Nm ck_ht_next\n.Nd iterate to next entry in hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_next \"ck_ht_t *ht\" \"ck_ht_iterator_t *iterator\" \"ck_ht_entry_t **entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_next\nfunction will increment the iterator object pointed to by\n.Fa iterator\nto point to the next non-empty hash table entry. If\n.Fn ck_ht_next\nreturns\n.Dv true\nthen the pointer pointed to by\n.Fa entry\nis initialized to the current hash table entry pointed to by\nthe\n.Fa iterator\nobject.\n.Pp\nIt is expected that\n.Fa iterator\nhas been initialized using the\n.Xr ck_ht_iterator_init 3\nfunction or statically initialized using\n.Dv CK_HT_ITERATOR_INITIALIZER.\n.Sh RETURN VALUES\nIf\n.Fn ck_ht_next\nreturns\n.Dv true\nthen the object pointed to by\n.Fa entry\npoints to a valid hash table entry. If\n.Fn ck_ht_next\nreturns\n.Dv false\nthen value of the object pointed to by\n.Fa entry\nis undefined.\n.Sh ERRORS\nBehavior is undefined if\n.Fa iterator\nor\n.Fa ht\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_put_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_PUT_SPMC 3\n.Sh NAME\n.Nm ck_ht_put_spmc\n.Nd store unique key-value pair into hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_put_spmc \"ck_ht_t *ht\" \"ck_ht_hash_t h\" \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_put_spmc\nfunction will store the key-value pair specified in the\n.Fa entry\nargument in the hash table pointed to by the\n.Fa ht\nargument. The key specified in\n.Fa entry\nis expected to have the hash value specified by the\n.Fa h\nargument.\n.Pp\nIf\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_set 3\nfunction. If\n.Fa ht\nwas created with CK_HT_MODE_DIRECT then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_set_direct 3\nfunction.\n.Pp\nIt is expected that\n.Fa h\nwas initialized with\n.Xr ck_ht_hash 3\nif\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING. If\n.Fa ht\nwas initialized with CK_HT_MODE_DIRECT then it is\nexpected that\n.Fa h\nwas initialized with the\n.Xr ck_ht_hash_direct 3\nfunction.\n.Pp\nIf the call to\n.Fn ck_ht_put_spmc\nwas successful then the key-value pair in\n.Fa entry\nwas successfully stored in the hash table pointed\nto by\n.Fa ht\nand will fail if the key specified in\n.Fa entry\nalready exists with-in the hash table. Replacement semantics\nare provided by the\n.Xr ck_ht_set_spmc 3\nfunction.\n.Pp\nThis function is safe to call in the presence of concurrent\n.Xr ck_ht_get_spmc 3\noperations.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_ht_put_spmc\nreturns\n.Dv true\nand otherwise returns\n.Dv false\non failure.\n.Sh ERRORS\n.Bl -tag -width Er\nBehavior is undefined if\n.Fa entry\nor\n.Fa ht\nare uninitialized. The function will return\n.Dv false\nif the hash table required to be grown but failed\nwhile attempting to grow or if the key specified\nin\n.Fa entry\nwas already present in the hash table.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_remove_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_GROW_SPMC 3\n.Sh NAME\n.Nm ck_ht_remove_spmc\n.Nd resize a hash table if necessary\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_remove_spmc \"ck_ht_t *ht\" \"ck_ht_hash_t h\" \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_remove_spmc\nfunction will remove the key-value pair associated with the\nkey specified by the\n.Fa entry\nargument.\n.Pp\nIf\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_set_key 3\nor\n.Xr ck_ht_entry_set 3\nfunctions. If\n.Fa ht\nwas created with CK_HT_MODE_DIRECT then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_key_set_direct 3\nor\n.Xr ck_ht_entry_set_direct 3\nfunctions.\n.Pp\nIt is expected that\n.Fa h\nwas initialized with\n.Xr ck_ht_hash 3\nif\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING. If\n.Fa ht\nwas initialized with CK_HT_MODE_DIRECT then it is\nexpected that\n.Fa h\nwas initialized with the\n.Xr ck_ht_hash_direct 3\nfunction.\n.Sh RETURN VALUES\nIf successful,\n.Fa entry\nwill contain the key-value pair that was found in the hash table\nand\n.Fn ck_ht_remove_spmc\nwill return\n.Dv true.\nIf the entry could not be found then\n.Fn ck_ht_remove_spmc\nwill return\n.Dv false.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_reset_size_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 5, 2013\n.Dt CK_HT_RESET_SPMC 3\n.Sh NAME\n.Nm ck_ht_reset_size_spmc\n.Nd remove all entries from a hash table and reset size\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_reset_size_spmc \"ck_ht_t *ht\" \"uint64_t capacity\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_reset_size_spmc\nfunction will remove all key-value pairs stored in the hash\ntable pointed to by the\n.Fa ht\nargument and create a new generation of the hash table that\nis preallocated for\n.Fa capacity\nentries.\n.Sh RETURN VALUES\nIf successful,\n.Fn ck_ht_reset_size_spmc\nwill return\n.Dv true\nand will otherwise return\n.Dv false.\nThis function will only fail if a replacement hash table\ncould not be allocated internally.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_reset_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_RESET_SPMC 3\n.Sh NAME\n.Nm ck_ht_reset_spmc\n.Nd remove all entries from a hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_reset_spmc \"ck_ht_t *ht\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_reset_spmc\nfunction will remove all key-value pairs stored in the hash\ntable pointed to by the\n.Fa ht\nargument.\n.Sh RETURN VALUES\nIf successful,\n.Fn ck_ht_reset_spmc\nwill return\n.Dv true\nand will otherwise return\n.Dv false.\nThis function will only fail if a replacement hash table\ncould not be allocated internally.\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_set_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd March 29, 2012\n.Dt CK_HT_SET_SPMC 3\n.Sh NAME\n.Nm ck_ht_set_spmc\n.Nd store key-value pair into hash table\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft bool\n.Fn ck_ht_set_spmc \"ck_ht_t *ht\" \"ck_ht_hash_t h\" \"ck_ht_entry_t *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_set_spmc\nfunction will store the key-value pair specified in the\n.Fa entry\nargument in the hash table pointed to by the\n.Fa ht\nargument. The key specified in\n.Fa entry\nis expected to have the hash value specified by the\n.Fa h\nargument.\n.Pp\nIf\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_set 3\nfunction. If\n.Fa ht\nwas created with CK_HT_MODE_DIRECT then\n.Fa entry\nmust have been initialized with the\n.Xr ck_ht_entry_set_direct 3\nfunction.\n.Pp\nIt is expected that\n.Fa h\nwas initialized with\n.Xr ck_ht_hash 3\nif\n.Fa ht\nwas created with CK_HT_MODE_BYTESTRING. If\n.Fa ht\nwas initialized with CK_HT_MODE_DIRECT then it is\nexpected that\n.Fa h\nwas initialized with the\n.Xr ck_ht_hash_direct 3\nfunction.\n.Pp\nIf the call to\n.Fn ck_ht_set_spmc\nwas successful then the key-value pair in\n.Fa entry\nwill contain the previous key-value pair associated\nwith the key originally contained in the\n.Fa entry\nargument. If the operation was unsuccessful then\n.Fa entry\nis unmodified.\n.Pp\nThis function is safe to call in the presence of concurrent\n.Xr ck_ht_get_spmc\noperations.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_ht_set_spmc\nreturns\n.Dv true\nand otherwise returns\n.Dv false\non failure.\n.Sh ERRORS\n.Bl -tag -width Er\nBehavior is undefined if\n.Fa entry\nor\n.Fa ht\nare uninitialized. The function will return\n.Dv false\nif the hash table required to be grown but failed\nwhile attempting to grow.\n.El\n.Sh SEE ALSO\n.Xr ck_ht_stat 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ht_stat",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_HT_STAT 3\n.Sh NAME\n.Nm ck_ht_stat\n.Nd get hash table status\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ht.h\n.Ft void\n.Fn ck_ht_stat \"ck_ht_t *ht\" \"struct ck_ht_stat *st\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ht_stat 3\nfunction will store various hash set statistics in the object\npointed to by\n.Fa st .\nThe ck_ht_stat structure is defined as follows:\n.Bd -literal -offset indent\nstruct ck_ht_stat {\n\tuint64_t probe_maximum; /* Longest read-side probe sequence. */\n\tuint64_t n_entries;     /* Current number of keys in hash set. */\n};\n.Ed\n.Sh RETURN VALUES\n.Fn ck_ht_stat 3\nhas no return value.\n.Sh ERRORS\nBehavior is undefined if\n.Fa ht\nhas not been initialized.\n.Sh SEE ALSO\n.Xr ck_ht_count 3 ,\n.Xr ck_ht_init 3 ,\n.Xr ck_ht_destroy 3 ,\n.Xr ck_ht_hash 3 ,\n.Xr ck_ht_hash_direct 3 ,\n.Xr ck_ht_set_spmc 3 ,\n.Xr ck_ht_put_spmc 3 ,\n.Xr ck_ht_gc 3 ,\n.Xr ck_ht_get_spmc 3 ,\n.Xr ck_ht_grow_spmc 3 ,\n.Xr ck_ht_remove_spmc 3 ,\n.Xr ck_ht_reset_spmc 3 ,\n.Xr ck_ht_reset_size_spmc 3 ,\n.Xr ck_ht_entry_empty 3 ,\n.Xr ck_ht_entry_key_set 3 ,\n.Xr ck_ht_entry_key_set_direct 3 ,\n.Xr ck_ht_entry_key 3 ,\n.Xr ck_ht_entry_key_length 3 ,\n.Xr ck_ht_entry_value 3 ,\n.Xr ck_ht_entry_set 3 ,\n.Xr ck_ht_entry_set_direct 3 ,\n.Xr ck_ht_entry_key_direct 3 ,\n.Xr ck_ht_entry_value_direct 3 ,\n.Xr ck_ht_iterator_init 3 ,\n.Xr ck_ht_next 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pflock",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2014.\n.Dt ck_pflock 3\n.Sh NAME\n.Nm ck_pflock_init ,\n.Nm ck_pflock_write_lock ,\n.Nm ck_pflock_write_unlock ,\n.Nm ck_pflock_read_lock ,\n.Nm ck_pflock_read_unlock ,\n.Nd centralized phase-fair reader-writer locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pflock.h\n.Pp\n.Dv ck_pflock_t lock = CK_PFLOCK_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_pflock_init \"ck_pflock_t *lock\"\n.Ft void\n.Fn ck_pflock_write_lock \"ck_pflock_t *lock\"\n.Ft void\n.Fn ck_pflock_write_unlock \"ck_pflock_t *lock\"\n.Ft void\n.Fn ck_pflock_read_lock \"ck_pflock_t *lock\"\n.Ft void\n.Fn ck_pflock_read_unlock \"ck_pflock_t *lock\"\n.Sh DESCRIPTION\nThis is a centralized phase-fair reader-writer lock. It\nrequires little space overhead and has a low latency\nfast path.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_pflock.h>\n\nstatic ck_pflock_t lock = CK_TFLOCK_INITIALIZER;\n\nstatic void\nreader(void)\n{\n\n\tfor (;;) {\n\t\tck_pflock_read_lock(&lock);\n\t\t/* Read-side critical section. */\n\t\tck_pflock_read_unlock(&lock);\n\t}\n\n\treturn;\n}\n\nstatic void\nwriter(void)\n{\n\n\tfor (;;) {\n\t\tck_pflock_write_lock(&lock);\n\t\t/* Write-side critical section. */\n\t\tck_pflock_write_unlock(&lock);\n\t}\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_brlock 3 ,\n.Xr ck_rwlock 3 ,\n.Xr ck_tflock 3 ,\n.Xr ck_swlock 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr 3\n.Sh NAME\n.Nm ck_pr\n.Nd concurrency primitives interface\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Sh DESCRIPTION\nck_pr.h provides an interface to volatile atomic instructions,\nmemory barriers and busy-wait facilities as provided by the\nunderlying processor. The presence of an atomic operation\nis detected by the presence of a corresponding CK_F_PR macro.\nFor example, the availability of\n.Xr ck_pr_add_16 3\nwould be determined by the presence of CK_F_PR_ADD_16.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_acquire 3 ,\n.Xr ck_pr_fence_release 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_add",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_add 3\n.Sh NAME\n.Nm ck_pr_add_ptr ,\n.Nm ck_pr_add_double ,\n.Nm ck_pr_add_char ,\n.Nm ck_pr_add_uint ,\n.Nm ck_pr_add_int ,\n.Nm ck_pr_add_64 ,\n.Nm ck_pr_add_32 ,\n.Nm ck_pr_add_16 ,\n.Nm ck_pr_add_8\n.Nd atomic addition operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_add_ptr \"void *target\" \"uintptr_t delta\"\n.Ft void\n.Fn ck_pr_add_double \"double *target\" \"double delta\"\n.Ft void\n.Fn ck_pr_add_char \"char *target\" \"char delta\"\n.Ft void\n.Fn ck_pr_add_uint \"unsigned int *target\" \"unsigned int delta\"\n.Ft void\n.Fn ck_pr_add_int \"int *target\" \"int delta\"\n.Ft void\n.Fn ck_pr_add_64 \"uint64_t *target\" \"uint64_t delta\"\n.Ft void\n.Fn ck_pr_add_32 \"uint32_t *target\" \"uint32_t delta\"\n.Ft void\n.Fn ck_pr_add_16 \"uint16_t *target\" \"uint16_t delta\"\n.Ft void\n.Fn ck_pr_add_8 \"uint8_t *target\" \"uint8_t delta\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_add 3\nfamily of functions atomically add the value specified by\n.Fa delta\nto the value pointed to by\n.Fa target .\n.Sh RETURN VALUES\nThis family of functions does not have a return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_and",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_and 3\n.Sh NAME\n.Nm ck_pr_and_ptr ,\n.Nm ck_pr_and_char ,\n.Nm ck_pr_and_uint ,\n.Nm ck_pr_and_int ,\n.Nm ck_pr_and_64 ,\n.Nm ck_pr_and_32 ,\n.Nm ck_pr_and_16 ,\n.Nm ck_pr_and_8\n.Nd atomic bitwise-and operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_and_ptr \"void *target\" \"uintptr_t delta\"\n.Ft void\n.Fn ck_pr_and_char \"char *target\" \"char delta\"\n.Ft void\n.Fn ck_pr_and_uint \"unsigned int *target\" \"unsigned int delta\"\n.Ft void\n.Fn ck_pr_and_int \"int *target\" \"int delta\"\n.Ft void\n.Fn ck_pr_and_64 \"uint64_t *target\" \"uint64_t delta\"\n.Ft void\n.Fn ck_pr_and_32 \"uint32_t *target\" \"uint32_t delta\"\n.Ft void\n.Fn ck_pr_and_16 \"uint16_t *target\" \"uint16_t delta\"\n.Ft void\n.Fn ck_pr_and_8 \"uint8_t *target\" \"uint8_t delta\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_and 3\nfamily of functions atomically compute and store the\nresult of a bitwise-and of the value pointed to by\n.Fa target\nand\n.Fa delta\ninto the value pointed to by\n.Fa target .\n.Sh RETURN VALUES\nThis family of functions does not have a return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_barrier",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_barrier 3\n.Sh NAME\n.Nm ck_pr_barrier\n.Nd compiler optimization barrier\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_barrier void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_barrier 3\nfunction is used to disable code movement optimizations\nacross the invocation of the function.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_btc",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_btc 3\n.Sh NAME\n.Nm ck_pr_btc_ptr ,\n.Nm ck_pr_btc_uint ,\n.Nm ck_pr_btc_int ,\n.Nm ck_pr_btc_64 ,\n.Nm ck_pr_btc_32 ,\n.Nm ck_pr_btc_16\n.Nd atomic bit test-and-complement operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft bool\n.Fn ck_pr_btc_ptr \"void *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btc_uint \"uint *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btc_int \"int *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btc_64 \"uint64_t *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btc_32 \"uint32_t *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btc_16 \"uint16_t *target\" \"unsigned int bit_index\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_btc 3\nfamily of functions atomically fetch the value\nof the bit in\n.Fa target\nat index\n.Fa bit_index\nand set that bit to its complement.\n.Sh RETURN VALUES\nThese family of functions return the original value of\nthe bit at offset\n.Fa bit_index\nthat is in the value pointed to by\n.Fa target .\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_btr 3 ,\n.Xr ck_pr_cas 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_btr",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_btr 3\n.Sh NAME\n.Nm ck_pr_btr_ptr ,\n.Nm ck_pr_btr_uint ,\n.Nm ck_pr_btr_int ,\n.Nm ck_pr_btr_64 ,\n.Nm ck_pr_btr_32 ,\n.Nm ck_pr_btr_16\n.Nd atomic bit test-and-reset operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft bool\n.Fn ck_pr_btr_ptr \"void *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btr_uint \"uint *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btr_int \"int *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btr_64 \"uint64_t *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btr_32 \"uint32_t *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_btr_16 \"uint16_t *target\" \"unsigned int bit_index\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_btr 3\nfamily of functions atomically fetch the value\nof the bit in\n.Fa target\nat index\n.Fa bit_index\nand set that bit to 0.\n.Sh RETURN VALUES\nThis family of functions returns the original value of\nthe bit at offset\n.Fa bit_index\nthat is in the value pointed to by\n.Fa target .\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_cas 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_bts",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_bts 3\n.Sh NAME\n.Nm ck_pr_bts_ptr ,\n.Nm ck_pr_bts_uint ,\n.Nm ck_pr_bts_int ,\n.Nm ck_pr_bts_64 ,\n.Nm ck_pr_bts_32 ,\n.Nm ck_pr_bts_16\n.Nd atomic bit test-and-set operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft bool\n.Fn ck_pr_bts_ptr \"void *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_bts_uint \"uint *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_bts_int \"int *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_bts_64 \"uint64_t *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_bts_32 \"uint32_t *target\" \"unsigned int bit_index\"\n.Ft bool\n.Fn ck_pr_bts_16 \"uint16_t *target\" \"unsigned int bit_index\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_bts 3\nfamily of functions atomically fetch the value\nof the bit in\n.Fa target\nat index\n.Fa bit_index\nand set that bit to 1.\n.Sh RETURN VALUES\nThis family of functions returns the original value of\nthe bit at offset\n.Fa bit_index\nthat is in the value pointed to by\n.Fa target .\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_btr 3 ,\n.Xr ck_pr_cas 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_cas",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_cas 3\n.Sh NAME\n.Nm ck_pr_cas_ptr ,\n.Nm ck_pr_cas_ptr_value ,\n.Nm ck_pr_cas_ptr_2 ,\n.Nm ck_pr_cas_ptr_2_value ,\n.Nm ck_pr_cas_double ,\n.Nm ck_pr_cas_double_value ,\n.Nm ck_pr_cas_char ,\n.Nm ck_pr_cas_char_value ,\n.Nm ck_pr_cas_uint ,\n.Nm ck_pr_cas_uint_value ,\n.Nm ck_pr_cas_int ,\n.Nm ck_pr_cas_int_value ,\n.Nm ck_pr_cas_64_2 ,\n.Nm ck_pr_cas_64_2_value ,\n.Nm ck_pr_cas_64 ,\n.Nm ck_pr_cas_64_value ,\n.Nm ck_pr_cas_32 ,\n.Nm ck_pr_cas_32_value ,\n.Nm ck_pr_cas_16 ,\n.Nm ck_pr_cas_16_value ,\n.Nm ck_pr_cas_8 ,\n.Nm ck_pr_cas_8_value\n.Nd atomic compare-and-swap operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft bool\n.Fn ck_pr_cas_ptr \"void *target\" \"void *old_value\" \"void *new_value\"\n.Ft bool\n.Fn ck_pr_cas_ptr_value \"void *target\" \"void *old_value\" \"void *new_value\" \"void *original_value\"\n.Ft bool\n.Fn ck_pr_cas_ptr_2 \"void *target\" \"void *old_value\" \"void *new_value\"\n.Ft bool\n.Fn ck_pr_cas_ptr_2_value \"void *target\" \"void *old_value\" \"void *new_value\" \"void *original_value\"\n.Ft bool\n.Fn ck_pr_cas_double \"double *target\" \"double old_value\" \"double new_value\"\n.Ft bool\n.Fn ck_pr_cas_double_value \"double *target\" \"double old_value\" \"double new_value\" \"double *original_value\"\n.Ft bool\n.Fn ck_pr_cas_char \"char *target\" \"char old_value\" \"char new_value\"\n.Ft bool\n.Fn ck_pr_cas_char_value \"char *target\" \"char old_value\" \"char new_value\" \"char *original_value\"\n.Ft bool\n.Fn ck_pr_cas_uint \"unsigned int *target\" \"unsigned int old_value\" \"unsigned int new_value\"\n.Ft bool\n.Fn ck_pr_cas_uint_value \"unsigned int *target\" \"unsigned int old_value\" \"unsigned int new_value\" \"unsigned int *original_value\"\n.Ft bool\n.Fn ck_pr_cas_int \"int *target\" \"int old_value\" \"int new_value\"\n.Ft bool\n.Fn ck_pr_cas_int_value \"int *target\" \"int old_value\" \"int new_value\" \"int *original_value\"\n.Ft bool\n.Fn ck_pr_cas_64_2 \"uint64_t target[static 2]\" \"uint64_t old_value[static 2]\" \"uint64_t new_value[static 2]\"\n.Ft bool\n.Fn ck_pr_cas_64_2_value \"uint64_t target[static 2]\" \"uint64_t old_value[static 2]\" \"uint64_t new_value[static 2]\" \"uint64_t original_value[static 2]\"\n.Ft bool\n.Fn ck_pr_cas_64 \"uint64_t *target\" \"uint64_t old_value\" \"uint64_t new_value\"\n.Ft bool\n.Fn ck_pr_cas_64_value \"uint64_t *target\" \"uint64_t old_value\" \"uint64_t new_value\" \"uint64_t *original_value\"\n.Ft bool\n.Fn ck_pr_cas_32 \"uint32_t *target\" \"uint32_t old_value\" \"uint32_t new_value\"\n.Ft bool\n.Fn ck_pr_cas_32_value \"uint32_t *target\" \"uint32_t old_value\" \"uint32_t new_value\" \"uint32_t *original_value\"\n.Ft bool\n.Fn ck_pr_cas_16 \"uint16_t *target\" \"uint16_t old_value\" \"uint16_t new_value\"\n.Ft bool\n.Fn ck_pr_cas_16_value \"uint16_t *target\" \"uint16_t old_value\" \"uint16_t new_value\" \"uint16_t *original_value\"\n.Ft bool\n.Fn ck_pr_cas_8 \"uint8_t *target\" \"uint8_t old_value\" \"uint8_t new_value\"\n.Ft bool\n.Fn ck_pr_cas_8_value \"uint8_t *target\" \"uint8_t old_value\" \"uint8_t new_value\" \"uint8_t *original_value\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_cas 3\nfamily of functions atomically compare the value in\n.Fa target\nfor equality with\n.Fa old_value\nand if so, replace the value pointed to by\n.Fa target\nwith the value specified by\n.Fa new_value .\nIf the value in\n.Fa target\nwas not equal to the value specified by\n.Fa old_value\nthen no modifications occur to the value in\n.Fa target .\nThe *_value form of these functions unconditionally update\n.Fa original_value .\n.Sh RETURN VALUES\nThis family of functions return true if the value in\n.Fa target\nwas modified as a result of the operation. Otherwise, they\nreturn false.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_dec",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_dec 3\n.Sh NAME\n.Nm ck_pr_dec_ptr ,\n.Nm ck_pr_dec_ptr_zero ,\n.Nm ck_pr_dec_double ,\n.Nm ck_pr_dec_double_zero ,\n.Nm ck_pr_dec_char ,\n.Nm ck_pr_dec_char_zero ,\n.Nm ck_pr_dec_uint ,\n.Nm ck_pr_dec_uint_zero ,\n.Nm ck_pr_dec_int ,\n.Nm ck_pr_dec_int_zero ,\n.Nm ck_pr_dec_64 ,\n.Nm ck_pr_dec_64_zero ,\n.Nm ck_pr_dec_32 ,\n.Nm ck_pr_dec_32_zero ,\n.Nm ck_pr_dec_16 ,\n.Nm ck_pr_dec_16_zero ,\n.Nm ck_pr_dec_8 ,\n.Nm ck_pr_dec_8_zero\n.Nd atomic decrement operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_dec_ptr \"void *target\"\n.Ft void\n.Fn ck_pr_dec_ptr_zero \"void *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_double \"double *target\"\n.Ft void\n.Fn ck_pr_dec_double_zero \"double *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_char \"char *target\"\n.Ft void\n.Fn ck_pr_dec_char_zero \"char *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_uint \"unsigned int *target\"\n.Ft void\n.Fn ck_pr_dec_uint_zero \"unsigned int *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_int \"int *target\"\n.Ft void\n.Fn ck_pr_dec_int_zero \"int *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_64 \"uint64_t *target\"\n.Ft void\n.Fn ck_pr_dec_64_zero \"uint64_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_32 \"uint32_t *target\"\n.Ft void\n.Fn ck_pr_dec_32_zero \"uint32_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_16 \"uint16_t *target\"\n.Ft void\n.Fn ck_pr_dec_16_zero \"uint16_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_dec_8 \"uint8_t *target\"\n.Ft void\n.Fn ck_pr_dec_8_zero \"uint8_t *target\" \"bool *z\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_dec 3\nfamily of functions atomically decrement the value pointed to\nby\n.Fa target .\n.Sh RETURN VALUES\nThe ck_pr_dec_zero family of functions set the value pointed to by\n.Fa z\nto true if the result\nof the decrement operation was 0. They set the value pointed to by\n.Fa z\nto false otherwise.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_faa",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_faa 3\n.Sh NAME\n.Nm ck_pr_faa_ptr ,\n.Nm ck_pr_faa_double ,\n.Nm ck_pr_faa_char ,\n.Nm ck_pr_faa_uint ,\n.Nm ck_pr_faa_int ,\n.Nm ck_pr_faa_64 ,\n.Nm ck_pr_faa_32 ,\n.Nm ck_pr_faa_16 ,\n.Nm ck_pr_faa_8\n.Nd atomic fetch-and-add operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft uintptr_t\n.Fn ck_pr_faa_ptr \"void *target\" \"uintptr_t delta\"\n.Ft double\n.Fn ck_pr_faa_double \"double *target\" \"double delta\"\n.Ft char\n.Fn ck_pr_faa_char \"char *target\" \"char delta\"\n.Ft unsigned int\n.Fn ck_pr_faa_uint \"unsigned int *target\" \"unsigned int delta\"\n.Ft int\n.Fn ck_pr_faa_int \"int *target\" \"int delta\"\n.Ft uint64_t\n.Fn ck_pr_faa_64 \"uint64_t *target\" \"uint64_t delta\"\n.Ft uint32_t\n.Fn ck_pr_faa_32 \"uint32_t *target\" \"uint32_t delta\"\n.Ft uint16_t\n.Fn ck_pr_faa_16 \"uint16_t *target\" \"uint16_t delta\"\n.Ft uint8_t\n.Fn ck_pr_faa_8 \"uint8_t *target\" \"uint8_t delta\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_faa 3\nfamily of functions atomically fetch the value pointed to\nby\n.Fa target\nand add the value specified by\n.Fa delta\nto the value pointed to by\n.Fa target .\n.Sh RETURN VALUES\nThis function returns the value pointed to by\n.Fa target\nat the time of operation invocation before the\naddition operation is applied.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fas",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_fas 3\n.Sh NAME\n.Nm ck_pr_fas_ptr ,\n.Nm ck_pr_fas_double ,\n.Nm ck_pr_fas_char ,\n.Nm ck_pr_fas_uint ,\n.Nm ck_pr_fas_int ,\n.Nm ck_pr_fas_64 ,\n.Nm ck_pr_fas_32 ,\n.Nm ck_pr_fas_16 ,\n.Nm ck_pr_fas_8\n.Nd atomic swap operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void *\n.Fn ck_pr_fas_ptr \"void *target\" \"void *new_value\"\n.Ft double\n.Fn ck_pr_fas_double \"double *target\" \"double new_value\"\n.Ft char\n.Fn ck_pr_fas_char \"char *target\" \"char new_value\"\n.Ft unsigned int\n.Fn ck_pr_fas_uint \"unsigned int *target\" \"unsigned int new_value\"\n.Ft int\n.Fn ck_pr_fas_int \"int *target\" \"int new_value\"\n.Ft uint64_t\n.Fn ck_pr_fas_64 \"uint64_t *target\" \"uint64_t new_value\"\n.Ft uint32_t\n.Fn ck_pr_fas_32 \"uint32_t *target\" \"uint32_t new_value\"\n.Ft uint16_t\n.Fn ck_pr_fas_16 \"uint16_t *target\" \"uint16_t new_value\"\n.Ft uint8_t\n.Fn ck_pr_fas_8 \"uint8_t *target\" \"uint8_t new_value\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fas 3\nfamily of functions atomically fetch the value pointed to\nby\n.Fa target\nand replace the value pointed to by\n.Fa target\nwith the value specified by\n.Fa new_value .\n.Sh RETURN VALUES\nThis function returns the value pointed to by\n.Fa target\nat the time of operation invocation before it was\natomically replaced with\n.Fa new_value .\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_acquire",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd January 2, 2014\n.Dt CK_PR_FENCE_ACQUIRE 3\n.Sh NAME\n.Nm ck_pr_fence_acquire\n.Nd enforce acquire semantics\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_acquire void\n.Sh DESCRIPTION\nThis function enforces the partial ordering of any loads prior\nto invocation with respect to any following stores, loads and\natomic operations. It is typically used to implement critical\nsections.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_release 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_atomic",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 16, 2013\n.Dt CK_PR_FENCE_ATOMIC 3\n.Sh NAME\n.Nm ck_pr_fence_atomic\n.Nd enforce partial ordering of atomic read-modify-write operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_atomic void\n.Ft void\n.Fn ck_pr_fence_strict_atomic void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_atomic\nfunction enforces the ordering of any\natomic read-modify-write operations relative to\nthe invocation of the function. This function\nalways serve as an implicit compiler barrier. On\narchitectures implementing CK_MD_TSO, this operation\nonly serves as a compiler barrier and no fences\nare emitted. On architectures implementing\nCK_MD_PSO and CK_MD_RMO, a store fence is\nemitted. To force the unconditional emission of\na fence, use\n.Fn ck_pr_fence_strict_atomic .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b = 0;\nstatic int c = 0;\n\nvoid\nfunction(void)\n{\n\n\tck_pr_fas_int(&a, 1);\n\n\t/*\n\t * Guarantee that the update to a is completed\n\t * with respect to the updates of b and c.\n\t */\n\tck_pr_fence_atomic();\n\tck_pr_fas_int(&b, 2);\n\tck_pr_fas_int(&c, 2);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_atomic_load",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 16, 2013\n.Dt CK_PR_FENCE_ATOMIC_LOAD 3\n.Sh NAME\n.Nm ck_pr_fence_atomic_load\n.Nd enforce ordering of atomic read-modify-write operations to load operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_atomic_load void\n.Ft void\n.Fn ck_pr_fence_strict_atomic_load void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_atomic_load\nfunction enforces the ordering of any\natomic read-modify-write operations relative to\nany load operations following the function invocation. This function\nalways serve as an implicit compiler barrier. On\narchitectures implementing CK_MD_TSO, this operation\nonly serves as a compiler barrier and no fences\nare emitted. To force the unconditional emission of\na fence, use\n.Fn ck_pr_fence_strict_atomic_load .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b = 0;\n\nvoid\nfunction(void)\n{\n\tint c;\n\n\tck_pr_fas_int(&a, 1);\n\n\t/*\n\t * Guarantee that the update to a is completed\n\t * with respect to the load of *b.\n\t */\n\tck_pr_fence_atomic_load();\n\tc = ck_pr_load_int(&b);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_atomic_store",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 16, 2013\n.Dt CK_PR_FENCE_ATOMIC_STORE 3\n.Sh NAME\n.Nm ck_pr_fence_atomic_store\n.Nd enforce ordering of atomic read-modify-write operations to store operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_atomic_store void\n.Ft void\n.Fn ck_pr_fence_strict_atomic_store void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_atomic_store\nfunction enforces the ordering of any\natomic read-modify-write operations relative to\nany load operations following the function invocation. This function\nalways serve as an implicit compiler barrier. On\narchitectures implementing CK_MD_TSO, this operation\nonly serves as a compiler barrier and no fences\nare emitted. To force the unconditional emission of\na fence, use\n.Fn ck_pr_fence_strict_atomic_store .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b = 0;\n\nvoid\nfunction(void)\n{\n\tint c;\n\n\tck_pr_fas_int(&a, 1);\n\n\t/*\n\t * Guarantee that the update to a is completed\n\t * with respect to the store into the value pointed\n\t * to by b.\n\t */\n\tck_pr_fence_atomic_store();\n\tc = ck_pr_store_int(&b, 2);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_load",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_fence_load 3\n.Sh NAME\n.Nm ck_pr_fence_load\n.Nd enforce partial ordering of load operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_load void\n.Ft void\n.Fn ck_pr_fence_strict_load void\n.Sh DESCRIPTION\nThis function enforces the ordering of any memory load\nand\n.Fn ck_pr_load 3\noperations relative to the invocation of the function. Any\nstore operations that were committed on remote processors\nand received by the calling processor before the invocation of\n.Fn ck_pr_fence_load\nis also be made visible only after a call to\n.Fn ck_pr_fence_load .\nThis function always serves as an implicit compiler barrier.\nOn architectures with CK_MD_TSO or CK_MD_PSO specified (total store ordering\nand partial store ordering respectively), this operation only serves\nas a compiler barrier and no fence instructions will be emitted. To\nforce the unconditional emission of a load fence, use\n.Fn ck_pr_fence_strict_load .\nArchitectures implementing CK_MD_RMO always emit a load fence.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic unsigned int a;\nstatic unsigned int b;\n\nvoid\nfunction(void)\n{\n\tunsigned int snapshot_a, snapshot_b;\n\n\tsnapshot_a = ck_pr_load_uint(&a);\n\n\t/*\n\t * Guarantee that the load from \"a\" completes\n\t * before the load from \"b\".\n\t */\n\tck_pr_fence_load();\n\tsnapshot_b = ck_pr_load_uint(&b);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_load_atomic",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 18, 2013\n.Dt CK_PR_FENCE_LOAD_ATOMIC 3\n.Sh NAME\n.Nm ck_pr_fence_load_atomic\n.Nd enforce ordering of load operations to atomic read-modify-write operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_load_atomic void\n.Ft void\n.Fn ck_pr_fence_strict_load_atomic void\n.Sh DESCRIPTION\nThis function enforces the ordering of any memory load\nand\n.Fn ck_pr_load 3\noperations with respect to store operations relative to\nthe invocation of the function. Any store operations that\nwere committed on remote processors\nand received by the calling processor before the invocation of\n.Fn ck_pr_fence_load_atomic\nis also be made visible only after a call to\nthe ck_pr_fence_load family of functions.\nThis function always serves as an implicit compiler barrier.\nOn architectures with CK_MD_TSO or CK_MD_PSO specified (total store ordering\nand partial store ordering respectively), this operation only serves\nas a compiler barrier and no fence instructions will be emitted. To\nforce the unconditional emission of a load fence, use\n.Fn ck_pr_fence_strict_load_atomic .\nArchitectures implementing CK_MD_RMO always emit a fence.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic unsigned int a;\nstatic unsigned int b;\n\nvoid\nfunction(void)\n{\n\tunsigned int snapshot_a, snapshot_b;\n\n\tsnapshot_a = ck_pr_load_uint(&a);\n\n\t/*\n\t * Guarantee that the load from \"a\" completes\n\t * before the update to \"b\".\n\t */\n\tck_pr_fence_load_atomic();\n\tck_pr_fas_uint(&b, 1);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_load_depends",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_fence_load_depends 3\n.Sh NAME\n.Nm ck_pr_fence_load_depends\n.Nd data dependency barrier\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_load_depends void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_load_depends 3\nemits necessary fences for pure data-dependent loads. It currently only serves as a compiler\nbarrier for Concurrency Kit's supported platforms. Unless you're on architecture\nwhich re-orders data-dependent loads (such as the defunct Alpha), this function is unnecessary.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_load_store",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 18, 2013\n.Dt CK_PR_FENCE_LOAD_STORE 3\n.Sh NAME\n.Nm ck_pr_fence_load_store\n.Nd enforce ordering of load operations to store operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_load_store void\n.Ft void\n.Fn ck_pr_fence_strict_load_store void\n.Sh DESCRIPTION\nThis function enforces the ordering of any memory load\nand\n.Fn ck_pr_load 3\noperations with respect to store operations relative to\nthe invocation of the function. Any store operations that\nwere committed on remote processors\nand received by the calling processor before the invocation of\n.Fn ck_pr_fence_load_store\nis also be made visible only after a call to\nthe ck_pr_fence_load family of functions.\nThis function always serves as an implicit compiler barrier.\nOn architectures with CK_MD_TSO or CK_MD_PSO specified (total store ordering\nand partial store ordering respectively), this operation only serves\nas a compiler barrier and no fence instructions will be emitted. To\nforce the unconditional emission of a load fence, use\n.Fn ck_pr_fence_strict_load_store .\nArchitectures implementing CK_MD_RMO always emit a fence.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic unsigned int a;\nstatic unsigned int b;\n\nvoid\nfunction(void)\n{\n\tunsigned int snapshot_a;\n\n\tsnapshot_a = ck_pr_load_uint(&a);\n\n\t/*\n\t * Guarantee that the load from \"a\" completes\n\t * before the store to \"b\".\n\t */\n\tck_pr_fence_load_store();\n\tck_pr_store_uint(&b, 1);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_memory",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_fence_memory 3\n.Sh NAME\n.Nm ck_pr_fence_memory\n.Nd enforce partial ordering of all memory operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_memory\n.Ft void\n.Fn ck_pr_fence_strict_memory\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_memory 3\nfunction enforces the ordering of any memory operations\nwith respect to the invocation of the function. This function\nalways serves as an implicit compiler barrier.\nAchitectures implementing CK_MD_TSO do not emit\na barrier, but compiler barrier semantics remain.\nArchitectures implementing CK_MD_PSO and CK_MD_RMO always emit\nan instructions which provides the specified ordering\nguarantees. To force the unconditional emission of a memory\nfence, use\n.Fn ck_pr_fence_strict_memory .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b;\nstatic int c;\nstatic int d;\n\nvoid\nfunction(void)\n{\n\tint snapshot_a;\n\n\tck_pr_store_int(&b, 1);\n\tsnapshot_a = ck_pr_load_int(&a);\n\n\t/*\n\t * Make sure previous memory operations are\n\t * ordered with respect to memory operations\n\t * following the ck_pr_fence_memory.\n\t */\n\tck_pr_fence_memory();\n\n\tck_pr_store_int(&d, 3);\n\tck_pr_store_int(&c, 2);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_release",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd January 2, 2014\n.Dt CK_PR_FENCE_RELEASE 3\n.Sh NAME\n.Nm ck_pr_fence_release\n.Nd enforce release semantics\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_release void\n.Sh DESCRIPTION\nThis function enforces the partial ordering of any loads prior\nto invocation with respect to any following stores and any stores\nprior to invocation with respect to any following stores.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_acquire 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_store",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_fence_store 3\n.Sh NAME\n.Nm ck_pr_fence_store\n.Nd enforce partial ordering of store operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_store void\n.Ft void\n.Fn ck_pr_fence_strict_store void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_store\nfunction enforces the ordering of any memory store,\n.Fn ck_pr_store\nand atomic read-modify-write operations relative to\nthe invocation of the function. This function\nalways serve as an implicit compiler barrier. On\narchitectures implementing CK_MD_TSO, this operation\nonly serves as a compiler barrier and no fences\nare emitted. On architectures implementing\nCK_MD_PSO and CK_MD_RMO, a store fence is\nemitted. To force the unconditional emission of\na store fence, use\n.Fn ck_pr_fence_strict_store .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b = 0;\nstatic int c = 0;\n\nvoid\nfunction(void)\n{\n\n\tck_pr_store_int(&a, 1);\n\n\t/*\n\t * Guarantee that the store to a is completed\n\t * with respect to the stores of b and c.\n\t */\n\tck_pr_fence_store();\n\tck_pr_store_int(&b, 2);\n\tck_pr_store_int(&c, 2);\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_store_atomic",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 18, 2013\n.Dt CK_PR_FENCE_STORE_ATOMIC 3\n.Sh NAME\n.Nm ck_pr_fence_store_atomic\n.Nd enforce ordering of store operations to load operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_store_atomic void\n.Ft void\n.Fn ck_pr_fence_strict_store_atomic void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_store_atomic\nfunction enforces the ordering of any memory store,\n.Fn ck_pr_store\nand atomic read-modify-write operations to atomic read-modify-write\noperations relative to the invocation of the function. This function\nalways serve as an implicit compiler barrier.\nThis functions will emit a fence for PSO and RMO\ntargets. In order to force the emission of a fence use the\n.Fn ck_pr_fence_strict_store_atomic\nfunction.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b = 0;\n\nvoid\nfunction(void)\n{\n\n\tck_pr_store_int(&a, 1);\n\n\t/*\n\t * Guarantee that the store to a is completed\n\t * with respect to the update of b.\n\t */\n\tck_pr_fence_store_atomic();\n\tck_pr_add_int(&b, 2);\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_store_load 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_fence_store_load",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 18, 2013\n.Dt CK_PR_FENCE_STORE_LOAD 3\n.Sh NAME\n.Nm ck_pr_fence_store_load\n.Nd enforce ordering of store operations to load operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_fence_store_load void\n.Ft void\n.Fn ck_pr_fence_strict_store_load void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_fence_store_load\nfunction enforces the ordering of any memory store,\n.Fn ck_pr_store\nand atomic read-modify-write operations to load\noperations relative to the invocation of the function. This function\nalways serve as an implicit compiler barrier.\nA fence will currently always be emitted for this\noperation, including for TSO memory model targets.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int a = 0;\nstatic int b = 0;\n\nvoid\nfunction(void)\n{\n\tunsigned int snapshot_b;\n\n\tck_pr_store_int(&a, 1);\n\n\t/*\n\t * Guarantee that the store to a is completed\n\t * with respect to load from b.\n\t */\n\tck_pr_fence_store_load();\n\tsnapshot_b = ck_pr_load_int(&b, 2);\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_stall 3 ,\n.Xr ck_pr_fence_atomic 3 ,\n.Xr ck_pr_fence_atomic_store 3 ,\n.Xr ck_pr_fence_atomic_load 3 ,\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_atomic 3 ,\n.Xr ck_pr_fence_load_store 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_store_atomic 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_inc",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_inc 3\n.Sh NAME\n.Nm ck_pr_inc_ptr ,\n.Nm ck_pr_inc_ptr_zero ,\n.Nm ck_pr_inc_double ,\n.Nm ck_pr_inc_double_zero ,\n.Nm ck_pr_inc_char ,\n.Nm ck_pr_inc_char_zero ,\n.Nm ck_pr_inc_uint ,\n.Nm ck_pr_inc_uint_zero ,\n.Nm ck_pr_inc_int ,\n.Nm ck_pr_inc_int_zero ,\n.Nm ck_pr_inc_64 ,\n.Nm ck_pr_inc_64_zero ,\n.Nm ck_pr_inc_32 ,\n.Nm ck_pr_inc_32_zero ,\n.Nm ck_pr_inc_16 ,\n.Nm ck_pr_inc_16_zero ,\n.Nm ck_pr_inc_8 ,\n.Nm ck_pr_inc_8_zero\n.Nd atomic increment operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_inc_ptr \"void *target\"\n.Ft void\n.Fn ck_pr_inc_ptr_zero \"void *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_double \"double *target\"\n.Ft void\n.Fn ck_pr_inc_double_zero \"double *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_char \"char *target\"\n.Ft void\n.Fn ck_pr_inc_char_zero \"char *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_uint \"unsigned int *target\"\n.Ft void\n.Fn ck_pr_inc_uint_zero \"unsigned int *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_int \"int *target\"\n.Ft void\n.Fn ck_pr_inc_int_zero \"int *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_64 \"uint64_t *target\"\n.Ft void\n.Fn ck_pr_inc_64_zero \"uint64_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_32 \"uint32_t *target\"\n.Ft void\n.Fn ck_pr_inc_32_zero \"uint32_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_16 \"uint16_t *target\"\n.Ft void\n.Fn ck_pr_inc_16_zero \"uint16_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_inc_8 \"uint8_t *target\"\n.Ft void\n.Fn ck_pr_inc_8_zero \"uint8_t *target\" \"bool *z\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_inc 3\nfamily of functions atomically increment the value pointed to\nby\n.Fa target .\n.Sh RETURN VALUES\nThe ck_pr_inc_zero family of functions set the value pointed to by\n.Fa z\nto true if the result of the increment operation was 0. The functions set\nthe value pointed to by\n.Fa z\nfalse otherwise.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_load",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 15, 2013\n.Dt ck_pr_load 3\n.Sh NAME\n.Nm ck_pr_load_ptr ,\n.Nm ck_pr_load_double ,\n.Nm ck_pr_load_uint ,\n.Nm ck_pr_load_int ,\n.Nm ck_pr_load_char ,\n.Nm ck_pr_load_64 ,\n.Nm ck_pr_load_32 ,\n.Nm ck_pr_load_16 ,\n.Nm ck_pr_load_8\n.Nd atomic volatile load operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void *\n.Fn ck_pr_load_ptr \"const void *target\"\n.Ft double\n.Fn ck_pr_load_double \"const double *target\"\n.Ft unsigned int\n.Fn ck_pr_load_uint \"const unsigned int *target\"\n.Ft int\n.Fn ck_pr_load_int \"const int *target\"\n.Ft char\n.Fn ck_pr_load_char \"const char *target\"\n.Ft uint64_t\n.Fn ck_pr_load_64 \"const uint64_t *target\"\n.Ft uint32_t\n.Fn ck_pr_load_32 \"const uint32_t *target\"\n.Ft uint16_t\n.Fn ck_pr_load_16 \"const uint16_t *target\"\n.Ft uint8_t\n.Fn ck_pr_load_8 \"const uint8_t *target\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_load 3\nfamily of functions atomically loads the value\npointed to by\n.Fa target\nand returns it. This family of functions always\nserves as an implicit compiler barrier and is not\nsusceptible to re-ordering by the compiler.\n.Sh RETURN VALUES\nThis family of functions returns the value contained\nin the location pointed to by the first argument.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_neg",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_neg 3\n.Sh NAME\n.Nm ck_pr_neg_ptr ,\n.Nm ck_pr_neg_ptr_zero ,\n.Nm ck_pr_neg_double ,\n.Nm ck_pr_neg_double_zero ,\n.Nm ck_pr_neg_char ,\n.Nm ck_pr_neg_char_zero ,\n.Nm ck_pr_neg_uint ,\n.Nm ck_pr_neg_uint_zero ,\n.Nm ck_pr_neg_int ,\n.Nm ck_pr_neg_int_zero ,\n.Nm ck_pr_neg_64 ,\n.Nm ck_pr_neg_64_zero ,\n.Nm ck_pr_neg_32 ,\n.Nm ck_pr_neg_32_zero ,\n.Nm ck_pr_neg_16 ,\n.Nm ck_pr_neg_16_zero ,\n.Nm ck_pr_neg_8 ,\n.Nm ck_pr_neg_8_zero\n.Nd atomic negation operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_neg_ptr \"void *target\"\n.Ft void\n.Fn ck_pr_neg_ptr_zero \"void *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_double \"double *target\"\n.Ft void\n.Fn ck_pr_neg_double_zero \"double *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_char \"char *target\"\n.Ft void\n.Fn ck_pr_neg_char_zero \"char *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_uint \"unsigned int *target\"\n.Ft void\n.Fn ck_pr_neg_uint_zero \"unsigned int *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_int \"int *target\"\n.Ft void\n.Fn ck_pr_neg_int_zero \"int *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_64 \"uint64_t *target\"\n.Ft void\n.Fn ck_pr_neg_64_zero \"uint64_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_32 \"uint32_t *target\"\n.Ft void\n.Fn ck_pr_neg_32_zero \"uint32_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_16 \"uint16_t *target\"\n.Ft void\n.Fn ck_pr_neg_16_zero \"uint16_t *target\" \"bool *z\"\n.Ft void\n.Fn ck_pr_neg_8 \"uint8_t *target\"\n.Ft void\n.Fn ck_pr_neg_8_zero \"uint8_t *target\" \"bool *z\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_neg 3\nfamily of functions atomically negate the value pointed to\nby\n.Fa target .\n.Sh RETURN VALUES\nThe ck_pr_neg_zero functions set the value pointed to by\n.Fa z\nif the result of the negation operation was 0. They set the\npointed to value to false otherwise.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_not",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_not 3\n.Sh NAME\n.Nm ck_pr_not_ptr ,\n.Nm ck_pr_not_double ,\n.Nm ck_pr_not_char ,\n.Nm ck_pr_not_uint ,\n.Nm ck_pr_not_int ,\n.Nm ck_pr_not_64 ,\n.Nm ck_pr_not_32 ,\n.Nm ck_pr_not_16 ,\n.Nm ck_pr_not_8\n.Nd atomic complement operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_not_ptr \"void *target\"\n.Ft void\n.Fn ck_pr_not_double \"double *target\"\n.Ft void\n.Fn ck_pr_not_char \"char *target\"\n.Ft void\n.Fn ck_pr_not_uint \"unsigned int *target\"\n.Ft void\n.Fn ck_pr_not_int \"int *target\"\n.Ft void\n.Fn ck_pr_not_64 \"uint64_t *target\"\n.Ft void\n.Fn ck_pr_not_32 \"uint32_t *target\"\n.Ft void\n.Fn ck_pr_not_16 \"uint16_t *target\"\n.Ft void\n.Fn ck_pr_not_8 \"uint8_t *target\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_not 3\nfamily of functions atomically complement the value pointed to\nby\n.Fa target .\n.Sh RETURN VALUES\nThese functions have no return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_or",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_or 3\n.Sh NAME\n.Nm ck_pr_or_ptr ,\n.Nm ck_pr_or_char ,\n.Nm ck_pr_or_uint ,\n.Nm ck_pr_or_int ,\n.Nm ck_pr_or_64 ,\n.Nm ck_pr_or_32 ,\n.Nm ck_pr_or_16 ,\n.Nm ck_pr_or_8\n.Nd atomic bitwise-or operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_or_ptr \"void *target\" \"uintptr_t delta\"\n.Ft void\n.Fn ck_pr_or_char \"char *target\" \"char delta\"\n.Ft void\n.Fn ck_pr_or_uint \"unsigned int *target\" \"unsigned int delta\"\n.Ft void\n.Fn ck_pr_or_int \"int *target\" \"int delta\"\n.Ft void\n.Fn ck_pr_or_64 \"uint64_t *target\" \"uint64_t delta\"\n.Ft void\n.Fn ck_pr_or_32 \"uint32_t *target\" \"uint32_t delta\"\n.Ft void\n.Fn ck_pr_or_16 \"uint16_t *target\" \"uint16_t delta\"\n.Ft void\n.Fn ck_pr_or_8 \"uint8_t *target\" \"uint8_t delta\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_or 3\nfamily of functions atomically compute and store the\nresult of a bitwise-or of the value pointed to by\n.Fa target\nand\n.Fa delta\ninto the value pointed to by\n.Fa target .\n.Sh RETURN VALUES\nThis family of functions does not have a return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_rtm",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 17, 2013\n.Dt ck_pr_rtm 3\n.Sh NAME\n.Nm ck_pr_rtm_begin ,\n.Nm ck_pr_rtm_end ,\n.Nm ck_pr_rtm_abort ,\n.Nm ck_pr_rtm_test\n.Nd restricted transactional memory\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft unsigned int\n.Fn ck_pr_rtm_begin \"void\"\n.Ft void\n.Fn ck_pr_rtm_end \"void\"\n.Ft void\n.Fn ck_pr_rtm_abort \"const unsigned int status\"\n.Ft bool\n.Fn ck_pr_rtm_test \"void\"\n.Sh DESCRIPTION\nThese family of functions implement support for restricted\ntransactional memory, if available on the underlying platform.\nCurrently, support is only provided for Intel Haswell and\nnewer x86 microarchitectures that have the TSX-NI feature.\n.Pp\nThe\n.Fn ck_pr_rtm_begin\nfunction returns CK_PR_RTM_STARTED if a transaction was successfully\nstarted. In case of an abort, either internal (through a ck_pr_rtm_abort)\nor external, program flow will return to the point which the function\nwas called except the return value will consist of a bitmap with one or\nmore of the following bits set:\n.Bl -tag -width indent\n.It CK_PR_RTM_EXPLICIT\nSet if the transactionally was explicitly aborted through\n.Fn ck_pr_rtm_abort .\n.It CK_PR_RTM_RETRY\nSet if the transaction failed but can still succeed if\nretried.\n.It CK_PR_RTM_CONFLICT\nThe transaction failed due to a conflict in one of the memory\naddresses that are part of the working set of the transaction.\n.It CK_PR_RTM_CAPACITY\nSet if the architecture-defined transaction size limit was exceeded.\n.It CK_PR_RTM_DEBUG\nSet if a hardware breakpoint was triggered.\n.It CK_PR_RTM_NESTED\nSet if a nested transaction failed.\n.El\n.Pp\nThe user is also able to specify a one byte abort status\nby calling\n.Fn ck_pr_rtm_abort .\nThis status byte can be extracted by calling the\n.Fn CK_PR_RTM_CODE\nfunction with the return value of\n.Fn ck_pr_rtm_begin\nas an argument. The return value of\n.Fn CK_PR_RTM_CODE\nwill be the value of this status byte.\nFor additional information, please see the Intel instruction\nset manuals.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_stall",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 7, 2013\n.Dt ck_pr_stall 3\n.Sh NAME\n.Nm ck_pr_stall\n.Nd busy-wait primitive\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_stall void\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_stall 3\nfunction should be used inside retry paths of busy-wait loops.\nIt not only serves as a compiler barrier, but on some architectures\nit emits cycle-saving instructions.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n\n#include <ck_pr.h>\n\nstatic int ready = 0;\n\nvoid\nfunction(void)\n{\n\n\t/* Busy-wait until ready is non-zero. */\n\twhile (ck_pr_load_int(&ready) == 0)\n\t\tck_pr_stall();\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_barrier 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_store",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 15, 2013\n.Dt ck_pr_store 3\n.Sh NAME\n.Nm ck_pr_store_ptr ,\n.Nm ck_pr_store_double ,\n.Nm ck_pr_store_uint ,\n.Nm ck_pr_store_int ,\n.Nm ck_pr_store_char ,\n.Nm ck_pr_store_64 ,\n.Nm ck_pr_store_32 ,\n.Nm ck_pr_store_16 ,\n.Nm ck_pr_store_8\n.Nd atomic volatile store operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_store_ptr \"void *target\" \"void *value\"\n.Ft void\n.Fn ck_pr_store_double \"double *target\" \"double value\"\n.Ft void\n.Fn ck_pr_store_uint \"unsigned int *target\" \"unsigned int value\"\n.Ft void\n.Fn ck_pr_store_int \"int *target\" \"int value\"\n.Ft void\n.Fn ck_pr_store_char \"char *target\" \"char value\"\n.Ft void\n.Fn ck_pr_store_64 \"uint64_t *target\" \"uint64_t value\"\n.Ft void\n.Fn ck_pr_store_32 \"uint32_t *target\" \"uint32_t value\"\n.Ft void\n.Fn ck_pr_store_16 \"uint16_t *target\" \"uint16_t value\"\n.Ft void\n.Fn ck_pr_store_8 \"uint8_t *target\" \"uint8_t value\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_store 3\nfamily of functions atomically stores the value specified\nby\n.Fa value\ninto the location pointed to by\n.Fa target .\nThis family of functions always serves as an implicit compiler\nbarrier and is not susceptible to compiler re-ordering.\n.Sh RETURN VALUES\nThis family of functions has no return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_sub",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_sub 3\n.Sh NAME\n.Nm ck_pr_sub_ptr ,\n.Nm ck_pr_sub_double ,\n.Nm ck_pr_sub_char ,\n.Nm ck_pr_sub_uint ,\n.Nm ck_pr_sub_int ,\n.Nm ck_pr_sub_64 ,\n.Nm ck_pr_sub_32 ,\n.Nm ck_pr_sub_16 ,\n.Nm ck_pr_sub_8\n.Nd atomic subtraction operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_sub_ptr \"void *target\" \"uintptr_t delta\"\n.Ft void\n.Fn ck_pr_sub_double \"double *target\" \"double delta\"\n.Ft void\n.Fn ck_pr_sub_char \"char *target\" \"char delta\"\n.Ft void\n.Fn ck_pr_sub_uint \"unsigned int *target\" \"unsigned int delta\"\n.Ft void\n.Fn ck_pr_sub_int \"int *target\" \"int delta\"\n.Ft void\n.Fn ck_pr_sub_64 \"uint64_t *target\" \"uint64_t delta\"\n.Ft void\n.Fn ck_pr_sub_32 \"uint32_t *target\" \"uint32_t delta\"\n.Ft void\n.Fn ck_pr_sub_16 \"uint16_t *target\" \"uint16_t delta\"\n.Ft void\n.Fn ck_pr_sub_8 \"uint8_t *target\" \"uint8_t delta\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_sub 3\nfamily of functions atomically subtract the value specified by\n.Fa delta\nfrom the value pointed to by\n.Fa target .\n.Sh RETURN VALUES\nThis family of functions does not have a return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_xor 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_pr_xor",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 11, 2013\n.Dt ck_pr_xor 3\n.Sh NAME\n.Nm ck_pr_xor_ptr ,\n.Nm ck_pr_xor_char ,\n.Nm ck_pr_xor_uint ,\n.Nm ck_pr_xor_int ,\n.Nm ck_pr_xor_64 ,\n.Nm ck_pr_xor_32 ,\n.Nm ck_pr_xor_16 ,\n.Nm ck_pr_xor_8\n.Nd atomic bitwise-xor operations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_pr.h\n.Ft void\n.Fn ck_pr_xor_ptr \"void *target\" \"uintptr_t delta\"\n.Ft void\n.Fn ck_pr_xor_char \"char *target\" \"char delta\"\n.Ft void\n.Fn ck_pr_xor_uint \"unsigned int *target\" \"unsigned int delta\"\n.Ft void\n.Fn ck_pr_xor_int \"int *target\" \"int delta\"\n.Ft void\n.Fn ck_pr_xor_64 \"uint64_t *target\" \"uint64_t delta\"\n.Ft void\n.Fn ck_pr_xor_32 \"uint32_t *target\" \"uint32_t delta\"\n.Ft void\n.Fn ck_pr_xor_16 \"uint16_t *target\" \"uint16_t delta\"\n.Ft void\n.Fn ck_pr_xor_8 \"uint8_t *target\" \"uint8_t delta\"\n.Sh DESCRIPTION\nThe\n.Fn ck_pr_xor 3\nfamily of functions atomically compute and store the\nresult of a bitwise-xor of the value pointed to by\n.Fa target\nand\n.Fa delta\ninto the value pointed to by\n.Fa target .\n.Sh RETURN VALUES\nThis family of functions does not have a return value.\n.Sh SEE ALSO\n.Xr ck_pr_fence_load 3 ,\n.Xr ck_pr_fence_load_depends 3 ,\n.Xr ck_pr_fence_store 3 ,\n.Xr ck_pr_fence_memory 3 ,\n.Xr ck_pr_load 3 ,\n.Xr ck_pr_store 3 ,\n.Xr ck_pr_fas 3 ,\n.Xr ck_pr_faa 3 ,\n.Xr ck_pr_inc 3 ,\n.Xr ck_pr_dec 3 ,\n.Xr ck_pr_neg 3 ,\n.Xr ck_pr_not 3 ,\n.Xr ck_pr_add 3 ,\n.Xr ck_pr_sub 3 ,\n.Xr ck_pr_or 3 ,\n.Xr ck_pr_and 3 ,\n.Xr ck_pr_cas 3 ,\n.Xr ck_pr_btc 3 ,\n.Xr ck_pr_bts 3 ,\n.Xr ck_pr_btr 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_queue",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 28, 2013.\n.Dt ck_queue 3\n.Sh NAME\n.Nm CK_LIST_EMPTY ,\n.Nm CK_LIST_ENTRY ,\n.Nm CK_LIST_FIRST ,\n.Nm CK_LIST_FOREACH ,\n.Nm CK_LIST_FOREACH_SAFE ,\n.Nm CK_LIST_HEAD ,\n.Nm CK_LIST_HEAD_INITIALIZER ,\n.Nm CK_LIST_INIT ,\n.Nm CK_LIST_INSERT_AFTER ,\n.Nm CK_LIST_INSERT_BEFORE ,\n.Nm CK_LIST_INSERT_HEAD ,\n.Nm CK_LIST_MOVE ,\n.Nm CK_LIST_NEXT ,\n.Nm CK_LIST_REMOVE ,\n.Nm CK_LIST_SWAP ,\n.Nm CK_SLIST_EMPTY ,\n.Nm CK_SLIST_ENTRY ,\n.Nm CK_SLIST_FIRST ,\n.Nm CK_SLIST_FOREACH ,\n.Nm CK_SLIST_FOREACH_PREVPTR ,\n.Nm CK_SLIST_FOREACH_SAFE ,\n.Nm CK_SLIST_HEAD ,\n.Nm CK_SLIST_HEAD_INITIALIZER ,\n.Nm CK_SLIST_INIT ,\n.Nm CK_SLIST_INSERT_AFTER ,\n.Nm CK_SLIST_INSERT_HEAD ,\n.Nm CK_SLIST_MOVE ,\n.Nm CK_SLIST_NEXT ,\n.Nm CK_SLIST_REMOVE ,\n.Nm CK_SLIST_REMOVE_AFTER ,\n.Nm CK_SLIST_REMOVE_HEAD ,\n.Nm CK_SLIST_SWAP ,\n.Nm CK_STAILQ_CONCAT ,\n.Nm CK_STAILQ_EMPTY ,\n.Nm CK_STAILQ_ENTRY ,\n.Nm CK_STAILQ_FIRST ,\n.Nm CK_STAILQ_FOREACH ,\n.Nm CK_STAILQ_FOREACH_SAFE ,\n.Nm CK_STAILQ_HEAD ,\n.Nm CK_STAILQ_HEAD_INITIALIZER ,\n.Nm CK_STAILQ_INIT ,\n.Nm CK_STAILQ_INSERT_AFTER ,\n.Nm CK_STAILQ_INSERT_HEAD ,\n.Nm CK_STAILQ_INSERT_TAIL ,\n.Nm CK_STAILQ_MOVE ,\n.Nm CK_STAILQ_NEXT ,\n.Nm CK_STAILQ_REMOVE ,\n.Nm CK_STAILQ_REMOVE_AFTER ,\n.Nm CK_STAILQ_REMOVE_HEAD ,\n.Nm CK_STAILQ_SWAP\n.Nd multi-reader single-writer singly-linked lists, singly-linked tail queues and lists\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_queue.h\n.Fn CK_LIST_EMPTY\n.Fn CK_LIST_ENTRY\n.Fn CK_LIST_FIRST\n.Fn CK_LIST_FOREACH\n.Fn CK_LIST_FOREACH_SAFE\n.Fn CK_LIST_HEAD\n.Fn CK_LIST_HEAD_INITIALIZER\n.Fn CK_LIST_INIT\n.Fn CK_LIST_INSERT_AFTER\n.Fn CK_LIST_INSERT_BEFORE\n.Fn CK_LIST_INSERT_HEAD\n.Fn CK_LIST_MOVE\n.Fn CK_LIST_NEXT\n.Fn CK_LIST_REMOVE\n.Fn CK_LIST_SWAP\n.Fn CK_SLIST_EMPTY\n.Fn CK_SLIST_ENTRY\n.Fn CK_SLIST_FIRST\n.Fn CK_SLIST_FOREACH\n.Fn CK_SLIST_FOREACH_PREVPTR\n.Fn CK_SLIST_FOREACH_SAFE\n.Fn CK_SLIST_HEAD\n.Fn CK_SLIST_HEAD_INITIALIZER\n.Fn CK_SLIST_INIT\n.Fn CK_SLIST_INSERT_AFTER\n.Fn CK_SLIST_INSERT_HEAD\n.Fn CK_SLIST_MOVE\n.Fn CK_SLIST_NEXT\n.Fn CK_SLIST_REMOVE\n.Fn CK_SLIST_REMOVE_AFTER\n.Fn CK_SLIST_REMOVE_HEAD\n.Fn CK_SLIST_SWAP\n.Fn CK_STAILQ_CONCAT\n.Fn CK_STAILQ_EMPTY\n.Fn CK_STAILQ_ENTRY\n.Fn CK_STAILQ_FIRST\n.Fn CK_STAILQ_FOREACH\n.Fn CK_STAILQ_FOREACH_SAFE\n.Fn CK_STAILQ_HEAD\n.Fn CK_STAILQ_HEAD_INITIALIZER\n.Fn CK_STAILQ_INIT\n.Fn CK_STAILQ_INSERT_AFTER\n.Fn CK_STAILQ_INSERT_HEAD\n.Fn CK_STAILQ_INSERT_TAIL\n.Fn CK_STAILQ_MOVE\n.Fn CK_STAILQ_NEXT\n.Fn CK_STAILQ_REMOVE\n.Fn CK_STAILQ_REMOVE_AFTER\n.Fn CK_STAILQ_REMOVE_HEAD\n.Fn CK_STAILQ_SWAP\n.Sh DESCRIPTION\nSee your system's manual page for\n.Xr queue\nfor additional information. ck_queue is a queue.h-compatible\nimplementation of many-reader-single-writer queues. It allows\nfor safe concurrent iteration, peeking and read-side access\nin the presence of a single concurrent writer without any\nusage of locks. In many cases, adoption of ck_queue will\nsimply require prefixing all queue operations with CK_.\n.Sh SEE ALSO\n.Xr queue\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_apply",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" Copyright 2014 Backtrace I/O, Inc.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 1, 2014\n.Dt CK_RHS_APPLY 3\n.Sh NAME\n.Nm ck_rhs_apply\n.Nd apply a function to hash set value\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft void *\n.Fn ck_rhs_apply_fn_t \"void *key\" \"void *closure\"\n.Ft bool\n.Fn ck_rhs_apply \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\" \"ck_rhs_apply_fn_t *function\" \"void *argument\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_apply 3\nfunction will lookup the hash set slot associated with\n.Fa key\nand pass it to function pointed to by\n.Fa function\nfor further action. This callback may remove or replace\nthe value by respectively returning NULL or a pointer to\nanother object with an identical key. The first argument\npassed to\n.Fa function\nis a pointer to the object found in the hash set and\nthe second argument is the\n.Fa argument\npointer passed to\n.Fn ck_rhs_apply 3 .\nIf the pointer returned by\n.Fa function\nis equivalent to the first argument then no modification\nis made to the hash set.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_apply 3\nreturns true and otherwise returns false on failure.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_count",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_COUNT 3\n.Sh NAME\n.Nm ck_rhs_count\n.Nd returns number of entries in hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft unsigned long\n.Fn ck_rhs_count \"ck_rhs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_count 3\nfunction returns the number of keys currently\nstored in\n.Fa hs .\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_destroy",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_DESTROY 3\n.Sh NAME\n.Nm ck_rhs_destroy\n.Nd destroy hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft void\n.Fn ck_rhs_destroy \"ck_rhs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_destroy 3\nfunction will request that the underlying allocator, as specified by the\n.Xr ck_rhs_init 3\nfunction, immediately destroy the object pointed to by the\n.Fa hs\nargument.\nThe user must guarantee that no threads are accessing the object pointed to\nby\n.Fa hs\nwhen\n.Fn ck_rhs_destroy 3\nis called.\n.Sh RETURN VALUES\n.Fn ck_rhs_destroy 3\nhas no return value.\n.Sh ERRORS\nThis function is guaranteed not to fail.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_fas",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd June 20, 2013\n.Dt CK_RHS_FAS 3\n.Sh NAME\n.Nm ck_rhs_fas\n.Nd fetch and store key in hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_fas \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\" \"void **previous\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_fas 3\nfunction will fetch and store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_RHS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_rhs_fas 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nThe key must already exist in the hash set, and is\nreplaced by\n.Fa key\nand the previous value is stored into the void pointer\npointed to by the\n.Fa previous\nargument. If the key does not exist in the hash set\nthen the function will return false and the hash set\nis unchanged. This function\nis guaranteed to be stable with respect to memory usage.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_fas 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_gc",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 17, 2013\n.Dt CK_RHS_GC 3\n.Sh NAME\n.Nm ck_rhs_gc\n.Nd perform maintenance on a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_gc \"ck_rhs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_gc 3\nfunction will perform various maintenance routines on the hash set\npointed to by\n.Fa hs ,\nincluding recalculating the maximum number of probes.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_gc 3\nreturns true and otherwise returns false on failure due to memory allocation\nfailure.\n.Sh ERRORS\nThis function will only return false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_get",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_GET 3\n.Sh NAME\n.Nm ck_rhs_get\n.Nd load a key from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft void *\n.Fn ck_rhs_get \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_get 3\nfunction will return a pointer to a key in the hash set\n.Fa hs\nthat is of equivalent value to the object pointed to by\n.Fa key .\nThe key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which is to have been previously generated using the\n.Xr CK_RHS_HASH 3\nmacro).\n.Sh RETURN VALUES\nIf the provided key is a member of\n.Fa hs\nthen a pointer to the key as stored in\n.Fa hs\nis returned. If the key was not found in\n.Fa hs\nthen a value of\n.Dv NULL\nis returned.\n.Sh ERRORS\nBehavior is undefined if\n.Fa entry\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_grow",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_GROW 3\n.Sh NAME\n.Nm ck_rhs_grow\n.Nd enlarge hash set capacity\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_grow \"ck_rhs_t *hs\" \"unsigned long capacity\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_grow 3\nfunction will resize the hash set in order to be\nable to store at least the number of entries specified by\n.Fa capacity\nat a load factor of one. The default hash set load factor\nis 0.5. If you wish to minimize the likelihood of memory allocations\nfor a hash set meant to store n entries, then specify a\n.Fa capacity\nof 2n. The default behavior of ck_rhs is to round\n.Fa capacity\nto the next power of two if it is not already a power of two.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_grow 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. This function will only\nreturn false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_INIT 3\n.Sh NAME\n.Nm ck_rhs_init\n.Nd initialize a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft typedef unsigned long\n.Fn ck_rhs_hash_cb_t \"const void *key\" \"unsigned long seed\"\n.Ft typedef bool\n.Fn ck_rhs_compare_cb_t \"const void *c1\" \"const void *c2\"\n.Ft bool\n.Fn ck_rhs_init \"ck_rhs_t *hs\" \"unsigned int mode\" \"ck_rhs_hash_cb_t *hash_function\" \"ck_rhs_compare_cb_t *compare\" \"struct ck_malloc *allocator\" \"unsigned long capacity\" \"unsigned long seed\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_init\nfunction initializes the hash set pointed to by the\n.Fa hs\npointer.\n.Pp\nThe argument\n.Fa mode\nspecifies the type of key-value pairs to be stored in the\nhash set as well as the expected concurrent access model.\nThe value of\n.Fa mode\nconsists of a bitfield of one of the following:\n.Bl -tag -width indent\n.It CK_RHS_MODE_OBJECT\nThe hash set is meant to store pointers to objects. This provides\na hint that only CK_MD_VMA_BITS are necessary to encode the key\nargument. Any unused pointer bits are leveraged for internal\noptimizations.\n.It CK_RHS_MODE_DIRECT\nThe hash set is meant to directly store key values and that all\nbits of the key are used to encode values.\n.It CK_RHS_MODE_READ_MOSTLY\nOptimize read operations over put/delete.\n.El\n.Pp\nThe concurrent access model is specified by:\n.Bl -tag -width indent\n.It CK_RHS_MODE_SPMC\nThe hash set should allow for concurrent readers in the\npresence of a single writer.\n.It CK_RHS_MODE_MPMC\nThe hash set should allow for concurrent readers in the\npresence of concurrent writers. This is currently unsupported.\n.El\n.Pp\nThe developer is free to specify additional workload hints.\nThese hints are one of:\n.Bl -tag -width indent\n.El\n.Pp\nThe argument\n.Fa hash_function\nis a mandatory pointer to a user-specified hash function.\nA user-specified hash function takes two arguments. The\n.Fa key\nargument is a pointer to a key. The\n.Fa seed\nargument is the initial seed associated with the hash set.\nThis initial seed is specified by the user in\n.Xr ck_rhs_init 3 .\n.Pp\nThe\n.Fa compare\nargument is an optional pointer to a user-specified\nkey comparison function. If NULL is specified in this\nargument, then pointer equality will be used to determine\nkey equality. A user-specified comparison function takes\ntwo arguments representing pointers to the objects being\ncompared for equality. It is expected to return true\nif the keys are of equal value and false otherwise.\n.Pp\nThe\n.Fa allocator\nargument is a pointer to a structure containing\n.Fa malloc\nand\n.Fa free\nfunction pointers which respectively define the memory allocation and\ndestruction functions to be used by the hash set being initialized.\n.Pp\nThe argument\n.Fa capacity\nrepresents the initial number of keys the hash\nset is expected to contain. This argument is simply a hint\nand the underlying implementation is free to allocate more\nor less memory than necessary to contain the number of entries\n.Fa capacity\nspecifies.\n.Pp\nThe argument\n.Fa seed\nspecifies the initial seed used by the underlying hash function.\nThe user is free to choose a value of their choice.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_rhs_init\nreturns a value of\n.Dv true\nand otherwise returns a value of\n.Dv false\nto indicate an error.\n.Sh ERRORS\n.Bl -tag -width Er\n.Pp\nThe behavior of\n.Fn ck_rhs_init\nis undefined if\n.Fa hs\nis not a pointer to a\n.Tn ck_rhs_t\nobject.\n.El\n.Sh SEE ALSO\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_iterator_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_ITERATOR_INIT 3\n.Sh NAME\n.Nm ck_rhs_iterator_init\n.Nd initialize hash set iterator\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Pp\n.Dv ck_rhs_iterator_t iterator = CK_RHS_ITERATOR_INITIALIZER\n.Pp\n.Ft void\n.Fn ck_rhs_iterator_init \"ck_rhs_iterator_t *iterator\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_iterator_init 3\nfunction will initialize the object pointed to\nby the\n.Fa iterator\nargument. Alternatively, an iterator may be statically\ninitialized by assigning it to the CK_RHS_ITERATOR_INITIALIZER value.\n.Pp\nAn iterator is used to iterate through hash set entries with the\n.Xr ck_rhs_next 3\nfunction.\n.Sh RETURN VALUES\n.Fn ck_rhs_iterator_init 3\nhas no return value.\n.Sh ERRORS\nThis function will not fail.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_move",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 18, 2013\n.Dt CK_RHS_MOVE 3\n.Sh NAME\n.Nm ck_rhs_move\n.Nd move one from hash set to another\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_move \"ck_rhs_t *destination\" \"ck_rhs_t *source\" \"ck_rhs_hash_cb_t *hash_cb\" \"ck_rhs_compare_cb_t *compare_cb\" \"struct ck_malloc *m\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_move 3\nfunction will initialize\n.Fa source\nfrom\n.Fa destination .\nThe hash function is set to\n.Fa hash_cb ,\ncomparison function to\n.Fa compare_cb\nand the allocator callbacks to\n.Fa m .\nFurther modifications to\n.Fa source\nwill result in undefined behavior. Concurrent\n.Xr ck_rhs_get 3\nand\n.Xr ck_rhs_fas 3\noperations to\n.Fa source\nare legal until the next write operation to\n.Fa destination .\n.Pp\nThis operation moves ownership from one hash set object\nto another and re-assigns callback functions to developer-specified\nvalues. This allows for dynamic configuration of allocation\ncallbacks and is necessary for use-cases involving executable code\nwhich may be unmapped underneath the hash set.\n.Sh RETURN VALUES\nUpon successful completion\n.Fn ck_rhs_move 3\nreturns true and otherwise returns false to indicate an error.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_next",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_NEXT 3\n.Sh NAME\n.Nm ck_rhs_next\n.Nd iterate to next entry in hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_next \"ck_rhs_t *hs\" \"ck_rhs_iterator_t *iterator\" \"void **entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_next 3\nfunction will increment the iterator object pointed to by\n.Fa iterator\nto point to the next non-empty hash set entry. If\n.Fn ck_rhs_next 3\nreturns true then the pointer pointed to by\n.Fa entry\nis initialized to the current hash set key pointed to by the\n.Fa iterator\nobject.\n.Pp\nIt is expected that\n.Fa iterator\nhas been initialized using the\n.Xr ck_rhs_iterator_init 3\nfunction or statically initialized using CK_RHS_ITERATOR_INITIALIZER.\n.Sh RETURN VALUES\nIf\n.Fn ck_rhs_next 3\nreturns true then the object pointed to by\n.Fa entry\npoints to a valid hash set key. If\n.Fn ck_rhs_next 3\nreturns false then the value of the object pointed to by\n.Fa entry\nis undefined.\n.Sh ERRORS\nBehavior is undefined if\n.Fa iterator\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_put",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_PUT 3\n.Sh NAME\n.Nm ck_rhs_put\n.Nd store unique key into a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_put \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_put 3\nfunction will store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_RHS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_rhs_put 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nThe function will fail if a key with an\nequivalent value to\n.Fa key\nis already present in the hash set. For replacement\nsemantics, please see the\n.Xr ck_rhs_set 3\nfunction.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_put 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized. The function will also\nreturn false if the hash set could not be enlarged\nto accomodate key insertion.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_put_unique",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 7, 2013\n.Dt CK_RHS_PUT_UNIQUE 3\n.Sh NAME\n.Nm ck_rhs_put_unique\n.Nd unconditionally store unique key into a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_put_unique \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_put_unique 3\nfunction will store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_RHS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_rhs_put 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nThe function will cause undefined behavior if a key with an\nequivalent value is already present in the hash set. For replacement\nsemantics, please see the\n.Xr ck_rhs_set 3\nfunction.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_put_unique 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized. The function will also\nreturn false if the hash set could not be enlarged\nto accomodate key insertion. The function will\nresult in undefined behavior if called for an\nalready inserted key value.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_rebuild",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd December 7, 2013\n.Dt CK_RHS_REBUILD 3\n.Sh NAME\n.Nm ck_rhs_rebuild\n.Nd rebuild a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_rebuild \"ck_rhs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_rebuild 3\nfunction will regenerate the hash set pointed to by\n.Fa hs .\nThis has the side-effect of pruning degradatory side-effects\nof workloads that are delete heavy. The regenerated hash\nset should have shorter probe sequences on average. This\noperation will require a significant amount of memory\nand is free to allocate a duplicate hash set in the\nrebuild process.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_rebuild 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nThis function will only return false if there are internal memory allocation\nfailures.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_remove",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_REMOVE 3\n.Sh NAME\n.Nm ck_rhs_remove\n.Nd remove key from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft void *\n.Fn ck_rhs_remove \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_remove 3\nfunction will attempt to remove the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_RHS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_rhs_remove 3\nwas successful then the key contained in the hash\nset is returned. If the key was not a member of the hash\nset then\n.Dv  NULL\nis returned.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_remove 3\nreturns a pointer to a key and otherwise returns\n.Dv NULL\non failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_reset",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_RESET 3\n.Sh NAME\n.Nm ck_rhs_reset\n.Nd remove all keys from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_reset \"ck_rhs_t *hs\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_reset 3\nfunction will remove all keys stored in the hash\nset pointed to by the\n.Fa hs\nargument.\n.Sh RETURN VALUES\nIf successful,\n.Fn ck_rhs_reset 3\nwill return true and will otherwise return false on failure. This\nfunction will only fail if a replacement hash set could not be\nallocated internally.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_reset_size",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 5, 2013\n.Dt CK_RHS_RESET_SIZE 3\n.Sh NAME\n.Nm ck_rhs_reset_size\n.Nd remove all keys from a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_reset_size \"ck_rhs_t *hs\" \"unsigned long size\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_reset_size 3\nfunction will remove all keys stored in the hash\nset pointed to by the\n.Fa hs\nargument and create a new generation of the hash set that\nis preallocated for\n.Fa size\nentries.\n.Sh RETURN VALUES\nIf successful,\n.Fn ck_rhs_reset_size 3\nwill return true and will otherwise return false on failure. This\nfunction will only fail if a replacement hash set could not be\nallocated internally.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_set",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_SET 3\n.Sh NAME\n.Nm ck_rhs_set\n.Nd store key into a hash set\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_set \"ck_rhs_t *hs\" \"unsigned long hash\" \"const void *key\" \"void **previous\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_set 3\nfunction will store the key specified by the\n.Fa key\nargument in the hash set pointed to by the\n.Fa hs\nargument. The key specified by\n.Fa key\nis expected to have the hash value specified by the\n.Fa hash\nargument (which was previously generated using the\n.Xr CK_RHS_HASH 3\nmacro).\n.Pp\nIf the call to\n.Fn ck_rhs_set 3\nwas successful then the key specified by\n.Fa key\nwas successfully stored in the hash set pointed to by\n.Fa hs .\nIf the key already exists in the hash set, then it is\nreplaced by\n.Fa key\nand the previous value is stored into the void pointer\npointed to by the\n.Fa previous\nargument. If previous is set to\n.Dv NULL\nthen\n.Fa key\nwas not a replacement for an existing entry in the hash set.\n.Sh RETURN VALUES\nUpon successful completion,\n.Fn ck_rhs_set 3\nreturns true and otherwise returns false on failure.\n.Sh ERRORS\nBehavior is undefined if\n.Fa key\nor\n.Fa hs\nare uninitialized. The function will also\nreturn false if the hash set could not be enlarged\nto accomodate key insertion.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3 ,\n.Xr ck_rhs_stat 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_set_load_factor",
    "content": ".\\\"\n.\\\" Copyright 2015 Olivier Houchard.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd May 16, 2015\n.Dt CK_RHS_SET_LOAD_FACTOR 3\n.Sh NAME\n.Nm ck_rhs_set_load_factor\n.Nd change the hash set load factor\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft bool\n.Fn ck_rhs_set_load_factor \"ck_rhs_t *hs\" \"unsigned int load_factor\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_set_load_factor 3\nfunction will change the load factor of the hash set. The hash set will grow if it is load_factor% filled.\n.Ed\n.Sh RETURN VALUES\n.Fn ck_rhs_set_load_factor 3\nreturns true on success, or false if either the load factor is invalid (0 or > 100), or if growing was required, but failed.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rhs_stat",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd September 17, 2012\n.Dt CK_RHS_STAT 3\n.Sh NAME\n.Nm ck_rhs_stat\n.Nd get hash set status\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rhs.h\n.Ft void\n.Fn ck_rhs_stat \"ck_rhs_t *hs\" \"struct ck_rhs_stat *st\"\n.Sh DESCRIPTION\nThe\n.Fn ck_rhs_stat 3\nfunction will store various hash set statistics in\nthe object pointed to by\n.Fa st .\nThe ck_rhs_stat structure is defined as follows:\n.Bd -literal -offset indent\nstruct ck_rhs_stat {\n\tunsigned long n_entries;    /* Current number of keys in hash set. */\n\tunsigned int probe_maximum; /* Longest read-side probe sequence. */\n};\n.Ed\n.Sh RETURN VALUES\n.Fn ck_rhs_stat 3\nhas no return value.\n.Sh ERRORS\nBehavior is undefined if\n.Fa hs\nis uninitialized. Behavior is\nundefined if this function is called by a non-writer\nthread.\n.Sh SEE ALSO\n.Xr ck_rhs_init 3 ,\n.Xr ck_rhs_move 3 ,\n.Xr ck_rhs_destroy 3 ,\n.Xr CK_RHS_HASH 3 ,\n.Xr ck_rhs_iterator_init 3 ,\n.Xr ck_rhs_next 3 ,\n.Xr ck_rhs_get 3 ,\n.Xr ck_rhs_put 3 ,\n.Xr ck_rhs_put_unique 3 ,\n.Xr ck_rhs_set 3 ,\n.Xr ck_rhs_fas 3 ,\n.Xr ck_rhs_remove 3 ,\n.Xr ck_rhs_grow 3 ,\n.Xr ck_rhs_gc 3 ,\n.Xr ck_rhs_rebuild 3 ,\n.Xr ck_rhs_count 3 ,\n.Xr ck_rhs_reset 3 ,\n.Xr ck_rhs_reset_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_capacity",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_CAPACITY 3\n.Sh NAME\n.Nm ck_ring_capacity\n.Nd returns number of pointer slots in bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft unsigned int\n.Fn ck_ring_capacity \"ck_ring_t *ring\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_capacity 3\nfunction returns the number of pointers that can be\nheld in the buffer pointed to by\n.Fa ring .\nNote that a ring can only hold\n.Fn ck_ring_capacity 3\nminus one entries at a time.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_dequeue_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_DEQUEUE_SPMC 3\n.Sh NAME\n.Nm ck_ring_dequeue_spmc\n.Nd dequeue pointer from bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_dequeue_spmc \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *result\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_dequeue_spmc 3\nfunction dequeues a pointer from the bounded buffer\npointed to by\n.Fa ring\nin FIFO fashion. The pointer is stored in the pointer\npointed to by\n.Fa result .\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring .\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa result .\nThis function is safe to call without locking for UINT_MAX\nconcurrent invocations of\n.Fn ck_ring_dequeue_spmc 3\nor\n.Fn ck_ring_trydequeue_spmc 3\nand up to one concurrent\n.Fn ck_ring_enqueue_spmc 3\nor\n.Fn ck_ring_tryenqueue_spmc 3\ninvocation. This function provides lock-free progress\nguarantees.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\ndequeue(void)\n{\n\tvoid *result;\n\n\t/* Dequeue from ring until it is empty. */\n\twhile (ck_ring_dequeue_spmc(&ring, &buffer, &result) == true) {\n\t\t/*\n\t\t * Results contains the oldest pointer in ring\n\t\t * since the dequeue operation returned true.\n\t\t */\n\t\toperation(result);\n\t}\n\n\t/* An empty ring was encountered, leave. */\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the buffer was non-empty.\nThe result of the dequeue operation is stored in the\nvalue pointed to by\n.Fa result .\nThe function will return false if the buffer was empty\nand the value in\n.Fa result\nwill be undefined.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_dequeue_spsc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_DEQUEUE_SPSC 3\n.Sh NAME\n.Nm ck_ring_dequeue_spsc\n.Nd dequeue pointer from bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_dequeue_spsc \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *result\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_dequeue_spsc 3\nfunction dequeues a pointer from the bounded buffer\npointed to by\n.Fa ring\nin FIFO fashion. The pointer is stored in the pointer\npointed to by\n.Fa result .\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring\nand point to an array of ck_ring_buffer_t of sufficient\nlength (according to the power-of-2 elements in the buffer).\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa result .\nThis function is safe to call without locking for one\nconcurrent invocation of\n.Fn ck_ring_dequeue_spsc 3\nand up to one concurrent\n.Fn ck_ring_enqueue_spsc 3\ninvocation. This function provides wait-free progress\nguarantees.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\ndequeue(void)\n{\n\tvoid *result;\n\n\t/* Dequeue from ring until it is empty. */\n\twhile (ck_ring_dequeue_spsc(&ring, &buffer, &result) == true) {\n\t\t/*\n\t\t * Results contains the oldest pointer in ring\n\t\t * since the dequeue operation returned true.\n\t\t */\n\t\toperation(result);\n\t}\n\n\t/* An empty ring was encountered, leave. */\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the buffer was non-empty.\nThe result of the dequeue operation is stored in the\nvalue pointed to by\n.Fa result .\nThe function will return false if the buffer was empty\nand the value in\n.Fa result\nwill be undefined.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_enqueue_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_ENQUEUE_SPMC 3\n.Sh NAME\n.Nm ck_ring_enqueue_spmc\n.Nd enqueue pointer into bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_enqueue_spmc \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_enqueue_spmc 3\nfunction enqueues the pointer\n.Fa entry\ninto the bounded buffer pointed to by\n.Fa ring\nin FIFO fashion.\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring\nand point to an array of ck_ring_buffer_t of sufficient\nlength (according to the power-of-2 elements in the buffer).\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa entry .\nThis function is safe to call without locking for UINT_MAX\nconcurrent invocations of\n.Fn ck_ring_dequeue_spmc 3\nor\n.Fn ck_ring_trydequeue_spmc 3 .\nThis function provides wait-free progress\nguarantees for one active invocation.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\nenqueue(void)\n{\n\tvoid *entry = some_object;\n\n\t/* Attempt to enqueue pointer to some_object into buffer. */\n\tif (ck_ring_enqueue_spmc(&ring, &buffer, &entry) == false) {\n\t\t/*\n\t\t * The buffer was full and the enqueue operation\n\t\t * has failed.\n\t\t */\n\t\treturn;\n\t}\n\n\t/* Enqueue operation completed successfully. */\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the value of\n.Fa entry\nwas successfully enqueued into\n.Fa ring .\nThe function will return false if the value of\n.Fa entry\ncould not be enqueued which only occurs if\n.Fa ring\nwas full.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_enqueue_spmc_size",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_ENQUEUE_SPMC_SIZE 3\n.Sh NAME\n.Nm ck_ring_enqueue_spmc_size\n.Nd enqueue pointer into bounded FIFO and return size of buffer\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_enqueue_spmc_size \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *entry\" \"unsigned int *length\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_enqueue_spmc 3\nfunction enqueues the pointer\n.Fa entry\ninto the bounded buffer pointed to by\n.Fa ring\nin FIFO fashion.\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring\nand point to an array of ck_ring_buffer_t of sufficient\nlength (according to the power-of-2 elements in the buffer).\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa entry .\nThis function is safe to call without locking for UINT_MAX\nconcurrent invocations of\n.Fn ck_ring_dequeue_spmc 3\nor\n.Fn ck_ring_trydequeue_spmc 3 .\nThis function provides wait-free progress\nguarantees for one active invocation.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\nenqueue(void)\n{\n\tvoid *entry = some_object;\n\tunsigned int length;\n\n\t/* Attempt to enqueue pointer to some_object into buffer. */\n\tif (ck_ring_enqueue_spmc_size(&ring, &buffer, &entry, &length) == false) {\n\t\t/*\n\t\t * The buffer was full and the enqueue operation\n\t\t * has failed.\n\t\t */\n\t\treturn;\n\t}\n\n\t/*\n\t * If entry was the 101st or greater pointer in the buffer,\n\t * do something.\n\t */\n\tif (length > 100) {\n\t\tdo_something;\n\t}\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the value of\n.Fa entry\nwas successfully enqueued into\n.Fa ring .\nThe function will return false if the value of\n.Fa entry\ncould not be enqueued which only occurs if\n.Fa ring\nwas full. The number of entries in the buffer\nwith respect to the point in time that\n.Fa entry\nis enqueued is stored in the integer pointed to by\n.Fa length .\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_enqueue_spsc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_ENQUEUE_SPSC 3\n.Sh NAME\n.Nm ck_ring_enqueue_spsc\n.Nd enqueue pointer into bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_enqueue_spsc \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *entry\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_enqueue_spsc 3\nfunction enqueues the pointer\n.Fa entry\ninto the bounded buffer pointed to by\n.Fa ring\nin FIFO fashion.\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring\nand point to an array of ck_ring_buffer_t of sufficient\nlength (according to the power-of-2 elements in the buffer).\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa entry .\nThis function is safe to call without locking for up to\none concurrent invocation of\n.Fn ck_ring_dequeue_spsc 3 .\nThis function provides wait-free progress\nguarantees.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\nenqueue(void)\n{\n\tvoid *entry = some_object;\n\n\t/* Attempt to enqueue pointer to some_object into buffer. */\n\tif (ck_ring_enqueue_spsc(&ring, &buffer, &entry) == false) {\n\t\t/*\n\t\t * The buffer was full and the enqueue operation\n\t\t * has failed.\n\t\t */\n\t\treturn;\n\t}\n\n\t/* Enqueue operation completed successfully. */\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the value of\n.Fa entry\nwas successfully enqueued into\n.Fa ring .\nThe function will return false if the value of\n.Fa entry\ncould not be enqueued which only occurs if\n.Fa ring\nwas full.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_enqueue_spsc_size",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_ENQUEUE_SPSC_SIZE 3\n.Sh NAME\n.Nm ck_ring_enqueue_spsc_size\n.Nd enqueue pointer into bounded FIFO and return size of buffer\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_enqueue_spsc_size \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *entry\" \"unsigned int *size\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_enqueue_spsc_size 3\nfunction enqueues the pointer\n.Fa entry\ninto the bounded buffer pointed to by\n.Fa ring\nin FIFO fashion.\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring\nand point to an array of ck_ring_buffer_t of sufficient\nlength (according to the power-of-2 elements in the buffer).\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa entry .\nThis function is safe to call without locking for up to\none concurrent invocation of\n.Fn ck_ring_dequeue_spsc 3 .\nThis function provides wait-free progress\nguarantees.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\nenqueue(void)\n{\n\tvoid *entry = some_object;\n\tunsigned int length;\n\n\t/* Attempt to enqueue pointer to some_object into buffer. */\n\tif (ck_ring_enqueue_spsc(&ring, &buffer, &entry, &length) == false) {\n\t\t/*\n\t\t * The buffer was full and the enqueue operation\n\t\t * has failed.\n\t\t */\n\t\treturn;\n\t}\n\n\t/*\n\t * If buffer length was 100 items or more at the time entry was\n\t * enqueued, do something.\n\t */\n\tif (length > 100) {\n\t\tdo_something;\n\t}\n\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the value of\n.Fa entry\nwas successfully enqueued into\n.Fa ring .\nThis function will return the number of items\nin\n.Fa ring\nwith respect to the linearization point (the\npoint in item that\n.Fa entry\nis enqueued).\nThe function will return false if the value of\n.Fa entry\ncould not be enqueued which only occurs if\n.Fa ring\nwas full.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_init",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_INIT 3\n.Sh NAME\n.Nm ck_ring_init\n.Nd initialize bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft void\n.Fn ck_ring_init \"ck_ring_t *ring\" \"unsigned int size\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_init\nfunction initializes a bounded FIFO buffer pointed to by\n.Fa ring\nfor the storage of up to\n.Fa size\nnumber of pointers.\nThe\n.Fa size\nargument must be a power-of-two greater than or equal to 4.\n.Sh RETURN VALUES\nThis function has no return value.\n.Sh SEE ALSO\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_size",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_SIZE 3\n.Sh NAME\n.Nm ck_ring_size\n.Nd return number of pointers enqueued in bounded FIFO\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft unsigned int\n.Fn ck_ring_size \"ck_ring_t *ring\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_size 3\nfunction returns the number of pointers currently\nenqueued in the buffer pointed to by\n.Fa ring .\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_trydequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_ring_trydequeue_spmc",
    "content": ".\\\"\n.\\\" Copyright 2012-2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 20, 2013\n.Dt CK_RING_TRYDEQUEUE_SPMC 3\n.Sh NAME\n.Nm ck_ring_trydequeue_spmc\n.Nd dequeue from bounded FIFO and allow for spurious failure\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_ring.h\n.Ft bool\n.Fn ck_ring_trydequeue_spmc \"ck_ring_t *ring\" \"ck_ring_buffer_t *buffer\" \"void *result\"\n.Sh DESCRIPTION\nThe\n.Fn ck_ring_trydequeue_spmc 3\nfunction attempts to dequeue a pointer from the bounded buffer\npointed to by\n.Fa ring\nin FIFO fashion. The pointer is stored in the pointer\npointed to by\n.Fa result .\nThe buffer pointed to by\n.Fa buffer\nmust be unique to\n.Fa ring\nand point to an array of ck_ring_buffer_t of sufficient\nlength (according to the power-of-2 elements in the buffer).\nThe decoupling of the ring from the buffer serves\nto address use-cases involving multiple address spaces\nand DMA, among others.\nIf you are on non-POSIX platforms or wish for strict\ncompliance with C, then it is recommended to pass a\npointer of type void ** for\n.Fa result .\nThis function is safe to call without locking for UINT_MAX\nconcurrent\n.Fn ck_ring_dequeue_spmc 3\nor\n.Fn ck_ring_trydequeue_spmc 3\ninvocations and up to one concurrent\n.Fn ck_ring_enqueue_spmc 3\nor\n.Fn ck_ring_tryenqueue_spmc 3\ninvocation. This operation will always complete\nin a bounded number of steps. It is\npossible for the function to return false even\nif\n.Fa ring\nis non-empty. This\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_ring.h>\n\n/* This ring was previously initialized with ck_ring_init. */\nck_ring_t ring;\n\n/* The ring was initialized for 1023 elements. */\nck_ring_buffer_t buffer[1024];\n\nvoid\ndequeue(void)\n{\n\tvoid *result;\n\n\t/* Dequeue from ring until contention is actively observed. */\n\twhile (ck_ring_trydequeue_spmc(&ring, &buffer, &result) == true) {\n\t\t/*\n\t\t * Results contains the oldest pointer in ring\n\t\t * since the dequeue operation returned true.\n\t\t */\n\t\toperation(result);\n\t}\n\n\t/* An empty ring was encountered, leave. */\n\treturn;\n}\n.Ed\n.Sh RETURN VALUES\nThe function returns true if the dequeue operation\ncompletely successfully in a bounded number of steps.\nThe result of the dequeue operation is stored in the\nvalue pointed to by\n.Fa result .\nOtherwise, the function will return false if the buffer was empty\nor if the operation could not be completed in a bounded\nnumber of steps. If the function returns false, then the contents\nof\n.Fa result\nare undefined.\n.Sh SEE ALSO\n.Xr ck_ring_init 3 ,\n.Xr ck_ring_dequeue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc 3 ,\n.Xr ck_ring_enqueue_spmc_size 3 ,\n.Xr ck_ring_dequeue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc 3 ,\n.Xr ck_ring_enqueue_spsc_size 3 ,\n.Xr ck_ring_capacity 3 ,\n.Xr ck_ring_size 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rwcohort",
    "content": ".\\\"\n.\\\" Copyright 2013 Brendon Scheinman.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 23, 2013.\n.Dt ck_rwcohort 3\n.Sh NAME\n.Nm ck_rwcohort\n.Nd generalized interface for reader-writer locks using cohort locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rwcohort.h\nIn each of the following macros, \"STRATEGY\" should be replaced with either \"NEUTRAL\", \"RP\", or \"WP\"\ndepending on which locking strategy the user prefers.  RP and WP represent reader preference and\nwriter preference, respectively, while NEUTRAL represents a strategy neutral to reads vs. writes.\n.Fn CK_RWCOHORT_STRATEGY_PROTOTYPE \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_STRATEGY_NAME \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_STRATEGY_INSTANCE \"COHORT_NAME cohort_name\"\n.Fn CK_RWCOHORT_STRATEGY_INIT \"COHORT_NAME cohort_name\" \"RWCOHORT lock\" \"unsigned int wait_limit\"\nNote: the wait_limit argument should be omitted for locks using the neutral strategy\n.Fn CK_RWCOHORT_STRATEGY_READ_LOCK \"COHORT_NAME cohort_name\" \"RWCOHORT lock\" \"COHORT cohort\" \\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_STRATEGY_READ_UNLOCK \"COHORT_NAME cohort_name\" \"RWCOHORT lock\" \"COHORT cohort\" \\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_STRATEGY_WRITE_LOCK \"COHORT_NAME cohort_name\" \"RWCOHORT lock\" \"COHORT cohort\" \\\n\"void *global_context\" \"void *local_context\"\n.Fn CK_RWCOHORT_STRATEGY_WRITE_UNLOCK \"COHORT_NAME cohort_name\" \"RWCOHORT lock\" \"COHORT cohort\" \\\n\"void *global_context\" \"void *local_context\"\n.Pp\nArguments of type RWCOHORT must be pointers to structs defined using the\n.Xr CK_RWCOHORT_STRATEGY_PROTOTYPE 3\nmacro with the same strategy and cohort name as the current call.\n.Pp\nArguments of type COHORT must be pointers to structs defined using the\n.Xr CK_COHORT_PROTOTYPE 3\nmacro.\n.Sh DESCRIPTION\nck_rwcohort.h provides an interface for defining reader-writer locks\nthat use cohort locks internally to increase performance on NUMA\narchitectures.  See\n.Xr ck_cohort 3\nfor more information about cohort locks.\n.Pp\nBefore using a reader-writer cohort lock, the user must define a cohort type using\neither the\n.Xr CK_COHORT_PROTOTYPE 3\nor the\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3\nmacros, and define a reader-writer lock type using the\n.Xr CK_RWCOHORT_PROTOTYPE 3\nmacro.\n.Pp\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <stdlib.h>\n#include <pthread.h>\n\n#include <ck_pr.h>\n#include <ck_cohort.h>\n#include <ck_rwcohort.h>\n#include <ck_spinlock.h>\n\n/* Create cohort methods with signatures that match the required signature */\n\nstatic void\nck_spinlock_lock_with_context(ck_spinlock_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_lock(lock);\n\treturn;\n}\n\nstatic void\nck_spinlock_unlock_with_context(ck_spinlock_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_unlock(lock);\n\treturn;\n}\n\nstatic bool\nck_spinlock_locked_with_context(ck_spinlock_t *lock, void *context)\n{\n\t(void)context;\n\treturn ck_spinlock_locked(lock);\n}\n\n/*\n * define a cohort type named \"test_cohort\" that will use\n * the above methods for both its global and local locks\n */\nCK_COHORT_PROTOTYPE(test_cohort,\n\tck_spinlock_lock_with_context, ck_spinlock_unlock_with_context, ck_spinlock_locked_with_context,\n\tck_spinlock_lock_with_context, ck_spinlock_unlock_with_context, ck_spinlock_locked_with_context)\n\n/* define a reader-writer type using the same cohort type */\nCK_RWCOHORT_WP_PROTOTYPE(test_cohort)\n\nstatic ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;\nstatic CK_COHORT_INSTANCE(test_cohort) *cohorts;\nstatic CK_RWCOHORT_WP_INSTANCE(test_cohort) rw_cohort = CK_RWCOHORT_WP_INITIALIZER;\nstatic unsigned int ready;\n\nstatic void *\nfunction(void *context)\n{\n\tCK_COHORT_INSTANCE(test_cohort) *cohort = context;\n\n\twhile (ck_pr_load_uint(&ready) == 0);\n\n\twhile (ck_pr_load_uint(&ready) > 0) {\n\t\t/*\n\t\t * acquire the cohort lock before performing critical section.\n\t\t * note that we pass NULL for both the global and local context\n\t\t * arguments because neither the lock nor unlock functions\n\t\t * will use them.\n\t\t */\n\t\tCK_COHORT_LOCK(test_cohort, cohort, NULL, NULL);\n\n\t\t/* perform critical section */\n\n\t\t/* relinquish cohort lock */\n\t\tCK_COHORT_UNLOCK(test_cohort, cohort, NULL, NULL);\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(void)\n{\n\tunsigned int nthr = 4;\n\tunsigned int n_cohorts = 2;\n\tunsigned int i;\n\n\t/* allocate 2 cohorts of the defined type */\n\tCK_COHORT_INSTANCE(test_cohort) *cohorts =\n\t    calloc(n_cohorts, sizeof(CK_COHORT_INSTANCE(test_cohort)));\n\n\t/* create local locks to use with each cohort */\n\tck_spinlock_t *local_locks =\n\t\tcalloc(n_cohorts, sizeof(ck_spinlock_t));\n\n\tpthread_t *threads =\n\t\tcalloc(nthr, sizeof(pthread_t));\n\n\t/* initialize each of the cohorts before using them */\n\tfor (i = 0 ; i < n_cohorts ; ++i) {\n\t\tCK_COHORT_INIT(test_cohort, cohorts + i, &global_lock, local_locks + i,\n\t\t\tCK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\t}\n\n\t/* start each thread and assign cohorts equally */\n\tfor (i = 0 ; i < nthr ; ++i) {\n\t\tpthread_create(threads + i, NULL, function, cohorts + (i % n_cohorts));\n\t}\n\n\tck_pr_store_uint(&ready, 1);\n\tsleep(10);\n\tck_pr_store_uint(&ready, 0);\n\n\tfor (i = 0 ; i < nthr ; ++i) {\n\t\tpthread_join(threads[i], NULL);\n\t}\n\n\treturn 0;\n}\n.Ed\n.Sh SEE ALSO\n.Xr CK_COHORT_PROTOTYPE 3 ,\n.Xr CK_COHORT_TRYLOCK_PROTOTYPE 3 ,\n.Xr CK_COHORT_INSTANCE 3 ,\n.Xr CK_COHORT_INITIALIZER 3 ,\n.Xr CK_COHORT_INIT 3 ,\n.Xr CK_COHORT_LOCK 3 ,\n.Xr CK_COHORT_UNLOCK 3 ,\n.Xr CK_COHORT_LOCKED 3 ,\n.Xr CK_COHORT_TRYLOCK 3 ,\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_rwlock",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 26, 2013.\n.Dt ck_rwlock 3\n.Sh NAME\n.Nm ck_rwlock_init ,\n.Nm ck_rwlock_write_lock ,\n.Nm ck_rwlock_write_unlock ,\n.Nm ck_rwlock_write_trylock ,\n.Nm ck_rwlock_write_downgrade ,\n.Nm ck_rwlock_locked_writer ,\n.Nm ck_rwlock_read_lock ,\n.Nm ck_rwlock_read_trylock ,\n.Nm ck_rwlock_read_unlock ,\n.Nm ck_rwlock_locked_reader ,\n.Nm ck_rwlock_recursive_write_lock ,\n.Nm ck_rwlock_recursive_write_trylock ,\n.Nm ck_rwlock_recurisve_write_unlock ,\n.Nm ck_rwlock_recursive_read_lock ,\n.Nm ck_rwlock_recursive_read_trylock ,\n.Nm ck_rwlock_recursive_read_unlock\n.Nd centralized write-biased reader-writer locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_rwlock.h\n.Pp\n.Dv ck_rwlock_t lock = CK_RWLOCK_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_rwlock_init \"ck_rwlock_t *lock\"\n.Ft void\n.Fn ck_rwlock_write_lock \"ck_rwlock_t *lock\"\n.Ft void\n.Fn ck_rwlock_write_unlock \"ck_rwlock_t *lock\"\n.Ft bool\n.Fn ck_rwlock_write_trylock \"ck_rwlock_t *lock\"\n.Ft bool\n.Fn ck_rwlock_write_downgrade \"ck_rwlock_t *lock\"\n.Ft bool\n.Fn ck_rwlock_locked_writer \"ck_rwlock_t *lock\"\n.Ft void\n.Fn ck_rwlock_read_lock \"ck_rwlock_t *lock\"\n.Ft bool\n.Fn ck_rwlock_read_trylock \"ck_rwlock_t *lock\"\n.Ft void\n.Fn ck_rwlock_read_unlock \"ck_rwlock_t *lock\"\n.Ft bool\n.Fn ck_rwlock_locked_reader \"ck_rwlock_t *lock\"\n.Pp\n.Dv ck_rwlock_recursive_t lock = CK_RWLOCK_RECURSIVE_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_rwlock_recursive_write_lock \"ck_rwlock_recursive_t *lock\" \"unsigned int tid\"\n.Ft bool\n.Fn ck_rwlock_recursive_write_trylock \"ck_rwlock_recursive_t *lock\" \"unsigned int tid\"\n.Ft void\n.Fn ck_rwlock_recurisve_write_unlock \"ck_rwlock_recursive_t *lock\"\n.Ft void\n.Fn ck_rwlock_recursive_read_lock \"ck_rwlock_recursive_t *lock\"\n.Ft bool\n.Fn ck_rwlock_recursive_read_trylock \"ck_rwlock_recursive_t *lock\"\n.Ft void\n.Fn ck_rwlock_recursive_read_unlock \"ck_rwlock_recursive_t *lock\"\n.Sh DESCRIPTION\nThis is a centralized write-biased reader-writer lock. It\nrequires very little space overhead and has a low latency\nfast path. Write-side recursion requires usage of ck_rwlock_recursive.\nRead-side recursion is disallowed. The\n.Fn ck_rwlock_write_downgrade\nfunction degrades the caller's write-side acquisition to a read-side\nacquisition without forfeit of current critical section.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_rwlock.h>\n\nstatic ck_rwlock_t lock = CK_RWLOCK_INITIALIZER;\n\nstatic void\nreader(void)\n{\n\n\tfor (;;) {\n\t\tck_rwlock_read_lock(&lock);\n\t\t/* Read-side critical section. */\n\t\tck_rwlock_read_unlock(&lock);\n\n\t\tif (ck_rwlock_read_trylock(&lock) == true) {\n\t\t\t/* Read-side critical section. */\n\t\t\tck_rwlock_read_unlock(&lock);\n\t\t}\n\t}\n\n\treturn;\n}\n\nstatic void\nwriter(void)\n{\n\n\tfor (;;) {\n\t\tck_rwlock_write_lock(&lock);\n\t\t/* Write-side critical section. */\n\t\tck_rwlock_write_unlock(&lock);\n\n\t\tif (ck_rwlock_write_trylock(&lock, 1) == true) {\n\t\t\t/* Write-side critical section. */\n\t\t\tck_rwlock_write_unlock(&lock);\n\t\t}\n\t}\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_brlock 3 ,\n.Xr ck_elide 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_sequence",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 26, 2013.\n.Dt ck_sequence 3\n.Sh NAME\n.Nm ck_sequence_init ,\n.Nm ck_sequence_read_begin ,\n.Nm ck_sequence_read_retry ,\n.Nm ck_sequence_write_begin ,\n.Nm ck_sequence_write_end\n.Nd sequence locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_sequence.h\n.Pp\n.Dv ck_sequence_t seqlock = CK_SEQUENCE_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_sequence_init \"ck_sequence_t *sq\"\n.Ft unsigned int\n.Fn ck_sequence_read_begin \"const ck_sequence_t *sq\"\n.Ft bool\n.Fn ck_sequence_read_retry \"const ck_sequence_t *sq\" \"unsigned int version\"\n.Ft void\n.Fn ck_sequence_write_begin \"ck_sequence_t *sq\"\n.Ft void\n.Fn ck_sequence_write_end \"ck_sequence_t *sq\"\n.Sh DESCRIPTION\nIt is recommended to use ck_sequence when a small amount of data that cannot be\naccessed atomically has to be synchronized with readers in a fashion that does\nnot block any writer. Readers are able to execute their read-side critical\nsections without any atomic operations. A ck_sequence_t must be initialized\nbefore use. It may be initialized using either a static initializer\n(CK_SEQUENCE_INITIALIZER) or using\n.Fn ck_sequence_init .\nBefore readers attempt to\nread data that may be concurrently modified they must first save the return\nvalue of\n.Fn ck_sequence_read_begin .\nWhile or after a reader has completed copying\nthe data associated with a ck_sequence_t it must pass the earlier return value\nof\n.Fn ck_sequence_read_begin\nto\n.Fn \"ck_sequence_read_retry\". If\n.Fn ck_sequence_read_retry\nreturns true then the copy of data may be inconsistent and the read process\nmust be retried. Writers must rely on their own synchronization primitives.\nOnce a writer has entered its respective critical section, it must call\n.Fn ck_sequence_write_begin\nto signal intent to update the data protected\nby the ck_sequence_t. Before the writer leaves its critical section it must\nexecute\n.Fn ck_sequence_write_end\nto indicate that the updates have left respective objects in a consistent state.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_sequence.h>\n#include <stdlib.h>\n\nstatic struct example {\n\tint a;\n\tint b;\n\tint c;\n} global;\n\nstatic ck_sequence_t seqlock = CK_SEQUENCE_INITIALIZER;\n\nvoid\nreader(void)\n{\n\tstruct example copy;\n\tunsigned int version;\n\n\t/*\n\t * Attempt a read of the data structure. If the structure\n\t * has been modified between ck_sequence_read_begin and\n\t * ck_sequence_read_retry then attempt another read since\n\t * the data may be in an inconsistent state.\n\t */\n\tdo {\n\t\tversion = ck_sequence_read_begin(&seqlock);\n\t\tcopy = global;\n\t} while (ck_sequence_read_retry(&seqlock, version));\n\n\t/*\n\t * The previous may also be expressed using CK_SEQUENCE_READ.\n\t * Generally recommend to only use ck_sequence_read_retry\n\t * if you would like to detect a conflicting write at some\n\t * higher granularity.\n\t */\n\tCK_SEQUENCE_READ(&seqlock, &version) {\n\t\tcopy = global;\n\t}\n\n\treturn;\n}\n\nvoid\nwriter(void)\n{\n\n\tfor (;;) {\n\t\tck_sequence_write_begin(&seqlock);\n\t\tglobal.a = rand();\n\t\tglobal.b = global.a + global.b;\n\t\tglobal.c = global.b + global.c;\n\t\tck_sequence_write_end(&seqlock);\n\t}\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_brlock 3 ,\n.Xr ck_bytelock 3 ,\n.Xr ck_rwlock 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_spinlock",
    "content": ".\\\"\n.\\\" Copyright 2013 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd July 26, 2013.\n.Dt ck_spinlock 3\n.Sh NAME\n.Nm ck_spinlock_init ,\n.Nm ck_spinlock_lock ,\n.Nm ck_spinlock_unlock ,\n.Nm ck_spinlock_locked ,\n.Nm ck_spinlock_trylock ,\n.Nm ck_spinlock_anderson_init ,\n.Nm ck_spinlock_anderson_locked ,\n.Nm ck_spinlock_anderson_lock ,\n.Nm ck_spinlock_anderson_unlock ,\n.Nm ck_spinlock_cas_init ,\n.Nm ck_spinlock_cas_locked ,\n.Nm ck_spinlock_cas_lock ,\n.Nm ck_spinlock_cas_lock_eb ,\n.Nm ck_spinlock_cas_trylock ,\n.Nm ck_spinlock_cas_unlock ,\n.Nm ck_spinlock_clh_init ,\n.Nm ck_spinlock_clh_locked ,\n.Nm ck_spinlock_clh_lock ,\n.Nm ck_spinlock_clh_unlock ,\n.Nm ck_spinlock_dec_init ,\n.Nm ck_spinlock_dec_locked ,\n.Nm ck_spinlock_dec_lock ,\n.Nm ck_spinlock_dec_lock_eb ,\n.Nm ck_spinlock_dec_trylock ,\n.Nm ck_spinlock_dec_unlock ,\n.Nm ck_spinlock_fas_init ,\n.Nm ck_spinlock_fas_lock ,\n.Nm ck_spinlock_fas_lock_eb ,\n.Nm ck_spinlock_fas_locked ,\n.Nm ck_spinlock_fas_trylock ,\n.Nm ck_spinlock_fas_unlock ,\n.Nm ck_spinlock_hclh_init ,\n.Nm ck_spinlock_hclh_locked ,\n.Nm ck_spinlock_hclh_lock ,\n.Nm ck_spinlock_hclh_unlock ,\n.Nm ck_spinlock_mcs_init ,\n.Nm ck_spinlock_mcs_locked ,\n.Nm ck_spinlock_mcs_lock ,\n.Nm ck_spinlock_mcs_trylock ,\n.Nm ck_spinlock_mcs_unlock ,\n.Nm ck_spinlock_ticket_init ,\n.Nm ck_spinlock_ticket_locked ,\n.Nm ck_spinlock_ticket_lock ,\n.Nm ck_spinlock_ticket_lock_pb ,\n.Nm ck_spinlock_ticket_trylock ,\n.Nm ck_spinlock_ticket_unlock\n.Nd spinlock implementations\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_spinlock.h\n.Pp\n.Dv ck_spinlock_t spinlock = CK_SPINLOCK_INITIALIZER;\n.Ft void\n.Fn ck_spinlock_init \"ck_spinlock_t *lock\"\n.Ft void\n.Fn ck_spinlock_lock \"ck_spinlock_t *lock\"\n.Ft void\n.Fn ck_spinlock_unlock \"ck_spinlock_t *lock\"\n.Ft bool\n.Fn ck_spinlock_locked \"ck_spinlock_t *lock\"\n.Ft bool\n.Fn ck_spinlock_trylock \"ck_spinlock_t *lock\"\n.Ft void\n.Fn ck_spinlock_anderson_init \"ck_spinlock_anderson_t *lock\" \"ck_spinlock_anderson_thread_t *slots\" \"unsigned int count\"\n.Ft bool\n.Fn ck_spinlock_anderson_locked \"ck_spinlock_anderson_t *lock\"\n.Ft void\n.Fn ck_spinlock_anderson_lock \"ck_spinlock_anderson_t *lock\" \"ck_spinlock_anderson_thread_t **slot\"\n.Ft void\n.Fn ck_spinlock_anderson_unlock \"ck_spinlock_anderson_t *lock\" \"ck_spinlock_anderson_thread_t *slot\"\n.Pp\n.Dv ck_spinlock_cas_t spinlock = CK_SPINLOCK_CAS_INITIALIZER;\n.Ft void\n.Fn ck_spinlock_cas_init \"ck_spinlock_cas_t *lock\"\n.Ft bool\n.Fn ck_spinlock_cas_locked \"ck_spinlock_cas_t *lock\"\n.Ft void\n.Fn ck_spinlock_cas_lock \"ck_spinlock_cas_t *lock\"\n.Ft void\n.Fn ck_spinlock_cas_lock_eb \"ck_spinlock_cas_t *lock\"\n.Ft bool\n.Fn ck_spinlock_cas_trylock \"ck_spinlock_cas_t *lock\"\n.Ft void\n.Fn ck_spinlock_cas_unlock \"ck_spinlock_cas_t *lock\"\n.Ft void\n.Fn ck_spinlock_clh_init \"ck_spinlock_clh_t **lock\" \"ck_spinlock_clh_t *unowned\"\n.Ft bool\n.Fn ck_spinlock_clh_locked \"ck_spinlock_clh_t **lock\"\n.Ft void\n.Fn ck_spinlock_clh_lock \"ck_spinlock_clh_t **lock\" \"ck_spinlock_clh_t *node\"\n.Ft void\n.Fn ck_spinlock_clh_unlock \"ck_spinlock_clh_t **node\"\n.Pp\n.Dv ck_spinlock_dec_t spinlock = CK_SPINLOCK_DEC_INITIALIZER;\n.Ft void\n.Fn ck_spinlock_dec_init \"ck_spinlock_dec_t *lock\"\n.Ft bool\n.Fn ck_spinlock_dec_locked \"ck_spinlock_dec_t *lock\"\n.Ft void\n.Fn ck_spinlock_dec_lock \"ck_spinlock_dec_t *lock\"\n.Ft void\n.Fn ck_spinlock_dec_lock_eb \"ck_spinlock_dec_t *lock\"\n.Ft bool\n.Fn ck_spinlock_dec_trylock \"ck_spinlock_dec_t *lock\"\n.Ft void\n.Fn ck_spinlock_dec_unlock \"ck_spinlock_dec_t *lock\"\n.Pp\n.Dv ck_spinlock_fas_t spinlock = CK_SPINLOCK_FAS_INITIALIZER;\n.Ft void\n.Fn ck_spinlock_fas_init \"ck_spinlock_fas_t *lock\"\n.Ft void\n.Fn ck_spinlock_fas_lock \"ck_spinlock_fas_t *lock\"\n.Ft void\n.Fn ck_spinlock_fas_lock_eb \"ck_spinlock_fas_t *lock\"\n.Ft bool\n.Fn ck_spinlock_fas_locked \"ck_spinlock_fas_t *lock\"\n.Ft bool\n.Fn ck_spinlock_fas_trylock \"ck_spinlock_fas_t *lock\"\n.Ft void\n.Fn ck_spinlock_fas_unlock \"ck_spinlock_fas_t *lock\"\n.Pp\n.Ft void\n.Fn ck_spinlock_hclh_init \"ck_spinlock_hclh_t **lock\" \"ck_spinlock_hclh_t *unowned\"\n.Ft bool\n.Fn ck_spinlock_hclh_locked \"ck_spinlock_hclh_t **lock\"\n.Ft void\n.Fn ck_spinlock_hclh_lock \"ck_spinlock_hclh_t **lock\" \"ck_spinlock_hclh_t *node\"\n.Ft void\n.Fn ck_spinlock_hclh_unlock \"ck_spinlock_hclh_t **node\"\n.Pp\n.Dv ck_spinlock_mcs_t spinlock = CK_SPINLOCK_MCS_INITIALIZER;\n.Ft void\n.Fn ck_spinlock_mcs_init \"ck_spinlock_mcs_t **lock\"\n.Ft bool\n.Fn ck_spinlock_mcs_locked \"ck_spinlock_mcs_t **lock\"\n.Ft void\n.Fn ck_spinlock_mcs_lock \"ck_spinlock_mcs_t **lock\" \"ck_spinlock_mcs_t *node\"\n.Ft bool\n.Fn ck_spinlock_mcs_trylock \"ck_spinlock_mcs_t **lock\" \"ck_spinlock_mcs_t *node\"\n.Ft void\n.Fn ck_spinlock_mcs_unlock \"ck_spinlock_mcs_t **lock\" \"ck_spinlock_mcs_t *node\"\n.Pp\n.Dv ck_spinlock_ticket_t spinlock = CK_SPINLOCK_TICKET_INITIALIZER;\n.Ft void\n.Fn ck_spinlock_ticket_init \"ck_spinlock_ticket_t *lock\"\n.Ft bool\n.Fn ck_spinlock_ticket_locked \"ck_spinlock_ticket_t *lock\"\n.Ft void\n.Fn ck_spinlock_ticket_lock \"ck_spinlock_ticket_t *lock\"\n.Ft void\n.Fn ck_spinlock_ticket_lock_pb \"ck_spinlock_ticket_t *lock\" \"unsigned int period\"\n.Ft bool\n.Fn ck_spinlock_ticket_trylock \"ck_spinlock_ticket_t *lock\"\n.Ft void\n.Fn ck_spinlock_ticket_unlock \"ck_spinlock_ticket_t *lock\"\n.Sh DESCRIPTION\nA family of busy-wait spinlock implementations. The ck_spinlock_t implementation is simply\na wrapper around the fetch-and-swap (ck_spinlock_fas_t) implementation. The table below\nprovides a summary of the current implementations.\n.Bd -literal\n|            Namespace | Algorithm                   | Type          | Restrictions            | Fair   |\n\\'----------------------|-----------------------------|---------------|-------------------------|--------'\n  ck_spinlock_anderson   Anderson                      Array           Fixed number of threads   Yes\n       ck_spinlock_cas   Compare-and-Swap              Centralized     None                      No\n       ck_spinlock_clh   Craig, Landin and Hagersten   Queue           Lifetime requirements     Yes\n       ck_spinlock_dec   Decrement (Linux kernel)      Centralized     UINT_MAX concurrency      No\n       ck_spinlock_fas   Fetch-and-store               Centralized     None                      No\n       ck_spinlock_hclh  Hierarchical CLH              Queue           Lifetime requirements     Yes *\n       ck_spinlock_mcs   Mellor-Crummey and Scott      Queue           None                      Yes\n    ck_spinlock_ticket   Ticket                        Centralized     None                      Yes\n.Ed\n.Pp\n* Hierarchical CLH only offers weak fairness for threads accross cluster\nnodes.\n.Pp\nIf contention is low and there is no hard requirement for starvation-freedom\nthen a centralized greedy (unfair) spinlock is recommended. If contention is\nhigh and there is no requirement for starvation-freedom then a centralized\ngreedy spinlock is recommended to be used with an exponential backoff\nmechanism. If contention is generally low and there is a hard requirement for\nstarvation-freedom then the ticket lock is recommended. If contention is high\nand there is a hard requirement for starvation-freedom then the Craig and\nLandin and Hagersten queue spinlock is recommended unless stack allocation is\nnecessary or NUMA factor is high, in which case the Mellor-Crummey and Scott\nspinlock is recommended. If you cannot afford O(n) space-usage from array\nor queue spinlocks but still require fairness under high contention then\nthe ticket lock with proportional back-off is recommended.\nIf NUMA factor is high but prefer a greedy lock, then please see\n.Xr ck_cohort 3 .\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_spinlock.h>\n#include <stdbool.h>\n\n/*\n * Alternatively, the mutex may be initialized at run-time with\n * ck_spinlock_init(&mutex).\n */\nck_spinlock_t mutex = CK_SPINLOCK_INITIALIZER;\n\nvoid\nexample(void)\n{\n\n        ck_spinlock_lock(&mutex);\n        /*\n         * Critical section.\n         */\n        ck_spinlock_unlock(&mutex);\n\n        ck_spinlock_lock_eb(&mutex);\n        /*\n         * Critical section.\n         */\n        ck_spinlock_unlock(&mutex);\n\n        if (ck_spinlock_trylock(&mutex) == true) {\n                /*\n                 * Critical section.\n                 */\n                ck_spinlock_unlock(&mutex);\n        }\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_cohort 3 ,\n.Xr ck_elide 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_swlock",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2014.\n.Dt ck_swlock 3\n.Sh NAME\n.Nm ck_swlock_init ,\n.Nm ck_swlock_write_latch ,\n.Nm ck_swlock_write_unlatch ,\n.Nm ck_swlock_write_lock ,\n.Nm ck_swlock_write_unlock ,\n.Nm ck_swlock_write_trylock ,\n.Nm ck_swlock_write_downgrade ,\n.Nm ck_swlock_locked_writer ,\n.Nm ck_swlock_read_lock ,\n.Nm ck_swlock_read_trylock ,\n.Nm ck_swlock_read_unlock ,\n.Nm ck_swlock_locked_reader\n.Nd centralized copy-safe write-biased single-writer read-write locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_swlock.h\n.Pp\n.Dv ck_swlock_t lock = CK_SWLOCK_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_swlock_init \"ck_swlock_t *lock\"\n.Ft void\n.Fn ck_swlock_write_lock \"ck_swlock_t *lock\"\n.Ft void\n.Fn ck_swlock_write_unlock \"ck_swlock_t *lock\"\n.Ft void\n.Fn ck_swlatch_write_latch \"ck_swlatch_t *latch\"\n.Ft void\n.Fn ck_swlatch_write_unlatch \"ck_swlatch_t *latch\"\n.Ft bool\n.Fn ck_swlock_write_trylock \"ck_swlock_t *lock\"\n.Ft bool\n.Fn ck_swlock_write_downgrade \"ck_swlock_t *lock\"\n.Ft bool\n.Fn ck_swlock_locked_writer \"ck_swlock_t *lock\"\n.Ft void\n.Fn ck_swlock_read_lock \"ck_swlock_t *lock\"\n.Ft bool\n.Fn ck_swlock_read_trylock \"ck_swlock_t *lock\"\n.Ft void\n.Fn ck_swlock_read_unlock \"ck_swlock_t *lock\"\n.Ft bool\n.Fn ck_swlock_locked_reader \"ck_swlock_t *lock\"\n.Sh DESCRIPTION\nThis is a centralized write-biased single-writer reader-writer lock. It\nrequires half the space that ck_rwlock does and has a low latency\nfast path. The lock supports latch and unlatch operations that\nallow it to be used in a copy-safe manner (reader-bits may be\nover-written safely).\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_swlock.h>\n\nstatic ck_swlock_t lock = CK_SWLOCK_INITIALIZER;\n\nstatic void\nreader(void)\n{\n\n\tfor (;;) {\n\t\tck_swlock_read_lock(&lock);\n\t\t/* Read-side critical section. */\n\t\tck_swlock_read_unlock(&lock);\n\n\t\tif (ck_swlock_read_trylock(&lock) == true) {\n\t\t\t/* Read-side critical section. */\n\t\t\tck_swlock_read_unlock(&lock);\n\t\t}\n\t}\n\n\treturn;\n}\n\nstatic void\nwriter(void)\n{\n\tck_swlock_t contrived;\n\n\tfor (;;) {\n\t\tck_swlock_write_lock(&lock);\n\t\t/* Write-side critical section. */\n\t\tck_swlock_write_unlock(&lock);\n\n\t\tif (ck_swlock_write_trylock(&lock) == true) {\n\t\t\t/* Write-side critical section. */\n\t\t\tck_swlock_write_unlock(&lock);\n\t\t}\n\n\t\tck_swlock_write_latch(&lock);\n\t\t/* Write-side critical section. */\n\n\t\t/* This is safe to do with-in a latch. */\n\t\tcontrived = lock;\n\t\tlock = contrived;\n\t\tck_swlock_write_unlatch(&lock);\n\t}\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_brlock 3 ,\n.Xr ck_elide 3 ,\n.Xr ck_pflock 3 ,\n.Xr ck_rwlock 3 ,\n.Xr ck_tflock 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/ck_tflock",
    "content": ".\\\"\n.\\\" Copyright 2014 Samy Al Bahra.\n.\\\" All rights reserved.\n.\\\"\n.\\\" Redistribution and use in source and binary forms, with or without\n.\\\" modification, are permitted provided that the following conditions\n.\\\" are met:\n.\\\" 1. Redistributions of source code must retain the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer.\n.\\\" 2. Redistributions in binary form must reproduce the above copyright\n.\\\"    notice, this list of conditions and the following disclaimer in the\n.\\\"    documentation and/or other materials provided with the distribution.\n.\\\"\n.\\\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n.\\\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n.\\\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n.\\\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n.\\\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n.\\\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n.\\\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n.\\\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n.\\\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n.\\\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n.\\\" SUCH DAMAGE.\n.\\\"\n.\\\"\n.Dd April 22, 2014.\n.Dt ck_tflock 3\n.Sh NAME\n.Nm ck_tflock_ticket_init ,\n.Nm ck_tflock_ticket_write_lock ,\n.Nm ck_tflock_ticket_write_unlock ,\n.Nm ck_tflock_ticket_read_lock ,\n.Nm ck_tflock_ticket_read_unlock ,\n.Nd centralized task-fair reader-writer locks\n.Sh LIBRARY\nConcurrency Kit (libck, \\-lck)\n.Sh SYNOPSIS\n.In ck_tflock.h\n.Pp\n.Dv ck_tflock_ticket_t lock = CK_TFLOCK_TICKET_INITIALIZER;\n.Pp\n.Ft void\n.Fn ck_tflock_ticket_init \"ck_tflock_ticket_t *lock\"\n.Ft void\n.Fn ck_tflock_ticket_write_lock \"ck_tflock_ticket_t *lock\"\n.Ft void\n.Fn ck_tflock_ticket_write_unlock \"ck_tflock_ticket_t *lock\"\n.Ft void\n.Fn ck_tflock_ticket_read_lock \"ck_tflock_ticket_t *lock\"\n.Ft void\n.Fn ck_tflock_ticket_read_unlock \"ck_tflock_ticket_t *lock\"\n.Sh DESCRIPTION\nThis is a centralized task-fair reader-writer lock. It\nrequires little space overhead and has a low latency\nfast path.\n.Sh EXAMPLE\n.Bd -literal -offset indent\n#include <ck_tflock.h>\n\nstatic ck_tflock_ticket_t lock = CK_TFLOCK_INITIALIZER;\n\nstatic void\nreader(void)\n{\n\n\tfor (;;) {\n\t\tck_tflock_ticket_read_lock(&lock);\n\t\t/* Read-side critical section. */\n\t\tck_tflock_ticket_read_unlock(&lock);\n\t}\n\n\treturn;\n}\n\nstatic void\nwriter(void)\n{\n\n\tfor (;;) {\n\t\tck_tflock_ticket_write_lock(&lock);\n\t\t/* Write-side critical section. */\n\t\tck_tflock_ticket_write_unlock(&lock);\n\t}\n\n\treturn;\n}\n.Ed\n.Sh SEE ALSO\n.Xr ck_brlock 3 ,\n.Xr ck_rwlock 3 ,\n.Xr ck_pflock 3 ,\n.Xr ck_swlock 3\n.Pp\nAdditional information available at http://concurrencykit.org/\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/doc/refcheck.pl",
    "content": "#!/usr/bin/perl\n\nuse warnings;\nuse strict;\n\nmy @files = @ARGV;\n\nmy $h;\n\nforeach my $file (@files) {\n    $h->{$file} = 1;\n}\n\nforeach my $file (@files) {\n    open(my $fh, \"<\", $file) or die \"cannot open < $file: $!\";\n    while (<$fh>) {\n        chomp;\n        if ($_ =~ /\\.Xr ((ck|CK)_[a-zA-Z_]+) ([0-9])/) {\n\t    my $name = $1;\n\t    my $section = $3;\n\t    if (!$h->{$name}) {\n\t\tprint STDERR \"$file: ref to missing ${name}($section)\\n\";\n\t    }\n        }\n    }\n    close($fh) or die(\"cannot close $file: $!\");\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_array.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra\n * Copyright 2013-2014 AppNexus, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_ARRAY_H\n#define CK_ARRAY_H\n\n#include <ck_cc.h>\n#include <ck_malloc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\nstruct _ck_array {\n\tunsigned int n_committed;\n\tunsigned int length;\n\tvoid *values[];\n};\n\nstruct ck_array {\n\tstruct ck_malloc *allocator;\n\tstruct _ck_array *active;\n\tunsigned int n_entries;\n\tstruct _ck_array *transaction;\n};\ntypedef struct ck_array ck_array_t;\n\nstruct ck_array_iterator {\n\tstruct _ck_array *snapshot;\n};\ntypedef struct ck_array_iterator ck_array_iterator_t;\n\n#define CK_ARRAY_MODE_SPMC 0U\n#define CK_ARRAY_MODE_MPMC (void) /* Unsupported. */\n\nbool ck_array_init(ck_array_t *, unsigned int, struct ck_malloc *, unsigned int);\nbool ck_array_commit(ck_array_t *);\nbool ck_array_put(ck_array_t *, void *);\nint ck_array_put_unique(ck_array_t *, void *);\nbool ck_array_remove(ck_array_t *, void *);\nvoid ck_array_deinit(ck_array_t *, bool);\n\nCK_CC_INLINE static unsigned int\nck_array_length(struct ck_array *array)\n{\n\tstruct _ck_array *a = ck_pr_load_ptr(&array->active);\n\n\tck_pr_fence_load();\n\treturn ck_pr_load_uint(&a->n_committed);\n}\n\nCK_CC_INLINE static void *\nck_array_buffer(struct ck_array *array, unsigned int *length)\n{\n\tstruct _ck_array *a = ck_pr_load_ptr(&array->active);\n\n\tck_pr_fence_load();\n\t*length = ck_pr_load_uint(&a->n_committed);\n\treturn a->values;\n}\n\nCK_CC_INLINE static bool\nck_array_initialized(struct ck_array *array)\n{\n\n\treturn ck_pr_load_ptr(&array->active) != NULL;\n}\n\n#define CK_ARRAY_FOREACH(a, i, b)\t\t   \t\\\n\t(i)->snapshot = ck_pr_load_ptr(&(a)->active);\t\\\n\tck_pr_fence_load();\t\t\t\t\\\n\tfor (unsigned int _ck_i = 0;\t\t   \t\\\n\t    _ck_i < (a)->active->n_committed &&\t\t\\\n\t    ((*b) = (a)->active->values[_ck_i], 1);\t\\\n\t    _ck_i++)\n\n#endif /* CK_ARRAY_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_backoff.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_BACKOFF_H\n#define CK_BACKOFF_H\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n\n#ifndef CK_BACKOFF_CEILING\n#define CK_BACKOFF_CEILING ((1 << 20) - 1)\n#endif\n\n#define CK_BACKOFF_INITIALIZER (1 << 9)\n\ntypedef unsigned int ck_backoff_t;\n\n/*\n * This is a exponential back-off implementation.\n */\nCK_CC_INLINE static void\nck_backoff_eb(unsigned int *c)\n{\n\tunsigned int i, ceiling;\n\n\tceiling = *c;\n\tfor (i = 0; i < ceiling; i++)\n\t\tck_pr_barrier();\n\n\t*c = ceiling <<= ceiling < CK_BACKOFF_CEILING;\n\treturn;\n}\n\n#endif /* CK_BACKOFF_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_barrier.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_BARRIER_H\n#define CK_BARRIER_H\n\n#include <ck_spinlock.h>\n\nstruct ck_barrier_centralized {\n\tunsigned int value;\n\tunsigned int sense;\n};\ntypedef struct ck_barrier_centralized ck_barrier_centralized_t;\n\nstruct ck_barrier_centralized_state {\n\tunsigned int sense;\n};\ntypedef struct ck_barrier_centralized_state ck_barrier_centralized_state_t;\n\n#define CK_BARRIER_CENTRALIZED_INITIALIZER \t {0, 0}\n#define CK_BARRIER_CENTRALIZED_STATE_INITIALIZER {0}\n\nvoid ck_barrier_centralized(ck_barrier_centralized_t *,\n    ck_barrier_centralized_state_t *, unsigned int);\n\nstruct ck_barrier_combining_group {\n\tunsigned int k;\n\tunsigned int count;\n\tunsigned int sense;\n\tstruct ck_barrier_combining_group *parent;\n\tstruct ck_barrier_combining_group *left;\n\tstruct ck_barrier_combining_group *right;\n\tstruct ck_barrier_combining_group *next;\n} CK_CC_CACHELINE;\ntypedef struct ck_barrier_combining_group ck_barrier_combining_group_t;\n\nstruct ck_barrier_combining_state {\n\tunsigned int sense;\n};\ntypedef struct ck_barrier_combining_state ck_barrier_combining_state_t;\n\n#define CK_BARRIER_COMBINING_STATE_INITIALIZER {~0}\n\nstruct ck_barrier_combining {\n\tstruct ck_barrier_combining_group *root;\n\tck_spinlock_fas_t mutex;\n};\ntypedef struct ck_barrier_combining ck_barrier_combining_t;\n\nvoid ck_barrier_combining_init(ck_barrier_combining_t *, ck_barrier_combining_group_t *);\n\nvoid ck_barrier_combining_group_init(ck_barrier_combining_t *,\n    ck_barrier_combining_group_t *, unsigned int);\n\nvoid ck_barrier_combining(ck_barrier_combining_t *,\n    ck_barrier_combining_group_t *,\n    ck_barrier_combining_state_t *);\n\nstruct ck_barrier_dissemination_flag {\n\tunsigned int tflag;\n\tunsigned int *pflag;\n};\ntypedef struct ck_barrier_dissemination_flag ck_barrier_dissemination_flag_t;\n\nstruct ck_barrier_dissemination {\n\tunsigned int nthr;\n\tunsigned int size;\n\tunsigned int tid;\n\tstruct ck_barrier_dissemination_flag *flags[2];\n};\ntypedef struct ck_barrier_dissemination ck_barrier_dissemination_t;\n\nstruct ck_barrier_dissemination_state {\n\tint \t\tparity;\n\tunsigned int \tsense;\n\tunsigned int\ttid;\n};\ntypedef struct ck_barrier_dissemination_state ck_barrier_dissemination_state_t;\n\nvoid ck_barrier_dissemination_init(ck_barrier_dissemination_t *,\n    ck_barrier_dissemination_flag_t **, unsigned int);\n\nvoid ck_barrier_dissemination_subscribe(ck_barrier_dissemination_t *,\n    ck_barrier_dissemination_state_t *);\n\nunsigned int ck_barrier_dissemination_size(unsigned int);\n\nvoid ck_barrier_dissemination(ck_barrier_dissemination_t *,\n    ck_barrier_dissemination_state_t *);\n\nstruct ck_barrier_tournament_round {\n\tint role;\n\tunsigned int *opponent;\n\tunsigned int flag;\n};\ntypedef struct ck_barrier_tournament_round ck_barrier_tournament_round_t;\n\nstruct ck_barrier_tournament {\n\tunsigned int tid;\n\tunsigned int size;\n\tstruct ck_barrier_tournament_round **rounds;\n};\ntypedef struct ck_barrier_tournament ck_barrier_tournament_t;\n\nstruct ck_barrier_tournament_state {\n\tunsigned int sense;\n\tunsigned int vpid;\n};\ntypedef struct ck_barrier_tournament_state ck_barrier_tournament_state_t;\n\nvoid ck_barrier_tournament_subscribe(ck_barrier_tournament_t *,\n\t\t\t\t     ck_barrier_tournament_state_t *);\nvoid ck_barrier_tournament_init(ck_barrier_tournament_t *,\n\t\t\t\tck_barrier_tournament_round_t **,\n\t\t\t\tunsigned int);\nunsigned int ck_barrier_tournament_size(unsigned int);\nvoid ck_barrier_tournament(ck_barrier_tournament_t *, ck_barrier_tournament_state_t *);\n\nstruct ck_barrier_mcs {\n\tunsigned int tid;\n\tunsigned int *children[2];\n\tunsigned int childnotready[4];\n\tunsigned int dummy;\n\tunsigned int havechild[4];\n\tunsigned int *parent;\n\tunsigned int parentsense;\n};\ntypedef struct ck_barrier_mcs ck_barrier_mcs_t;\n\nstruct ck_barrier_mcs_state {\n\tunsigned int sense;\n\tunsigned int vpid;\n};\ntypedef struct ck_barrier_mcs_state ck_barrier_mcs_state_t;\n\nvoid ck_barrier_mcs_init(ck_barrier_mcs_t *, unsigned int);\nvoid ck_barrier_mcs_subscribe(ck_barrier_mcs_t *, ck_barrier_mcs_state_t *);\nvoid ck_barrier_mcs(ck_barrier_mcs_t *, ck_barrier_mcs_state_t *);\n\n#endif /* CK_BARRIER_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_bitmap.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * Copyright 2012-2014 AppNexus, Inc.\n * Copyright 2014 Paul Khuong.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_BITMAP_H\n#define CK_BITMAP_H\n\n#include <ck_cc.h>\n#include <ck_limits.h>\n#include <ck_pr.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n#include <ck_string.h>\n\n#if !defined(CK_F_PR_LOAD_UINT) || !defined(CK_F_PR_STORE_UINT) || \\\n    !defined(CK_F_PR_AND_UINT) || !defined(CK_F_PR_OR_UINT) || \\\n    !defined(CK_F_CC_CTZ)\n#error \"ck_bitmap is not supported on your platform.\"\n#endif\n\n#define CK_BITMAP_BLOCK \t(sizeof(unsigned int) * CHAR_BIT)\n#define CK_BITMAP_OFFSET(i)\t((i) % CK_BITMAP_BLOCK)\n#define CK_BITMAP_BIT(i)\t(1U << CK_BITMAP_OFFSET(i))\n#define CK_BITMAP_PTR(x, i)\t((x) + ((i) / CK_BITMAP_BLOCK))\n#define CK_BITMAP_BLOCKS(n)\t(((n) + CK_BITMAP_BLOCK - 1) / CK_BITMAP_BLOCK)\n\n#define CK_BITMAP_INSTANCE(n_entries)\t\t\t\t\t\\\n\tunion {\t\t\t\t\t\t\t\t\\\n\t\tstruct {\t\t\t\t\t\t\\\n\t\t\tunsigned int n_bits;\t\t\t\t\\\n\t\t\tunsigned int map[CK_BITMAP_BLOCKS(n_entries)];\t\\\n\t\t} content;\t\t\t\t\t\t\\\n\t\tstruct ck_bitmap bitmap;\t\t\t\t\\\n\t}\n\n#define CK_BITMAP_ITERATOR_INIT(a, b) \\\n\tck_bitmap_iterator_init((a), &(b)->bitmap)\n\n#define CK_BITMAP_INIT(a, b, c) \\\n\tck_bitmap_init(&(a)->bitmap, (b), (c))\n\n#define CK_BITMAP_NEXT(a, b, c) \\\n\tck_bitmap_next(&(a)->bitmap, (b), (c))\n\n#define CK_BITMAP_SET(a, b) \\\n\tck_bitmap_set(&(a)->bitmap, (b))\n\n#define CK_BITMAP_BTS(a, b) \\\n\tck_bitmap_bts(&(a)->bitmap, (b))\n\n#define CK_BITMAP_RESET(a, b) \\\n\tck_bitmap_reset(&(a)->bitmap, (b))\n\n#define CK_BITMAP_TEST(a, b) \\\n\tck_bitmap_test(&(a)->bitmap, (b))\n\n#define CK_BITMAP_UNION(a, b) \\\n\tck_bitmap_union(&(a)->bitmap, &(b)->bitmap)\n\n#define CK_BITMAP_INTERSECTION(a, b) \\\n\tck_bitmap_intersection(&(a)->bitmap, &(b)->bitmap)\n\n#define CK_BITMAP_INTERSECTION_NEGATE(a, b) \\\n\tck_bitmap_intersection_negate(&(a)->bitmap, &(b)->bitmap)\n\n#define CK_BITMAP_CLEAR(a) \\\n\tck_bitmap_clear(&(a)->bitmap)\n\n#define CK_BITMAP_EMPTY(a, b) \\\n\tck_bitmap_empty(&(a)->bitmap, b)\n\n#define CK_BITMAP_FULL(a, b) \\\n\tck_bitmap_full(&(a)->bitmap, b)\n\n#define CK_BITMAP_COUNT(a, b) \\\n\tck_bitmap_count(&(a)->bitmap, b)\n\n#define CK_BITMAP_COUNT_INTERSECT(a, b, c) \\\n\tck_bitmap_count_intersect(&(a)->bitmap, b, c)\n\n#define CK_BITMAP_BITS(a) \\\n\tck_bitmap_bits(&(a)->bitmap)\n\n#define CK_BITMAP_BUFFER(a) \\\n\tck_bitmap_buffer(&(a)->bitmap)\n\n#define CK_BITMAP(a) \\\n\t(&(a)->bitmap)\n\nstruct ck_bitmap {\n\tunsigned int n_bits;\n\tunsigned int map[];\n};\ntypedef struct ck_bitmap ck_bitmap_t;\n\nstruct ck_bitmap_iterator {\n\tunsigned int cache;\n\tunsigned int n_block;\n\tunsigned int n_limit;\n};\ntypedef struct ck_bitmap_iterator ck_bitmap_iterator_t;\n\nCK_CC_INLINE static unsigned int\nck_bitmap_base(unsigned int n_bits)\n{\n\n\treturn CK_BITMAP_BLOCKS(n_bits) * sizeof(unsigned int);\n}\n\n/*\n * Returns the required number of bytes for a ck_bitmap_t object supporting the\n * specified number of bits.\n */\nCK_CC_INLINE static unsigned int\nck_bitmap_size(unsigned int n_bits)\n{\n\n\treturn ck_bitmap_base(n_bits) + sizeof(struct ck_bitmap);\n}\n\n/*\n * Returns total number of bits in specified bitmap.\n */\nCK_CC_INLINE static unsigned int\nck_bitmap_bits(const struct ck_bitmap *bitmap)\n{\n\n\treturn bitmap->n_bits;\n}\n\n/*\n * Returns a pointer to the bit buffer associated\n * with the specified bitmap.\n */\nCK_CC_INLINE static void *\nck_bitmap_buffer(struct ck_bitmap *bitmap)\n{\n\n\treturn bitmap->map;\n}\n\n/*\n * Sets the bit at the offset specified in the second argument.\n */\nCK_CC_INLINE static void\nck_bitmap_set(struct ck_bitmap *bitmap, unsigned int n)\n{\n\n\tck_pr_or_uint(CK_BITMAP_PTR(bitmap->map, n), CK_BITMAP_BIT(n));\n\treturn;\n}\n\n/*\n * Performs a test-and-set operation at the offset specified in the\n * second argument.\n * Returns true if the bit at the specified offset was already set,\n * false otherwise.\n */\nCK_CC_INLINE static bool\nck_bitmap_bts(struct ck_bitmap *bitmap, unsigned int n)\n{\n\n\treturn ck_pr_bts_uint(CK_BITMAP_PTR(bitmap->map, n),\n\t    CK_BITMAP_OFFSET(n));\n}\n\n/*\n * Resets the bit at the offset specified in the second argument.\n */\nCK_CC_INLINE static void\nck_bitmap_reset(struct ck_bitmap *bitmap, unsigned int n)\n{\n\n\tck_pr_and_uint(CK_BITMAP_PTR(bitmap->map, n), ~CK_BITMAP_BIT(n));\n\treturn;\n}\n\n/*\n * Determines whether the bit at offset specified in the\n * second argument is set.\n */\nCK_CC_INLINE static bool\nck_bitmap_test(const struct ck_bitmap *bitmap, unsigned int n)\n{\n\tunsigned int block;\n\n\tblock = ck_pr_load_uint(CK_BITMAP_PTR(bitmap->map, n));\n\treturn block & CK_BITMAP_BIT(n);\n}\n\n/*\n * Combines bits from second bitmap into the first bitmap. This is not a\n * linearized operation with respect to the complete bitmap.\n */\nCK_CC_INLINE static void\nck_bitmap_union(struct ck_bitmap *dst, const struct ck_bitmap *src)\n{\n\tunsigned int n;\n\tunsigned int n_buckets = dst->n_bits;\n\n\tif (src->n_bits < dst->n_bits)\n\t\tn_buckets = src->n_bits;\n\n\tn_buckets = CK_BITMAP_BLOCKS(n_buckets);\n\tfor (n = 0; n < n_buckets; n++) {\n\t\tck_pr_or_uint(&dst->map[n],\n\t\t    ck_pr_load_uint(&src->map[n]));\n\t}\n\n\treturn;\n}\n\n/*\n * Intersects bits from second bitmap into the first bitmap. This is\n * not a linearized operation with respect to the complete bitmap.\n * Any trailing bit in dst is cleared.\n */\nCK_CC_INLINE static void\nck_bitmap_intersection(struct ck_bitmap *dst, const struct ck_bitmap *src)\n{\n\tunsigned int n;\n\tunsigned int n_buckets = dst->n_bits;\n\tunsigned int n_intersect = n_buckets;\n\n\tif (src->n_bits < n_intersect)\n\t\tn_intersect = src->n_bits;\n\n\tn_buckets = CK_BITMAP_BLOCKS(n_buckets);\n\tn_intersect = CK_BITMAP_BLOCKS(n_intersect);\n\tfor (n = 0; n < n_intersect; n++) {\n\t\tck_pr_and_uint(&dst->map[n],\n\t\t    ck_pr_load_uint(&src->map[n]));\n\t}\n\n\tfor (; n < n_buckets; n++)\n\t\tck_pr_store_uint(&dst->map[n], 0);\n\n\treturn;\n}\n\n/*\n * Intersects the complement of bits from second bitmap into the first\n * bitmap. This is not a linearized operation with respect to the\n * complete bitmap.  Any trailing bit in dst is left as is.\n */\nCK_CC_INLINE static void\nck_bitmap_intersection_negate(struct ck_bitmap *dst,\n    const struct ck_bitmap *src)\n{\n\tunsigned int n;\n\tunsigned int n_intersect = dst->n_bits;\n\n\tif (src->n_bits < n_intersect)\n\t\tn_intersect = src->n_bits;\n\n\tn_intersect = CK_BITMAP_BLOCKS(n_intersect);\n\tfor (n = 0; n < n_intersect; n++) {\n\t\tck_pr_and_uint(&dst->map[n],\n\t\t    (~ck_pr_load_uint(&src->map[n])));\n\t}\n\n\treturn;\n}\n\n/*\n * Resets all bits in the provided bitmap. This is not a linearized\n * operation in ck_bitmap.\n */\nCK_CC_INLINE static void\nck_bitmap_clear(struct ck_bitmap *bitmap)\n{\n\tunsigned int i;\n\tunsigned int n_buckets = ck_bitmap_base(bitmap->n_bits) /\n\t    sizeof(unsigned int);\n\n\tfor (i = 0; i < n_buckets; i++)\n\t\tck_pr_store_uint(&bitmap->map[i], 0);\n\n\treturn;\n}\n\n/*\n * Returns true if the first limit bits in bitmap are cleared.  If\n * limit is greater than the bitmap size, limit is truncated to that\n * size.\n */\nCK_CC_INLINE static bool\nck_bitmap_empty(const ck_bitmap_t *bitmap, unsigned int limit)\n{\n\tunsigned int i, words, slop;\n\n\tif (limit > bitmap->n_bits)\n\t\tlimit = bitmap->n_bits;\n\n\twords = limit / CK_BITMAP_BLOCK;\n\tslop = limit % CK_BITMAP_BLOCK;\n\tfor (i = 0; i < words; i++) {\n\t\tif (ck_pr_load_uint(&bitmap->map[i]) != 0) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tif (slop > 0) {\n\t\tunsigned int word;\n\n\t\tword = ck_pr_load_uint(&bitmap->map[i]);\n\t\tif ((word & ((1U << slop) - 1)) != 0)\n\t\t\treturn false;\n\t}\n\n\treturn true;\n}\n\n/*\n * Returns true if the first limit bits in bitmap are set.  If limit\n * is greater than the bitmap size, limit is truncated to that size.\n */\nCK_CC_UNUSED static bool\nck_bitmap_full(const ck_bitmap_t *bitmap, unsigned int limit)\n{\n\tunsigned int i, slop, words;\n\n\tif (limit > bitmap->n_bits) {\n\t\tlimit = bitmap->n_bits;\n\t}\n\n\twords = limit / CK_BITMAP_BLOCK;\n\tslop = limit % CK_BITMAP_BLOCK;\n\tfor (i = 0; i < words; i++) {\n\t\tif (ck_pr_load_uint(&bitmap->map[i]) != -1U)\n\t\t\treturn false;\n\t}\n\n\tif (slop > 0) {\n\t\tunsigned int word;\n\n\t\tword = ~ck_pr_load_uint(&bitmap->map[i]);\n\t\tif ((word & ((1U << slop) - 1)) != 0)\n\t\t\treturn false;\n\t}\n\treturn true;\n}\n\n/*\n * Returns the number of set bit in bitmap, upto (and excluding)\n * limit.  If limit is greater than the bitmap size, it is truncated\n * to that size.\n */\nCK_CC_INLINE static unsigned int\nck_bitmap_count(const ck_bitmap_t *bitmap, unsigned int limit)\n{\n\tunsigned int count, i, slop, words;\n\n\tif (limit > bitmap->n_bits)\n\t\tlimit = bitmap->n_bits;\n\n\twords = limit / CK_BITMAP_BLOCK;\n\tslop = limit % CK_BITMAP_BLOCK;\n\tfor (i = 0, count = 0; i < words; i++)\n\t\tcount += ck_cc_popcount(ck_pr_load_uint(&bitmap->map[i]));\n\n\tif (slop > 0) {\n\t\tunsigned int word;\n\n\t\tword = ck_pr_load_uint(&bitmap->map[i]);\n\t\tcount += ck_cc_popcount(word & ((1U << slop) - 1));\n\t}\n\treturn count;\n}\n\n/*\n * Returns the number of set bit in the intersection of two bitmaps,\n * upto (and excluding) limit.  If limit is greater than either bitmap\n * size, it is truncated to the smallest.\n */\nCK_CC_INLINE static unsigned int\nck_bitmap_count_intersect(const ck_bitmap_t *x, const ck_bitmap_t *y,\n    unsigned int limit)\n{\n\tunsigned int count, i, slop, words;\n\n\tif (limit > x->n_bits)\n\t\tlimit = x->n_bits;\n\n\tif (limit > y->n_bits)\n\t\tlimit = y->n_bits;\n\n\twords = limit / CK_BITMAP_BLOCK;\n\tslop = limit % CK_BITMAP_BLOCK;\n\tfor (i = 0, count = 0; i < words; i++) {\n\t\tunsigned int xi, yi;\n\n\t\txi = ck_pr_load_uint(&x->map[i]);\n\t\tyi = ck_pr_load_uint(&y->map[i]);\n\t\tcount += ck_cc_popcount(xi & yi);\n\t}\n\n\tif (slop > 0) {\n\t\tunsigned int word, xi, yi;\n\n\t\txi = ck_pr_load_uint(&x->map[i]);\n\t\tyi = ck_pr_load_uint(&y->map[i]);\n\t\tword = xi & yi;\n\t\tcount += ck_cc_popcount(word & ((1U << slop) - 1));\n\t}\n\treturn count;\n}\n\n/*\n * Initializes a ck_bitmap pointing to a region of memory with\n * ck_bitmap_size(n_bits) bytes. Third argument determines whether\n * default bit value is 1 (true) or 0 (false).\n */\nCK_CC_INLINE static void\nck_bitmap_init(struct ck_bitmap *bitmap,\n\t       unsigned int n_bits,\n\t       bool set)\n{\n\tunsigned int base = ck_bitmap_base(n_bits);\n\n\tbitmap->n_bits = n_bits;\n\tmemset(bitmap->map, -(int)set, base);\n\n\tif (set == true) {\n\t\tunsigned int b = n_bits % CK_BITMAP_BLOCK;\n\n\t\tif (b == 0)\n\t\t\treturn;\n\n\t\t*CK_BITMAP_PTR(bitmap->map, n_bits - 1) &= (1U << b) - 1U;\n\t}\n\n\treturn;\n}\n\n/*\n * Initialize iterator for use with provided bitmap.\n */\nCK_CC_INLINE static void\nck_bitmap_iterator_init(struct ck_bitmap_iterator *i,\n    const struct ck_bitmap *bitmap)\n{\n\n\ti->n_block = 0;\n\ti->n_limit = CK_BITMAP_BLOCKS(bitmap->n_bits);\n\tif (i->n_limit > 0) {\n\t\ti->cache = ck_pr_load_uint(&bitmap->map[0]);\n\t} else {\n\t\ti->cache = 0;\n\t}\n\treturn;\n}\n\n/*\n * Iterate to next bit.\n */\nCK_CC_INLINE static bool\nck_bitmap_next(const struct ck_bitmap *bitmap,\n\t       struct ck_bitmap_iterator *i,\n\t       unsigned int *bit)\n{\n\tunsigned int cache = i->cache;\n\tunsigned int n_block = i->n_block;\n\tunsigned int n_limit = i->n_limit;\n\n\tif (cache == 0) {\n\t\tif (n_block >= n_limit)\n\t\t\treturn false;\n\n\t\tfor (n_block++; n_block < n_limit; n_block++) {\n\t\t\tcache = ck_pr_load_uint(&bitmap->map[n_block]);\n\t\t\tif (cache != 0)\n\t\t\t\tgoto non_zero;\n\t\t}\n\n\t\ti->cache = 0;\n\t\ti->n_block = n_block;\n\t\treturn false;\n\t}\n\nnon_zero:\n\t*bit = CK_BITMAP_BLOCK * n_block + ck_cc_ctz(cache);\n\ti->cache = cache & (cache - 1);\n\ti->n_block = n_block;\n\treturn true;\n}\n\n#endif /* CK_BITMAP_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_brlock.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_BRLOCK_H\n#define CK_BRLOCK_H\n\n/*\n * Big reader spinlocks provide cache-local contention-free read\n * lock acquisition in the absence of writers. This comes at the\n * cost of O(n) write lock acquisition. They were first implemented\n * in the Linux kernel by Ingo Molnar and David S. Miller around the\n * year 2000.\n *\n * This implementation is thread-agnostic which comes at the cost\n * of larger reader objects due to necessary linkage overhead. In\n * order to cut down on TLB pressure, it is recommended to allocate\n * these objects on the same page.\n */\n\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\nstruct ck_brlock_reader {\n\tunsigned int n_readers;\n\tstruct ck_brlock_reader *previous;\n\tstruct ck_brlock_reader *next;\n};\ntypedef struct ck_brlock_reader ck_brlock_reader_t;\n\n#define CK_BRLOCK_READER_INITIALIZER {0}\n\nstruct ck_brlock {\n\tstruct ck_brlock_reader *readers;\n\tunsigned int writer;\n};\ntypedef struct ck_brlock ck_brlock_t;\n\n#define CK_BRLOCK_INITIALIZER {NULL, false}\n\nCK_CC_INLINE static void\nck_brlock_init(struct ck_brlock *br)\n{\n\n\tbr->readers = NULL;\n\tbr->writer = false;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_brlock_write_lock(struct ck_brlock *br)\n{\n\tstruct ck_brlock_reader *cursor;\n\n\t/*\n\t * As the frequency of write acquisitions should be low,\n\t * there is no point to more advanced contention avoidance.\n\t */\n\twhile (ck_pr_fas_uint(&br->writer, true) == true)\n\t\tck_pr_stall();\n\n\tck_pr_fence_atomic_load();\n\n\t/* The reader list is protected under the writer br. */\n\tfor (cursor = br->readers; cursor != NULL; cursor = cursor->next) {\n\t\twhile (ck_pr_load_uint(&cursor->n_readers) != 0)\n\t\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_brlock_write_unlock(struct ck_brlock *br)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&br->writer, false);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_brlock_write_trylock(struct ck_brlock *br, unsigned int factor)\n{\n\tstruct ck_brlock_reader *cursor;\n\tunsigned int steps = 0;\n\n\twhile (ck_pr_fas_uint(&br->writer, true) == true) {\n\t\tif (++steps >= factor)\n\t\t\treturn false;\n\n\t\tck_pr_stall();\n\t}\n\n\t/*\n\t * We do not require a strict fence here as atomic RMW operations\n\t * are serializing.\n\t */\n\tck_pr_fence_atomic_load();\n\n\tfor (cursor = br->readers; cursor != NULL; cursor = cursor->next) {\n\t\twhile (ck_pr_load_uint(&cursor->n_readers) != 0) {\n\t\t\tif (++steps >= factor) {\n\t\t\t\tck_brlock_write_unlock(br);\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tck_pr_stall();\n\t\t}\n\t}\n\n\tck_pr_fence_lock();\n\treturn true;\n}\n\nCK_CC_INLINE static void\nck_brlock_read_register(struct ck_brlock *br, struct ck_brlock_reader *reader)\n{\n\n\treader->n_readers = 0;\n\treader->previous = NULL;\n\n\t/* Implicit compiler barrier. */\n\tck_brlock_write_lock(br);\n\n\treader->next = ck_pr_load_ptr(&br->readers);\n\tif (reader->next != NULL)\n\t\treader->next->previous = reader;\n\tck_pr_store_ptr(&br->readers, reader);\n\n\tck_brlock_write_unlock(br);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_brlock_read_unregister(struct ck_brlock *br, struct ck_brlock_reader *reader)\n{\n\n\tck_brlock_write_lock(br);\n\n\tif (reader->next != NULL)\n\t\treader->next->previous = reader->previous;\n\n\tif (reader->previous != NULL)\n\t\treader->previous->next = reader->next;\n\telse\n\t\tbr->readers = reader->next;\n\n\tck_brlock_write_unlock(br);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_brlock_read_lock(struct ck_brlock *br, struct ck_brlock_reader *reader)\n{\n\n\tif (reader->n_readers >= 1) {\n\t\tck_pr_store_uint(&reader->n_readers, reader->n_readers + 1);\n\t\treturn;\n\t}\n\n\tfor (;;) {\n\t\twhile (ck_pr_load_uint(&br->writer) == true)\n\t\t\tck_pr_stall();\n\n#if defined(__x86__) || defined(__x86_64__)\n\t\tck_pr_fas_uint(&reader->n_readers, 1);\n\n\t\t/*\n\t\t * Serialize reader counter update with respect to load of\n\t\t * writer.\n\t\t */\n\t\tck_pr_fence_atomic_load();\n#else\n\t\tck_pr_store_uint(&reader->n_readers, 1);\n\n\t\t/*\n\t\t * Serialize reader counter update with respect to load of\n\t\t * writer.\n\t\t */\n\t\tck_pr_fence_store_load();\n#endif\n\n\t\tif (ck_pr_load_uint(&br->writer) == false)\n\t\t\tbreak;\n\n\t\tck_pr_store_uint(&reader->n_readers, 0);\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_brlock_read_trylock(struct ck_brlock *br,\n\t\t       struct ck_brlock_reader *reader,\n\t\t       unsigned int factor)\n{\n\tunsigned int steps = 0;\n\n\tif (reader->n_readers >= 1) {\n\t\tck_pr_store_uint(&reader->n_readers, reader->n_readers + 1);\n\t\treturn true;\n\t}\n\n\tfor (;;) {\n\t\twhile (ck_pr_load_uint(&br->writer) == true) {\n\t\t\tif (++steps >= factor)\n\t\t\t\treturn false;\n\n\t\t\tck_pr_stall();\n\t\t}\n\n#if defined(__x86__) || defined(__x86_64__)\n\t\tck_pr_fas_uint(&reader->n_readers, 1);\n\n\t\t/*\n\t\t * Serialize reader counter update with respect to load of\n\t\t * writer.\n\t\t */\n\t\tck_pr_fence_atomic_load();\n#else\n\t\tck_pr_store_uint(&reader->n_readers, 1);\n\n\t\t/*\n\t\t * Serialize reader counter update with respect to load of\n\t\t * writer.\n\t\t */\n\t\tck_pr_fence_store_load();\n#endif\n\n\t\tif (ck_pr_load_uint(&br->writer) == false)\n\t\t\tbreak;\n\n\t\tck_pr_store_uint(&reader->n_readers, 0);\n\n\t\tif (++steps >= factor)\n\t\t\treturn false;\n\t}\n\n\tck_pr_fence_lock();\n\treturn true;\n}\n\nCK_CC_INLINE static void\nck_brlock_read_unlock(struct ck_brlock_reader *reader)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&reader->n_readers, reader->n_readers - 1);\n\treturn;\n}\n\n#endif /* CK_BRLOCK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_bytelock.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_BYTELOCK_H\n#define CK_BYTELOCK_H\n\n/*\n * The implementations here are derived from the work described in:\n *   Dice, D. and Shavit, N. 2010. TLRW: return of the read-write lock.\n *   In Proceedings of the 22nd ACM Symposium on Parallelism in Algorithms\n *   and Architectures (Thira, Santorini, Greece, June 13 - 15, 2010).\n *   SPAA '10. ACM, New York, NY, 284-293.\n */\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n#include <ck_limits.h>\n\nstruct ck_bytelock {\n\tunsigned int owner;\n\tunsigned int n_readers;\n\tuint8_t readers[CK_MD_CACHELINE - sizeof(unsigned int) * 2] CK_CC_ALIGN(8);\n};\ntypedef struct ck_bytelock ck_bytelock_t;\n\n#define CK_BYTELOCK_INITIALIZER { 0, 0, {0} }\n#define CK_BYTELOCK_UNSLOTTED   UINT_MAX\n\nCK_CC_INLINE static void\nck_bytelock_init(struct ck_bytelock *bytelock)\n{\n\tunsigned int i;\n\n\tbytelock->owner = 0;\n\tbytelock->n_readers = 0;\n\tfor (i = 0; i < sizeof bytelock->readers; i++)\n\t\tbytelock->readers[i] = false;\n\n\tck_pr_barrier();\n\treturn;\n}\n\n#ifdef CK_F_PR_LOAD_64\n#define CK_BYTELOCK_LENGTH sizeof(uint64_t)\n#define CK_BYTELOCK_LOAD ck_pr_load_64\n#define CK_BYTELOCK_TYPE uint64_t\n#elif defined(CK_F_PR_LOAD_32)\n#define CK_BYTELOCK_LENGTH sizeof(uint32_t)\n#define CK_BYTELOCK_LOAD ck_pr_load_32\n#define CK_BYTELOCK_TYPE uint32_t\n#else\n#error Unsupported platform.\n#endif\n\nCK_CC_INLINE static void\nck_bytelock_write_lock(struct ck_bytelock *bytelock, unsigned int slot)\n{\n\tCK_BYTELOCK_TYPE *readers = (void *)bytelock->readers;\n\tunsigned int i;\n\n\t/* Announce upcoming writer acquisition. */\n\twhile (ck_pr_cas_uint(&bytelock->owner, 0, slot) == false)\n\t\tck_pr_stall();\n\n\t/* If we are slotted, we might be upgrading from a read lock. */\n\tif (slot <= sizeof bytelock->readers)\n\t\tck_pr_store_8(&bytelock->readers[slot - 1], false);\n\n\t/*\n\t * Wait for slotted readers to drain out. This also provides the\n\t * lock acquire semantics.\n\t */\n\tck_pr_fence_atomic_load();\n\n\tfor (i = 0; i < sizeof(bytelock->readers) / CK_BYTELOCK_LENGTH; i++) {\n\t\twhile (CK_BYTELOCK_LOAD(&readers[i]) != false)\n\t\t\tck_pr_stall();\n\t}\n\n\t/* Wait for unslotted readers to drain out. */\n\twhile (ck_pr_load_uint(&bytelock->n_readers) != 0)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\n#undef CK_BYTELOCK_LENGTH\n#undef CK_BYTELOCK_LOAD\n#undef CK_BYTELOCK_TYPE\n\nCK_CC_INLINE static void\nck_bytelock_write_unlock(struct ck_bytelock *bytelock)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&bytelock->owner, 0);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_bytelock_read_lock(struct ck_bytelock *bytelock, unsigned int slot)\n{\n\n\tif (ck_pr_load_uint(&bytelock->owner) == slot) {\n\t\tck_pr_store_8(&bytelock->readers[slot - 1], true);\n\t\tck_pr_fence_strict_store();\n\t\tck_pr_store_uint(&bytelock->owner, 0);\n\t\treturn;\n\t}\n\n\t/* Unslotted threads will have to use the readers counter. */\n\tif (slot > sizeof bytelock->readers) {\n\t\tfor (;;) {\n\t\t\tck_pr_inc_uint(&bytelock->n_readers);\n\t\t\tck_pr_fence_atomic_load();\n\t\t\tif (ck_pr_load_uint(&bytelock->owner) == 0)\n\t\t\t\tbreak;\n\t\t\tck_pr_dec_uint(&bytelock->n_readers);\n\n\t\t\twhile (ck_pr_load_uint(&bytelock->owner) != 0)\n\t\t\t\tck_pr_stall();\n\t\t}\n\n\t\tck_pr_fence_lock();\n\t\treturn;\n\t}\n\n\tslot -= 1;\n\tfor (;;) {\n#ifdef CK_F_PR_FAA_8\n\t\tck_pr_fas_8(&bytelock->readers[slot], true);\n\t\tck_pr_fence_atomic_load();\n#else\n\t\tck_pr_store_8(&bytelock->readers[slot], true);\n\t\tck_pr_fence_store_load();\n#endif\n\n\t\t/*\n\t\t * If there is no owner at this point, our slot has\n\t\t * already been published and it is guaranteed no\n\t\t * write acquisition will succeed until we drain out.\n\t\t */\n\t\tif (ck_pr_load_uint(&bytelock->owner) == 0)\n\t\t\tbreak;\n\n\t\tck_pr_store_8(&bytelock->readers[slot], false);\n\t\twhile (ck_pr_load_uint(&bytelock->owner) != 0)\n\t\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_bytelock_read_unlock(struct ck_bytelock *bytelock, unsigned int slot)\n{\n\n\tck_pr_fence_unlock();\n\n\tif (slot > sizeof bytelock->readers)\n\t\tck_pr_dec_uint(&bytelock->n_readers);\n\telse\n\t\tck_pr_store_8(&bytelock->readers[slot - 1], false);\n\n\treturn;\n}\n\n#endif /* CK_BYTELOCK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_cc.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2014 Paul Khuong.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_CC_H\n#define CK_CC_H\n\n#if defined(__GNUC__) || defined(__SUNPRO_C)\n#include \"gcc/ck_cc.h\"\n#endif\n\n#ifndef CK_CC_RESTRICT\n#define CK_CC_RESTRICT\n#endif\n\n#ifndef CK_CC_INLINE\n#define CK_CC_INLINE inline\n#endif\n\n#ifndef CK_CC_FORCE_INLINE\n#define CK_CC_FORCE_INLINE inline\n#endif\n\n#define CK_CC_DECONST_PTR(X) ((void *)(uintptr_t)(X))\n\n/*\n * Container function.\n * This relies on (compiler) implementation-defined behavior.\n */\n#define CK_CC_CONTAINER(F, T, M, N)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T *\t\t\t\t\t\t\t\\\n\tN(F *p)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tF *n = p;\t\t\t\t\t\t\t\\\n\t\treturn (T *)(void *)(((char *)n) - ((size_t)&((T *)0)->M));\t\\\n\t}\n\n#define CK_CC_PAD(x) union { char pad[x]; }\n\n#ifndef CK_CC_ALIASED\n#define CK_CC_ALIASED\n#endif\n\n#ifndef CK_CC_UNUSED\n#define CK_CC_UNUSED\n#endif\n\n#ifndef CK_CC_USED\n#define CK_CC_USED\n#endif\n\n#ifndef CK_CC_IMM\n#define CK_CC_IMM\n#endif\n\n#ifndef CK_CC_PACKED\n#define CK_CC_PACKED\n#endif\n\n#ifndef CK_CC_WEAKREF\n#define CK_CC_WEAKREF\n#endif\n\n#ifndef CK_CC_ALIGN\n#define CK_CC_ALIGN(X)\n#endif\n\n#ifndef CK_CC_CACHELINE\n#define CK_CC_CACHELINE\n#endif\n\n#ifndef CK_CC_LIKELY\n#define CK_CC_LIKELY(x) x\n#endif\n\n#ifndef CK_CC_UNLIKELY\n#define CK_CC_UNLIKELY(x) x\n#endif\n\n#ifndef CK_CC_TYPEOF\n#define CK_CC_TYPEOF(X, DEFAULT) (DEFAULT)\n#endif\n\n#ifndef CK_F_CC_FFS\n#define CK_F_CC_FFS\nCK_CC_INLINE static int\nck_cc_ffs(unsigned int x)\n{\n\tunsigned int i;\n\n\tif (x == 0)\n\t\treturn 0;\n\n\tfor (i = 1; (x & 1) == 0; i++, x >>= 1);\n\n\treturn i;\n}\n#endif\n\n#ifndef CK_F_CC_CLZ\n#define CK_F_CC_CLZ\n#include <ck_limits.h>\n\nCK_CC_INLINE static int\nck_cc_clz(unsigned int x)\n{\n\tunsigned int count, i;\n\n\tfor (count = 0, i = sizeof(unsigned int) * CHAR_BIT; i > 0; count++) {\n\t\tunsigned int bit = 1U << --i;\n\n\t\tif (x & bit)\n\t\t\tbreak;\n\t}\n\n\treturn count;\n}\n#endif\n\n#ifndef CK_F_CC_CTZ\n#define CK_F_CC_CTZ\nCK_CC_INLINE static int\nck_cc_ctz(unsigned int x)\n{\n\tunsigned int i;\n\n\tif (x == 0)\n\t\treturn 0;\n\n\tfor (i = 0; (x & 1) == 0; i++, x >>= 1);\n\n\treturn i;\n}\n#endif\n\n#ifndef CK_F_CC_POPCOUNT\n#define CK_F_CC_POPCOUNT\nCK_CC_INLINE static int\nck_cc_popcount(unsigned int x)\n{\n\tunsigned int acc;\n\n\tfor (acc = 0; x != 0; x >>= 1)\n\t\tacc += x & 1;\n\n\treturn acc;\n}\n#endif\n\n\n#ifdef __cplusplus\n#define CK_CPP_CAST(type, arg) static_cast<type>(arg)\n#else\n#define CK_CPP_CAST(type, arg) arg\n#endif\n\n#endif /* CK_CC_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_cohort.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copyright 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_COHORT_H\n#define CK_COHORT_H\n\n/*\n * This is an implementation of lock cohorts as described in:\n *     Dice, D.; Marathe, V.; and Shavit, N. 2012.\n *     Lock Cohorting: A General Technique for Designing NUMA Locks\n */\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stddef.h>\n\nenum ck_cohort_state {\n\tCK_COHORT_STATE_GLOBAL = 0,\n\tCK_COHORT_STATE_LOCAL = 1\n};\n\n#define CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT 10\n\n#define CK_COHORT_NAME(N) ck_cohort_##N\n#define CK_COHORT_INSTANCE(N) struct CK_COHORT_NAME(N)\n#define CK_COHORT_INIT(N, C, GL, LL, P) ck_cohort_##N##_init(C, GL, LL, P)\n#define CK_COHORT_LOCK(N, C, GC, LC) ck_cohort_##N##_lock(C, GC, LC)\n#define CK_COHORT_UNLOCK(N, C, GC, LC) ck_cohort_##N##_unlock(C, GC, LC)\n#define CK_COHORT_TRYLOCK(N, C, GLC, LLC, LUC) ck_cohort_##N##_trylock(C, GLC, LLC, LUC)\n#define CK_COHORT_LOCKED(N, C, GC, LC) ck_cohort_##N##_locked(C, GC, LC)\n\n#define CK_COHORT_PROTOTYPE(N, GL, GU, GI, LL, LU, LI)\t\t\t\t\\\n\tCK_COHORT_INSTANCE(N) {\t\t\t\t\t\t\t\\\n\t\tvoid *global_lock;\t\t\t\t\t\t\\\n\t\tvoid *local_lock;\t\t\t\t\t\t\\\n\t\tenum ck_cohort_state release_state;\t\t\t\t\\\n\t\tunsigned int waiting_threads;\t\t\t\t\t\\\n\t\tunsigned int acquire_count;\t\t\t\t\t\\\n\t\tunsigned int local_pass_limit;\t\t\t\t\t\\\n\t};\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\\\n\tck_cohort_##N##_init(struct ck_cohort_##N *cohort,\t\t\t\\\n\t    void *global_lock, void *local_lock, unsigned int pass_limit)\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tcohort->global_lock = global_lock;\t\t\t\t\\\n\t\tcohort->local_lock = local_lock;\t\t\t\t\\\n\t\tcohort->release_state = CK_COHORT_STATE_GLOBAL;\t\t\t\\\n\t\tcohort->waiting_threads = 0;\t\t\t\t\t\\\n\t\tcohort->acquire_count = 0;\t\t\t\t\t\\\n\t\tcohort->local_pass_limit = pass_limit;\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\\\n\tck_cohort_##N##_lock(CK_COHORT_INSTANCE(N) *cohort,\t\t\t\\\n\t    void *global_context, void *local_context)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_inc_uint(&cohort->waiting_threads);\t\t\t\\\n\t\tLL(cohort->local_lock, local_context);\t\t\t\t\\\n\t\tck_pr_dec_uint(&cohort->waiting_threads);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (cohort->release_state == CK_COHORT_STATE_GLOBAL) {\t\t\\\n\t\t\tGL(cohort->global_lock, global_context);\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\t++cohort->acquire_count;\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\\\n\tck_cohort_##N##_unlock(CK_COHORT_INSTANCE(N) *cohort,\t\t\t\\\n\t    void *global_context, void *local_context)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (ck_pr_load_uint(&cohort->waiting_threads) > 0\t\t\\\n\t\t    && cohort->acquire_count < cohort->local_pass_limit) {\t\\\n\t\t\tcohort->release_state = CK_COHORT_STATE_LOCAL;\t\t\\\n\t\t} else {\t\t\t\t\t\t\t\\\n\t\t\tGU(cohort->global_lock, global_context);\t\t\\\n\t\t\tcohort->release_state = CK_COHORT_STATE_GLOBAL;\t\t\\\n\t\t\tcohort->acquire_count = 0;\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_fence_release();\t\t\t\t\t\t\\\n\t\tLU(cohort->local_lock, local_context);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_cohort_##N##_locked(CK_COHORT_INSTANCE(N) *cohort,\t\t\t\\\n\t    void *global_context, void *local_context)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\treturn GI(cohort->local_lock, local_context) ||\t\t\t\\\n\t\t    LI(cohort->global_lock, global_context);\t\t\t\\\n\t}\n\n#define CK_COHORT_TRYLOCK_PROTOTYPE(N, GL, GU, GI, GTL, LL, LU, LI, LTL)\t\\\n\tCK_COHORT_PROTOTYPE(N, GL, GU, GI, LL, LU, LI)\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_cohort_##N##_trylock(CK_COHORT_INSTANCE(N) *cohort,\t\t\t\\\n\t    void *global_context, void *local_context,\t\t\t\t\\\n\t    void *local_unlock_context)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tbool trylock_result;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_inc_uint(&cohort->waiting_threads);\t\t\t\\\n\t\ttrylock_result = LTL(cohort->local_lock, local_context);\t\\\n\t\tck_pr_dec_uint(&cohort->waiting_threads);\t\t\t\\\n\t\tif (trylock_result == false) {\t\t\t\t\t\\\n\t\t\treturn false;\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (cohort->release_state == CK_COHORT_STATE_GLOBAL &&\t\t\\\n\t\t    GTL(cohort->global_lock, global_context) == false) {\t\\\n\t\t    \tLU(cohort->local_lock, local_unlock_context);\t\t\\\n\t\t\treturn false;\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\\\n\t\t++cohort->acquire_count;\t\t\t\t\t\\\n\t\treturn true;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_COHORT_INITIALIZER {\t\t\t\t\t\t\t\\\n\t.global_lock = NULL,\t\t\t\t\t\t\t\\\n\t.local_lock = NULL,\t\t\t\t\t\t\t\\\n\t.release_state = CK_COHORT_STATE_GLOBAL,\t\t\t\t\\\n\t.waiting_threads = 0,\t\t\t\t\t\t\t\\\n\t.acquire_count = 0,\t\t\t\t\t\t\t\\\n\t.local_pass_limit = CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT\t\t\t\\\n}\n\n#endif /* CK_COHORT_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_elide.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_ELIDE_H\n#define CK_ELIDE_H\n\n/*\n * As RTM is currently only supported on TSO x86 architectures,\n * fences have been omitted. They will be necessary for other\n * non-TSO architectures with TM support.\n */\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_string.h>\n\n/*\n * skip_-prefixed counters represent the number of consecutive\n * elisions to forfeit. retry_-prefixed counters represent the\n * number of elision retries to attempt before forfeit.\n *\n *     _busy: Lock was busy\n *    _other: Unknown explicit abort\n * _conflict: Data conflict in elision section\n */\nstruct ck_elide_config {\n\tunsigned short skip_busy;\n\tshort retry_busy;\n\tunsigned short skip_other;\n\tshort retry_other;\n\tunsigned short skip_conflict;\n\tshort retry_conflict;\n};\n\n#define CK_ELIDE_CONFIG_DEFAULT_INITIALIZER {\t\\\n\t.skip_busy = 5,\t\t\t\t\\\n\t.retry_busy = 256,\t\t\t\\\n\t.skip_other = 3,\t\t\t\\\n\t.retry_other = 3,\t\t\t\\\n\t.skip_conflict = 2,\t\t\t\\\n\t.retry_conflict = 5\t\t\t\\\n}\n\nstruct ck_elide_stat {\n\tunsigned int n_fallback;\n\tunsigned int n_elide;\n\tunsigned short skip;\n};\ntypedef struct ck_elide_stat ck_elide_stat_t;\n\n#define CK_ELIDE_STAT_INITIALIZER { 0, 0, 0 }\n\nCK_CC_INLINE static void\nck_elide_stat_init(ck_elide_stat_t *st)\n{\n\n\tmemset(st, 0, sizeof(*st));\n\treturn;\n}\n\n#ifdef CK_F_PR_RTM\nenum _ck_elide_hint {\n\tCK_ELIDE_HINT_RETRY = 0,\n\tCK_ELIDE_HINT_SPIN,\n\tCK_ELIDE_HINT_STOP\n};\n\n#define CK_ELIDE_LOCK_BUSY 0xFF\n\nstatic enum _ck_elide_hint\n_ck_elide_fallback(int *retry,\n    struct ck_elide_stat *st,\n    struct ck_elide_config *c,\n    unsigned int status)\n{\n\n\tst->n_fallback++;\n\tif (*retry > 0)\n\t\treturn CK_ELIDE_HINT_RETRY;\n\n\tif (st->skip != 0)\n\t\treturn CK_ELIDE_HINT_STOP;\n\n\tif (status & CK_PR_RTM_EXPLICIT) {\n\t\tif (CK_PR_RTM_CODE(status) == CK_ELIDE_LOCK_BUSY) {\n\t\t\tst->skip = c->skip_busy;\n\t\t\t*retry = c->retry_busy;\n\t\t\treturn CK_ELIDE_HINT_SPIN;\n\t\t}\n\n\t\tst->skip = c->skip_other;\n\t\treturn CK_ELIDE_HINT_STOP;\n\t}\n\n\tif ((status & CK_PR_RTM_RETRY) &&\n\t    (status & CK_PR_RTM_CONFLICT)) {\n\t\tst->skip = c->skip_conflict;\n\t\t*retry = c->retry_conflict;\n\t\treturn CK_ELIDE_HINT_RETRY;\n\t}\n\n\t/*\n\t * Capacity, debug and nesting abortions are likely to be\n\t * invariant conditions for the acquisition, execute regular\n\t * path instead. If retry bit is not set, then take the hint.\n\t */\n\tst->skip = USHRT_MAX;\n\treturn CK_ELIDE_HINT_STOP;\n}\n\n/*\n * Defines an elision implementation according to the following variables:\n *     N - Namespace of elision implementation.\n *     T - Typename of mutex.\n *   L_P - Lock predicate, returns false if resource is available.\n *     L - Function to call if resource is unavailable of transaction aborts.\n *   U_P - Unlock predicate, returns false if elision failed.\n *     U - Function to call if transaction failed.\n */\n#define CK_ELIDE_PROTOTYPE(N, T, L_P, L, U_P, U)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_elide_##N##_lock_adaptive(T *lock,\t\t\t\t\t\t\\\n\t    struct ck_elide_stat *st,\t\t\t\t\t\t\t\\\n\t    struct ck_elide_config *c)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tenum _ck_elide_hint hint;\t\t\t\t\t\t\\\n\t\tint retry;\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (CK_CC_UNLIKELY(st->skip != 0)) {\t\t\t\t\t\\\n\t\t\tst->skip--;\t\t\t\t\t\t\t\\\n\t\t\tgoto acquire;\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tretry = c->retry_conflict;\t\t\t\t\t\t\\\n\t\tdo {\t\t\t\t\t\t\t\t\t\\\n\t\t\tunsigned int status = ck_pr_rtm_begin();\t\t\t\\\n\t\t\tif (status == CK_PR_RTM_STARTED) {\t\t\t\t\\\n\t\t\t\tif (L_P(lock) == true)\t\t\t\t\t\\\n\t\t\t\t\tck_pr_rtm_abort(CK_ELIDE_LOCK_BUSY);\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn;\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\thint = _ck_elide_fallback(&retry, st, c, status);\t\t\\\n\t\t\tif (hint == CK_ELIDE_HINT_RETRY)\t\t\t\t\\\n\t\t\t\tcontinue;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (hint == CK_ELIDE_HINT_SPIN) {\t\t\t\t\\\n\t\t\t\twhile (--retry != 0) {\t\t\t\t\t\\\n\t\t\t\t\tif (L_P(lock) == false)\t\t\t\t\\\n\t\t\t\t\t\tbreak;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t\t\t}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tcontinue;\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (hint == CK_ELIDE_HINT_STOP)\t\t\t\t\t\\\n\t\t\t\tbreak;\t\t\t\t\t\t\t\\\n\t\t} while (CK_CC_LIKELY(--retry > 0));\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\tacquire:\t\t\t\t\t\t\t\t\t\\\n\t\tL(lock);\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_elide_##N##_unlock_adaptive(struct ck_elide_stat *st, T *lock)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (U_P(lock) == false) {\t\t\t\t\t\t\\\n\t\t\tck_pr_rtm_end();\t\t\t\t\t\t\\\n\t\t\tst->skip = 0;\t\t\t\t\t\t\t\\\n\t\t\tst->n_elide++;\t\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\t\t\\\n\t\t\tU(lock);\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_elide_##N##_lock(T *lock)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (ck_pr_rtm_begin() != CK_PR_RTM_STARTED) {\t\t\t\t\\\n\t\t\tL(lock);\t\t\t\t\t\t\t\\\n\t\t\treturn;\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (L_P(lock) == true)\t\t\t\t\t\t\t\\\n\t\t\tck_pr_rtm_abort(CK_ELIDE_LOCK_BUSY);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_elide_##N##_unlock(T *lock)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (U_P(lock) == false) {\t\t\t\t\t\t\\\n\t\t\tck_pr_rtm_end();\t\t\t\t\t\t\\\n\t\t} else {\t\t\t\t\t\t\t\t\\\n\t\t\tU(lock);\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_ELIDE_TRYLOCK_PROTOTYPE(N, T, TL_P, TL)\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_elide_##N##_trylock(T *lock)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tif (ck_pr_rtm_begin() != CK_PR_RTM_STARTED)\t\t\\\n\t\t\treturn false;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tif (TL_P(lock) == true)\t\t\t\t\t\\\n\t\t\tck_pr_rtm_abort(CK_ELIDE_LOCK_BUSY);\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn true;\t\t\t\t\t\t\\\n\t}\n#else\n/*\n * If RTM is not enabled on the target platform (CK_F_PR_RTM) then these\n * elision wrappers directly calls into the user-specified lock operations.\n * Unfortunately, the storage cost of both ck_elide_config and ck_elide_stat\n * are paid (typically a storage cost that is a function of lock objects and\n * thread count).\n */\n#define CK_ELIDE_PROTOTYPE(N, T, L_P, L, U_P, U)\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_elide_##N##_lock_adaptive(T *lock,\t\t\t\t\\\n\t    struct ck_elide_stat *st,\t\t\t\t\t\\\n\t    struct ck_elide_config *c)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t(void)st;\t\t\t\t\t\t\\\n\t\t(void)c;\t\t\t\t\t\t\\\n\t\tL(lock);\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_elide_##N##_unlock_adaptive(struct ck_elide_stat *st,\t\\\n\t    T *lock)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t(void)st;\t\t\t\t\t\t\\\n\t\tU(lock);\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_elide_##N##_lock(T *lock)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tL(lock);\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_elide_##N##_unlock(T *lock)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tU(lock);\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_ELIDE_TRYLOCK_PROTOTYPE(N, T, TL_P, TL)\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_elide_##N##_trylock(T *lock)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn TL_P(lock);\t\t\t\t\t\\\n\t}\n#endif /* !CK_F_PR_RTM */\n\n/*\n * Best-effort elision lock operations. First argument is name (N)\n * associated with implementation and the second is a pointer to\n * the type specified above (T).\n *\n * Unlike the adaptive variant, this interface does not have any retry\n * semantics. In environments where jitter is low, this may yield a tighter\n * fast path.\n */\n#define CK_ELIDE_LOCK(NAME, LOCK)\tck_elide_##NAME##_lock(LOCK)\n#define CK_ELIDE_UNLOCK(NAME, LOCK)\tck_elide_##NAME##_unlock(LOCK)\n#define CK_ELIDE_TRYLOCK(NAME, LOCK)\tck_elide_##NAME##_trylock(LOCK)\n\n/*\n * Adaptive elision lock operations. In addition to name and pointer\n * to the lock, you must pass in a pointer to an initialized\n * ck_elide_config structure along with a per-thread stat structure.\n */\n#define CK_ELIDE_LOCK_ADAPTIVE(NAME, STAT, CONFIG, LOCK) \\\n\tck_elide_##NAME##_lock_adaptive(LOCK, STAT, CONFIG)\n\n#define CK_ELIDE_UNLOCK_ADAPTIVE(NAME, STAT, LOCK) \\\n\tck_elide_##NAME##_unlock_adaptive(STAT, LOCK)\n\n#endif /* CK_ELIDE_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_epoch.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_EPOCH_H\n#define CK_EPOCH_H\n\n/*\n * The implementation here is inspired from the work described in:\n *   Fraser, K. 2004. Practical Lock-Freedom. PhD Thesis, University\n *   of Cambridge Computing Laboratory.\n */\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stack.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_EPOCH_LENGTH\n#define CK_EPOCH_LENGTH 4\n#endif\n\n/*\n * This is used for sense detection with-respect to concurrent\n * epoch sections.\n */\n#define CK_EPOCH_SENSE\t\t(2)\n\nstruct ck_epoch_entry;\ntypedef struct ck_epoch_entry ck_epoch_entry_t;\ntypedef void ck_epoch_cb_t(ck_epoch_entry_t *);\n\n/*\n * This should be embedded into objects you wish to be the target of\n * ck_epoch_cb_t functions (with ck_epoch_call).\n */\nstruct ck_epoch_entry {\n\tck_epoch_cb_t *function;\n\tck_stack_entry_t stack_entry;\n};\n\n/*\n * A section object may be passed to every begin-end pair to allow for\n * forward progress guarantees with-in prolonged active sections.\n */\nstruct ck_epoch_section {\n\tunsigned int bucket;\n};\ntypedef struct ck_epoch_section ck_epoch_section_t;\n\n/*\n * Return pointer to ck_epoch_entry container object.\n */\n#define CK_EPOCH_CONTAINER(T, M, N) \\\n\tCK_CC_CONTAINER(struct ck_epoch_entry, T, M, N)\n\nstruct ck_epoch_ref {\n\tunsigned int epoch;\n\tunsigned int count;\n};\n\nstruct ck_epoch_record {\n\tck_stack_entry_t record_next;\n\tstruct ck_epoch *global;\n\tunsigned int state;\n\tunsigned int epoch;\n\tunsigned int active;\n\tstruct {\n\t\tstruct ck_epoch_ref bucket[CK_EPOCH_SENSE];\n\t} local CK_CC_CACHELINE;\n\tunsigned int n_pending;\n\tunsigned int n_peak;\n\tunsigned int n_dispatch;\n\tvoid *ct;\n\tck_stack_t pending[CK_EPOCH_LENGTH];\n} CK_CC_CACHELINE;\ntypedef struct ck_epoch_record ck_epoch_record_t;\n\nstruct ck_epoch {\n\tunsigned int epoch;\n\tunsigned int n_free;\n\tck_stack_t records;\n};\ntypedef struct ck_epoch ck_epoch_t;\n\n/*\n * Internal functions.\n */\nvoid _ck_epoch_addref(ck_epoch_record_t *, ck_epoch_section_t *);\nbool _ck_epoch_delref(ck_epoch_record_t *, ck_epoch_section_t *);\n\nCK_CC_FORCE_INLINE static void *\nck_epoch_record_ct(const ck_epoch_record_t *record)\n{\n\n\treturn ck_pr_load_ptr(&record->ct);\n}\n\n/*\n * Marks the beginning of an epoch-protected section.\n */\nCK_CC_FORCE_INLINE static void\nck_epoch_begin(ck_epoch_record_t *record, ck_epoch_section_t *section)\n{\n\tstruct ck_epoch *epoch = record->global;\n\n\t/*\n\t * Only observe new epoch if thread is not recursing into a read\n\t * section.\n\t */\n\tif (record->active == 0) {\n\t\tunsigned int g_epoch;\n\n\t\t/*\n\t\t * It is possible for loads to be re-ordered before the store\n\t\t * is committed into the caller's epoch and active fields.\n\t\t * For this reason, store to load serialization is necessary.\n\t\t */\n#if defined(CK_MD_TSO)\n\t\tck_pr_fas_uint(&record->active, 1);\n\t\tck_pr_fence_atomic_load();\n#else\n\t\tck_pr_store_uint(&record->active, 1);\n\t\tck_pr_fence_memory();\n#endif\n\n\t\t/*\n\t\t * This load is allowed to be re-ordered prior to setting\n\t\t * active flag due to monotonic nature of the global epoch.\n\t\t * However, stale values lead to measurable performance\n\t\t * degradation in some torture tests so we disallow early load\n\t\t * of global epoch.\n\t\t */\n\t\tg_epoch = ck_pr_load_uint(&epoch->epoch);\n\t\tck_pr_store_uint(&record->epoch, g_epoch);\n\t} else {\n\t\tck_pr_store_uint(&record->active, record->active + 1);\n\t}\n\n\tif (section != NULL)\n\t\t_ck_epoch_addref(record, section);\n\n\treturn;\n}\n\n/*\n * Marks the end of an epoch-protected section. Returns true if no more\n * sections exist for the caller.\n */\nCK_CC_FORCE_INLINE static bool\nck_epoch_end(ck_epoch_record_t *record, ck_epoch_section_t *section)\n{\n\n\tck_pr_fence_release();\n\tck_pr_store_uint(&record->active, record->active - 1);\n\n\tif (section != NULL)\n\t\treturn _ck_epoch_delref(record, section);\n\n\treturn record->active == 0;\n}\n\n/*\n * Defers the execution of the function pointed to by the \"cb\"\n * argument until an epoch counter loop. This allows for a\n * non-blocking deferral.\n *\n * We can get away without a fence here due to the monotonic nature\n * of the epoch counter. Worst case, this will result in some delays\n * before object destruction.\n */\nCK_CC_FORCE_INLINE static void\nck_epoch_call(ck_epoch_record_t *record,\n\t      ck_epoch_entry_t *entry,\n\t      ck_epoch_cb_t *function)\n{\n\tstruct ck_epoch *epoch = record->global;\n\tunsigned int e = ck_pr_load_uint(&epoch->epoch);\n\tunsigned int offset = e & (CK_EPOCH_LENGTH - 1);\n\n\trecord->n_pending++;\n\tentry->function = function;\n\tck_stack_push_spnc(&record->pending[offset], &entry->stack_entry);\n\treturn;\n}\n\n/*\n * Same as ck_epoch_call, but allows for records to be shared and is reentrant.\n */\nCK_CC_FORCE_INLINE static void\nck_epoch_call_strict(ck_epoch_record_t *record,\n\t      ck_epoch_entry_t *entry,\n\t      ck_epoch_cb_t *function)\n{\n\tstruct ck_epoch *epoch = record->global;\n\tunsigned int e = ck_pr_load_uint(&epoch->epoch);\n\tunsigned int offset = e & (CK_EPOCH_LENGTH - 1);\n\n\tck_pr_inc_uint(&record->n_pending);\n\tentry->function = function;\n\n\t/* Store fence is implied by push operation. */\n\tck_stack_push_upmc(&record->pending[offset], &entry->stack_entry);\n\treturn;\n}\n\n/*\n * This callback is used for synchronize_wait to allow for custom blocking\n * behavior.\n */\ntypedef void ck_epoch_wait_cb_t(ck_epoch_t *, ck_epoch_record_t *,\n    void *);\n\n/*\n * Return latest epoch value. This operation provides load ordering.\n */\nCK_CC_FORCE_INLINE static unsigned int\nck_epoch_value(const ck_epoch_t *ep)\n{\n\n\tck_pr_fence_load();\n\treturn ck_pr_load_uint(&ep->epoch);\n}\n\nvoid ck_epoch_init(ck_epoch_t *);\n\n/*\n * Attempts to recycle an unused epoch record. If one is successfully\n * allocated, the record context pointer is also updated.\n */\nck_epoch_record_t *ck_epoch_recycle(ck_epoch_t *, void *);\n\n/*\n * Registers an epoch record. An optional context pointer may be passed that\n * is retrievable with ck_epoch_record_ct.\n */\nvoid ck_epoch_register(ck_epoch_t *, ck_epoch_record_t *, void *);\n\n/*\n * Marks a record as available for re-use by a subsequent recycle operation.\n * Note that the record cannot be physically destroyed.\n */\nvoid ck_epoch_unregister(ck_epoch_record_t *);\n\nbool ck_epoch_poll(ck_epoch_record_t *);\nvoid ck_epoch_synchronize(ck_epoch_record_t *);\nvoid ck_epoch_synchronize_wait(ck_epoch_t *, ck_epoch_wait_cb_t *, void *);\nvoid ck_epoch_barrier(ck_epoch_record_t *);\nvoid ck_epoch_barrier_wait(ck_epoch_record_t *, ck_epoch_wait_cb_t *, void *);\n\n/*\n * Reclaim entries associated with a record. This is safe to call only on\n * the caller's record or records that are using call_strict.\n */\nvoid ck_epoch_reclaim(ck_epoch_record_t *);\n\n#endif /* CK_EPOCH_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_fifo.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_FIFO_H\n#define CK_FIFO_H\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n#include <ck_stddef.h>\n\n#ifndef CK_F_FIFO_SPSC\n#define CK_F_FIFO_SPSC\nstruct ck_fifo_spsc_entry {\n\tvoid *value;\n\tstruct ck_fifo_spsc_entry *next;\n};\ntypedef struct ck_fifo_spsc_entry ck_fifo_spsc_entry_t;\n\nstruct ck_fifo_spsc {\n\tck_spinlock_t m_head;\n\tstruct ck_fifo_spsc_entry *head;\n\tchar pad[CK_MD_CACHELINE - sizeof(struct ck_fifo_spsc_entry *) - sizeof(ck_spinlock_t)];\n\tck_spinlock_t m_tail;\n\tstruct ck_fifo_spsc_entry *tail;\n\tstruct ck_fifo_spsc_entry *head_snapshot;\n\tstruct ck_fifo_spsc_entry *garbage;\n};\ntypedef struct ck_fifo_spsc ck_fifo_spsc_t;\n\nCK_CC_INLINE static bool\nck_fifo_spsc_enqueue_trylock(struct ck_fifo_spsc *fifo)\n{\n\n\treturn ck_spinlock_trylock(&fifo->m_tail);\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_enqueue_lock(struct ck_fifo_spsc *fifo)\n{\n\n\tck_spinlock_lock(&fifo->m_tail);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_enqueue_unlock(struct ck_fifo_spsc *fifo)\n{\n\n\tck_spinlock_unlock(&fifo->m_tail);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_fifo_spsc_dequeue_trylock(struct ck_fifo_spsc *fifo)\n{\n\n\treturn ck_spinlock_trylock(&fifo->m_head);\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_dequeue_lock(struct ck_fifo_spsc *fifo)\n{\n\n\tck_spinlock_lock(&fifo->m_head);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_dequeue_unlock(struct ck_fifo_spsc *fifo)\n{\n\n\tck_spinlock_unlock(&fifo->m_head);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_init(struct ck_fifo_spsc *fifo, struct ck_fifo_spsc_entry *stub)\n{\n\n\tck_spinlock_init(&fifo->m_head);\n\tck_spinlock_init(&fifo->m_tail);\n\n\tstub->next = NULL;\n\tfifo->head = fifo->tail = fifo->head_snapshot = fifo->garbage = stub;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_deinit(struct ck_fifo_spsc *fifo, struct ck_fifo_spsc_entry **garbage)\n{\n\n\t*garbage = fifo->head;\n\tfifo->head = fifo->tail = NULL;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_spsc_enqueue(struct ck_fifo_spsc *fifo,\n\t\t     struct ck_fifo_spsc_entry *entry,\n\t\t     void *value)\n{\n\n\tentry->value = value;\n\tentry->next = NULL;\n\n\t/* If stub->next is visible, guarantee that entry is consistent. */\n\tck_pr_fence_store();\n\tck_pr_store_ptr(&fifo->tail->next, entry);\n\tfifo->tail = entry;\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_fifo_spsc_dequeue(struct ck_fifo_spsc *fifo, void *value)\n{\n\tstruct ck_fifo_spsc_entry *entry;\n\n\t/*\n\t * The head pointer is guaranteed to always point to a stub entry.\n\t * If the stub entry does not point to an entry, then the queue is\n\t * empty.\n\t */\n\tentry = ck_pr_load_ptr(&fifo->head->next);\n\tif (entry == NULL)\n\t\treturn false;\n\n\t/* If entry is visible, guarantee store to value is visible. */\n\tck_pr_store_ptr_unsafe(value, entry->value);\n\tck_pr_fence_store();\n\tck_pr_store_ptr(&fifo->head, entry);\n\treturn true;\n}\n\n/*\n * Recycle a node. This technique for recycling nodes is based on\n * Dmitriy Vyukov's work.\n */\nCK_CC_INLINE static struct ck_fifo_spsc_entry *\nck_fifo_spsc_recycle(struct ck_fifo_spsc *fifo)\n{\n\tstruct ck_fifo_spsc_entry *garbage;\n\n\tif (fifo->head_snapshot == fifo->garbage) {\n\t\tfifo->head_snapshot = ck_pr_load_ptr(&fifo->head);\n\t\tif (fifo->head_snapshot == fifo->garbage)\n\t\t\treturn NULL;\n\t}\n\n\tgarbage = fifo->garbage;\n\tfifo->garbage = garbage->next;\n\treturn garbage;\n}\n\nCK_CC_INLINE static bool\nck_fifo_spsc_isempty(struct ck_fifo_spsc *fifo)\n{\n\tstruct ck_fifo_spsc_entry *head = ck_pr_load_ptr(&fifo->head);\n\treturn ck_pr_load_ptr(&head->next) == NULL;\n}\n\n#define CK_FIFO_SPSC_ISEMPTY(f)\t((f)->head->next == NULL)\n#define CK_FIFO_SPSC_FIRST(f)\t((f)->head->next)\n#define CK_FIFO_SPSC_NEXT(m)\t((m)->next)\n#define CK_FIFO_SPSC_SPARE(f)\t((f)->head)\n#define CK_FIFO_SPSC_FOREACH(fifo, entry)\t\t\t\\\n\tfor ((entry) = CK_FIFO_SPSC_FIRST(fifo);\t\t\\\n\t     (entry) != NULL;\t\t\t\t\t\\\n\t     (entry) = CK_FIFO_SPSC_NEXT(entry))\n#define CK_FIFO_SPSC_FOREACH_SAFE(fifo, entry, T)\t\t\\\n\tfor ((entry) = CK_FIFO_SPSC_FIRST(fifo);\t\t\\\n\t     (entry) != NULL && ((T) = (entry)->next, 1);\t\\\n\t     (entry) = (T))\n\n#endif /* CK_F_FIFO_SPSC */\n\n#ifdef CK_F_PR_CAS_PTR_2\n#ifndef CK_F_FIFO_MPMC\n#define CK_F_FIFO_MPMC\nstruct ck_fifo_mpmc_entry;\nstruct ck_fifo_mpmc_pointer {\n\tstruct ck_fifo_mpmc_entry *pointer;\n\tchar *generation CK_CC_PACKED;\n} CK_CC_ALIGN(16);\n\nstruct ck_fifo_mpmc_entry {\n\tvoid *value;\n\tstruct ck_fifo_mpmc_pointer next;\n};\ntypedef struct ck_fifo_mpmc_entry ck_fifo_mpmc_entry_t;\n\nstruct ck_fifo_mpmc {\n\tstruct ck_fifo_mpmc_pointer head;\n\tchar pad[CK_MD_CACHELINE - sizeof(struct ck_fifo_mpmc_pointer)];\n\tstruct ck_fifo_mpmc_pointer tail;\n};\ntypedef struct ck_fifo_mpmc ck_fifo_mpmc_t;\n\nCK_CC_INLINE static void\nck_fifo_mpmc_init(struct ck_fifo_mpmc *fifo, struct ck_fifo_mpmc_entry *stub)\n{\n\n\tstub->next.pointer = NULL;\n\tstub->next.generation = NULL;\n\tfifo->head.pointer = fifo->tail.pointer = stub;\n\tfifo->head.generation = fifo->tail.generation = NULL;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_mpmc_deinit(struct ck_fifo_mpmc *fifo, struct ck_fifo_mpmc_entry **garbage)\n{\n\n\t*garbage = fifo->head.pointer;\n\tfifo->head.pointer = fifo->tail.pointer = NULL;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_fifo_mpmc_enqueue(struct ck_fifo_mpmc *fifo,\n\t\t     struct ck_fifo_mpmc_entry *entry,\n\t\t     void *value)\n{\n\tstruct ck_fifo_mpmc_pointer tail, next, update;\n\n\t/*\n\t * Prepare the upcoming node and make sure to commit the updates\n\t * before publishing.\n\t */\n\tentry->value = value;\n\tentry->next.pointer = NULL;\n\tentry->next.generation = 0;\n\tck_pr_fence_store_atomic();\n\n\tfor (;;) {\n\t\ttail.generation = ck_pr_load_ptr(&fifo->tail.generation);\n\t\tck_pr_fence_load();\n\t\ttail.pointer = ck_pr_load_ptr(&fifo->tail.pointer);\n\t\tnext.generation = ck_pr_load_ptr(&tail.pointer->next.generation);\n\t\tck_pr_fence_load();\n\t\tnext.pointer = ck_pr_load_ptr(&tail.pointer->next.pointer);\n\n\t\tif (ck_pr_load_ptr(&fifo->tail.generation) != tail.generation)\n\t\t\tcontinue;\n\n\t\tif (next.pointer != NULL) {\n\t\t\t/*\n\t\t\t * If the tail pointer has an entry following it then\n\t\t\t * it needs to be forwarded to the next entry. This\n\t\t\t * helps us guarantee we are always operating on the\n\t\t\t * last entry.\n\t\t\t */\n\t\t\tupdate.pointer = next.pointer;\n\t\t\tupdate.generation = tail.generation + 1;\n\t\t\tck_pr_cas_ptr_2(&fifo->tail, &tail, &update);\n\t\t} else {\n\t\t\t/*\n\t\t\t * Attempt to commit new entry to the end of the\n\t\t\t * current tail.\n\t\t\t */\n\t\t\tupdate.pointer = entry;\n\t\t\tupdate.generation = next.generation + 1;\n\t\t\tif (ck_pr_cas_ptr_2(&tail.pointer->next, &next, &update) == true)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tck_pr_fence_atomic();\n\n\t/* After a successful insert, forward the tail to the new entry. */\n\tupdate.generation = tail.generation + 1;\n\tck_pr_cas_ptr_2(&fifo->tail, &tail, &update);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_fifo_mpmc_tryenqueue(struct ck_fifo_mpmc *fifo,\n\t\t        struct ck_fifo_mpmc_entry *entry,\n\t\t        void *value)\n{\n\tstruct ck_fifo_mpmc_pointer tail, next, update;\n\n\tentry->value = value;\n\tentry->next.pointer = NULL;\n\tentry->next.generation = 0;\n\n\tck_pr_fence_store_atomic();\n\n\ttail.generation = ck_pr_load_ptr(&fifo->tail.generation);\n\tck_pr_fence_load();\n\ttail.pointer = ck_pr_load_ptr(&fifo->tail.pointer);\n\tnext.generation = ck_pr_load_ptr(&tail.pointer->next.generation);\n\tck_pr_fence_load();\n\tnext.pointer = ck_pr_load_ptr(&tail.pointer->next.pointer);\n\n\tif (ck_pr_load_ptr(&fifo->tail.generation) != tail.generation)\n\t\treturn false;\n\n\tif (next.pointer != NULL) {\n\t\t/*\n\t\t * If the tail pointer has an entry following it then\n\t\t * it needs to be forwarded to the next entry. This\n\t\t * helps us guarantee we are always operating on the\n\t\t * last entry.\n\t\t */\n\t\tupdate.pointer = next.pointer;\n\t\tupdate.generation = tail.generation + 1;\n\t\tck_pr_cas_ptr_2(&fifo->tail, &tail, &update);\n\t\treturn false;\n\t} else {\n\t\t/*\n\t\t * Attempt to commit new entry to the end of the\n\t\t * current tail.\n\t\t */\n\t\tupdate.pointer = entry;\n\t\tupdate.generation = next.generation + 1;\n\t\tif (ck_pr_cas_ptr_2(&tail.pointer->next, &next, &update) == false)\n\t\t\treturn false;\n\t}\n\n\tck_pr_fence_atomic();\n\n\t/* After a successful insert, forward the tail to the new entry. */\n\tupdate.generation = tail.generation + 1;\n\tck_pr_cas_ptr_2(&fifo->tail, &tail, &update);\n\treturn true;\n}\n\nCK_CC_INLINE static bool\nck_fifo_mpmc_dequeue(struct ck_fifo_mpmc *fifo,\n\t\t     void *value,\n\t\t     struct ck_fifo_mpmc_entry **garbage)\n{\n\tstruct ck_fifo_mpmc_pointer head, tail, next, update;\n\n\tfor (;;) {\n\t\thead.generation = ck_pr_load_ptr(&fifo->head.generation);\n\t\tck_pr_fence_load();\n\t\thead.pointer = ck_pr_load_ptr(&fifo->head.pointer);\n\t\ttail.generation = ck_pr_load_ptr(&fifo->tail.generation);\n\t\tck_pr_fence_load();\n\t\ttail.pointer = ck_pr_load_ptr(&fifo->tail.pointer);\n\n\t\tnext.generation = ck_pr_load_ptr(&head.pointer->next.generation);\n\t\tck_pr_fence_load();\n\t\tnext.pointer = ck_pr_load_ptr(&head.pointer->next.pointer);\n\n\t\tupdate.pointer = next.pointer;\n\t\tif (head.pointer == tail.pointer) {\n\t\t\t/*\n\t\t\t * The head is guaranteed to always point at a stub\n\t\t\t * entry. If the stub entry has no references then the\n\t\t\t * queue is empty.\n\t\t\t */\n\t\t\tif (next.pointer == NULL)\n\t\t\t\treturn false;\n\n\t\t\t/* Forward the tail pointer if necessary. */\n\t\t\tupdate.generation = tail.generation + 1;\n\t\t\tck_pr_cas_ptr_2(&fifo->tail, &tail, &update);\n\t\t} else {\n\t\t\t/*\n\t\t\t * It is possible for head snapshot to have been\n\t\t\t * re-used. Avoid deferencing during enqueue\n\t\t\t * re-use.\n\t\t\t */\n\t\t\tif (next.pointer == NULL)\n\t\t\t\tcontinue;\n\n\t\t\t/* Save value before commit. */\n\t\t\t*(void **)value = ck_pr_load_ptr(&next.pointer->value);\n\n\t\t\t/* Forward the head pointer to the next entry. */\n\t\t\tupdate.generation = head.generation + 1;\n\t\t\tif (ck_pr_cas_ptr_2(&fifo->head, &head, &update) == true)\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t*garbage = head.pointer;\n\treturn true;\n}\n\nCK_CC_INLINE static bool\nck_fifo_mpmc_trydequeue(struct ck_fifo_mpmc *fifo,\n\t\t\tvoid *value,\n\t\t\tstruct ck_fifo_mpmc_entry **garbage)\n{\n\tstruct ck_fifo_mpmc_pointer head, tail, next, update;\n\n\thead.generation = ck_pr_load_ptr(&fifo->head.generation);\n\tck_pr_fence_load();\n\thead.pointer = ck_pr_load_ptr(&fifo->head.pointer);\n\n\ttail.generation = ck_pr_load_ptr(&fifo->tail.generation);\n\tck_pr_fence_load();\n\ttail.pointer = ck_pr_load_ptr(&fifo->tail.pointer);\n\n\tnext.generation = ck_pr_load_ptr(&head.pointer->next.generation);\n\tck_pr_fence_load();\n\tnext.pointer = ck_pr_load_ptr(&head.pointer->next.pointer);\n\n\tupdate.pointer = next.pointer;\n\tif (head.pointer == tail.pointer) {\n\t\t/*\n\t\t * The head is guaranteed to always point at a stub\n\t\t * entry. If the stub entry has no references then the\n\t\t * queue is empty.\n\t\t */\n\t\tif (next.pointer == NULL)\n\t\t\treturn false;\n\n\t\t/* Forward the tail pointer if necessary. */\n\t\tupdate.generation = tail.generation + 1;\n\t\tck_pr_cas_ptr_2(&fifo->tail, &tail, &update);\n\t\treturn false;\n\t} else {\n\t\t/*\n\t\t * It is possible for head snapshot to have been\n\t\t * re-used. Avoid deferencing during enqueue.\n\t\t */\n\t\tif (next.pointer == NULL)\n\t\t\treturn false;\n\n\t\t/* Save value before commit. */\n\t\t*(void **)value = ck_pr_load_ptr(&next.pointer->value);\n\n\t\t/* Forward the head pointer to the next entry. */\n\t\tupdate.generation = head.generation + 1;\n\t\tif (ck_pr_cas_ptr_2(&fifo->head, &head, &update) == false)\n\t\t\treturn false;\n\t}\n\n\t*garbage = head.pointer;\n\treturn true;\n}\n\n#define CK_FIFO_MPMC_ISEMPTY(f)\t((f)->head.pointer->next.pointer == NULL)\n#define CK_FIFO_MPMC_FIRST(f)\t((f)->head.pointer->next.pointer)\n#define CK_FIFO_MPMC_NEXT(m)\t((m)->next.pointer)\n#define CK_FIFO_MPMC_FOREACH(fifo, entry)\t\t\t\t\\\n\tfor ((entry) = CK_FIFO_MPMC_FIRST(fifo);\t\t\t\\\n\t     (entry) != NULL;\t\t\t\t\t\t\\\n\t     (entry) = CK_FIFO_MPMC_NEXT(entry))\n#define CK_FIFO_MPMC_FOREACH_SAFE(fifo, entry, T)\t\t\t\\\n\tfor ((entry) = CK_FIFO_MPMC_FIRST(fifo);\t\t\t\\\n\t     (entry) != NULL && ((T) = (entry)->next.pointer, 1);\t\\\n\t     (entry) = (T))\n\n#endif /* CK_F_FIFO_MPMC */\n#endif /* CK_F_PR_CAS_PTR_2 */\n\n#endif /* CK_FIFO_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_hp.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_HP_H\n#define CK_HP_H\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stack.h>\n\n#ifndef CK_HP_CACHE\n#define CK_HP_CACHE 512\n#endif\n\nstruct ck_hp_hazard;\ntypedef void (*ck_hp_destructor_t)(void *);\n\nstruct ck_hp {\n\tck_stack_t subscribers;\n\tunsigned int n_subscribers;\n\tunsigned int n_free;\n\tunsigned int threshold;\n\tunsigned int degree;\n\tck_hp_destructor_t destroy;\n};\ntypedef struct ck_hp ck_hp_t;\n\nstruct ck_hp_hazard {\n\tvoid *pointer;\n\tvoid *data;\n\tck_stack_entry_t pending_entry;\n};\ntypedef struct ck_hp_hazard ck_hp_hazard_t;\n\nenum {\n\tCK_HP_USED = 0,\n\tCK_HP_FREE = 1\n};\n\nstruct ck_hp_record {\n\tint state;\n\tvoid **pointers;\n\tvoid *cache[CK_HP_CACHE];\n\tstruct ck_hp *global;\n\tck_stack_t pending;\n\tunsigned int n_pending;\n\tck_stack_entry_t global_entry;\n\tunsigned int n_peak;\n\tuint64_t n_reclamations;\n} CK_CC_CACHELINE;\ntypedef struct ck_hp_record ck_hp_record_t;\n\nCK_CC_INLINE static void\nck_hp_set(struct ck_hp_record *record, unsigned int i, void *pointer)\n{\n\n\tck_pr_store_ptr(&record->pointers[i], pointer);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_hp_set_fence(struct ck_hp_record *record, unsigned int i, void *pointer)\n{\n\n#ifdef CK_MD_TSO\n\tck_pr_fas_ptr(&record->pointers[i], pointer);\n#else\n\tck_pr_store_ptr(&record->pointers[i], pointer);\n\tck_pr_fence_memory();\n#endif\n\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_hp_clear(struct ck_hp_record *record)\n{\n\tvoid **pointers = record->pointers;\n\tunsigned int i;\n\n\tfor (i = 0; i < record->global->degree; i++)\n\t\t*pointers++ = NULL;\n\n\treturn;\n}\n\nvoid ck_hp_init(ck_hp_t *, unsigned int, unsigned int, ck_hp_destructor_t);\nvoid ck_hp_set_threshold(ck_hp_t *, unsigned int);\nvoid ck_hp_register(ck_hp_t *, ck_hp_record_t *, void **);\nvoid ck_hp_unregister(ck_hp_record_t *);\nck_hp_record_t *ck_hp_recycle(ck_hp_t *);\nvoid ck_hp_reclaim(ck_hp_record_t *);\nvoid ck_hp_free(ck_hp_record_t *, ck_hp_hazard_t *, void *, void *);\nvoid ck_hp_retire(ck_hp_record_t *, ck_hp_hazard_t *, void *, void *);\nvoid ck_hp_purge(ck_hp_record_t *);\n\n#endif /* CK_HP_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_hp_fifo.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_HP_FIFO_H\n#define CK_HP_FIFO_H\n\n#include <ck_cc.h>\n#include <ck_hp.h>\n#include <ck_pr.h>\n#include <ck_stddef.h>\n\n#define CK_HP_FIFO_SLOTS_COUNT (2)\n#define CK_HP_FIFO_SLOTS_SIZE  (sizeof(void *) * CK_HP_FIFO_SLOTS_COUNT)\n\n/*\n * Though it is possible to embed the data structure, measurements need\n * to be made for the cost of this. If we were to embed the hazard pointer\n * state into the data structure, this means every deferred reclamation\n * will also include a cache invalidation when linking into the hazard pointer\n * pending queue. This may lead to terrible cache line bouncing.\n */\nstruct ck_hp_fifo_entry {\n\tvoid *value;\n\tck_hp_hazard_t hazard;\n\tstruct ck_hp_fifo_entry *next;\n};\ntypedef struct ck_hp_fifo_entry ck_hp_fifo_entry_t;\n\nstruct ck_hp_fifo {\n\tstruct ck_hp_fifo_entry *head;\n\tstruct ck_hp_fifo_entry *tail;\n};\ntypedef struct ck_hp_fifo ck_hp_fifo_t;\n\nCK_CC_INLINE static void\nck_hp_fifo_init(struct ck_hp_fifo *fifo, struct ck_hp_fifo_entry *stub)\n{\n\n\tfifo->head = fifo->tail = stub;\n\tstub->next = NULL;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_hp_fifo_deinit(struct ck_hp_fifo *fifo, struct ck_hp_fifo_entry **stub)\n{\n\n\t*stub = fifo->head;\n\tfifo->head = fifo->tail = NULL;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_hp_fifo_enqueue_mpmc(ck_hp_record_t *record,\n\t\t\tstruct ck_hp_fifo *fifo,\n\t\t\tstruct ck_hp_fifo_entry *entry,\n\t\t\tvoid *value)\n{\n\tstruct ck_hp_fifo_entry *tail, *next;\n\n\tentry->value = value;\n\tentry->next = NULL;\n\tck_pr_fence_store_atomic();\n\n\tfor (;;) {\n\t\ttail = ck_pr_load_ptr(&fifo->tail);\n\t\tck_hp_set_fence(record, 0, tail);\n\t\tif (tail != ck_pr_load_ptr(&fifo->tail))\n\t\t\tcontinue;\n\n\t\tnext = ck_pr_load_ptr(&tail->next);\n\t\tif (next != NULL) {\n\t\t\tck_pr_cas_ptr(&fifo->tail, tail, next);\n\t\t\tcontinue;\n\t\t} else if (ck_pr_cas_ptr(&fifo->tail->next, next, entry) == true)\n\t\t\tbreak;\n\t}\n\n\tck_pr_fence_atomic();\n\tck_pr_cas_ptr(&fifo->tail, tail, entry);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_hp_fifo_tryenqueue_mpmc(ck_hp_record_t *record,\n\t\t\t   struct ck_hp_fifo *fifo,\n\t\t\t   struct ck_hp_fifo_entry *entry,\n\t\t\t   void *value)\n{\n\tstruct ck_hp_fifo_entry *tail, *next;\n\n\tentry->value = value;\n\tentry->next = NULL;\n\tck_pr_fence_store_atomic();\n\n\ttail = ck_pr_load_ptr(&fifo->tail);\n\tck_hp_set_fence(record, 0, tail);\n\tif (tail != ck_pr_load_ptr(&fifo->tail))\n\t\treturn false;\n\n\tnext = ck_pr_load_ptr(&tail->next);\n\tif (next != NULL) {\n\t\tck_pr_cas_ptr(&fifo->tail, tail, next);\n\t\treturn false;\n\t} else if (ck_pr_cas_ptr(&fifo->tail->next, next, entry) == false)\n\t\treturn false;\n\n\tck_pr_fence_atomic();\n\tck_pr_cas_ptr(&fifo->tail, tail, entry);\n\treturn true;\n}\n\nCK_CC_INLINE static struct ck_hp_fifo_entry *\nck_hp_fifo_dequeue_mpmc(ck_hp_record_t *record,\n\t\t\tstruct ck_hp_fifo *fifo,\n\t\t\tvoid *value)\n{\n\tstruct ck_hp_fifo_entry *head, *tail, *next;\n\n\tfor (;;) {\n\t\thead = ck_pr_load_ptr(&fifo->head);\n\t\tck_pr_fence_load();\n\t\ttail = ck_pr_load_ptr(&fifo->tail);\n\t\tck_hp_set_fence(record, 0, head);\n\t\tif (head != ck_pr_load_ptr(&fifo->head))\n\t\t\tcontinue;\n\n\t\tnext = ck_pr_load_ptr(&head->next);\n\t\tck_hp_set_fence(record, 1, next);\n\t\tif (head != ck_pr_load_ptr(&fifo->head))\n\t\t\tcontinue;\n\n\t\tif (head == tail) {\n\t\t\tif (next == NULL)\n\t\t\t\treturn NULL;\n\n\t\t\tck_pr_cas_ptr(&fifo->tail, tail, next);\n\t\t\tcontinue;\n\t\t} else if (ck_pr_cas_ptr(&fifo->head, head, next) == true)\n\t\t\tbreak;\n\t}\n\n\tck_pr_store_ptr_unsafe(value, next->value);\n\treturn head;\n}\n\nCK_CC_INLINE static struct ck_hp_fifo_entry *\nck_hp_fifo_trydequeue_mpmc(ck_hp_record_t *record,\n\t\t\t   struct ck_hp_fifo *fifo,\n\t\t\t   void *value)\n{\n\tstruct ck_hp_fifo_entry *head, *tail, *next;\n\n\thead = ck_pr_load_ptr(&fifo->head);\n\tck_pr_fence_load();\n\ttail = ck_pr_load_ptr(&fifo->tail);\n\tck_hp_set_fence(record, 0, head);\n\tif (head != ck_pr_load_ptr(&fifo->head))\n\t\treturn NULL;\n\n\tnext = ck_pr_load_ptr(&head->next);\n\tck_hp_set_fence(record, 1, next);\n\tif (head != ck_pr_load_ptr(&fifo->head))\n\t\treturn NULL;\n\n\tif (head == tail) {\n\t\tif (next == NULL)\n\t\t\treturn NULL;\n\n\t\tck_pr_cas_ptr(&fifo->tail, tail, next);\n\t\treturn NULL;\n\t} else if (ck_pr_cas_ptr(&fifo->head, head, next) == false)\n\t\treturn NULL;\n\n\tck_pr_store_ptr_unsafe(value, next->value);\n\treturn head;\n}\n\n#define CK_HP_FIFO_ISEMPTY(f) ((f)->head->next == NULL)\n#define CK_HP_FIFO_FIRST(f)   ((f)->head->next)\n#define CK_HP_FIFO_NEXT(m)    ((m)->next)\n#define CK_HP_FIFO_FOREACH(fifo, entry)                       \t\\\n        for ((entry) = CK_HP_FIFO_FIRST(fifo);                \t\\\n             (entry) != NULL;                                   \\\n             (entry) = CK_HP_FIFO_NEXT(entry))\n#define CK_HP_FIFO_FOREACH_SAFE(fifo, entry, T)\t\t\t\\\n        for ((entry) = CK_HP_FIFO_FIRST(fifo);\t\t\t\\\n             (entry) != NULL && ((T) = (entry)->next, 1);\t\\\n             (entry) = (T))\n\n#endif /* CK_HP_FIFO_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_hp_stack.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_HP_STACK_H\n#define CK_HP_STACK_H\n\n#include <ck_cc.h>\n#include <ck_hp.h>\n#include <ck_pr.h>\n#include <ck_stack.h>\n#include <ck_stddef.h>\n\n#define CK_HP_STACK_SLOTS_COUNT 1\n#define CK_HP_STACK_SLOTS_SIZE  sizeof(void *)\n\nCK_CC_INLINE static void\nck_hp_stack_push_mpmc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\n\tck_stack_push_upmc(target, entry);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_hp_stack_trypush_mpmc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\n\treturn ck_stack_trypush_upmc(target, entry);\n}\n\nCK_CC_INLINE static struct ck_stack_entry *\nck_hp_stack_pop_mpmc(ck_hp_record_t *record, struct ck_stack *target)\n{\n\tstruct ck_stack_entry *entry, *update;\n\n\tdo {\n\t\tentry = ck_pr_load_ptr(&target->head);\n\t\tif (entry == NULL)\n\t\t\treturn NULL;\n\n\t\tck_hp_set_fence(record, 0, entry);\n\t} while (entry != ck_pr_load_ptr(&target->head));\n\n\twhile (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false) {\n\t\tif (entry == NULL)\n\t\t\treturn NULL;\n\n\t\tck_hp_set_fence(record, 0, entry);\n\n\t\tupdate = ck_pr_load_ptr(&target->head);\n\t\twhile (entry != update) {\n\t\t\tck_hp_set_fence(record, 0, update);\n\t\t\tentry = update;\n\t\t\tupdate = ck_pr_load_ptr(&target->head);\n\t\t\tif (update == NULL)\n\t\t\t\treturn NULL;\n\t\t}\n\t}\n\n\treturn entry;\n}\n\nCK_CC_INLINE static bool\nck_hp_stack_trypop_mpmc(ck_hp_record_t *record, struct ck_stack *target, struct ck_stack_entry **r)\n{\n\tstruct ck_stack_entry *entry;\n\n\tentry = ck_pr_load_ptr(&target->head);\n\tif (entry == NULL)\n\t\treturn false;\n\n\tck_hp_set_fence(record, 0, entry);\n\tif (entry != ck_pr_load_ptr(&target->head))\n\t\tgoto leave;\n\n\tif (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false)\n\t\tgoto leave;\n\n\t*r = entry;\n\treturn true;\n\nleave:\n\tck_hp_set(record, 0, NULL);\n\treturn false;\n}\n\n#endif /* CK_HP_STACK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_hs.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_HS_H\n#define CK_HS_H\n\n#include <ck_cc.h>\n#include <ck_malloc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\n/*\n * Indicates a single-writer many-reader workload. Mutually\n * exclusive with CK_HS_MODE_MPMC\n */\n#define CK_HS_MODE_SPMC\t\t1\n\n/*\n * Indicates that values to be stored are not pointers but\n * values. Allows for full precision. Mutually exclusive\n * with CK_HS_MODE_OBJECT.\n */\n#define CK_HS_MODE_DIRECT\t2\n\n/*\n * Indicates that the values to be stored are pointers.\n * Allows for space optimizations in the presence of pointer\n * packing. Mutually exclusive with CK_HS_MODE_DIRECT.\n */\n#define CK_HS_MODE_OBJECT\t8\n\n/*\n * Indicates a delete-heavy workload. This will reduce the\n * need for garbage collection at the cost of approximately\n * 12% to 20% increased memory usage.\n */\n#define CK_HS_MODE_DELETE\t16\n\n/* Currently unsupported. */\n#define CK_HS_MODE_MPMC    (void)\n\n/*\n * Hash callback function.\n */\ntypedef unsigned long ck_hs_hash_cb_t(const void *, unsigned long);\n\n/*\n * Returns pointer to object if objects are equivalent.\n */\ntypedef bool ck_hs_compare_cb_t(const void *, const void *);\n\n#if defined(CK_MD_POINTER_PACK_ENABLE) && defined(CK_MD_VMA_BITS)\n#define CK_HS_PP\n#define CK_HS_KEY_MASK ((1U << ((sizeof(void *) * 8) - CK_MD_VMA_BITS)) - 1)\n#endif\n\nstruct ck_hs_map;\nstruct ck_hs {\n\tstruct ck_malloc *m;\n\tstruct ck_hs_map *map;\n\tunsigned int mode;\n\tunsigned long seed;\n\tck_hs_hash_cb_t *hf;\n\tck_hs_compare_cb_t *compare;\n};\ntypedef struct ck_hs ck_hs_t;\n\nstruct ck_hs_stat {\n\tunsigned long tombstones;\n\tunsigned long n_entries;\n\tunsigned int probe_maximum;\n};\n\nstruct ck_hs_iterator {\n\tvoid **cursor;\n\tunsigned long offset;\n\tstruct ck_hs_map *map;\n};\ntypedef struct ck_hs_iterator ck_hs_iterator_t;\n\n#define CK_HS_ITERATOR_INITIALIZER { NULL, 0, NULL }\n\n/* Convenience wrapper to table hash function. */\n#define CK_HS_HASH(T, F, K) F((K), (T)->seed)\n\ntypedef void *ck_hs_apply_fn_t(void *, void *);\nbool ck_hs_apply(ck_hs_t *, unsigned long, const void *, ck_hs_apply_fn_t *, void *);\nvoid ck_hs_iterator_init(ck_hs_iterator_t *);\nbool ck_hs_next(ck_hs_t *, ck_hs_iterator_t *, void **);\nbool ck_hs_next_spmc(ck_hs_t *, ck_hs_iterator_t *, void **);\nbool ck_hs_move(ck_hs_t *, ck_hs_t *, ck_hs_hash_cb_t *,\n    ck_hs_compare_cb_t *, struct ck_malloc *);\nbool ck_hs_init(ck_hs_t *, unsigned int, ck_hs_hash_cb_t *,\n    ck_hs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long);\nvoid ck_hs_destroy(ck_hs_t *);\nvoid *ck_hs_get(ck_hs_t *, unsigned long, const void *);\nbool ck_hs_put(ck_hs_t *, unsigned long, const void *);\nbool ck_hs_put_unique(ck_hs_t *, unsigned long, const void *);\nbool ck_hs_set(ck_hs_t *, unsigned long, const void *, void **);\nbool ck_hs_fas(ck_hs_t *, unsigned long, const void *, void **);\nvoid *ck_hs_remove(ck_hs_t *, unsigned long, const void *);\nbool ck_hs_grow(ck_hs_t *, unsigned long);\nbool ck_hs_rebuild(ck_hs_t *);\nbool ck_hs_gc(ck_hs_t *, unsigned long, unsigned long);\nunsigned long ck_hs_count(ck_hs_t *);\nbool ck_hs_reset(ck_hs_t *);\nbool ck_hs_reset_size(ck_hs_t *, unsigned long);\nvoid ck_hs_stat(ck_hs_t *, struct ck_hs_stat *);\n\n#endif /* CK_HS_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_ht.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_HT_H\n#define CK_HT_H\n\n#include <ck_pr.h>\n\n#define CK_F_HT\n#if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_STORE_64)\n#define CK_HT_TYPE uint64_t\n#define CK_HT_TYPE_LOAD\t\tck_pr_load_64\n#define CK_HT_TYPE_STORE \tck_pr_store_64\n#define CK_HT_TYPE_MAX\t\tUINT64_MAX\n#else\n#define CK_HT_TYPE uint32_t\n#define CK_HT_TYPE_LOAD\t\tck_pr_load_32\n#define CK_HT_TYPE_STORE\tck_pr_store_32\n#define CK_HT_TYPE_MAX\t\tUINT32_MAX\n#endif\n\n\n#include <ck_cc.h>\n#include <ck_malloc.h>\n#include <ck_md.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\nstruct ck_ht_hash {\n\tuint64_t value;\n};\ntypedef struct ck_ht_hash ck_ht_hash_t;\n\n#define CK_HT_MODE_DIRECT\t1U\n#define CK_HT_MODE_BYTESTRING\t2U\n#define CK_HT_WORKLOAD_DELETE\t4U\n\n#if defined(CK_MD_POINTER_PACK_ENABLE) && defined(CK_MD_VMA_BITS)\n#define CK_HT_PP\n#define CK_HT_KEY_LENGTH ((sizeof(void *) * 8) - CK_MD_VMA_BITS)\n#define CK_HT_KEY_MASK   ((1U << CK_HT_KEY_LENGTH) - 1)\n#else\n#define CK_HT_KEY_LENGTH 65535U\n#endif\n\nstruct ck_ht_entry {\n#ifdef CK_HT_PP\n\tuintptr_t key;\n\tuintptr_t value CK_CC_PACKED;\n} CK_CC_ALIGN(16);\n#else\n\tuintptr_t key;\n\tuintptr_t value;\n\tCK_HT_TYPE key_length;\n\tCK_HT_TYPE hash;\n} CK_CC_ALIGN(32);\n#endif\ntypedef struct ck_ht_entry ck_ht_entry_t;\n\n/*\n * The user is free to define their own stub values.\n */\n#ifndef CK_HT_KEY_EMPTY\n#define CK_HT_KEY_EMPTY\t\t((uintptr_t)0)\n#endif\n\n#ifndef CK_HT_KEY_TOMBSTONE\n#define CK_HT_KEY_TOMBSTONE\t(~CK_HT_KEY_EMPTY)\n#endif\n\n/*\n * Hash callback function. First argument is updated to contain a hash value,\n * second argument is the key, third argument is key length and final argument\n * is the hash table seed value.\n */\ntypedef void ck_ht_hash_cb_t(ck_ht_hash_t *, const void *, size_t, uint64_t);\n\nstruct ck_ht_map;\nstruct ck_ht {\n\tstruct ck_malloc *m;\n\tstruct ck_ht_map *map;\n\tunsigned int mode;\n\tuint64_t seed;\n\tck_ht_hash_cb_t *h;\n};\ntypedef struct ck_ht ck_ht_t;\n\nstruct ck_ht_stat {\n\tuint64_t probe_maximum;\n\tuint64_t n_entries;\n};\n\nstruct ck_ht_iterator {\n\tstruct ck_ht_entry *current;\n\tuint64_t offset;\n};\ntypedef struct ck_ht_iterator ck_ht_iterator_t;\n\n#define CK_HT_ITERATOR_INITIALIZER { NULL, 0 }\n\nCK_CC_INLINE static void\nck_ht_iterator_init(struct ck_ht_iterator *iterator)\n{\n\n\titerator->current = NULL;\n\titerator->offset = 0;\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_ht_entry_empty(ck_ht_entry_t *entry)\n{\n\n\treturn entry->key == CK_HT_KEY_EMPTY;\n}\n\nCK_CC_INLINE static void\nck_ht_entry_key_set_direct(ck_ht_entry_t *entry, uintptr_t key)\n{\n\n\tentry->key = key;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_ht_entry_key_set(ck_ht_entry_t *entry, const void *key, uint16_t key_length)\n{\n\n#ifdef CK_HT_PP\n\tentry->key = (uintptr_t)key | ((uintptr_t)key_length << CK_MD_VMA_BITS);\n#else\n\tentry->key = (uintptr_t)key;\n\tentry->key_length = key_length;\n#endif\n\n\treturn;\n}\n\nCK_CC_INLINE static void *\nck_ht_entry_key(ck_ht_entry_t *entry)\n{\n\n#ifdef CK_HT_PP\n\treturn (void *)(entry->key & (((uintptr_t)1 << CK_MD_VMA_BITS) - 1));\n#else\n\treturn (void *)entry->key;\n#endif\n}\n\nCK_CC_INLINE static uint16_t\nck_ht_entry_key_length(ck_ht_entry_t *entry)\n{\n\n#ifdef CK_HT_PP\n\treturn entry->key >> CK_MD_VMA_BITS;\n#else\n\treturn entry->key_length;\n#endif\n}\n\nCK_CC_INLINE static void *\nck_ht_entry_value(ck_ht_entry_t *entry)\n{\n\n#ifdef CK_HT_PP\n\treturn (void *)(entry->value & (((uintptr_t)1 << CK_MD_VMA_BITS) - 1));\n#else\n\treturn (void *)entry->value;\n#endif\n}\n\nCK_CC_INLINE static void\nck_ht_entry_set(struct ck_ht_entry *entry,\n\t\tck_ht_hash_t h,\n\t\tconst void *key,\n\t\tuint16_t key_length,\n\t\tconst void *value)\n{\n\n#ifdef CK_HT_PP\n\tentry->key = (uintptr_t)key | ((uintptr_t)key_length << CK_MD_VMA_BITS);\n\tentry->value = (uintptr_t)value | ((uintptr_t)(h.value >> 32) << CK_MD_VMA_BITS);\n#else\n\tentry->key = (uintptr_t)key;\n\tentry->value = (uintptr_t)value;\n\tentry->key_length = key_length;\n\tentry->hash = h.value;\n#endif\n\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_ht_entry_set_direct(struct ck_ht_entry *entry,\n\t\t       ck_ht_hash_t h,\n\t\t       uintptr_t key,\n\t\t       uintptr_t value)\n{\n\n\tentry->key = key;\n\tentry->value = value;\n\n#ifndef CK_HT_PP\n\tentry->hash = h.value;\n#else\n\t(void)h;\n#endif\n\treturn;\n}\n\nCK_CC_INLINE static uintptr_t\nck_ht_entry_key_direct(ck_ht_entry_t *entry)\n{\n\n\treturn entry->key;\n}\n\nCK_CC_INLINE static uintptr_t\nck_ht_entry_value_direct(ck_ht_entry_t *entry)\n{\n\n\treturn entry->value;\n}\n\n/*\n * Iteration must occur without any concurrent mutations on\n * the hash table.\n */\nbool ck_ht_next(ck_ht_t *, ck_ht_iterator_t *, ck_ht_entry_t **entry);\n\nvoid ck_ht_stat(ck_ht_t *, struct ck_ht_stat *);\nvoid ck_ht_hash(ck_ht_hash_t *, ck_ht_t *, const void *, uint16_t);\nvoid ck_ht_hash_direct(ck_ht_hash_t *, ck_ht_t *, uintptr_t);\nbool ck_ht_init(ck_ht_t *, unsigned int, ck_ht_hash_cb_t *,\n    struct ck_malloc *, CK_HT_TYPE, uint64_t);\nvoid ck_ht_destroy(ck_ht_t *);\nbool ck_ht_set_spmc(ck_ht_t *, ck_ht_hash_t, ck_ht_entry_t *);\nbool ck_ht_put_spmc(ck_ht_t *, ck_ht_hash_t, ck_ht_entry_t *);\nbool ck_ht_get_spmc(ck_ht_t *, ck_ht_hash_t, ck_ht_entry_t *);\nbool ck_ht_gc(struct ck_ht *, unsigned long, unsigned long);\nbool ck_ht_grow_spmc(ck_ht_t *, CK_HT_TYPE);\nbool ck_ht_remove_spmc(ck_ht_t *, ck_ht_hash_t, ck_ht_entry_t *);\nbool ck_ht_reset_spmc(ck_ht_t *);\nbool ck_ht_reset_size_spmc(ck_ht_t *, CK_HT_TYPE);\nCK_HT_TYPE ck_ht_count(ck_ht_t *);\n\n#endif /* CK_HT_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_limits.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(__linux__) && defined(__KERNEL__)\n#include <linux/kernel.h>\n\n#ifndef UINT8_MAX\n#define UINT8_MAX ((u8)(~0U))\n#endif\n#ifndef UINT16_MAX\n#define UINT16_MAX USHRT_MAX\n#endif\n#ifndef UINT32_MAX\n#define UINT32_MAX UINT_MAX\n#endif\n#ifndef UINT64_MAX\n#define UINT64_MAX ULLONG_MAX\n#endif\n\n#elif defined(__FreeBSD__) && defined(_KERNEL)\n#include <sys/stdint.h>\n#include <sys/limits.h>\n#else\n#include <limits.h>\n#endif /* __linux__ && __KERNEL__ */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_malloc.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_MALLOC_H\n#define CK_MALLOC_H\n\n#include <ck_stdbool.h>\n#include <sys/types.h>\n\nstruct ck_malloc {\n\tvoid *(*malloc)(size_t);\n\tvoid *(*realloc)(void *, size_t, size_t, bool);\n\tvoid (*free)(void *, size_t, bool);\n};\n\n#endif /* CK_MALLOC_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_md.h.in",
    "content": "/*\n * Copyright 2011-2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_MD_H\n#define CK_MD_H\n\n#ifndef CK_MD_CACHELINE\n#define CK_MD_CACHELINE (64)\n#endif\n\n#ifndef CK_MD_PAGESIZE\n#define CK_MD_PAGESIZE (4096)\n#endif\n\n#ifndef @RTM_ENABLE@\n#define @RTM_ENABLE@\n#endif /* @RTM_ENABLE@ */\n\n#ifndef @LSE_ENABLE@\n#define @LSE_ENABLE@\n#endif /* @LSE_ENABLE@ */\n\n#ifndef @POINTER_PACK_ENABLE@\n#define @POINTER_PACK_ENABLE@\n#endif /* @POINTER_PACK_ENABLE@ */\n\n#ifndef @VMA_BITS@ \n#define @VMA_BITS@ @VMA_BITS_VALUE@\n#endif /* @VMA_BITS@ */\n\n#ifndef @MM@\n#define @MM@\n#endif /* @MM@ */\n\n#ifndef @DISABLE_DOUBLE@\n#define @DISABLE_DOUBLE@\n#endif /* @DISABLE_DOUBLE@ */\n\n#define CK_VERSION \"@VERSION@\"\n#define CK_GIT_SHA \"@GIT_SHA@\"\n\n#endif /* CK_MD_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_pflock.h",
    "content": "/*\n * Copyright 2013 John Wittrock.\n * Copyright 2013-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PFLOCK_H\n#define CK_PFLOCK_H\n\n/*\n * This is an implementation of phase-fair locks derived from the work\n * described in:\n *    Brandenburg, B. and Anderson, J. 2010. Spin-Based\n *    Reader-Writer Synchronization for Multiprocessor Real-Time Systems\n */\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n\nstruct ck_pflock {\n\tuint32_t rin;\n\tuint32_t rout;\n\tuint32_t win;\n\tuint32_t wout;\n};\ntypedef struct ck_pflock ck_pflock_t;\n\n#define CK_PFLOCK_LSB   0xFFFFFFF0\n#define CK_PFLOCK_RINC  0x100\t\t/* Reader increment value. */\n#define CK_PFLOCK_WBITS 0x3\t\t/* Writer bits in reader. */\n#define CK_PFLOCK_PRES  0x2\t\t/* Writer present bit. */\n#define CK_PFLOCK_PHID  0x1\t\t/* Phase ID bit. */\n\n#define CK_PFLOCK_INITIALIZER {0, 0, 0, 0}\n\nCK_CC_INLINE static void\nck_pflock_init(struct ck_pflock *pf)\n{\n\n\tpf->rin = 0;\n\tpf->rout = 0;\n\tpf->win = 0;\n\tpf->wout = 0;\n\tck_pr_barrier();\n\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_pflock_write_unlock(ck_pflock_t *pf)\n{\n\n\tck_pr_fence_unlock();\n\n\t/* Migrate from write phase to read phase. */\n\tck_pr_and_32(&pf->rin, CK_PFLOCK_LSB);\n\n\t/* Allow other writers to continue. */\n\tck_pr_faa_32(&pf->wout, 1);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_pflock_write_lock(ck_pflock_t *pf)\n{\n\tuint32_t ticket;\n\n\t/* Acquire ownership of write-phase. */\n\tticket = ck_pr_faa_32(&pf->win, 1);\n\twhile (ck_pr_load_32(&pf->wout) != ticket)\n\t\tck_pr_stall();\n\n\t/*\n\t * Acquire ticket on read-side in order to allow them\n\t * to flush. Indicates to any incoming reader that a\n\t * write-phase is pending.\n\t */\n\tticket = ck_pr_faa_32(&pf->rin,\n\t    (ticket & CK_PFLOCK_PHID) | CK_PFLOCK_PRES);\n\n\t/* Wait for any pending readers to flush. */\n\twhile (ck_pr_load_32(&pf->rout) != ticket)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_pflock_read_unlock(ck_pflock_t *pf)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_faa_32(&pf->rout, CK_PFLOCK_RINC);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_pflock_read_lock(ck_pflock_t *pf)\n{\n\tuint32_t w;\n\n\t/*\n\t * If no writer is present, then the operation has completed\n\t * successfully.\n\t */\n\tw = ck_pr_faa_32(&pf->rin, CK_PFLOCK_RINC) & CK_PFLOCK_WBITS;\n\tif (w == 0)\n\t\tgoto leave;\n\n\t/* Wait for current write phase to complete. */\n\twhile ((ck_pr_load_32(&pf->rin) & CK_PFLOCK_WBITS) == w)\n\t\tck_pr_stall();\n\nleave:\n\t/* Acquire semantics with respect to readers. */\n\tck_pr_fence_lock();\n\treturn;\n}\n\n#endif /* CK_PFLOCK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_H\n#define CK_PR_H\n\n#include <ck_cc.h>\n#include <ck_limits.h>\n#include <ck_md.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_USE_CC_BUILTINS\n#if defined(__x86_64__)\n#include \"gcc/x86_64/ck_pr.h\"\n#elif defined(__x86__)\n#include \"gcc/x86/ck_pr.h\"\n#elif defined(__sparcv9__)\n#include \"gcc/sparcv9/ck_pr.h\"\n#elif defined(__ppc64__)\n#include \"gcc/ppc64/ck_pr.h\"\n#elif defined(__s390x__)\n#include \"gcc/s390x/ck_pr.h\"\n#elif defined(__ppc__)\n#include \"gcc/ppc/ck_pr.h\"\n#elif defined(__arm__)\n#include \"gcc/arm/ck_pr.h\"\n#elif defined(__aarch64__)\n#include \"gcc/aarch64/ck_pr.h\"\n#elif !defined(__GNUC__)\n#error Your platform is unsupported\n#endif\n#endif /* !CK_USE_CC_BUILTINS */\n\n#if defined(__GNUC__)\n#include \"gcc/ck_pr.h\"\n#endif\n\n#define CK_PR_FENCE_EMIT(T)\t\t\t\\\n\tCK_CC_INLINE static void\t\t\\\n\tck_pr_fence_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\\\n\t\tck_pr_fence_strict_##T();\t\\\n\t\treturn;\t\t\t\t\\\n\t}\n#define CK_PR_FENCE_NOOP(T)\t\t\t\\\n\tCK_CC_INLINE static void\t\t\\\n\tck_pr_fence_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\\\n\t\treturn;\t\t\t\t\\\n\t}\n\n/*\n * None of the currently supported platforms allow for data-dependent\n * load ordering.\n */\nCK_PR_FENCE_NOOP(load_depends)\n#define ck_pr_fence_strict_load_depends ck_pr_fence_load_depends\n\n/*\n * In memory models where atomic operations do not have serializing\n * effects, atomic read-modify-write operations are modeled as stores.\n */\n#if defined(CK_MD_RMO)\n/*\n * Only stores to the same location have a global\n * ordering.\n */\nCK_PR_FENCE_EMIT(atomic)\nCK_PR_FENCE_EMIT(atomic_load)\nCK_PR_FENCE_EMIT(atomic_store)\nCK_PR_FENCE_EMIT(store_atomic)\nCK_PR_FENCE_EMIT(load_atomic)\nCK_PR_FENCE_EMIT(load_store)\nCK_PR_FENCE_EMIT(store_load)\nCK_PR_FENCE_EMIT(load)\nCK_PR_FENCE_EMIT(store)\nCK_PR_FENCE_EMIT(memory)\nCK_PR_FENCE_EMIT(acquire)\nCK_PR_FENCE_EMIT(release)\nCK_PR_FENCE_EMIT(acqrel)\nCK_PR_FENCE_EMIT(lock)\nCK_PR_FENCE_EMIT(unlock)\n#elif defined(CK_MD_PSO)\n/*\n * Anything can be re-ordered with respect to stores.\n * Otherwise, loads are executed in-order.\n */\nCK_PR_FENCE_EMIT(atomic)\nCK_PR_FENCE_NOOP(atomic_load)\nCK_PR_FENCE_EMIT(atomic_store)\nCK_PR_FENCE_EMIT(store_atomic)\nCK_PR_FENCE_NOOP(load_atomic)\nCK_PR_FENCE_EMIT(load_store)\nCK_PR_FENCE_EMIT(store_load)\nCK_PR_FENCE_NOOP(load)\nCK_PR_FENCE_EMIT(store)\nCK_PR_FENCE_EMIT(memory)\nCK_PR_FENCE_EMIT(acquire)\nCK_PR_FENCE_EMIT(release)\nCK_PR_FENCE_EMIT(acqrel)\nCK_PR_FENCE_EMIT(lock)\nCK_PR_FENCE_EMIT(unlock)\n#elif defined(CK_MD_TSO)\n/*\n * Only loads are re-ordered and only with respect to\n * prior stores. Atomic operations are serializing.\n */\nCK_PR_FENCE_NOOP(atomic)\nCK_PR_FENCE_NOOP(atomic_load)\nCK_PR_FENCE_NOOP(atomic_store)\nCK_PR_FENCE_NOOP(store_atomic)\nCK_PR_FENCE_NOOP(load_atomic)\nCK_PR_FENCE_NOOP(load_store)\nCK_PR_FENCE_EMIT(store_load)\nCK_PR_FENCE_NOOP(load)\nCK_PR_FENCE_NOOP(store)\nCK_PR_FENCE_EMIT(memory)\nCK_PR_FENCE_NOOP(acquire)\nCK_PR_FENCE_NOOP(release)\nCK_PR_FENCE_NOOP(acqrel)\nCK_PR_FENCE_NOOP(lock)\nCK_PR_FENCE_NOOP(unlock)\n#else\n#error \"No memory model has been defined.\"\n#endif /* CK_MD_TSO */\n\n#undef CK_PR_FENCE_EMIT\n#undef CK_PR_FENCE_NOOP\n\n#ifndef CK_F_PR_RFO\n#define CK_F_PR_RFO\nCK_CC_INLINE static void\nck_pr_rfo(const void *m)\n{\n\n\t(void)m;\n\treturn;\n}\n#endif /* CK_F_PR_RFO */\n\n#define CK_PR_STORE_SAFE(DST, VAL, TYPE)\t\t\t\\\n    ck_pr_md_store_##TYPE(\t\t\t\t\t\\\n        ((void)sizeof(*(DST) = (VAL)), (DST)),\t\t\t\\\n        (VAL))\n\n#define ck_pr_store_ptr(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), ptr)\n#define ck_pr_store_char(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), char)\n#ifndef CK_PR_DISABLE_DOUBLE\n#define ck_pr_store_double(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), double)\n#endif\n#define ck_pr_store_uint(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), uint)\n#define ck_pr_store_int(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), int)\n#define ck_pr_store_32(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 32)\n#define ck_pr_store_16(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 16)\n#define ck_pr_store_8(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 8)\n\n#define ck_pr_store_ptr_unsafe(DST, VAL) ck_pr_md_store_ptr((DST), (VAL))\n\n#ifdef CK_F_PR_LOAD_64\n#define ck_pr_store_64(DST, VAL) CK_PR_STORE_SAFE((DST), (VAL), 64)\n#endif /* CK_F_PR_LOAD_64 */\n\n#define CK_PR_LOAD_PTR_SAFE(SRC) (CK_CC_TYPEOF(*(SRC), (void *)))ck_pr_md_load_ptr((SRC))\n#define ck_pr_load_ptr(SRC) CK_PR_LOAD_PTR_SAFE((SRC))\n\n#define CK_PR_LOAD_SAFE(SRC, TYPE) ck_pr_md_load_##TYPE((SRC))\n#define ck_pr_load_char(SRC) CK_PR_LOAD_SAFE((SRC), char)\n#ifndef CK_PR_DISABLE_DOUBLE\n#define ck_pr_load_double(SRC) CK_PR_LOAD_SAFE((SRC), double)\n#endif\n#define ck_pr_load_uint(SRC) CK_PR_LOAD_SAFE((SRC), uint)\n#define ck_pr_load_int(SRC) CK_PR_LOAD_SAFE((SRC), int)\n#define ck_pr_load_32(SRC) CK_PR_LOAD_SAFE((SRC), 32)\n#define ck_pr_load_16(SRC) CK_PR_LOAD_SAFE((SRC), 16)\n#define ck_pr_load_8(SRC) CK_PR_LOAD_SAFE((SRC), 8)\n\n#ifdef CK_F_PR_LOAD_64\n#define ck_pr_load_64(SRC) CK_PR_LOAD_SAFE((SRC), 64)\n#endif /* CK_F_PR_LOAD_64 */\n\n#define CK_PR_BIN(K, S, M, T, P, C)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S(M *target, T value)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\tC punt;\t\t\t\t\t\t\t\\\n\t\tpunt = ck_pr_md_load_##S(target);\t\t\t\\\n\t\tprevious = (T)punt;\t\t\t\t\t\\\n\t\twhile (ck_pr_cas_##S##_value(target,\t\t\t\\\n\t\t\t\t\t     (C)previous,\t\t\\\n\t\t\t\t\t     (C)(previous P value),\t\\\n\t\t\t\t\t     &previous) == false)\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BIN_S(K, S, T, P) CK_PR_BIN(K, S, T, T, P, T)\n\n#if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)\n\n#ifndef CK_F_PR_ADD_CHAR\n#define CK_F_PR_ADD_CHAR\nCK_PR_BIN_S(add, char, char, +)\n#endif /* CK_F_PR_ADD_CHAR */\n\n#ifndef CK_F_PR_SUB_CHAR\n#define CK_F_PR_SUB_CHAR\nCK_PR_BIN_S(sub, char, char, -)\n#endif /* CK_F_PR_SUB_CHAR */\n\n#ifndef CK_F_PR_AND_CHAR\n#define CK_F_PR_AND_CHAR\nCK_PR_BIN_S(and, char, char, &)\n#endif /* CK_F_PR_AND_CHAR */\n\n#ifndef CK_F_PR_XOR_CHAR\n#define CK_F_PR_XOR_CHAR\nCK_PR_BIN_S(xor, char, char, ^)\n#endif /* CK_F_PR_XOR_CHAR */\n\n#ifndef CK_F_PR_OR_CHAR\n#define CK_F_PR_OR_CHAR\nCK_PR_BIN_S(or, char, char, |)\n#endif /* CK_F_PR_OR_CHAR */\n\n#endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */\n\n#if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)\n\n#ifndef CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_INT\nCK_PR_BIN_S(add, int, int, +)\n#endif /* CK_F_PR_ADD_INT */\n\n#ifndef CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_INT\nCK_PR_BIN_S(sub, int, int, -)\n#endif /* CK_F_PR_SUB_INT */\n\n#ifndef CK_F_PR_AND_INT\n#define CK_F_PR_AND_INT\nCK_PR_BIN_S(and, int, int, &)\n#endif /* CK_F_PR_AND_INT */\n\n#ifndef CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_INT\nCK_PR_BIN_S(xor, int, int, ^)\n#endif /* CK_F_PR_XOR_INT */\n\n#ifndef CK_F_PR_OR_INT\n#define CK_F_PR_OR_INT\nCK_PR_BIN_S(or, int, int, |)\n#endif /* CK_F_PR_OR_INT */\n\n#endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */\n\n#if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \\\n\t    !defined(CK_PR_DISABLE_DOUBLE)\n\n#ifndef CK_F_PR_ADD_DOUBLE\n#define CK_F_PR_ADD_DOUBLE\nCK_PR_BIN_S(add, double, double, +)\n#endif /* CK_F_PR_ADD_DOUBLE */\n\n#ifndef CK_F_PR_SUB_DOUBLE\n#define CK_F_PR_SUB_DOUBLE\nCK_PR_BIN_S(sub, double, double, -)\n#endif /* CK_F_PR_SUB_DOUBLE */\n\n#endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */\n\n#if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)\n\n#ifndef CK_F_PR_ADD_UINT\n#define CK_F_PR_ADD_UINT\nCK_PR_BIN_S(add, uint, unsigned int, +)\n#endif /* CK_F_PR_ADD_UINT */\n\n#ifndef CK_F_PR_SUB_UINT\n#define CK_F_PR_SUB_UINT\nCK_PR_BIN_S(sub, uint, unsigned int, -)\n#endif /* CK_F_PR_SUB_UINT */\n\n#ifndef CK_F_PR_AND_UINT\n#define CK_F_PR_AND_UINT\nCK_PR_BIN_S(and, uint, unsigned int, &)\n#endif /* CK_F_PR_AND_UINT */\n\n#ifndef CK_F_PR_XOR_UINT\n#define CK_F_PR_XOR_UINT\nCK_PR_BIN_S(xor, uint, unsigned int, ^)\n#endif /* CK_F_PR_XOR_UINT */\n\n#ifndef CK_F_PR_OR_UINT\n#define CK_F_PR_OR_UINT\nCK_PR_BIN_S(or, uint, unsigned int, |)\n#endif /* CK_F_PR_OR_UINT */\n\n#endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */\n\n#if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)\n\n#ifndef CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_PTR\nCK_PR_BIN(add, ptr, void, uintptr_t, +, void *)\n#endif /* CK_F_PR_ADD_PTR */\n\n#ifndef CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_PTR\nCK_PR_BIN(sub, ptr, void, uintptr_t, -, void *)\n#endif /* CK_F_PR_SUB_PTR */\n\n#ifndef CK_F_PR_AND_PTR\n#define CK_F_PR_AND_PTR\nCK_PR_BIN(and, ptr, void, uintptr_t, &, void *)\n#endif /* CK_F_PR_AND_PTR */\n\n#ifndef CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_PTR\nCK_PR_BIN(xor, ptr, void, uintptr_t, ^, void *)\n#endif /* CK_F_PR_XOR_PTR */\n\n#ifndef CK_F_PR_OR_PTR\n#define CK_F_PR_OR_PTR\nCK_PR_BIN(or, ptr, void, uintptr_t, |, void *)\n#endif /* CK_F_PR_OR_PTR */\n\n#endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */\n\n#if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)\n\n#ifndef CK_F_PR_ADD_64\n#define CK_F_PR_ADD_64\nCK_PR_BIN_S(add, 64, uint64_t, +)\n#endif /* CK_F_PR_ADD_64 */\n\n#ifndef CK_F_PR_SUB_64\n#define CK_F_PR_SUB_64\nCK_PR_BIN_S(sub, 64, uint64_t, -)\n#endif /* CK_F_PR_SUB_64 */\n\n#ifndef CK_F_PR_AND_64\n#define CK_F_PR_AND_64\nCK_PR_BIN_S(and, 64, uint64_t, &)\n#endif /* CK_F_PR_AND_64 */\n\n#ifndef CK_F_PR_XOR_64\n#define CK_F_PR_XOR_64\nCK_PR_BIN_S(xor, 64, uint64_t, ^)\n#endif /* CK_F_PR_XOR_64 */\n\n#ifndef CK_F_PR_OR_64\n#define CK_F_PR_OR_64\nCK_PR_BIN_S(or, 64, uint64_t, |)\n#endif /* CK_F_PR_OR_64 */\n\n#endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */\n\n#if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)\n\n#ifndef CK_F_PR_ADD_32\n#define CK_F_PR_ADD_32\nCK_PR_BIN_S(add, 32, uint32_t, +)\n#endif /* CK_F_PR_ADD_32 */\n\n#ifndef CK_F_PR_SUB_32\n#define CK_F_PR_SUB_32\nCK_PR_BIN_S(sub, 32, uint32_t, -)\n#endif /* CK_F_PR_SUB_32 */\n\n#ifndef CK_F_PR_AND_32\n#define CK_F_PR_AND_32\nCK_PR_BIN_S(and, 32, uint32_t, &)\n#endif /* CK_F_PR_AND_32 */\n\n#ifndef CK_F_PR_XOR_32\n#define CK_F_PR_XOR_32\nCK_PR_BIN_S(xor, 32, uint32_t, ^)\n#endif /* CK_F_PR_XOR_32 */\n\n#ifndef CK_F_PR_OR_32\n#define CK_F_PR_OR_32\nCK_PR_BIN_S(or, 32, uint32_t, |)\n#endif /* CK_F_PR_OR_32 */\n\n#endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */\n\n#if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)\n\n#ifndef CK_F_PR_ADD_16\n#define CK_F_PR_ADD_16\nCK_PR_BIN_S(add, 16, uint16_t, +)\n#endif /* CK_F_PR_ADD_16 */\n\n#ifndef CK_F_PR_SUB_16\n#define CK_F_PR_SUB_16\nCK_PR_BIN_S(sub, 16, uint16_t, -)\n#endif /* CK_F_PR_SUB_16 */\n\n#ifndef CK_F_PR_AND_16\n#define CK_F_PR_AND_16\nCK_PR_BIN_S(and, 16, uint16_t, &)\n#endif /* CK_F_PR_AND_16 */\n\n#ifndef CK_F_PR_XOR_16\n#define CK_F_PR_XOR_16\nCK_PR_BIN_S(xor, 16, uint16_t, ^)\n#endif /* CK_F_PR_XOR_16 */\n\n#ifndef CK_F_PR_OR_16\n#define CK_F_PR_OR_16\nCK_PR_BIN_S(or, 16, uint16_t, |)\n#endif /* CK_F_PR_OR_16 */\n\n#endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)\n\n#ifndef CK_F_PR_ADD_8\n#define CK_F_PR_ADD_8\nCK_PR_BIN_S(add, 8, uint8_t, +)\n#endif /* CK_F_PR_ADD_8 */\n\n#ifndef CK_F_PR_SUB_8\n#define CK_F_PR_SUB_8\nCK_PR_BIN_S(sub, 8, uint8_t, -)\n#endif /* CK_F_PR_SUB_8 */\n\n#ifndef CK_F_PR_AND_8\n#define CK_F_PR_AND_8\nCK_PR_BIN_S(and, 8, uint8_t, &)\n#endif /* CK_F_PR_AND_8 */\n\n#ifndef CK_F_PR_XOR_8\n#define CK_F_PR_XOR_8\nCK_PR_BIN_S(xor, 8, uint8_t, ^)\n#endif /* CK_F_PR_XOR_8 */\n\n#ifndef CK_F_PR_OR_8\n#define CK_F_PR_OR_8\nCK_PR_BIN_S(or, 8, uint8_t, |)\n#endif /* CK_F_PR_OR_8 */\n\n#endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */\n\n#undef CK_PR_BIN_S\n#undef CK_PR_BIN\n\n#define CK_PR_BTX(K, S, M, T, P, C, R)\t\t\t\t\t\t   \\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t   \\\n\tck_pr_##K##_##S(M *target, unsigned int offset)\t\t\t\t   \\\n\t{\t\t\t\t\t\t\t\t\t   \\\n\t\tT previous;\t\t\t\t\t\t\t   \\\n\t\tC punt;\t\t\t\t\t\t\t\t   \\\n\t\tpunt = ck_pr_md_load_##S(target);\t\t\t\t   \\\n\t\tprevious = (T)punt;\t\t\t\t\t\t   \\\n\t\twhile (ck_pr_cas_##S##_value(target, (C)previous,\t\t   \\\n\t\t\t(C)(previous P (R ((T)1 << offset))), &previous) == false) \\\n\t\t\t\tck_pr_stall();\t\t\t\t\t   \\\n\t\treturn ((previous >> offset) & 1);\t\t\t\t   \\\n\t}\n\n#define CK_PR_BTX_S(K, S, T, P, R) CK_PR_BTX(K, S, T, T, P, T, R)\n\n#if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)\n\n#ifndef CK_F_PR_BTC_INT\n#define CK_F_PR_BTC_INT\nCK_PR_BTX_S(btc, int, int, ^,)\n#endif /* CK_F_PR_BTC_INT */\n\n#ifndef CK_F_PR_BTR_INT\n#define CK_F_PR_BTR_INT\nCK_PR_BTX_S(btr, int, int, &, ~)\n#endif /* CK_F_PR_BTR_INT */\n\n#ifndef CK_F_PR_BTS_INT\n#define CK_F_PR_BTS_INT\nCK_PR_BTX_S(bts, int, int, |,)\n#endif /* CK_F_PR_BTS_INT */\n\n#endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */\n\n#if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)\n\n#ifndef CK_F_PR_BTC_UINT\n#define CK_F_PR_BTC_UINT\nCK_PR_BTX_S(btc, uint, unsigned int, ^,)\n#endif /* CK_F_PR_BTC_UINT */\n\n#ifndef CK_F_PR_BTR_UINT\n#define CK_F_PR_BTR_UINT\nCK_PR_BTX_S(btr, uint, unsigned int, &, ~)\n#endif /* CK_F_PR_BTR_UINT */\n\n#ifndef CK_F_PR_BTS_UINT\n#define CK_F_PR_BTS_UINT\nCK_PR_BTX_S(bts, uint, unsigned int, |,)\n#endif /* CK_F_PR_BTS_UINT */\n\n#endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */\n\n#if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)\n\n#ifndef CK_F_PR_BTC_PTR\n#define CK_F_PR_BTC_PTR\nCK_PR_BTX(btc, ptr, void, uintptr_t, ^, void *,)\n#endif /* CK_F_PR_BTC_PTR */\n\n#ifndef CK_F_PR_BTR_PTR\n#define CK_F_PR_BTR_PTR\nCK_PR_BTX(btr, ptr, void, uintptr_t, &, void *, ~)\n#endif /* CK_F_PR_BTR_PTR */\n\n#ifndef CK_F_PR_BTS_PTR\n#define CK_F_PR_BTS_PTR\nCK_PR_BTX(bts, ptr, void, uintptr_t, |, void *,)\n#endif /* CK_F_PR_BTS_PTR */\n\n#endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */\n\n#if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)\n\n#ifndef CK_F_PR_BTC_64\n#define CK_F_PR_BTC_64\nCK_PR_BTX_S(btc, 64, uint64_t, ^,)\n#endif /* CK_F_PR_BTC_64 */\n\n#ifndef CK_F_PR_BTR_64\n#define CK_F_PR_BTR_64\nCK_PR_BTX_S(btr, 64, uint64_t, &, ~)\n#endif /* CK_F_PR_BTR_64 */\n\n#ifndef CK_F_PR_BTS_64\n#define CK_F_PR_BTS_64\nCK_PR_BTX_S(bts, 64, uint64_t, |,)\n#endif /* CK_F_PR_BTS_64 */\n\n#endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */\n\n#if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)\n\n#ifndef CK_F_PR_BTC_32\n#define CK_F_PR_BTC_32\nCK_PR_BTX_S(btc, 32, uint32_t, ^,)\n#endif /* CK_F_PR_BTC_32 */\n\n#ifndef CK_F_PR_BTR_32\n#define CK_F_PR_BTR_32\nCK_PR_BTX_S(btr, 32, uint32_t, &, ~)\n#endif /* CK_F_PR_BTR_32 */\n\n#ifndef CK_F_PR_BTS_32\n#define CK_F_PR_BTS_32\nCK_PR_BTX_S(bts, 32, uint32_t, |,)\n#endif /* CK_F_PR_BTS_32 */\n\n#endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */\n\n#if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)\n\n#ifndef CK_F_PR_BTC_16\n#define CK_F_PR_BTC_16\nCK_PR_BTX_S(btc, 16, uint16_t, ^,)\n#endif /* CK_F_PR_BTC_16 */\n\n#ifndef CK_F_PR_BTR_16\n#define CK_F_PR_BTR_16\nCK_PR_BTX_S(btr, 16, uint16_t, &, ~)\n#endif /* CK_F_PR_BTR_16 */\n\n#ifndef CK_F_PR_BTS_16\n#define CK_F_PR_BTS_16\nCK_PR_BTX_S(bts, 16, uint16_t, |,)\n#endif /* CK_F_PR_BTS_16 */\n\n#endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */\n\n#undef CK_PR_BTX_S\n#undef CK_PR_BTX\n\n#define CK_PR_UNARY(K, X, S, M, T)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S(M *target)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tck_pr_##X##_##S(target, (T)1);\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_UNARY_Z(K, S, M, T, P, C, Z)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S##_zero(M *target, bool *zero)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\tC punt;\t\t\t\t\t\t\t\\\n\t\tpunt = (C)ck_pr_md_load_##S(target);\t\t\t\\\n\t\tprevious = (T)punt;\t\t\t\t\t\\\n\t\twhile (ck_pr_cas_##S##_value(target,\t\t\t\\\n\t\t\t\t\t     (C)previous,\t\t\\\n\t\t\t\t\t     (C)(previous P 1),\t\t\\\n\t\t\t\t\t     &previous) == false)\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t*zero = previous == (T)Z;\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_UNARY_S(K, X, S, M) CK_PR_UNARY(K, X, S, M, M)\n#define CK_PR_UNARY_Z_S(K, S, M, P, Z) CK_PR_UNARY_Z(K, S, M, M, P, M, Z)\n\n#if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)\n\n#ifndef CK_F_PR_INC_CHAR\n#define CK_F_PR_INC_CHAR\nCK_PR_UNARY_S(inc, add, char, char)\n#endif /* CK_F_PR_INC_CHAR */\n\n#ifndef CK_F_PR_INC_CHAR_ZERO\n#define CK_F_PR_INC_CHAR_ZERO\nCK_PR_UNARY_Z_S(inc, char, char, +, -1)\n#endif /* CK_F_PR_INC_CHAR_ZERO */\n\n#ifndef CK_F_PR_DEC_CHAR\n#define CK_F_PR_DEC_CHAR\nCK_PR_UNARY_S(dec, sub, char, char)\n#endif /* CK_F_PR_DEC_CHAR */\n\n#ifndef CK_F_PR_DEC_CHAR_ZERO\n#define CK_F_PR_DEC_CHAR_ZERO\nCK_PR_UNARY_Z_S(dec, char, char, -, 1)\n#endif /* CK_F_PR_DEC_CHAR_ZERO */\n\n#endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */\n\n#if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)\n\n#ifndef CK_F_PR_INC_INT\n#define CK_F_PR_INC_INT\nCK_PR_UNARY_S(inc, add, int, int)\n#endif /* CK_F_PR_INC_INT */\n\n#ifndef CK_F_PR_INC_INT_ZERO\n#define CK_F_PR_INC_INT_ZERO\nCK_PR_UNARY_Z_S(inc, int, int, +, -1)\n#endif /* CK_F_PR_INC_INT_ZERO */\n\n#ifndef CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_INT\nCK_PR_UNARY_S(dec, sub, int, int)\n#endif /* CK_F_PR_DEC_INT */\n\n#ifndef CK_F_PR_DEC_INT_ZERO\n#define CK_F_PR_DEC_INT_ZERO\nCK_PR_UNARY_Z_S(dec, int, int, -, 1)\n#endif /* CK_F_PR_DEC_INT_ZERO */\n\n#endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */\n\n#if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \\\n\t    !defined(CK_PR_DISABLE_DOUBLE)\n\n#ifndef CK_F_PR_INC_DOUBLE\n#define CK_F_PR_INC_DOUBLE\nCK_PR_UNARY_S(inc, add, double, double)\n#endif /* CK_F_PR_INC_DOUBLE */\n\n#ifndef CK_F_PR_DEC_DOUBLE\n#define CK_F_PR_DEC_DOUBLE\nCK_PR_UNARY_S(dec, sub, double, double)\n#endif /* CK_F_PR_DEC_DOUBLE */\n\n#endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */\n\n#if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)\n\n#ifndef CK_F_PR_INC_UINT\n#define CK_F_PR_INC_UINT\nCK_PR_UNARY_S(inc, add, uint, unsigned int)\n#endif /* CK_F_PR_INC_UINT */\n\n#ifndef CK_F_PR_INC_UINT_ZERO\n#define CK_F_PR_INC_UINT_ZERO\nCK_PR_UNARY_Z_S(inc, uint, unsigned int, +, UINT_MAX)\n#endif /* CK_F_PR_INC_UINT_ZERO */\n\n#ifndef CK_F_PR_DEC_UINT\n#define CK_F_PR_DEC_UINT\nCK_PR_UNARY_S(dec, sub, uint, unsigned int)\n#endif /* CK_F_PR_DEC_UINT */\n\n#ifndef CK_F_PR_DEC_UINT_ZERO\n#define CK_F_PR_DEC_UINT_ZERO\nCK_PR_UNARY_Z_S(dec, uint, unsigned int, -, 1)\n#endif /* CK_F_PR_DEC_UINT_ZERO */\n\n#endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */\n\n#if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)\n\n#ifndef CK_F_PR_INC_PTR\n#define CK_F_PR_INC_PTR\nCK_PR_UNARY(inc, add, ptr, void, uintptr_t)\n#endif /* CK_F_PR_INC_PTR */\n\n#ifndef CK_F_PR_INC_PTR_ZERO\n#define CK_F_PR_INC_PTR_ZERO\nCK_PR_UNARY_Z(inc, ptr, void, uintptr_t, +, void *, UINT_MAX)\n#endif /* CK_F_PR_INC_PTR_ZERO */\n\n#ifndef CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_PTR\nCK_PR_UNARY(dec, sub, ptr, void, uintptr_t)\n#endif /* CK_F_PR_DEC_PTR */\n\n#ifndef CK_F_PR_DEC_PTR_ZERO\n#define CK_F_PR_DEC_PTR_ZERO\nCK_PR_UNARY_Z(dec, ptr, void, uintptr_t, -, void *, 1)\n#endif /* CK_F_PR_DEC_PTR_ZERO */\n\n#endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */\n\n#if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)\n\n#ifndef CK_F_PR_INC_64\n#define CK_F_PR_INC_64\nCK_PR_UNARY_S(inc, add, 64, uint64_t)\n#endif /* CK_F_PR_INC_64 */\n\n#ifndef CK_F_PR_INC_64_ZERO\n#define CK_F_PR_INC_64_ZERO\nCK_PR_UNARY_Z_S(inc, 64, uint64_t, +, UINT64_MAX)\n#endif /* CK_F_PR_INC_64_ZERO */\n\n#ifndef CK_F_PR_DEC_64\n#define CK_F_PR_DEC_64\nCK_PR_UNARY_S(dec, sub, 64, uint64_t)\n#endif /* CK_F_PR_DEC_64 */\n\n#ifndef CK_F_PR_DEC_64_ZERO\n#define CK_F_PR_DEC_64_ZERO\nCK_PR_UNARY_Z_S(dec, 64, uint64_t, -, 1)\n#endif /* CK_F_PR_DEC_64_ZERO */\n\n#endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */\n\n#if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)\n\n#ifndef CK_F_PR_INC_32\n#define CK_F_PR_INC_32\nCK_PR_UNARY_S(inc, add, 32, uint32_t)\n#endif /* CK_F_PR_INC_32 */\n\n#ifndef CK_F_PR_INC_32_ZERO\n#define CK_F_PR_INC_32_ZERO\nCK_PR_UNARY_Z_S(inc, 32, uint32_t, +, UINT32_MAX)\n#endif /* CK_F_PR_INC_32_ZERO */\n\n#ifndef CK_F_PR_DEC_32\n#define CK_F_PR_DEC_32\nCK_PR_UNARY_S(dec, sub, 32, uint32_t)\n#endif /* CK_F_PR_DEC_32 */\n\n#ifndef CK_F_PR_DEC_32_ZERO\n#define CK_F_PR_DEC_32_ZERO\nCK_PR_UNARY_Z_S(dec, 32, uint32_t, -, 1)\n#endif /* CK_F_PR_DEC_32_ZERO */\n\n#endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */\n\n#if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)\n\n#ifndef CK_F_PR_INC_16\n#define CK_F_PR_INC_16\nCK_PR_UNARY_S(inc, add, 16, uint16_t)\n#endif /* CK_F_PR_INC_16 */\n\n#ifndef CK_F_PR_INC_16_ZERO\n#define CK_F_PR_INC_16_ZERO\nCK_PR_UNARY_Z_S(inc, 16, uint16_t, +, UINT16_MAX)\n#endif /* CK_F_PR_INC_16_ZERO */\n\n#ifndef CK_F_PR_DEC_16\n#define CK_F_PR_DEC_16\nCK_PR_UNARY_S(dec, sub, 16, uint16_t)\n#endif /* CK_F_PR_DEC_16 */\n\n#ifndef CK_F_PR_DEC_16_ZERO\n#define CK_F_PR_DEC_16_ZERO\nCK_PR_UNARY_Z_S(dec, 16, uint16_t, -, 1)\n#endif /* CK_F_PR_DEC_16_ZERO */\n\n#endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)\n\n#ifndef CK_F_PR_INC_8\n#define CK_F_PR_INC_8\nCK_PR_UNARY_S(inc, add, 8, uint8_t)\n#endif /* CK_F_PR_INC_8 */\n\n#ifndef CK_F_PR_INC_8_ZERO\n#define CK_F_PR_INC_8_ZERO\nCK_PR_UNARY_Z_S(inc, 8, uint8_t, +, UINT8_MAX)\n#endif /* CK_F_PR_INC_8_ZERO */\n\n#ifndef CK_F_PR_DEC_8\n#define CK_F_PR_DEC_8\nCK_PR_UNARY_S(dec, sub, 8, uint8_t)\n#endif /* CK_F_PR_DEC_8 */\n\n#ifndef CK_F_PR_DEC_8_ZERO\n#define CK_F_PR_DEC_8_ZERO\nCK_PR_UNARY_Z_S(dec, 8, uint8_t, -, 1)\n#endif /* CK_F_PR_DEC_8_ZERO */\n\n#endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */\n\n#undef CK_PR_UNARY_Z_S\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY_Z\n#undef CK_PR_UNARY\n\n#define CK_PR_N(K, S, M, T, P, C)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S(M *target)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\tC punt;\t\t\t\t\t\t\t\\\n\t\tpunt = (C)ck_pr_md_load_##S(target);\t\t\t\\\n\t\tprevious = (T)punt;\t\t\t\t\t\\\n\t\twhile (ck_pr_cas_##S##_value(target,\t\t\t\\\n\t\t\t\t\t     (C)previous,\t\t\\\n\t\t\t\t\t     (C)(P previous),\t\t\\\n\t\t\t\t\t     &previous) == false)\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_N_Z(S, M, T, C)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_neg_##S##_zero(M *target, bool *zero)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\tC punt;\t\t\t\t\t\t\t\\\n\t\tpunt = (C)ck_pr_md_load_##S(target);\t\t\t\\\n\t\tprevious = (T)punt;\t\t\t\t\t\\\n\t\twhile (ck_pr_cas_##S##_value(target,\t\t\t\\\n\t\t\t\t\t     (C)previous,\t\t\\\n\t\t\t\t\t     (C)(-previous),\t\t\\\n\t\t\t\t\t     &previous) == false)\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t*zero = previous == 0;\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_N_S(K, S, M, P)\tCK_PR_N(K, S, M, M, P, M)\n#define CK_PR_N_Z_S(S, M) \tCK_PR_N_Z(S, M, M, M)\n\n#if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)\n\n#ifndef CK_F_PR_NOT_CHAR\n#define CK_F_PR_NOT_CHAR\nCK_PR_N_S(not, char, char, ~)\n#endif /* CK_F_PR_NOT_CHAR */\n\n#ifndef CK_F_PR_NEG_CHAR\n#define CK_F_PR_NEG_CHAR\nCK_PR_N_S(neg, char, char, -)\n#endif /* CK_F_PR_NEG_CHAR */\n\n#ifndef CK_F_PR_NEG_CHAR_ZERO\n#define CK_F_PR_NEG_CHAR_ZERO\nCK_PR_N_Z_S(char, char)\n#endif /* CK_F_PR_NEG_CHAR_ZERO */\n\n#endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */\n\n#if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)\n\n#ifndef CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_INT\nCK_PR_N_S(not, int, int, ~)\n#endif /* CK_F_PR_NOT_INT */\n\n#ifndef CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_INT\nCK_PR_N_S(neg, int, int, -)\n#endif /* CK_F_PR_NEG_INT */\n\n#ifndef CK_F_PR_NEG_INT_ZERO\n#define CK_F_PR_NEG_INT_ZERO\nCK_PR_N_Z_S(int, int)\n#endif /* CK_F_PR_NEG_INT_ZERO */\n\n#endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */\n\n#if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \\\n\t    !defined(CK_PR_DISABLE_DOUBLE)\n\n#ifndef CK_F_PR_NEG_DOUBLE\n#define CK_F_PR_NEG_DOUBLE\nCK_PR_N_S(neg, double, double, -)\n#endif /* CK_F_PR_NEG_DOUBLE */\n\n#endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */\n\n#if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)\n\n#ifndef CK_F_PR_NOT_UINT\n#define CK_F_PR_NOT_UINT\nCK_PR_N_S(not, uint, unsigned int, ~)\n#endif /* CK_F_PR_NOT_UINT */\n\n#ifndef CK_F_PR_NEG_UINT\n#define CK_F_PR_NEG_UINT\nCK_PR_N_S(neg, uint, unsigned int, -)\n#endif /* CK_F_PR_NEG_UINT */\n\n#ifndef CK_F_PR_NEG_UINT_ZERO\n#define CK_F_PR_NEG_UINT_ZERO\nCK_PR_N_Z_S(uint, unsigned int)\n#endif /* CK_F_PR_NEG_UINT_ZERO */\n\n#endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */\n\n#if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)\n\n#ifndef CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_PTR\nCK_PR_N(not, ptr, void, uintptr_t, ~, void *)\n#endif /* CK_F_PR_NOT_PTR */\n\n#ifndef CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_PTR\nCK_PR_N(neg, ptr, void, uintptr_t, -, void *)\n#endif /* CK_F_PR_NEG_PTR */\n\n#ifndef CK_F_PR_NEG_PTR_ZERO\n#define CK_F_PR_NEG_PTR_ZERO\nCK_PR_N_Z(ptr, void, uintptr_t, void *)\n#endif /* CK_F_PR_NEG_PTR_ZERO */\n\n#endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */\n\n#if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)\n\n#ifndef CK_F_PR_NOT_64\n#define CK_F_PR_NOT_64\nCK_PR_N_S(not, 64, uint64_t, ~)\n#endif /* CK_F_PR_NOT_64 */\n\n#ifndef CK_F_PR_NEG_64\n#define CK_F_PR_NEG_64\nCK_PR_N_S(neg, 64, uint64_t, -)\n#endif /* CK_F_PR_NEG_64 */\n\n#ifndef CK_F_PR_NEG_64_ZERO\n#define CK_F_PR_NEG_64_ZERO\nCK_PR_N_Z_S(64, uint64_t)\n#endif /* CK_F_PR_NEG_64_ZERO */\n\n#endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */\n\n#if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)\n\n#ifndef CK_F_PR_NOT_32\n#define CK_F_PR_NOT_32\nCK_PR_N_S(not, 32, uint32_t, ~)\n#endif /* CK_F_PR_NOT_32 */\n\n#ifndef CK_F_PR_NEG_32\n#define CK_F_PR_NEG_32\nCK_PR_N_S(neg, 32, uint32_t, -)\n#endif /* CK_F_PR_NEG_32 */\n\n#ifndef CK_F_PR_NEG_32_ZERO\n#define CK_F_PR_NEG_32_ZERO\nCK_PR_N_Z_S(32, uint32_t)\n#endif /* CK_F_PR_NEG_32_ZERO */\n\n#endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */\n\n#if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)\n\n#ifndef CK_F_PR_NOT_16\n#define CK_F_PR_NOT_16\nCK_PR_N_S(not, 16, uint16_t, ~)\n#endif /* CK_F_PR_NOT_16 */\n\n#ifndef CK_F_PR_NEG_16\n#define CK_F_PR_NEG_16\nCK_PR_N_S(neg, 16, uint16_t, -)\n#endif /* CK_F_PR_NEG_16 */\n\n#ifndef CK_F_PR_NEG_16_ZERO\n#define CK_F_PR_NEG_16_ZERO\nCK_PR_N_Z_S(16, uint16_t)\n#endif /* CK_F_PR_NEG_16_ZERO */\n\n#endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)\n\n#ifndef CK_F_PR_NOT_8\n#define CK_F_PR_NOT_8\nCK_PR_N_S(not, 8, uint8_t, ~)\n#endif /* CK_F_PR_NOT_8 */\n\n#ifndef CK_F_PR_NEG_8\n#define CK_F_PR_NEG_8\nCK_PR_N_S(neg, 8, uint8_t, -)\n#endif /* CK_F_PR_NEG_8 */\n\n#ifndef CK_F_PR_NEG_8_ZERO\n#define CK_F_PR_NEG_8_ZERO\nCK_PR_N_Z_S(8, uint8_t)\n#endif /* CK_F_PR_NEG_8_ZERO */\n\n#endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */\n\n#undef CK_PR_N_Z_S\n#undef CK_PR_N_S\n#undef CK_PR_N_Z\n#undef CK_PR_N\n\n#define CK_PR_FAA(S, M, T, C)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static C\t\t\t\t\t\t\\\n\tck_pr_faa_##S(M *target, T delta)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\tC punt;\t\t\t\t\t\t\t\\\n\t\tpunt = (C)ck_pr_md_load_##S(target);\t\t\t\\\n\t\tprevious = (T)punt;\t\t\t\t\t\\\n\t\twhile (ck_pr_cas_##S##_value(target,\t\t\t\\\n\t\t\t\t\t     (C)previous,\t\t\\\n\t\t\t\t\t     (C)(previous + delta),\t\\\n\t\t\t\t\t     &previous) == false)\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn ((C)previous);\t\t\t\t\t\\\n\t}\n\n#define CK_PR_FAS(S, M, C)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static C\t\t\t\t\t\t\\\n\tck_pr_fas_##S(M *target, C update)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tC previous;\t\t\t\t\t\t\\\n\t\tprevious = ck_pr_md_load_##S(target);\t\t\t\\\n\t\twhile (ck_pr_cas_##S##_value(target,\t\t\t\\\n\t\t\t\t\t     previous,\t\t\t\\\n\t\t\t\t\t     update,\t\t\t\\\n\t\t\t\t\t     &previous) == false)\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn (previous);\t\t\t\t\t\\\n\t}\n\n#define CK_PR_FAA_S(S, M) CK_PR_FAA(S, M, M, M)\n#define CK_PR_FAS_S(S, M) CK_PR_FAS(S, M, M)\n\n#if defined(CK_F_PR_LOAD_CHAR) && defined(CK_F_PR_CAS_CHAR_VALUE)\n\n#ifndef CK_F_PR_FAA_CHAR\n#define CK_F_PR_FAA_CHAR\nCK_PR_FAA_S(char, char)\n#endif /* CK_F_PR_FAA_CHAR */\n\n#ifndef CK_F_PR_FAS_CHAR\n#define CK_F_PR_FAS_CHAR\nCK_PR_FAS_S(char, char)\n#endif /* CK_F_PR_FAS_CHAR */\n\n#endif /* CK_F_PR_LOAD_CHAR && CK_F_PR_CAS_CHAR_VALUE */\n\n#if defined(CK_F_PR_LOAD_INT) && defined(CK_F_PR_CAS_INT_VALUE)\n\n#ifndef CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_INT\nCK_PR_FAA_S(int, int)\n#endif /* CK_F_PR_FAA_INT */\n\n#ifndef CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_INT\nCK_PR_FAS_S(int, int)\n#endif /* CK_F_PR_FAS_INT */\n\n#endif /* CK_F_PR_LOAD_INT && CK_F_PR_CAS_INT_VALUE */\n\n#if defined(CK_F_PR_LOAD_DOUBLE) && defined(CK_F_PR_CAS_DOUBLE_VALUE) && \\\n\t    !defined(CK_PR_DISABLE_DOUBLE)\n\n#ifndef CK_F_PR_FAA_DOUBLE\n#define CK_F_PR_FAA_DOUBLE\nCK_PR_FAA_S(double, double)\n#endif /* CK_F_PR_FAA_DOUBLE */\n\n#ifndef CK_F_PR_FAS_DOUBLE\n#define CK_F_PR_FAS_DOUBLE\nCK_PR_FAS_S(double, double)\n#endif /* CK_F_PR_FAS_DOUBLE */\n\n#endif /* CK_F_PR_LOAD_DOUBLE && CK_F_PR_CAS_DOUBLE_VALUE && !CK_PR_DISABLE_DOUBLE */\n\n#if defined(CK_F_PR_LOAD_UINT) && defined(CK_F_PR_CAS_UINT_VALUE)\n\n#ifndef CK_F_PR_FAA_UINT\n#define CK_F_PR_FAA_UINT\nCK_PR_FAA_S(uint, unsigned int)\n#endif /* CK_F_PR_FAA_UINT */\n\n#ifndef CK_F_PR_FAS_UINT\n#define CK_F_PR_FAS_UINT\nCK_PR_FAS_S(uint, unsigned int)\n#endif /* CK_F_PR_FAS_UINT */\n\n#endif /* CK_F_PR_LOAD_UINT && CK_F_PR_CAS_UINT_VALUE */\n\n#if defined(CK_F_PR_LOAD_PTR) && defined(CK_F_PR_CAS_PTR_VALUE)\n\n#ifndef CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_PTR\nCK_PR_FAA(ptr, void, uintptr_t, void *)\n#endif /* CK_F_PR_FAA_PTR */\n\n#ifndef CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_PTR\nCK_PR_FAS(ptr, void, void *)\n#endif /* CK_F_PR_FAS_PTR */\n\n#endif /* CK_F_PR_LOAD_PTR && CK_F_PR_CAS_PTR_VALUE */\n\n#if defined(CK_F_PR_LOAD_64) && defined(CK_F_PR_CAS_64_VALUE)\n\n#ifndef CK_F_PR_FAA_64\n#define CK_F_PR_FAA_64\nCK_PR_FAA_S(64, uint64_t)\n#endif /* CK_F_PR_FAA_64 */\n\n#ifndef CK_F_PR_FAS_64\n#define CK_F_PR_FAS_64\nCK_PR_FAS_S(64, uint64_t)\n#endif /* CK_F_PR_FAS_64 */\n\n#endif /* CK_F_PR_LOAD_64 && CK_F_PR_CAS_64_VALUE */\n\n#if defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_CAS_32_VALUE)\n\n#ifndef CK_F_PR_FAA_32\n#define CK_F_PR_FAA_32\nCK_PR_FAA_S(32, uint32_t)\n#endif /* CK_F_PR_FAA_32 */\n\n#ifndef CK_F_PR_FAS_32\n#define CK_F_PR_FAS_32\nCK_PR_FAS_S(32, uint32_t)\n#endif /* CK_F_PR_FAS_32 */\n\n#endif /* CK_F_PR_LOAD_32 && CK_F_PR_CAS_32_VALUE */\n\n#if defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_CAS_16_VALUE)\n\n#ifndef CK_F_PR_FAA_16\n#define CK_F_PR_FAA_16\nCK_PR_FAA_S(16, uint16_t)\n#endif /* CK_F_PR_FAA_16 */\n\n#ifndef CK_F_PR_FAS_16\n#define CK_F_PR_FAS_16\nCK_PR_FAS_S(16, uint16_t)\n#endif /* CK_F_PR_FAS_16 */\n\n#endif /* CK_F_PR_LOAD_16 && CK_F_PR_CAS_16_VALUE */\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_CAS_8_VALUE)\n\n#ifndef CK_F_PR_FAA_8\n#define CK_F_PR_FAA_8\nCK_PR_FAA_S(8, uint8_t)\n#endif /* CK_F_PR_FAA_8 */\n\n#ifndef CK_F_PR_FAS_8\n#define CK_F_PR_FAS_8\nCK_PR_FAS_S(8, uint8_t)\n#endif /* CK_F_PR_FAS_8 */\n\n#endif /* CK_F_PR_LOAD_8 && CK_F_PR_CAS_8_VALUE */\n\n#undef CK_PR_FAA_S\n#undef CK_PR_FAS_S\n#undef CK_PR_FAA\n#undef CK_PR_FAS\n\n#endif /* CK_PR_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_queue.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*-\n * Copyright (c) 1991, 1993\n *\tThe Regents of the University of California.  All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 4. Neither the name of the University nor the names of its contributors\n *    may be used to endorse or promote products derived from this software\n *    without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n *\n *\t@(#)queue.h\t8.5 (Berkeley) 8/20/94\n * $FreeBSD: release/9.0.0/sys/sys/queue.h 221843 2011-05-13 15:49:23Z mdf $\n */\n\n#ifndef CK_QUEUE_H\n#define\tCK_QUEUE_H\n\n#include <ck_pr.h>\n\n/*\n * This file defines three types of data structures: singly-linked lists,\n * singly-linked tail queues and lists.\n *\n * A singly-linked list is headed by a single forward pointer. The elements\n * are singly linked for minimum space and pointer manipulation overhead at\n * the expense of O(n) removal for arbitrary elements. New elements can be\n * added to the list after an existing element or at the head of the list.\n * Elements being removed from the head of the list should use the explicit\n * macro for this purpose for optimum efficiency. A singly-linked list may\n * only be traversed in the forward direction.  Singly-linked lists are ideal\n * for applications with large datasets and few or no removals or for\n * implementing a LIFO queue.\n *\n * A singly-linked tail queue is headed by a pair of pointers, one to the\n * head of the list and the other to the tail of the list. The elements are\n * singly linked for minimum space and pointer manipulation overhead at the\n * expense of O(n) removal for arbitrary elements. New elements can be added\n * to the list after an existing element, at the head of the list, or at the\n * end of the list. Elements being removed from the head of the tail queue\n * should use the explicit macro for this purpose for optimum efficiency.\n * A singly-linked tail queue may only be traversed in the forward direction.\n * Singly-linked tail queues are ideal for applications with large datasets\n * and few or no removals or for implementing a FIFO queue.\n *\n * A list is headed by a single forward pointer (or an array of forward\n * pointers for a hash table header). The elements are doubly linked\n * so that an arbitrary element can be removed without a need to\n * traverse the list. New elements can be added to the list before\n * or after an existing element or at the head of the list. A list\n * may only be traversed in the forward direction.\n *\n * It is safe to use _FOREACH/_FOREACH_SAFE in the presence of concurrent\n * modifications to the list. Writers to these lists must, on the other hand,\n * implement writer-side synchronization. The _SWAP operations are not atomic.\n * This facility is currently unsupported on architectures such as the Alpha\n * which require load-depend memory fences.\n *\n *\t\t\t\tCK_SLIST\tCK_LIST\tCK_STAILQ\n * _HEAD\t\t\t+\t\t+\t+\n * _HEAD_INITIALIZER\t\t+\t\t+\t+\n * _ENTRY\t\t\t+\t\t+\t+\n * _INIT\t\t\t+\t\t+\t+\n * _EMPTY\t\t\t+\t\t+\t+\n * _FIRST\t\t\t+\t\t+\t+\n * _NEXT\t\t\t+\t\t+\t+\n * _FOREACH\t\t\t+\t\t+\t+\n * _FOREACH_SAFE\t\t+\t\t+\t+\n * _INSERT_HEAD\t\t\t+\t\t+\t+\n * _INSERT_BEFORE\t\t-\t\t+\t-\n * _INSERT_AFTER\t\t+\t\t+\t+\n * _INSERT_TAIL\t\t\t-\t\t-\t+\n * _REMOVE_AFTER\t\t+\t\t-\t+\n * _REMOVE_HEAD\t\t\t+\t\t-\t+\n * _REMOVE\t\t\t+\t\t+\t+\n * _SWAP\t\t\t+\t\t+\t+\n * _MOVE\t\t\t+\t\t+\t+\n */\n\n/*\n * Singly-linked List declarations.\n */\n#define\tCK_SLIST_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\t\\\n\tstruct type *slh_first;\t/* first element */\t\t\t\t\\\n}\n\n#define\tCK_SLIST_HEAD_INITIALIZER(head)\t\t\t\t\t\t\\\n\t{ NULL }\n\n#define\tCK_SLIST_ENTRY(type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\t\\\n\tstruct type *sle_next;\t/* next element */\t\t\t\t\\\n}\n\n/*\n * Singly-linked List functions.\n */\n#define\tCK_SLIST_EMPTY(head)\t\t\t\t\t\t\t\\\n\t(ck_pr_load_ptr(&(head)->slh_first) == NULL)\n\n#define\tCK_SLIST_FIRST(head)\t\t\t\t\t\t\t\\\n\t(ck_pr_load_ptr(&(head)->slh_first))\n\n#define\tCK_SLIST_NEXT(elm, field)\t\t\t\t\t\t\\\n\tck_pr_load_ptr(&((elm)->field.sle_next))\n\n#define\tCK_SLIST_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = CK_SLIST_FIRST((head));\t\t\t\t\t\\\n\t    (var) && (ck_pr_fence_load(), 1);\t\t\t\t\t\\\n\t    (var) = CK_SLIST_NEXT((var), field))\n\n#define\tCK_SLIST_FOREACH_SAFE(var, head, field, tvar)\t\t\t\t \\\n\tfor ((var) = CK_SLIST_FIRST(head);\t\t\t\t\t \\\n\t    (var) && (ck_pr_fence_load(), (tvar) = CK_SLIST_NEXT(var, field), 1);\\\n\t    (var) = (tvar))\n\n#define\tCK_SLIST_FOREACH_PREVPTR(var, varp, head, field)\t\t\t\\\n\tfor ((varp) = &(head)->slh_first;\t\t\t\t\t\\\n\t    ((var) = ck_pr_load_ptr(varp)) != NULL && (ck_pr_fence_load(), 1);\t\\\n\t    (varp) = &(var)->field.sle_next)\n\n#define\tCK_SLIST_INIT(head) do {\t\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->slh_first, NULL);\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tCK_SLIST_INSERT_AFTER(a, b, field) do {\t\t\t\t\t\\\n\t(b)->field.sle_next = (a)->field.sle_next;\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr(&(a)->field.sle_next, b);\t\t\t\t\\\n} while (0)\n\n#define\tCK_SLIST_INSERT_HEAD(head, elm, field) do {\t\t\t\t\\\n\t(elm)->field.sle_next = (head)->slh_first;\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->slh_first, elm);\t\t\t\t\\\n} while (0)\n\n#define CK_SLIST_REMOVE_AFTER(elm, field) do {\t\t\t\t\t\\\n\tck_pr_store_ptr(&(elm)->field.sle_next,\t\t\t\t\t\\\n\t    (elm)->field.sle_next->field.sle_next);\t\t\t\t\\\n} while (0)\n\n#define\tCK_SLIST_REMOVE(head, elm, type, field) do {\t\t\t\t\\\n\tif ((head)->slh_first == (elm)) {\t\t\t\t\t\\\n\t\tCK_SLIST_REMOVE_HEAD((head), field);\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\t\\\n\t\tstruct type *curelm = (head)->slh_first;\t\t\t\\\n\t\twhile (curelm->field.sle_next != (elm))\t\t\t\t\\\n\t\t\tcurelm = curelm->field.sle_next;\t\t\t\\\n\t\tCK_SLIST_REMOVE_AFTER(curelm, field);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tCK_SLIST_REMOVE_HEAD(head, field) do {\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->slh_first,\t\t\t\t\t\\\n\t\t(head)->slh_first->field.sle_next);\t\t\t\t\\\n} while (0)\n\n#define CK_SLIST_MOVE(head1, head2, field) do {\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head1)->slh_first, (head2)->slh_first);\t\t\\\n} while (0)\n\n/*\n * This operation is not applied atomically.\n */\n#define CK_SLIST_SWAP(a, b, type) do {\t\t\t\t\t\t\\\n\tstruct type *swap_first = (a)->slh_first;\t\t\t\t\\\n\t(a)->slh_first = (b)->slh_first;\t\t\t\t\t\\\n\t(b)->slh_first = swap_first;\t\t\t\t\t\t\\\n} while (0)\n\n/*\n * Singly-linked Tail queue declarations.\n */\n#define\tCK_STAILQ_HEAD(name, type)\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\\\n\tstruct type *stqh_first;/* first element */\t\t\t\\\n\tstruct type **stqh_last;/* addr of last next element */\t\t\\\n}\n\n#define\tCK_STAILQ_HEAD_INITIALIZER(head)\t\t\t\t\\\n\t{ NULL, &(head).stqh_first }\n\n#define\tCK_STAILQ_ENTRY(type)\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\\\n\tstruct type *stqe_next;\t/* next element */\t\t\t\\\n}\n\n/*\n * Singly-linked Tail queue functions.\n */\n#define\tCK_STAILQ_CONCAT(head1, head2) do {\t\t\t\t\t\\\n\tif ((head2)->stqh_first != NULL) {\t\t\t\t\t\\\n\t\tck_pr_store_ptr((head1)->stqh_last, (head2)->stqh_first);\t\\\n\t\tck_pr_fence_store();\t\t\t\t\t\t\\\n\t\t(head1)->stqh_last = (head2)->stqh_last;\t\t\t\\\n\t\tCK_STAILQ_INIT((head2));\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tCK_STAILQ_EMPTY(head)\t(ck_pr_load_ptr(&(head)->stqh_first) == NULL)\n\n#define\tCK_STAILQ_FIRST(head)\t(ck_pr_load_ptr(&(head)->stqh_first))\n\n#define\tCK_STAILQ_FOREACH(var, head, field)\t\t\t\t\\\n\tfor((var) = CK_STAILQ_FIRST((head));\t\t\t\t\\\n\t   (var) && (ck_pr_fence_load(), 1);\t\t\t\t\\\n\t   (var) = CK_STAILQ_NEXT((var), field))\n\n#define\tCK_STAILQ_FOREACH_SAFE(var, head, field, tvar)\t\t\t\\\n\tfor ((var) = CK_STAILQ_FIRST((head));\t\t\t\t\\\n\t    (var) && (ck_pr_fence_load(), (tvar) =\t\t\t\\\n\t\tCK_STAILQ_NEXT((var), field), 1);\t\t\t\\\n\t    (var) = (tvar))\n\n#define\tCK_STAILQ_INIT(head) do {\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->stqh_first, NULL);\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\\\n\t(head)->stqh_last = &(head)->stqh_first;\t\t\t\\\n} while (0)\n\n#define\tCK_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {\t\t\t\\\n\t(elm)->field.stqe_next = (tqelm)->field.stqe_next;\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr(&(tqelm)->field.stqe_next, elm);\t\t\t\\\n\tif ((elm)->field.stqe_next == NULL)\t\t\t\t\t\\\n\t\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\t\\\n} while (0)\n\n#define\tCK_STAILQ_INSERT_HEAD(head, elm, field) do {\t\t\t\t\\\n\t(elm)->field.stqe_next = (head)->stqh_first;\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->stqh_first, elm);\t\t\t\t\\\n\tif ((elm)->field.stqe_next == NULL)\t\t\t\t\t\\\n\t\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\t\\\n} while (0)\n\n#define\tCK_STAILQ_INSERT_TAIL(head, elm, field) do {\t\t\t\t\\\n\t(elm)->field.stqe_next = NULL;\t\t\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr((head)->stqh_last, (elm));\t\t\t\t\\\n\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\t\t\\\n} while (0)\n\n#define\tCK_STAILQ_NEXT(elm, field)\t\t\t\t\t\t\\\n\t(ck_pr_load_ptr(&(elm)->field.stqe_next))\n\n#define\tCK_STAILQ_REMOVE(head, elm, type, field) do {\t\t\t\t\\\n\tif ((head)->stqh_first == (elm)) {\t\t\t\t\t\\\n\t\tCK_STAILQ_REMOVE_HEAD((head), field);\t\t\t\t\\\n\t} else {\t\t\t\t\t\t\t\t\\\n\t\tstruct type *curelm = (head)->stqh_first;\t\t\t\\\n\t\twhile (curelm->field.stqe_next != (elm))\t\t\t\\\n\t\t\tcurelm = curelm->field.stqe_next;\t\t\t\\\n\t\tCK_STAILQ_REMOVE_AFTER(head, curelm, field);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n} while (0)\n\n#define CK_STAILQ_REMOVE_AFTER(head, elm, field) do {\t\t\t\t\\\n\tck_pr_store_ptr(&(elm)->field.stqe_next,\t\t\t\t\\\n\t    (elm)->field.stqe_next->field.stqe_next);\t\t\t\t\\\n\tif ((elm)->field.stqe_next == NULL)\t\t\t\t\t\\\n\t\t(head)->stqh_last = &(elm)->field.stqe_next;\t\t\t\\\n} while (0)\n\n#define\tCK_STAILQ_REMOVE_HEAD(head, field) do {\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->stqh_first,\t\t\t\t\t\\\n\t    (head)->stqh_first->field.stqe_next);\t\t\t\t\\\n\tif ((head)->stqh_first == NULL)\t\t\t\t\t\t\\\n\t\t(head)->stqh_last = &(head)->stqh_first;\t\t\t\\\n} while (0)\n\n#define CK_STAILQ_MOVE(head1, head2, field) do {\t\t\t\t\\\n\tck_pr_store_ptr(&(head1)->stqh_first, (head2)->stqh_first);\t\t\\\n\t(head1)->stqh_last = (head2)->stqh_last;\t\t\t\t\\\n\tif ((head2)->stqh_last == &(head2)->stqh_first)\t\t\t\t\\\n\t\t(head1)->stqh_last = &(head1)->stqh_first;\t\t\t\\\n} while (0)\n\n/*\n * This operation is not applied atomically.\n */\n#define CK_STAILQ_SWAP(head1, head2, type) do {\t\t\t\t\\\n\tstruct type *swap_first = CK_STAILQ_FIRST(head1);\t\t\\\n\tstruct type **swap_last = (head1)->stqh_last;\t\t\t\\\n\tCK_STAILQ_FIRST(head1) = CK_STAILQ_FIRST(head2);\t\t\\\n\t(head1)->stqh_last = (head2)->stqh_last;\t\t\t\\\n\tCK_STAILQ_FIRST(head2) = swap_first;\t\t\t\t\\\n\t(head2)->stqh_last = swap_last;\t\t\t\t\t\\\n\tif (CK_STAILQ_EMPTY(head1))\t\t\t\t\t\\\n\t\t(head1)->stqh_last = &(head1)->stqh_first;\t\t\\\n\tif (CK_STAILQ_EMPTY(head2))\t\t\t\t\t\\\n\t\t(head2)->stqh_last = &(head2)->stqh_first;\t\t\\\n} while (0)\n\n/*\n * List declarations.\n */\n#define\tCK_LIST_HEAD(name, type)\t\t\t\t\t\t\\\nstruct name {\t\t\t\t\t\t\t\t\t\\\n\tstruct type *lh_first;\t/* first element */\t\t\t\t\\\n}\n\n#define\tCK_LIST_HEAD_INITIALIZER(head)\t\t\t\t\t\t\\\n\t{ NULL }\n\n#define\tCK_LIST_ENTRY(type)\t\t\t\t\t\t\t\\\nstruct {\t\t\t\t\t\t\t\t\t\\\n\tstruct type *le_next;\t/* next element */\t\t\t\t\\\n\tstruct type **le_prev;\t/* address of previous next element */\t\t\\\n}\n\n#define\tCK_LIST_FIRST(head)\t\tck_pr_load_ptr(&(head)->lh_first)\n#define\tCK_LIST_EMPTY(head)\t\t(CK_LIST_FIRST(head) == NULL)\n#define\tCK_LIST_NEXT(elm, field)\tck_pr_load_ptr(&(elm)->field.le_next)\n\n#define\tCK_LIST_FOREACH(var, head, field)\t\t\t\t\t\\\n\tfor ((var) = CK_LIST_FIRST((head));\t\t\t\t\t\\\n\t    (var) && (ck_pr_fence_load(), 1);\t\t\t\t\t\\\n\t    (var) = CK_LIST_NEXT((var), field))\n\n#define\tCK_LIST_FOREACH_SAFE(var, head, field, tvar)\t\t\t\t  \\\n\tfor ((var) = CK_LIST_FIRST((head));\t\t\t\t\t  \\\n\t    (var) && (ck_pr_fence_load(), (tvar) = CK_LIST_NEXT((var), field), 1);\\\n\t    (var) = (tvar))\n\n#define\tCK_LIST_INIT(head) do {\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr(&(head)->lh_first, NULL);\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n} while (0)\n\n#define\tCK_LIST_INSERT_AFTER(listelm, elm, field) do {\t\t\t\t\\\n\t(elm)->field.le_next = (listelm)->field.le_next;\t\t\t\\\n\t(elm)->field.le_prev = &(listelm)->field.le_next;\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tif ((listelm)->field.le_next != NULL)\t\t\t\t\t\\\n\t\t(listelm)->field.le_next->field.le_prev = &(elm)->field.le_next;\\\n\tck_pr_store_ptr(&(listelm)->field.le_next, elm);\t\t\t\\\n} while (0)\n\n#define\tCK_LIST_INSERT_BEFORE(listelm, elm, field) do {\t\t\t\t\\\n\t(elm)->field.le_prev = (listelm)->field.le_prev;\t\t\t\\\n\t(elm)->field.le_next = (listelm);\t\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tck_pr_store_ptr((listelm)->field.le_prev, (elm));\t\t\t\\\n\t(listelm)->field.le_prev = &(elm)->field.le_next;\t\t\t\\\n} while (0)\n\n#define\tCK_LIST_INSERT_HEAD(head, elm, field) do {\t\t\t\t\\\n\t(elm)->field.le_next = (head)->lh_first;\t\t\t\t\\\n\tck_pr_fence_store();\t\t\t\t\t\t\t\\\n\tif ((elm)->field.le_next != NULL)\t\t\t\t\t\\\n\t\t(head)->lh_first->field.le_prev =  &(elm)->field.le_next;\t\\\n\tck_pr_store_ptr(&(head)->lh_first, elm);\t\t\t\t\\\n\t(elm)->field.le_prev = &(head)->lh_first;\t\t\t\t\\\n} while (0)\n\n#define\tCK_LIST_REMOVE(elm, field) do {\t\t\t\t\t\t\\\n\tck_pr_store_ptr((elm)->field.le_prev, (elm)->field.le_next);\t\t\\\n\tif ((elm)->field.le_next != NULL)\t\t\t\t\t\\\n\t\t(elm)->field.le_next->field.le_prev = (elm)->field.le_prev;\t\\\n} while (0)\n\n#define CK_LIST_MOVE(head1, head2, field) do {\t\t\t\t\\\n\tck_pr_store_ptr(&(head1)->lh_first, (head2)->lh_first);\t\t\\\n\tif ((head1)->lh_first != NULL)\t\t\t\t\t\\\n\t\t(head1)->lh_first->field.le_prev = &(head1)->lh_first;\t\\\n} while (0)\n\n/*\n * This operation is not applied atomically.\n */\n#define CK_LIST_SWAP(head1, head2, type, field) do {\t\t\t\\\n\tstruct type *swap_tmp = (head1)->lh_first;\t\t\t\\\n\t(head1)->lh_first = (head2)->lh_first;\t\t\t\t\\\n\t(head2)->lh_first = swap_tmp;\t\t\t\t\t\\\n\tif ((swap_tmp = (head1)->lh_first) != NULL)\t\t\t\\\n\t\tswap_tmp->field.le_prev = &(head1)->lh_first;\t\t\\\n\tif ((swap_tmp = (head2)->lh_first) != NULL)\t\t\t\\\n\t\tswap_tmp->field.le_prev = &(head2)->lh_first;\t\t\\\n} while (0)\n\n#endif /* CK_QUEUE_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_rhs.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_RHS_H\n#define CK_RHS_H\n\n#include <ck_cc.h>\n#include <ck_malloc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\n/*\n * Indicates a single-writer many-reader workload. Mutually\n * exclusive with CK_RHS_MODE_MPMC\n */\n#define CK_RHS_MODE_SPMC\t\t1\n\n/*\n * Indicates that values to be stored are not pointers but\n * values. Allows for full precision. Mutually exclusive\n * with CK_RHS_MODE_OBJECT.\n */\n#define CK_RHS_MODE_DIRECT\t2\n\n/*\n * Indicates that the values to be stored are pointers.\n * Allows for space optimizations in the presence of pointer\n * packing. Mutually exclusive with CK_RHS_MODE_DIRECT.\n */\n#define CK_RHS_MODE_OBJECT\t8\n\n/*\n * Indicated that the load is read-mostly, so get should be optimized\n * over put and delete\n */\n#define CK_RHS_MODE_READ_MOSTLY\t16\n\n/* Currently unsupported. */\n#define CK_RHS_MODE_MPMC    (void)\n\n/*\n * Hash callback function.\n */\ntypedef unsigned long ck_rhs_hash_cb_t(const void *, unsigned long);\n\n/*\n * Returns pointer to object if objects are equivalent.\n */\ntypedef bool ck_rhs_compare_cb_t(const void *, const void *);\n\n#if defined(CK_MD_POINTER_PACK_ENABLE) && defined(CK_MD_VMA_BITS)\n#define CK_RHS_PP\n#define CK_RHS_KEY_MASK ((1U << ((sizeof(void *) * 8) - CK_MD_VMA_BITS)) - 1)\n#endif\n\nstruct ck_rhs_map;\nstruct ck_rhs {\n\tstruct ck_malloc *m;\n\tstruct ck_rhs_map *map;\n\tunsigned int mode;\n\tunsigned int load_factor;\n\tunsigned long seed;\n\tck_rhs_hash_cb_t *hf;\n\tck_rhs_compare_cb_t *compare;\n};\ntypedef struct ck_rhs ck_rhs_t;\n\nstruct ck_rhs_stat {\n\tunsigned long n_entries;\n\tunsigned int probe_maximum;\n};\n\nstruct ck_rhs_iterator {\n\tvoid **cursor;\n\tunsigned long offset;\n};\ntypedef struct ck_rhs_iterator ck_rhs_iterator_t;\n\n#define CK_RHS_ITERATOR_INITIALIZER { NULL, 0 }\n\n/* Convenience wrapper to table hash function. */\n#define CK_RHS_HASH(T, F, K) F((K), (T)->seed)\n\ntypedef void *ck_rhs_apply_fn_t(void *, void *);\nbool ck_rhs_apply(ck_rhs_t *, unsigned long, const void *, ck_rhs_apply_fn_t *, void *);\nvoid ck_rhs_iterator_init(ck_rhs_iterator_t *);\nbool ck_rhs_next(ck_rhs_t *, ck_rhs_iterator_t *, void **);\nbool ck_rhs_move(ck_rhs_t *, ck_rhs_t *, ck_rhs_hash_cb_t *,\n    ck_rhs_compare_cb_t *, struct ck_malloc *);\nbool ck_rhs_init(ck_rhs_t *, unsigned int, ck_rhs_hash_cb_t *,\n    ck_rhs_compare_cb_t *, struct ck_malloc *, unsigned long, unsigned long);\nvoid ck_rhs_destroy(ck_rhs_t *);\nvoid *ck_rhs_get(ck_rhs_t *, unsigned long, const void *);\nbool ck_rhs_put(ck_rhs_t *, unsigned long, const void *);\nbool ck_rhs_put_unique(ck_rhs_t *, unsigned long, const void *);\nbool ck_rhs_set(ck_rhs_t *, unsigned long, const void *, void **);\nbool ck_rhs_fas(ck_rhs_t *, unsigned long, const void *, void **);\nvoid *ck_rhs_remove(ck_rhs_t *, unsigned long, const void *);\nbool ck_rhs_grow(ck_rhs_t *, unsigned long);\nbool ck_rhs_rebuild(ck_rhs_t *);\nbool ck_rhs_gc(ck_rhs_t *);\nunsigned long ck_rhs_count(ck_rhs_t *);\nbool ck_rhs_reset(ck_rhs_t *);\nbool ck_rhs_reset_size(ck_rhs_t *, unsigned long);\nvoid ck_rhs_stat(ck_rhs_t *, struct ck_rhs_stat *);\nbool ck_rhs_set_load_factor(ck_rhs_t *, unsigned int);\n\n#endif /* CK_RHS_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_ring.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_RING_H\n#define CK_RING_H\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_string.h>\n\n/*\n * Concurrent ring buffer.\n */\n\nstruct ck_ring {\n\tunsigned int c_head;\n\tchar pad[CK_MD_CACHELINE - sizeof(unsigned int)];\n\tunsigned int p_tail;\n\tunsigned int p_head;\n\tchar _pad[CK_MD_CACHELINE - sizeof(unsigned int) * 2];\n\tunsigned int size;\n\tunsigned int mask;\n};\ntypedef struct ck_ring ck_ring_t;\n\nstruct ck_ring_buffer {\n\tvoid *value;\n};\ntypedef struct ck_ring_buffer ck_ring_buffer_t;\n\nCK_CC_INLINE static unsigned int\nck_ring_size(const struct ck_ring *ring)\n{\n\tunsigned int c, p;\n\n\tc = ck_pr_load_uint(&ring->c_head);\n\tp = ck_pr_load_uint(&ring->p_tail);\n\treturn (p - c) & ring->mask;\n}\n\nCK_CC_INLINE static unsigned int\nck_ring_capacity(const struct ck_ring *ring)\n{\n\treturn ring->size;\n}\n\nCK_CC_INLINE static void\nck_ring_init(struct ck_ring *ring, unsigned int size)\n{\n\n\tring->size = size;\n\tring->mask = size - 1;\n\tring->p_tail = 0;\n\tring->p_head = 0;\n\tring->c_head = 0;\n\treturn;\n}\n\n/*\n * The _ck_ring_* namespace is internal only and must not used externally.\n */\nCK_CC_FORCE_INLINE static bool\n_ck_ring_enqueue_sp(struct ck_ring *ring,\n    void *CK_CC_RESTRICT buffer,\n    const void *CK_CC_RESTRICT entry,\n    unsigned int ts,\n    unsigned int *size)\n{\n\tconst unsigned int mask = ring->mask;\n\tunsigned int consumer, producer, delta;\n\n\tconsumer = ck_pr_load_uint(&ring->c_head);\n\tproducer = ring->p_tail;\n\tdelta = producer + 1;\n\tif (size != NULL)\n\t\t*size = (producer - consumer) & mask;\n\n\tif (CK_CC_UNLIKELY((delta & mask) == (consumer & mask)))\n\t\treturn false;\n\n\tbuffer = (char *)buffer + ts * (producer & mask);\n\tmemcpy(buffer, entry, ts);\n\n\t/*\n\t * Make sure to update slot value before indicating\n\t * that the slot is available for consumption.\n\t */\n\tck_pr_fence_store();\n\tck_pr_store_uint(&ring->p_tail, delta);\n\treturn true;\n}\n\nCK_CC_FORCE_INLINE static bool\n_ck_ring_enqueue_sp_size(struct ck_ring *ring,\n    void *CK_CC_RESTRICT buffer,\n    const void *CK_CC_RESTRICT entry,\n    unsigned int ts,\n    unsigned int *size)\n{\n\tunsigned int sz;\n\tbool r;\n\n\tr = _ck_ring_enqueue_sp(ring, buffer, entry, ts, &sz);\n\t*size = sz;\n\treturn r;\n}\n\nCK_CC_FORCE_INLINE static bool\n_ck_ring_dequeue_sc(struct ck_ring *ring,\n    const void *CK_CC_RESTRICT buffer,\n    void *CK_CC_RESTRICT target,\n    unsigned int size)\n{\n\tconst unsigned int mask = ring->mask;\n\tunsigned int consumer, producer;\n\n\tconsumer = ring->c_head;\n\tproducer = ck_pr_load_uint(&ring->p_tail);\n\n\tif (CK_CC_UNLIKELY(consumer == producer))\n\t\treturn false;\n\n\t/*\n\t * Make sure to serialize with respect to our snapshot\n\t * of the producer counter.\n\t */\n\tck_pr_fence_load();\n\n\tbuffer = (const char *)buffer + size * (consumer & mask);\n\tmemcpy(target, buffer, size);\n\n\t/*\n\t * Make sure copy is completed with respect to consumer\n\t * update.\n\t */\n\tck_pr_fence_store();\n\tck_pr_store_uint(&ring->c_head, consumer + 1);\n\treturn true;\n}\n\nCK_CC_FORCE_INLINE static bool\n_ck_ring_enqueue_mp(struct ck_ring *ring,\n    void *buffer,\n    const void *entry,\n    unsigned int ts,\n    unsigned int *size)\n{\n\tconst unsigned int mask = ring->mask;\n\tunsigned int producer, consumer, delta;\n\tbool r = true;\n\n\tproducer = ck_pr_load_uint(&ring->p_head);\n\n\tfor (;;) {\n\t\t/*\n\t\t * The snapshot of producer must be up to date with respect to\n\t\t * consumer.\n\t\t */\n\t\tck_pr_fence_load();\n\t\tconsumer = ck_pr_load_uint(&ring->c_head);\n\n\t\tdelta = producer + 1;\n\n\t\t/*\n\t\t * Only try to CAS if the producer is not clearly stale (not\n\t\t * less than consumer) and the buffer is definitely not full.\n\t\t */\n\t\tif (CK_CC_LIKELY((producer - consumer) < mask)) {\n\t\t\tif (ck_pr_cas_uint_value(&ring->p_head,\n\t\t\t    producer, delta, &producer) == true) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tunsigned int new_producer;\n\n\t\t\t/*\n\t\t\t * Slow path.  Either the buffer is full or we have a\n\t\t\t * stale snapshot of p_head.  Execute a second read of\n\t\t\t * p_read that must be ordered wrt the snapshot of\n\t\t\t * c_head.\n\t\t\t */\n\t\t\tck_pr_fence_load();\n\t\t\tnew_producer = ck_pr_load_uint(&ring->p_head);\n\n\t\t\t/*\n\t\t\t * Only fail if we haven't made forward progress in\n\t\t\t * production: the buffer must have been full when we\n\t\t\t * read new_producer (or we wrapped around UINT_MAX\n\t\t\t * during this iteration).\n\t\t\t */\n\t\t\tif (producer == new_producer) {\n\t\t\t\tr = false;\n\t\t\t\tgoto leave;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * p_head advanced during this iteration. Try again.\n\t\t\t */\n\t\t\tproducer = new_producer;\n\t\t}\n\t}\n\n\tbuffer = (char *)buffer + ts * (producer & mask);\n\tmemcpy(buffer, entry, ts);\n\n\t/*\n\t * Wait until all concurrent producers have completed writing\n\t * their data into the ring buffer.\n\t */\n\twhile (ck_pr_load_uint(&ring->p_tail) != producer)\n\t\tck_pr_stall();\n\n\t/*\n\t * Ensure that copy is completed before updating shared producer\n\t * counter.\n\t */\n\tck_pr_fence_store();\n\tck_pr_store_uint(&ring->p_tail, delta);\n\nleave:\n\tif (size != NULL)\n\t\t*size = (producer - consumer) & mask;\n\n\treturn r;\n}\n\nCK_CC_FORCE_INLINE static bool\n_ck_ring_enqueue_mp_size(struct ck_ring *ring,\n    void *buffer,\n    const void *entry,\n    unsigned int ts,\n    unsigned int *size)\n{\n\tunsigned int sz;\n\tbool r;\n\n\tr = _ck_ring_enqueue_mp(ring, buffer, entry, ts, &sz);\n\t*size = sz;\n\treturn r;\n}\n\nCK_CC_FORCE_INLINE static bool\n_ck_ring_trydequeue_mc(struct ck_ring *ring,\n    const void *buffer,\n    void *data,\n    unsigned int size)\n{\n\tconst unsigned int mask = ring->mask;\n\tunsigned int consumer, producer;\n\n\tconsumer = ck_pr_load_uint(&ring->c_head);\n\tck_pr_fence_load();\n\tproducer = ck_pr_load_uint(&ring->p_tail);\n\n\tif (CK_CC_UNLIKELY(consumer == producer))\n\t\treturn false;\n\n\tck_pr_fence_load();\n\n\tbuffer = (const char *)buffer + size * (consumer & mask);\n\tmemcpy(data, buffer, size);\n\n\tck_pr_fence_store_atomic();\n\treturn ck_pr_cas_uint(&ring->c_head, consumer, consumer + 1);\n}\n\nCK_CC_FORCE_INLINE static bool\n_ck_ring_dequeue_mc(struct ck_ring *ring,\n    const void *buffer,\n    void *data,\n    unsigned int ts)\n{\n\tconst unsigned int mask = ring->mask;\n\tunsigned int consumer, producer;\n\n\tconsumer = ck_pr_load_uint(&ring->c_head);\n\n\tdo {\n\t\tconst char *target;\n\n\t\t/*\n\t\t * Producer counter must represent state relative to\n\t\t * our latest consumer snapshot.\n\t\t */\n\t\tck_pr_fence_load();\n\t\tproducer = ck_pr_load_uint(&ring->p_tail);\n\n\t\tif (CK_CC_UNLIKELY(consumer == producer))\n\t\t\treturn false;\n\n\t\tck_pr_fence_load();\n\n\t\ttarget = (const char *)buffer + ts * (consumer & mask);\n\t\tmemcpy(data, target, ts);\n\n\t\t/* Serialize load with respect to head update. */\n\t\tck_pr_fence_store_atomic();\n\t} while (ck_pr_cas_uint_value(&ring->c_head,\n\t\t\t\t      consumer,\n\t\t\t\t      consumer + 1,\n\t\t\t\t      &consumer) == false);\n\n\treturn true;\n}\n\n/*\n * The ck_ring_*_spsc namespace is the public interface for interacting with a\n * ring buffer containing pointers. Correctness is only provided if there is up\n * to one concurrent consumer and up to one concurrent producer.\n */\nCK_CC_INLINE static bool\nck_ring_enqueue_spsc_size(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry,\n    unsigned int *size)\n{\n\n\treturn _ck_ring_enqueue_sp_size(ring, buffer, &entry,\n\t    sizeof(entry), size);\n}\n\nCK_CC_INLINE static bool\nck_ring_enqueue_spsc(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry)\n{\n\n\treturn _ck_ring_enqueue_sp(ring, buffer,\n\t    &entry, sizeof(entry), NULL);\n}\n\nCK_CC_INLINE static bool\nck_ring_dequeue_spsc(struct ck_ring *ring,\n    const struct ck_ring_buffer *buffer,\n    void *data)\n{\n\n\treturn _ck_ring_dequeue_sc(ring, buffer,\n\t    (void **)data, sizeof(void *));\n}\n\n/*\n * The ck_ring_*_mpmc namespace is the public interface for interacting with a\n * ring buffer containing pointers. Correctness is provided for any number of\n * producers and consumers.\n */\nCK_CC_INLINE static bool\nck_ring_enqueue_mpmc(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry)\n{\n\n\treturn _ck_ring_enqueue_mp(ring, buffer, &entry,\n\t    sizeof(entry), NULL);\n}\n\nCK_CC_INLINE static bool\nck_ring_enqueue_mpmc_size(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry,\n    unsigned int *size)\n{\n\n\treturn _ck_ring_enqueue_mp_size(ring, buffer, &entry,\n\t    sizeof(entry), size);\n}\n\nCK_CC_INLINE static bool\nck_ring_trydequeue_mpmc(struct ck_ring *ring,\n    const struct ck_ring_buffer *buffer,\n    void *data)\n{\n\n\treturn _ck_ring_trydequeue_mc(ring,\n\t    buffer, (void **)data, sizeof(void *));\n}\n\nCK_CC_INLINE static bool\nck_ring_dequeue_mpmc(struct ck_ring *ring,\n    const struct ck_ring_buffer *buffer,\n    void *data)\n{\n\n\treturn _ck_ring_dequeue_mc(ring, buffer, (void **)data,\n\t    sizeof(void *));\n}\n\n/*\n * The ck_ring_*_spmc namespace is the public interface for interacting with a\n * ring buffer containing pointers. Correctness is provided for any number of\n * consumers with up to one concurrent producer.\n */\nCK_CC_INLINE static bool\nck_ring_enqueue_spmc_size(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry,\n    unsigned int *size)\n{\n\n\treturn _ck_ring_enqueue_sp_size(ring, buffer, &entry,\n\t    sizeof(entry), size);\n}\n\nCK_CC_INLINE static bool\nck_ring_enqueue_spmc(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry)\n{\n\n\treturn _ck_ring_enqueue_sp(ring, buffer, &entry,\n\t    sizeof(entry), NULL);\n}\n\nCK_CC_INLINE static bool\nck_ring_trydequeue_spmc(struct ck_ring *ring,\n    const struct ck_ring_buffer *buffer,\n    void *data)\n{\n\n\treturn _ck_ring_trydequeue_mc(ring, buffer, (void **)data, sizeof(void *));\n}\n\nCK_CC_INLINE static bool\nck_ring_dequeue_spmc(struct ck_ring *ring,\n    const struct ck_ring_buffer *buffer,\n    void *data)\n{\n\n\treturn _ck_ring_dequeue_mc(ring, buffer, (void **)data, sizeof(void *));\n}\n\n/*\n * The ck_ring_*_mpsc namespace is the public interface for interacting with a\n * ring buffer containing pointers. Correctness is provided for any number of\n * producers with up to one concurrent consumers.\n */\nCK_CC_INLINE static bool\nck_ring_enqueue_mpsc(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry)\n{\n\n\treturn _ck_ring_enqueue_mp(ring, buffer, &entry,\n\t    sizeof(entry), NULL);\n}\n\nCK_CC_INLINE static bool\nck_ring_enqueue_mpsc_size(struct ck_ring *ring,\n    struct ck_ring_buffer *buffer,\n    const void *entry,\n    unsigned int *size)\n{\n\n\treturn _ck_ring_enqueue_mp_size(ring, buffer, &entry,\n\t    sizeof(entry), size);\n}\n\nCK_CC_INLINE static bool\nck_ring_dequeue_mpsc(struct ck_ring *ring,\n    const struct ck_ring_buffer *buffer,\n    void *data)\n{\n\n\treturn _ck_ring_dequeue_sc(ring, buffer, (void **)data,\n\t    sizeof(void *));\n}\n\n/*\n * CK_RING_PROTOTYPE is used to define a type-safe interface for inlining\n * values of a particular type in the ring the buffer.\n */\n#define CK_RING_PROTOTYPE(name, type)\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_spsc_size_##name(struct ck_ring *a,\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c,\t\t\t\t\t\\\n    unsigned int *d)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_sp_size(a, b, c,\t\\\n\t    sizeof(struct type), d);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_spsc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_sp(a, b, c,\t\t\\\n\t    sizeof(struct type), NULL);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_dequeue_spsc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_dequeue_sc(a, b, c,\t\t\\\n\t    sizeof(struct type));\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_spmc_size_##name(struct ck_ring *a,\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c,\t\t\t\t\t\\\n    unsigned int *d)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_sp_size(a, b, c,\t\\\n\t    sizeof(struct type), d);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_spmc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_sp(a, b, c,\t\t\\\n\t    sizeof(struct type), NULL);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_trydequeue_spmc_##name(struct ck_ring *a,\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_trydequeue_mc(a,\t\t\\\n\t    b, c, sizeof(struct type));\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_dequeue_spmc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_dequeue_mc(a, b, c,\t\t\\\n\t    sizeof(struct type));\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_mpsc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_mp(a, b, c,\t\t\\\n\t    sizeof(struct type), NULL);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_mpsc_size_##name(struct ck_ring *a,\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c,\t\t\t\t\t\\\n    unsigned int *d)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_mp_size(a, b, c,\t\\\n\t    sizeof(struct type), d);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_dequeue_mpsc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_dequeue_sc(a, b, c,\t\t\\\n\t    sizeof(struct type));\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_mpmc_size_##name(struct ck_ring *a,\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c,\t\t\t\t\t\\\n    unsigned int *d)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_mp_size(a, b, c,\t\\\n\t    sizeof(struct type), d);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_enqueue_mpmc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_enqueue_mp(a, b, c,\t\t\\\n\t    sizeof(struct type), NULL);\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_trydequeue_mpmc_##name(struct ck_ring *a,\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_trydequeue_mc(a,\t\t\\\n\t    b, c, sizeof(struct type));\t\t\t\\\n}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\\\nck_ring_dequeue_mpmc_##name(struct ck_ring *a,\t\t\\\n    struct type *b,\t\t\t\t\t\\\n    struct type *c)\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\\\n\treturn _ck_ring_dequeue_mc(a, b, c,\t\t\\\n\t    sizeof(struct type));\t\t\t\\\n}\n\n/*\n * A single producer with one concurrent consumer.\n */\n#define CK_RING_ENQUEUE_SPSC(name, a, b, c)\t\t\\\n\tck_ring_enqueue_spsc_##name(a, b, c)\n#define CK_RING_ENQUEUE_SPSC_SIZE(name, a, b, c, d)\t\\\n\tck_ring_enqueue_spsc_size_##name(a, b, c, d)\n#define CK_RING_DEQUEUE_SPSC(name, a, b, c)\t\t\\\n\tck_ring_dequeue_spsc_##name(a, b, c)\n\n/*\n * A single producer with any number of concurrent consumers.\n */\n#define CK_RING_ENQUEUE_SPMC(name, a, b, c)\t\t\\\n\tck_ring_enqueue_spmc_##name(a, b, c)\n#define CK_RING_ENQUEUE_SPMC_SIZE(name, a, b, c, d)\t\\\n\tck_ring_enqueue_spmc_size_##name(a, b, c, d)\n#define CK_RING_TRYDEQUEUE_SPMC(name, a, b, c)\t\t\\\n\tck_ring_trydequeue_spmc_##name(a, b, c)\n#define CK_RING_DEQUEUE_SPMC(name, a, b, c)\t\t\\\n\tck_ring_dequeue_spmc_##name(a, b, c)\n\n/*\n * Any number of concurrent producers with up to one\n * concurrent consumer.\n */\n#define CK_RING_ENQUEUE_MPSC(name, a, b, c)\t\t\\\n\tck_ring_enqueue_mpsc_##name(a, b, c)\n#define CK_RING_ENQUEUE_MPSC_SIZE(name, a, b, c, d)\t\\\n\tck_ring_enqueue_mpsc_size_##name(a, b, c, d)\n#define CK_RING_DEQUEUE_MPSC(name, a, b, c)\t\t\\\n\tck_ring_dequeue_mpsc_##name(a, b, c)\n\n/*\n * Any number of concurrent producers and consumers.\n */\n#define CK_RING_ENQUEUE_MPMC(name, a, b, c)\t\t\\\n\tck_ring_enqueue_mpmc_##name(a, b, c)\n#define CK_RING_ENQUEUE_MPMC_SIZE(name, a, b, c, d)\t\\\n\tck_ring_enqueue_mpmc_size_##name(a, b, c, d)\n#define CK_RING_TRYDEQUEUE_MPMC(name, a, b, c)\t\t\\\n\tck_ring_trydequeue_mpmc_##name(a, b, c)\n#define CK_RING_DEQUEUE_MPMC(name, a, b, c)\t\t\\\n\tck_ring_dequeue_mpmc_##name(a, b, c)\n\n#endif /* CK_RING_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_rwcohort.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copyright 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_RWCOHORT_H\n#define CK_RWCOHORT_H\n\n/*\n * This is an implementation of NUMA-aware reader-writer locks as described in:\n *     Calciu, I.; Dice, D.; Lev, Y.; Luchangco, V.; Marathe, V.; and Shavit, N. 2014.\n *     NUMA-Aware Reader-Writer Locks\n */\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stddef.h>\n#include <ck_cohort.h>\n\n#define CK_RWCOHORT_WP_NAME(N) ck_rwcohort_wp_##N\n#define CK_RWCOHORT_WP_INSTANCE(N) struct CK_RWCOHORT_WP_NAME(N)\n#define CK_RWCOHORT_WP_INIT(N, RW, WL) ck_rwcohort_wp_##N##_init(RW, WL)\n#define CK_RWCOHORT_WP_READ_LOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_wp_##N##_read_lock(RW, C, GC, LC)\n#define CK_RWCOHORT_WP_READ_UNLOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_wp_##N##_read_unlock(RW)\n#define CK_RWCOHORT_WP_WRITE_LOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_wp_##N##_write_lock(RW, C, GC, LC)\n#define CK_RWCOHORT_WP_WRITE_UNLOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_wp_##N##_write_unlock(RW, C, GC, LC)\n#define CK_RWCOHORT_WP_DEFAULT_WAIT_LIMIT 1000\n\n#define CK_RWCOHORT_WP_PROTOTYPE(N)\t\t\t\t\t\t\t\\\n\tCK_RWCOHORT_WP_INSTANCE(N) {\t\t\t\t\t\t\t\\\n\t\tunsigned int read_counter;\t\t\t\t\t\t\\\n\t\tunsigned int write_barrier;\t\t\t\t\t\t\\\n\t\tunsigned int wait_limit;\t\t\t\t\t\t\\\n\t};\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_wp_##N##_init(CK_RWCOHORT_WP_INSTANCE(N) *rw_cohort,\t\t\\\n\t    unsigned int wait_limit)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\trw_cohort->read_counter = 0;\t\t\t\t\t\t\\\n\t\trw_cohort->write_barrier = 0;\t\t\t\t\t\t\\\n\t\trw_cohort->wait_limit = wait_limit;\t\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_wp_##N##_write_lock(CK_RWCOHORT_WP_INSTANCE(N) *rw_cohort,\t\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\twhile (ck_pr_load_uint(&rw_cohort->write_barrier) > 0)\t\t\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tCK_COHORT_LOCK(N, cohort, global_context, local_context);\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\twhile (ck_pr_load_uint(&rw_cohort->read_counter) > 0) \t\t\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_wp_##N##_write_unlock(CK_RWCOHORT_WP_INSTANCE(N) *rw_cohort,\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t(void)rw_cohort;\t\t\t\t\t\t\t\\\n\t\tCK_COHORT_UNLOCK(N, cohort, global_context, local_context);\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_wp_##N##_read_lock(CK_RWCOHORT_WP_INSTANCE(N) *rw_cohort,\t\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int wait_count = 0;\t\t\t\t\t\t\\\n\t\tbool raised = false;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (;;) {\t\t\t\t\t\t\t\t\\\n\t\t\tck_pr_inc_uint(&rw_cohort->read_counter);\t\t\t\\\n\t\t\tck_pr_fence_atomic_load();\t\t\t\t\t\\\n\t\t\tif (CK_COHORT_LOCKED(N, cohort, global_context,\t\t\t\\\n\t\t\t    local_context) == false)\t\t\t\t\t\\\n\t\t\t\tbreak;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tck_pr_dec_uint(&rw_cohort->read_counter);\t\t\t\\\n\t\t\twhile (CK_COHORT_LOCKED(N, cohort, global_context,\t\t\\\n\t\t\t    local_context) == true) {\t\t\t\t\t\\\n\t\t\t\tck_pr_stall();\t\t\t\t\t\t\\\n\t\t\t\tif (++wait_count > rw_cohort->wait_limit &&\t\t\\\n\t\t\t\t    raised == false) {\t\t\t\t\t\\\n\t\t\t\t\tck_pr_inc_uint(&rw_cohort->write_barrier);\t\\\n\t\t\t\t\traised = true;\t\t\t\t\t\\\n\t\t\t\t}\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (raised == true)\t\t\t\t\t\t\t\\\n\t\t\tck_pr_dec_uint(&rw_cohort->write_barrier);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_fence_load();\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_wp_##N##_read_unlock(CK_RWCOHORT_WP_INSTANCE(N) *cohort)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_fence_load_atomic();\t\t\t\t\t\t\\\n\t\tck_pr_dec_uint(&cohort->read_counter);\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_RWCOHORT_WP_INITIALIZER {\t\t\t\t\t\t\t\\\n\t.read_counter = 0,\t\t\t\t\t\t\t\t\\\n\t.write_barrier = 0,\t\t\t\t\t\t\t\t\\\n\t.wait_limit = 0\t\t\t\t\t\t\t\t\t\\\n}\n\n#define CK_RWCOHORT_RP_NAME(N) ck_rwcohort_rp_##N\n#define CK_RWCOHORT_RP_INSTANCE(N) struct CK_RWCOHORT_RP_NAME(N)\n#define CK_RWCOHORT_RP_INIT(N, RW, WL) ck_rwcohort_rp_##N##_init(RW, WL)\n#define CK_RWCOHORT_RP_READ_LOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_rp_##N##_read_lock(RW, C, GC, LC)\n#define CK_RWCOHORT_RP_READ_UNLOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_rp_##N##_read_unlock(RW)\n#define CK_RWCOHORT_RP_WRITE_LOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_rp_##N##_write_lock(RW, C, GC, LC)\n#define CK_RWCOHORT_RP_WRITE_UNLOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_rp_##N##_write_unlock(RW, C, GC, LC)\n#define CK_RWCOHORT_RP_DEFAULT_WAIT_LIMIT 1000\n\n#define CK_RWCOHORT_RP_PROTOTYPE(N)\t\t\t\t\t\t\t\\\n\tCK_RWCOHORT_RP_INSTANCE(N) {\t\t\t\t\t\t\t\\\n\t\tunsigned int read_counter;\t\t\t\t\t\t\\\n\t\tunsigned int read_barrier;\t\t\t\t\t\t\\\n\t\tunsigned int wait_limit;\t\t\t\t\t\t\\\n\t};\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_rp_##N##_init(CK_RWCOHORT_RP_INSTANCE(N) *rw_cohort,\t\t\\\n\t    unsigned int wait_limit)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\trw_cohort->read_counter = 0;\t\t\t\t\t\t\\\n\t\trw_cohort->read_barrier = 0;\t\t\t\t\t\t\\\n\t\trw_cohort->wait_limit = wait_limit;\t\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_rp_##N##_write_lock(CK_RWCOHORT_RP_INSTANCE(N) *rw_cohort,\t\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int wait_count = 0;\t\t\t\t\t\t\\\n\t\tbool raised = false;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (;;) {\t\t\t\t\t\t\t\t\\\n\t\t\tCK_COHORT_LOCK(N, cohort, global_context, local_context);\t\\\n\t\t\tif (ck_pr_load_uint(&rw_cohort->read_counter) == 0)\t\t\\\n\t\t\t\tbreak;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tCK_COHORT_UNLOCK(N, cohort, global_context, local_context);\t\\\n\t\t\twhile (ck_pr_load_uint(&rw_cohort->read_counter) > 0) {\t\t\\\n\t\t\t\tck_pr_stall();\t\t\t\t\t\t\\\n\t\t\t\tif (++wait_count > rw_cohort->wait_limit &&\t\t\\\n\t\t\t\t    raised == false) {\t\t\t\t\t\\\n\t\t\t\t\tck_pr_inc_uint(&rw_cohort->read_barrier);\t\\\n\t\t\t\t\traised = true;\t\t\t\t\t\\\n\t\t\t\t}\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tif (raised == true)\t\t\t\t\t\t\t\\\n\t\t\tck_pr_dec_uint(&rw_cohort->read_barrier);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_rp_##N##_write_unlock(CK_RWCOHORT_RP_INSTANCE(N) *rw_cohort,\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context, void *local_context)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t(void)rw_cohort;\t\t\t\t\t\t\t\\\n\t\tCK_COHORT_UNLOCK(N, cohort, global_context, local_context);\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_rp_##N##_read_lock(CK_RWCOHORT_RP_INSTANCE(N) *rw_cohort,\t\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\twhile (ck_pr_load_uint(&rw_cohort->read_barrier) > 0)\t\t\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_inc_uint(&rw_cohort->read_counter);\t\t\t\t\\\n\t\tck_pr_fence_atomic_load();\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\twhile (CK_COHORT_LOCKED(N, cohort, global_context,\t\t\t\\\n\t\t    local_context) == true)\t\t\t\t\t\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_rp_##N##_read_unlock(CK_RWCOHORT_RP_INSTANCE(N) *cohort)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_fence_load_atomic();\t\t\t\t\t\t\\\n\t\tck_pr_dec_uint(&cohort->read_counter);\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_RWCOHORT_RP_INITIALIZER {\t\t\t\t\t\t\t\\\n\t.read_counter = 0,\t\t\t\t\t\t\t\t\\\n\t.read_barrier = 0,\t\t\t\t\t\t\t\t\\\n\t.wait_limit = 0\t\t\t\t\t\t\t\t\t\\\n}\n\n#define CK_RWCOHORT_NEUTRAL_NAME(N) ck_rwcohort_neutral_##N\n#define CK_RWCOHORT_NEUTRAL_INSTANCE(N) struct CK_RWCOHORT_NEUTRAL_NAME(N)\n#define CK_RWCOHORT_NEUTRAL_INIT(N, RW) ck_rwcohort_neutral_##N##_init(RW)\n#define CK_RWCOHORT_NEUTRAL_READ_LOCK(N, RW, C, GC, LC)\t\t\\\n\tck_rwcohort_neutral_##N##_read_lock(RW, C, GC, LC)\n#define CK_RWCOHORT_NEUTRAL_READ_UNLOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_neutral_##N##_read_unlock(RW)\n#define CK_RWCOHORT_NEUTRAL_WRITE_LOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_neutral_##N##_write_lock(RW, C, GC, LC)\n#define CK_RWCOHORT_NEUTRAL_WRITE_UNLOCK(N, RW, C, GC, LC)\t\\\n\tck_rwcohort_neutral_##N##_write_unlock(RW, C, GC, LC)\n#define CK_RWCOHORT_NEUTRAL_DEFAULT_WAIT_LIMIT 1000\n\n#define CK_RWCOHORT_NEUTRAL_PROTOTYPE(N)\t\t\t\t\t\t\\\n\tCK_RWCOHORT_NEUTRAL_INSTANCE(N) {\t\t\t\t\t\t\\\n\t\tunsigned int read_counter;\t\t\t\t\t\t\\\n\t};\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_neutral_##N##_init(CK_RWCOHORT_NEUTRAL_INSTANCE(N) *rw_cohort)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\trw_cohort->read_counter = 0;\t\t\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_neutral_##N##_write_lock(CK_RWCOHORT_NEUTRAL_INSTANCE(N) *rw_cohort,\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tCK_COHORT_LOCK(N, cohort, global_context, local_context);\t\t\\\n\t\twhile (ck_pr_load_uint(&rw_cohort->read_counter) > 0) {\t\t\t\\\n\t\t\tck_pr_stall();\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_neutral_##N##_write_unlock(CK_RWCOHORT_NEUTRAL_INSTANCE(N) *rw_cohort,\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context, void *local_context)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t(void)rw_cohort;\t\t\t\t\t\t\t\\\n\t\tCK_COHORT_UNLOCK(N, cohort, global_context, local_context);\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_neutral_##N##_read_lock(CK_RWCOHORT_NEUTRAL_INSTANCE(N) *rw_cohort,\t\\\n\t    CK_COHORT_INSTANCE(N) *cohort, void *global_context,\t\t\t\\\n\t    void *local_context)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tCK_COHORT_LOCK(N, cohort, global_context, local_context);\t\t\\\n\t\tck_pr_inc_uint(&rw_cohort->read_counter);\t\t\t\t\\\n\t\tCK_COHORT_UNLOCK(N, cohort, global_context, local_context);\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\t\\\n\tck_rwcohort_neutral_##N##_read_unlock(CK_RWCOHORT_NEUTRAL_INSTANCE(N) *cohort)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_fence_load_atomic();\t\t\t\t\t\t\\\n\t\tck_pr_dec_uint(&cohort->read_counter);\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_RWCOHORT_NEUTRAL_INITIALIZER {\t\t\t\t\t\t\\\n\t.read_counter = 0,\t\t\t\t\t\t\t\t\\\n}\n\n#endif /* CK_RWCOHORT_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_rwlock.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_RWLOCK_H\n#define CK_RWLOCK_H\n\n#include <ck_elide.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\nstruct ck_rwlock {\n\tunsigned int writer;\n\tunsigned int n_readers;\n};\ntypedef struct ck_rwlock ck_rwlock_t;\n\n#define CK_RWLOCK_INITIALIZER {0, 0}\n\nCK_CC_INLINE static void\nck_rwlock_init(struct ck_rwlock *rw)\n{\n\n\trw->writer = 0;\n\trw->n_readers = 0;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_rwlock_write_unlock(ck_rwlock_t *rw)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&rw->writer, 0);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_rwlock_locked_writer(ck_rwlock_t *rw)\n{\n\tbool r;\n\n\tr = ck_pr_load_uint(&rw->writer);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_rwlock_write_downgrade(ck_rwlock_t *rw)\n{\n\n\tck_pr_inc_uint(&rw->n_readers);\n\tck_rwlock_write_unlock(rw);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_rwlock_locked(ck_rwlock_t *rw)\n{\n\tbool l;\n\n\tl = ck_pr_load_uint(&rw->n_readers) |\n\t    ck_pr_load_uint(&rw->writer);\n\tck_pr_fence_acquire();\n\treturn l;\n}\n\nCK_CC_INLINE static bool\nck_rwlock_write_trylock(ck_rwlock_t *rw)\n{\n\n\tif (ck_pr_fas_uint(&rw->writer, 1) != 0)\n\t\treturn false;\n\n\tck_pr_fence_atomic_load();\n\n\tif (ck_pr_load_uint(&rw->n_readers) != 0) {\n\t\tck_rwlock_write_unlock(rw);\n\t\treturn false;\n\t}\n\n\tck_pr_fence_lock();\n\treturn true;\n}\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_rwlock_write, ck_rwlock_t,\n    ck_rwlock_locked, ck_rwlock_write_trylock)\n\nCK_CC_INLINE static void\nck_rwlock_write_lock(ck_rwlock_t *rw)\n{\n\n\twhile (ck_pr_fas_uint(&rw->writer, 1) != 0)\n\t\tck_pr_stall();\n\n\tck_pr_fence_atomic_load();\n\n\twhile (ck_pr_load_uint(&rw->n_readers) != 0)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_rwlock_write, ck_rwlock_t,\n    ck_rwlock_locked, ck_rwlock_write_lock,\n    ck_rwlock_locked_writer, ck_rwlock_write_unlock)\n\nCK_CC_INLINE static bool\nck_rwlock_read_trylock(ck_rwlock_t *rw)\n{\n\n\tif (ck_pr_load_uint(&rw->writer) != 0)\n\t\treturn false;\n\n\tck_pr_inc_uint(&rw->n_readers);\n\n\t/*\n\t * Serialize with respect to concurrent write\n\t * lock operation.\n\t */\n\tck_pr_fence_atomic_load();\n\n\tif (ck_pr_load_uint(&rw->writer) == 0) {\n\t\tck_pr_fence_lock();\n\t\treturn true;\n\t}\n\n\tck_pr_dec_uint(&rw->n_readers);\n\treturn false;\n}\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_rwlock_read, ck_rwlock_t,\n    ck_rwlock_locked_writer, ck_rwlock_read_trylock)\n\nCK_CC_INLINE static void\nck_rwlock_read_lock(ck_rwlock_t *rw)\n{\n\n\tfor (;;) {\n\t\twhile (ck_pr_load_uint(&rw->writer) != 0)\n\t\t\tck_pr_stall();\n\n\t\tck_pr_inc_uint(&rw->n_readers);\n\n\t\t/*\n\t\t * Serialize with respect to concurrent write\n\t\t * lock operation.\n\t\t */\n\t\tck_pr_fence_atomic_load();\n\n\t\tif (ck_pr_load_uint(&rw->writer) == 0)\n\t\t\tbreak;\n\n\t\tck_pr_dec_uint(&rw->n_readers);\n\t}\n\n\t/* Acquire semantics are necessary. */\n\tck_pr_fence_load();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_rwlock_locked_reader(ck_rwlock_t *rw)\n{\n\n\tck_pr_fence_load();\n\treturn ck_pr_load_uint(&rw->n_readers);\n}\n\nCK_CC_INLINE static void\nck_rwlock_read_unlock(ck_rwlock_t *rw)\n{\n\n\tck_pr_fence_load_atomic();\n\tck_pr_dec_uint(&rw->n_readers);\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_rwlock_read, ck_rwlock_t,\n    ck_rwlock_locked_writer, ck_rwlock_read_lock,\n    ck_rwlock_locked_reader, ck_rwlock_read_unlock)\n\n/*\n * Recursive writer reader-writer lock implementation.\n */\nstruct ck_rwlock_recursive {\n\tstruct ck_rwlock rw;\n\tunsigned int wc;\n};\ntypedef struct ck_rwlock_recursive ck_rwlock_recursive_t;\n\n#define CK_RWLOCK_RECURSIVE_INITIALIZER {CK_RWLOCK_INITIALIZER, 0}\n\nCK_CC_INLINE static void\nck_rwlock_recursive_write_lock(ck_rwlock_recursive_t *rw, unsigned int tid)\n{\n\tunsigned int o;\n\n\to = ck_pr_load_uint(&rw->rw.writer);\n\tif (o == tid)\n\t\tgoto leave;\n\n\twhile (ck_pr_cas_uint(&rw->rw.writer, 0, tid) == false)\n\t\tck_pr_stall();\n\n\tck_pr_fence_atomic_load();\n\n\twhile (ck_pr_load_uint(&rw->rw.n_readers) != 0)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\nleave:\n\trw->wc++;\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_rwlock_recursive_write_trylock(ck_rwlock_recursive_t *rw, unsigned int tid)\n{\n\tunsigned int o;\n\n\to = ck_pr_load_uint(&rw->rw.writer);\n\tif (o == tid)\n\t\tgoto leave;\n\n\tif (ck_pr_cas_uint(&rw->rw.writer, 0, tid) == false)\n\t\treturn false;\n\n\tck_pr_fence_atomic_load();\n\n\tif (ck_pr_load_uint(&rw->rw.n_readers) != 0) {\n\t\tck_pr_store_uint(&rw->rw.writer, 0);\n\t\treturn false;\n\t}\n\n\tck_pr_fence_lock();\nleave:\n\trw->wc++;\n\treturn true;\n}\n\nCK_CC_INLINE static void\nck_rwlock_recursive_write_unlock(ck_rwlock_recursive_t *rw)\n{\n\n\tif (--rw->wc == 0) {\n\t\tck_pr_fence_unlock();\n\t\tck_pr_store_uint(&rw->rw.writer, 0);\n\t}\n\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_rwlock_recursive_read_lock(ck_rwlock_recursive_t *rw)\n{\n\n\tck_rwlock_read_lock(&rw->rw);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_rwlock_recursive_read_trylock(ck_rwlock_recursive_t *rw)\n{\n\n\treturn ck_rwlock_read_trylock(&rw->rw);\n}\n\nCK_CC_INLINE static void\nck_rwlock_recursive_read_unlock(ck_rwlock_recursive_t *rw)\n{\n\n\tck_rwlock_read_unlock(&rw->rw);\n\treturn;\n}\n\n#endif /* CK_RWLOCK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_sequence.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SEQUENCE_H\n#define CK_SEQUENCE_H\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\nstruct ck_sequence {\n\tunsigned int sequence;\n};\ntypedef struct ck_sequence ck_sequence_t;\n\n#define CK_SEQUENCE_INITIALIZER { .sequence = 0 }\n\nCK_CC_INLINE static void\nck_sequence_init(struct ck_sequence *sq)\n{\n\n\tck_pr_store_uint(&sq->sequence, 0);\n\treturn;\n}\n\nCK_CC_INLINE static unsigned int\nck_sequence_read_begin(const struct ck_sequence *sq)\n{\n\tunsigned int version;\n\n\tfor (;;) {\n\t\tversion = ck_pr_load_uint(&sq->sequence);\n\n\t\t/*\n\t\t * If a sequence is even then associated data may be in a\n\t\t * consistent state.\n\t\t */\n\t\tif (CK_CC_LIKELY((version & 1) == 0))\n\t\t\tbreak;\n\n\t\t/*\n\t\t * If a sequence is odd then a thread is in the middle of an\n\t\t * update. Retry the read to avoid operating on inconsistent\n\t\t * data.\n\t\t */\n\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_load();\n\treturn version;\n}\n\nCK_CC_INLINE static bool\nck_sequence_read_retry(const struct ck_sequence *sq, unsigned int version)\n{\n\n\t/*\n\t * If the sequence number was updated then a read should be\n\t * re-attempted.\n\t */\n\tck_pr_fence_load();\n\treturn ck_pr_load_uint(&sq->sequence) != version;\n}\n\n#define CK_SEQUENCE_READ(seqlock, version) \t\t\t\t\t\t\\\n\tfor (*(version) = 1;\t\t\t\t\t\t\t\t\\\n\t    (*(version) != 0) && (*(version) = ck_sequence_read_begin(seqlock), 1);\t\\\n\t    *(version) = ck_sequence_read_retry(seqlock, *(version)))\n\n/*\n * This must be called after a successful mutex acquisition.\n */\nCK_CC_INLINE static void\nck_sequence_write_begin(struct ck_sequence *sq)\n{\n\n\t/*\n\t * Increment the sequence to an odd number to indicate\n\t * the beginning of a write update.\n\t */\n\tck_pr_store_uint(&sq->sequence, sq->sequence + 1);\n\tck_pr_fence_store();\n\treturn;\n}\n\n/*\n * This must be called before mutex ownership is relinquished.\n */\nCK_CC_INLINE static void\nck_sequence_write_end(struct ck_sequence *sq)\n{\n\n\t/*\n\t * Increment the sequence to an even number to indicate\n\t * completion of a write update.\n\t */\n\tck_pr_fence_store();\n\tck_pr_store_uint(&sq->sequence, sq->sequence + 1);\n\treturn;\n}\n\n#endif /* CK_SEQUENCE_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_spinlock.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_H\n#define CK_SPINLOCK_H\n\n#include \"spinlock/anderson.h\"\n#include \"spinlock/cas.h\"\n#include \"spinlock/clh.h\"\n#include \"spinlock/dec.h\"\n#include \"spinlock/fas.h\"\n#include \"spinlock/hclh.h\"\n#include \"spinlock/mcs.h\"\n#include \"spinlock/ticket.h\"\n\n/*\n * On tested x86, x86_64, PPC64 and SPARC64 targets,\n * ck_spinlock_fas proved to have lowest latency\n * in fast path testing or negligible degradation\n * from faster but less robust implementations.\n */\n#define CK_SPINLOCK_INITIALIZER CK_SPINLOCK_FAS_INITIALIZER\n#define ck_spinlock_t\t\tck_spinlock_fas_t\n#define ck_spinlock_init(x)\tck_spinlock_fas_init(x)\n#define ck_spinlock_lock(x)\tck_spinlock_fas_lock(x)\n#define ck_spinlock_lock_eb(x)\tck_spinlock_fas_lock_eb(x)\n#define ck_spinlock_unlock(x)\tck_spinlock_fas_unlock(x)\n#define ck_spinlock_locked(x)\tck_spinlock_fas_locked(x)\n#define ck_spinlock_trylock(x)\tck_spinlock_fas_trylock(x)\n\nCK_ELIDE_PROTOTYPE(ck_spinlock, ck_spinlock_t,\n    ck_spinlock_locked, ck_spinlock_lock,\n    ck_spinlock_locked, ck_spinlock_unlock)\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock, ck_spinlock_t,\n    ck_spinlock_locked, ck_spinlock_trylock)\n\n#endif /* CK_SPINLOCK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_stack.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_STACK_H\n#define CK_STACK_H\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\nstruct ck_stack_entry {\n\tstruct ck_stack_entry *next;\n};\ntypedef struct ck_stack_entry ck_stack_entry_t;\n\nstruct ck_stack {\n\tstruct ck_stack_entry *head;\n\tchar *generation CK_CC_PACKED;\n} CK_CC_ALIASED;\ntypedef struct ck_stack ck_stack_t;\n\n#define CK_STACK_INITIALIZER { NULL, NULL }\n\n#ifndef CK_F_STACK_PUSH_UPMC\n#define CK_F_STACK_PUSH_UPMC\n/*\n * Stack producer operation safe for multiple unique producers and multiple consumers.\n */\nCK_CC_INLINE static void\nck_stack_push_upmc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\tstruct ck_stack_entry *stack;\n\n\tstack = ck_pr_load_ptr(&target->head);\n\tentry->next = stack;\n\tck_pr_fence_store();\n\n\twhile (ck_pr_cas_ptr_value(&target->head, stack, entry, &stack) == false) {\n\t\tentry->next = stack;\n\t\tck_pr_fence_store();\n\t}\n\n\treturn;\n}\n#endif /* CK_F_STACK_PUSH_UPMC */\n\n#ifndef CK_F_STACK_TRYPUSH_UPMC\n#define CK_F_STACK_TRYPUSH_UPMC\n/*\n * Stack producer operation for multiple unique producers and multiple consumers.\n * Returns true on success and false on failure.\n */\nCK_CC_INLINE static bool\nck_stack_trypush_upmc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\tstruct ck_stack_entry *stack;\n\n\tstack = ck_pr_load_ptr(&target->head);\n\tentry->next = stack;\n\tck_pr_fence_store();\n\n\treturn ck_pr_cas_ptr(&target->head, stack, entry);\n}\n#endif /* CK_F_STACK_TRYPUSH_UPMC */\n\n#ifndef CK_F_STACK_POP_UPMC\n#define CK_F_STACK_POP_UPMC\n/*\n * Stack consumer operation safe for multiple unique producers and multiple consumers.\n */\nCK_CC_INLINE static struct ck_stack_entry *\nck_stack_pop_upmc(struct ck_stack *target)\n{\n\tstruct ck_stack_entry *entry, *next;\n\n\tentry = ck_pr_load_ptr(&target->head);\n\tif (entry == NULL)\n\t\treturn NULL;\n\n\tck_pr_fence_load();\n\tnext = entry->next;\n\twhile (ck_pr_cas_ptr_value(&target->head, entry, next, &entry) == false) {\n\t\tif (entry == NULL)\n\t\t\tbreak;\n\n\t\tck_pr_fence_load();\n\t\tnext = entry->next;\n\t}\n\n\treturn entry;\n}\n#endif\n\n#ifndef CK_F_STACK_TRYPOP_UPMC\n#define CK_F_STACK_TRYPOP_UPMC\n/*\n * Stack production operation for multiple unique producers and multiple consumers.\n * Returns true on success and false on failure. The value pointed to by the second\n * argument is set to a valid ck_stack_entry_t reference if true is returned. If\n * false is returned, then the value pointed to by the second argument is undefined.\n */\nCK_CC_INLINE static bool\nck_stack_trypop_upmc(struct ck_stack *target, struct ck_stack_entry **r)\n{\n\tstruct ck_stack_entry *entry;\n\n\tentry = ck_pr_load_ptr(&target->head);\n\tif (entry == NULL)\n\t\treturn false;\n\n\tck_pr_fence_load();\n\tif (ck_pr_cas_ptr(&target->head, entry, entry->next) == true) {\n\t\t*r = entry;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n#endif /* CK_F_STACK_TRYPOP_UPMC */\n\n#ifndef CK_F_STACK_BATCH_POP_UPMC\n#define CK_F_STACK_BATCH_POP_UPMC\n/*\n * Pop all items off the stack.\n */\nCK_CC_INLINE static struct ck_stack_entry *\nck_stack_batch_pop_upmc(struct ck_stack *target)\n{\n\tstruct ck_stack_entry *entry;\n\n\tentry = ck_pr_fas_ptr(&target->head, NULL);\n\tck_pr_fence_load();\n\treturn entry;\n}\n#endif /* CK_F_STACK_BATCH_POP_UPMC */\n\n#ifndef CK_F_STACK_PUSH_MPMC\n#define CK_F_STACK_PUSH_MPMC\n/*\n * Stack producer operation safe for multiple producers and multiple consumers.\n */\nCK_CC_INLINE static void\nck_stack_push_mpmc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\n\tck_stack_push_upmc(target, entry);\n\treturn;\n}\n#endif /* CK_F_STACK_PUSH_MPMC */\n\n#ifndef CK_F_STACK_TRYPUSH_MPMC\n#define CK_F_STACK_TRYPUSH_MPMC\n/*\n * Stack producer operation safe for multiple producers and multiple consumers.\n */\nCK_CC_INLINE static bool\nck_stack_trypush_mpmc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\n\treturn ck_stack_trypush_upmc(target, entry);\n}\n#endif /* CK_F_STACK_TRYPUSH_MPMC */\n\n#ifdef CK_F_PR_CAS_PTR_2_VALUE\n#ifndef CK_F_STACK_POP_MPMC\n#define CK_F_STACK_POP_MPMC\n/*\n * Stack consumer operation safe for multiple producers and multiple consumers.\n */\nCK_CC_INLINE static struct ck_stack_entry *\nck_stack_pop_mpmc(struct ck_stack *target)\n{\n\tstruct ck_stack original, update;\n\n\toriginal.generation = ck_pr_load_ptr(&target->generation);\n\tck_pr_fence_load();\n\toriginal.head = ck_pr_load_ptr(&target->head);\n\tif (original.head == NULL)\n\t\treturn NULL;\n\n\t/* Order with respect to next pointer. */\n\tck_pr_fence_load();\n\n\tupdate.generation = original.generation + 1;\n\tupdate.head = original.head->next;\n\n\twhile (ck_pr_cas_ptr_2_value(target, &original, &update, &original) == false) {\n\t\tif (original.head == NULL)\n\t\t\treturn NULL;\n\n\t\tupdate.generation = original.generation + 1;\n\n\t\t/* Order with respect to next pointer. */\n\t\tck_pr_fence_load();\n\t\tupdate.head = original.head->next;\n\t}\n\n\treturn original.head;\n}\n#endif /* CK_F_STACK_POP_MPMC */\n\n#ifndef CK_F_STACK_TRYPOP_MPMC\n#define CK_F_STACK_TRYPOP_MPMC\nCK_CC_INLINE static bool\nck_stack_trypop_mpmc(struct ck_stack *target, struct ck_stack_entry **r)\n{\n\tstruct ck_stack original, update;\n\n\toriginal.generation = ck_pr_load_ptr(&target->generation);\n\tck_pr_fence_load();\n\toriginal.head = ck_pr_load_ptr(&target->head);\n\tif (original.head == NULL)\n\t\treturn false;\n\n\tupdate.generation = original.generation + 1;\n\tck_pr_fence_load();\n\tupdate.head = original.head->next;\n\n\tif (ck_pr_cas_ptr_2_value(target, &original, &update, &original) == true) {\n\t\t*r = original.head;\n\t\treturn true;\n\t}\n\n\treturn false;\n}\n#endif /* CK_F_STACK_TRYPOP_MPMC */\n#endif /* CK_F_PR_CAS_PTR_2_VALUE */\n\n#ifndef CK_F_STACK_BATCH_POP_MPMC\n#define CK_F_STACK_BATCH_POP_MPMC\n/*\n * This is equivalent to the UP/MC version as NULL does not need a\n * a generation count.\n */\nCK_CC_INLINE static struct ck_stack_entry *\nck_stack_batch_pop_mpmc(struct ck_stack *target)\n{\n\n\treturn ck_stack_batch_pop_upmc(target);\n}\n#endif /* CK_F_STACK_BATCH_POP_MPMC */\n\n#ifndef CK_F_STACK_PUSH_MPNC\n#define CK_F_STACK_PUSH_MPNC\n/*\n * Stack producer operation safe with no concurrent consumers.\n */\nCK_CC_INLINE static void\nck_stack_push_mpnc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\tstruct ck_stack_entry *stack;\n\n\tentry->next = NULL;\n\tck_pr_fence_store_atomic();\n\tstack = ck_pr_fas_ptr(&target->head, entry);\n\tck_pr_store_ptr(&entry->next, stack);\n\tck_pr_fence_store();\n\n\treturn;\n}\n#endif /* CK_F_STACK_PUSH_MPNC */\n\n/*\n * Stack producer operation for single producer and no concurrent consumers.\n */\nCK_CC_INLINE static void\nck_stack_push_spnc(struct ck_stack *target, struct ck_stack_entry *entry)\n{\n\n\tentry->next = target->head;\n\ttarget->head = entry;\n\treturn;\n}\n\n/*\n * Stack consumer operation for no concurrent producers and single consumer.\n */\nCK_CC_INLINE static struct ck_stack_entry *\nck_stack_pop_npsc(struct ck_stack *target)\n{\n\tstruct ck_stack_entry *n;\n\n\tif (target->head == NULL)\n\t\treturn NULL;\n\n\tn = target->head;\n\ttarget->head = n->next;\n\n\treturn n;\n}\n\n/*\n * Pop all items off a stack.\n */\nCK_CC_INLINE static struct ck_stack_entry *\nck_stack_batch_pop_npsc(struct ck_stack *target)\n{\n\tstruct ck_stack_entry *n;\n\n\tn = target->head;\n\ttarget->head = NULL;\n\n\treturn n;\n}\n\n/*\n * Stack initialization function. Guarantees initialization across processors.\n */\nCK_CC_INLINE static void\nck_stack_init(struct ck_stack *stack)\n{\n\n\tstack->head = NULL;\n\tstack->generation = NULL;\n\treturn;\n}\n\n/* Defines a container_of functions for */\n#define CK_STACK_CONTAINER(T, M, N) CK_CC_CONTAINER(ck_stack_entry_t, T, M, N)\n\n#define CK_STACK_ISEMPTY(m) ((m)->head == NULL)\n#define CK_STACK_FIRST(s)   ((s)->head)\n#define CK_STACK_NEXT(m)    ((m)->next)\n#define CK_STACK_FOREACH(stack, entry)\t\t\t\t\\\n\tfor ((entry) = CK_STACK_FIRST(stack);\t\t\t\\\n\t     (entry) != NULL;\t\t\t\t\t\\\n\t     (entry) = CK_STACK_NEXT(entry))\n#define CK_STACK_FOREACH_SAFE(stack, entry, T)\t\t\t\\\n\tfor ((entry) = CK_STACK_FIRST(stack);\t\t\t\\\n\t     (entry) != NULL && ((T) = (entry)->next, 1);\t\\\n\t     (entry) = (T))\n\n#endif /* CK_STACK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_stdbool.h",
    "content": "/*\n * Copyright 2015 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(__FreeBSD__) && defined(_KERNEL)\n#include <sys/types.h>\n#else\n#include <stdbool.h>\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_stddef.h",
    "content": "/*\n * Copyright 2015 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(__FreeBSD__) && defined(_KERNEL)\n#include <sys/stddef.h>\n#else\n#include <stddef.h>\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_stdint.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(__linux__) && defined(__KERNEL__)\n#include <linux/kernel.h>\n#include <linux/types.h>\n#elif defined(__FreeBSD__) && defined(_KERNEL)\n#include <sys/stdint.h>\n#else\n#include <stdint.h>\n#endif /* __linux__ && __KERNEL__ */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_stdlib.h",
    "content": "/*\n * Copyright 2015 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(__FreeBSD__) && defined(_KERNEL)\n#include <sys/systm.h>\n#else\n#include <stdlib.h>\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_string.h",
    "content": "/*\n * Copyright 2015 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#if defined(__FreeBSD__) && defined(_KERNEL)\n#include <sys/systm.h>\n#else\n#include <string.h>\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_swlock.h",
    "content": "/*\n * Copyright 2014 Jaidev Sridhar.\n * Copyright 2014 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SWLOCK_H\n#define CK_SWLOCK_H\n\n#include <ck_elide.h>\n#include <ck_limits.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\nstruct ck_swlock {\n\tuint32_t value;\n};\ntypedef struct ck_swlock ck_swlock_t;\n\n#define CK_SWLOCK_INITIALIZER\t{0}\n#define CK_SWLOCK_WRITER_BIT\t(1UL << 31)\n#define CK_SWLOCK_LATCH_BIT\t(1UL << 30)\n#define CK_SWLOCK_WRITER_MASK\t(CK_SWLOCK_LATCH_BIT | CK_SWLOCK_WRITER_BIT)\n#define CK_SWLOCK_READER_MASK   (UINT32_MAX ^ CK_SWLOCK_WRITER_MASK)\n\nCK_CC_INLINE static void\nck_swlock_init(struct ck_swlock *rw)\n{\n\n\trw->value = 0;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_swlock_write_unlock(ck_swlock_t *rw)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_and_32(&rw->value, CK_SWLOCK_READER_MASK);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_swlock_locked_writer(ck_swlock_t *rw)\n{\n\tbool r;\n\n\tr = ck_pr_load_32(&rw->value) & CK_SWLOCK_WRITER_BIT;\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_swlock_write_downgrade(ck_swlock_t *rw)\n{\n\n\tck_pr_inc_32(&rw->value);\n\tck_swlock_write_unlock(rw);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_swlock_locked(ck_swlock_t *rw)\n{\n\tbool r;\n\n\tr = ck_pr_load_32(&rw->value);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static bool\nck_swlock_write_trylock(ck_swlock_t *rw)\n{\n\tbool r;\n\n\tr = ck_pr_cas_32(&rw->value, 0, CK_SWLOCK_WRITER_BIT);\n\tck_pr_fence_lock();\n\treturn r;\n}\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_swlock_write, ck_swlock_t,\n    ck_swlock_locked, ck_swlock_write_trylock)\n\nCK_CC_INLINE static void\nck_swlock_write_lock(ck_swlock_t *rw)\n{\n\n\tck_pr_or_32(&rw->value, CK_SWLOCK_WRITER_BIT);\n\twhile (ck_pr_load_32(&rw->value) & CK_SWLOCK_READER_MASK)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_swlock_write_latch(ck_swlock_t *rw)\n{\n\n\t/* Publish intent to acquire lock. */\n\tck_pr_or_32(&rw->value, CK_SWLOCK_WRITER_BIT);\n\n\t/* Stall until readers have seen the writer and cleared. */\n\twhile (ck_pr_cas_32(&rw->value, CK_SWLOCK_WRITER_BIT,\n\t    CK_SWLOCK_WRITER_MASK) == false)  {\n\t\tdo {\n\t\t\tck_pr_stall();\n\t\t} while (ck_pr_load_32(&rw->value) != CK_SWLOCK_WRITER_BIT);\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_swlock_write_unlatch(ck_swlock_t *rw)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_store_32(&rw->value, 0);\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_swlock_write, ck_swlock_t,\n    ck_swlock_locked, ck_swlock_write_lock,\n    ck_swlock_locked_writer, ck_swlock_write_unlock)\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_swlock_read, ck_swlock_t,\n    ck_swlock_locked_writer, ck_swlock_read_trylock)\n\nCK_CC_INLINE static bool\nck_swlock_read_trylock(ck_swlock_t *rw)\n{\n\tuint32_t l = ck_pr_load_32(&rw->value);\n\n\tif (l & CK_SWLOCK_WRITER_BIT)\n\t\treturn false;\n\n\tl = ck_pr_faa_32(&rw->value, 1) & CK_SWLOCK_WRITER_MASK;\n\tif (l == CK_SWLOCK_WRITER_BIT)\n\t\tck_pr_dec_32(&rw->value);\n\n\tck_pr_fence_lock();\n\treturn l == 0;\n}\n\nCK_CC_INLINE static void\nck_swlock_read_lock(ck_swlock_t *rw)\n{\n\tuint32_t l;\n\n\tfor (;;) {\n\t\twhile (ck_pr_load_32(&rw->value) & CK_SWLOCK_WRITER_BIT)\n\t\t\tck_pr_stall();\n\n\t\tl = ck_pr_faa_32(&rw->value, 1) & CK_SWLOCK_WRITER_MASK;\n\t\tif (l == 0)\n\t\t\tbreak;\n\n\t\t/*\n\t\t * If the latch bit has not been set, then the writer would\n\t\t * have observed the reader and will wait to completion of\n\t\t * read-side critical section.\n\t\t */\n\t\tif (l == CK_SWLOCK_WRITER_BIT)\n\t\t\tck_pr_dec_32(&rw->value);\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_swlock_locked_reader(ck_swlock_t *rw)\n{\n\n\tck_pr_fence_load();\n\treturn ck_pr_load_32(&rw->value) & CK_SWLOCK_READER_MASK;\n}\n\nCK_CC_INLINE static void\nck_swlock_read_unlock(ck_swlock_t *rw)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_dec_32(&rw->value);\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_swlock_read, ck_swlock_t,\n    ck_swlock_locked_writer, ck_swlock_read_lock,\n    ck_swlock_locked_reader, ck_swlock_read_unlock)\n\n#endif /* CK_SWLOCK_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/ck_tflock.h",
    "content": "/*\n * Copyright 2014 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_TFLOCK_TICKET_H\n#define CK_TFLOCK_TICKET_H\n\n/*\n * This is an implementation of task-fair locks derived from the work\n * described in:\n *\tJohn M. Mellor-Crummey and Michael L. Scott. 1991.\n *\tScalable reader-writer synchronization for shared-memory\n *\tmultiprocessors. SIGPLAN Not. 26, 7 (April 1991), 106-113.\n */\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n\nstruct ck_tflock_ticket {\n\tuint32_t request;\n\tuint32_t completion;\n};\ntypedef struct ck_tflock_ticket ck_tflock_ticket_t;\n\n#define CK_TFLOCK_TICKET_INITIALIZER { 0, 0 }\n\n#define CK_TFLOCK_TICKET_RC_INCR\t0x10000U\t/* Read-side increment. */\n#define CK_TFLOCK_TICKET_WC_INCR\t0x1U\t\t/* Write-side increment. */\n#define CK_TFLOCK_TICKET_W_MASK\t\t0xffffU\t\t/* Write-side mask. */\n#define CK_TFLOCK_TICKET_WC_TOPMSK\t0x8000U\t\t/* Write clear mask for overflow. */\n#define CK_TFLOCK_TICKET_RC_TOPMSK\t0x80000000U\t/* Read clear mask for overflow. */\n\nCK_CC_INLINE static uint32_t\nck_tflock_ticket_fca_32(uint32_t *target, uint32_t mask, uint32_t delta)\n{\n\tuint32_t snapshot = ck_pr_load_32(target);\n\tuint32_t goal;\n\n\tfor (;;) {\n\t\tgoal = (snapshot & ~mask) + delta;\n\t\tif (ck_pr_cas_32_value(target, snapshot, goal, &snapshot) == true)\n\t\t\tbreak;\n\n\t\tck_pr_stall();\n\t}\n\n\treturn snapshot;\n}\n\nCK_CC_INLINE static void\nck_tflock_ticket_init(struct ck_tflock_ticket *pf)\n{\n\n\tpf->request = pf->completion = 0;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_tflock_ticket_write_lock(struct ck_tflock_ticket *lock)\n{\n\tuint32_t previous;\n\n\tprevious = ck_tflock_ticket_fca_32(&lock->request, CK_TFLOCK_TICKET_WC_TOPMSK,\n\t    CK_TFLOCK_TICKET_WC_INCR);\n\tck_pr_fence_atomic_load();\n\twhile (ck_pr_load_32(&lock->completion) != previous)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_tflock_ticket_write_unlock(struct ck_tflock_ticket *lock)\n{\n\n\tck_pr_fence_unlock();\n\tck_tflock_ticket_fca_32(&lock->completion, CK_TFLOCK_TICKET_WC_TOPMSK,\n\t    CK_TFLOCK_TICKET_WC_INCR);\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_tflock_ticket_read_lock(struct ck_tflock_ticket *lock)\n{\n\tuint32_t previous;\n\n\tprevious = ck_tflock_ticket_fca_32(&lock->request,\n\t    CK_TFLOCK_TICKET_RC_TOPMSK, CK_TFLOCK_TICKET_RC_INCR) &\n\t    CK_TFLOCK_TICKET_W_MASK;\n\n\tck_pr_fence_atomic_load();\n\n\twhile ((ck_pr_load_32(&lock->completion) &\n\t    CK_TFLOCK_TICKET_W_MASK) != previous) {\n\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_tflock_ticket_read_unlock(struct ck_tflock_ticket *lock)\n{\n\n\tck_pr_fence_unlock();\n\tck_tflock_ticket_fca_32(&lock->completion, CK_TFLOCK_TICKET_RC_TOPMSK,\n\t    CK_TFLOCK_TICKET_RC_INCR);\n\treturn;\n}\n\n#endif /* CK_TFLOCK_TICKET_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/aarch64/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_16\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_64\n#define CK_F_PR_ADD_8\n#define CK_F_PR_ADD_CHAR\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_SHORT\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_16\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_64\n#define CK_F_PR_AND_8\n#define CK_F_PR_AND_CHAR\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_SHORT\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_BARRIER\n#define CK_F_PR_CAS_16\n#define CK_F_PR_CAS_16_VALUE\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_64_2\n#define CK_F_PR_CAS_64_2_VALUE\n#define CK_F_PR_CAS_DOUBLE\n#define CK_F_PR_CAS_DOUBLE_VALUE\n#define CK_F_PR_CAS_8\n#define CK_F_PR_CAS_8_VALUE\n#define CK_F_PR_CAS_CHAR\n#define CK_F_PR_CAS_CHAR_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_2\n#define CK_F_PR_CAS_PTR_2_VALUE\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_SHORT\n#define CK_F_PR_CAS_SHORT_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_16\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_64\n#define CK_F_PR_DEC_8\n#define CK_F_PR_DEC_CHAR\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_SHORT\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_FAA_16\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_64\n#define CK_F_PR_FAA_8\n#define CK_F_PR_FAA_CHAR\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_SHORT\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_16\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_64\n#define CK_F_PR_FAS_8\n#define CK_F_PR_FAS_CHAR\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_SHORT\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FENCE_ATOMIC\n#define CK_F_PR_FENCE_ATOMIC_LOAD\n#define CK_F_PR_FENCE_ATOMIC_STORE\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_ATOMIC\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_LOAD_STORE\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STORE_ATOMIC\n#define CK_F_PR_FENCE_STORE_LOAD\n#define CK_F_PR_FENCE_STRICT_ATOMIC\n#define CK_F_PR_FENCE_STRICT_ATOMIC_LOAD\n#define CK_F_PR_FENCE_STRICT_ATOMIC_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_ATOMIC\n#define CK_F_PR_FENCE_STRICT_LOAD_STORE\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_FENCE_STRICT_STORE_ATOMIC\n#define CK_F_PR_FENCE_STRICT_STORE_LOAD\n#define CK_F_PR_INC_16\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_64\n#define CK_F_PR_INC_8\n#define CK_F_PR_INC_CHAR\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_SHORT\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_DOUBLE\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_SHORT\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_NEG_16\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_64\n#define CK_F_PR_NEG_8\n#define CK_F_PR_NEG_CHAR\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_SHORT\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NOT_16\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_64\n#define CK_F_PR_NOT_8\n#define CK_F_PR_NOT_CHAR\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_SHORT\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_16\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_64\n#define CK_F_PR_OR_8\n#define CK_F_PR_OR_CHAR\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_SHORT\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_DOUBLE\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_SHORT\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_16\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_64\n#define CK_F_PR_SUB_8\n#define CK_F_PR_SUB_CHAR\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_SHORT\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_16\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_64\n#define CK_F_PR_XOR_8\n#define CK_F_PR_XOR_CHAR\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_SHORT\n#define CK_F_PR_XOR_UINT\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/aarch64/ck_pr.h",
    "content": "/*\n * Copyright 2009-2016 Samy Al Bahra.\n * Copyright 2013-2016 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_AARCH64_H\n#define CK_PR_AARCH64_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Minimum interface requirement met.\n */\n#define CK_F_PR\n\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\n\t__asm__ __volatile__(\"\" ::: \"memory\");\n\treturn;\n}\n\n#define CK_DMB_SY __asm __volatile(\"dmb ish\" : : \"r\" (0) : \"memory\")\n#define CK_DMB_LD __asm __volatile(\"dmb ishld\" : : \"r\" (0) : \"memory\")\n#define CK_DMB_ST __asm __volatile(\"dmb ishst\" : : \"r\" (0) : \"memory\")\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\tI;\t\t\t\t\t\\\n\t}\n\nCK_PR_FENCE(atomic, CK_DMB_ST)\nCK_PR_FENCE(atomic_store, CK_DMB_ST)\nCK_PR_FENCE(atomic_load, CK_DMB_SY)\nCK_PR_FENCE(store_atomic, CK_DMB_ST)\nCK_PR_FENCE(load_atomic, CK_DMB_SY)\nCK_PR_FENCE(store, CK_DMB_ST)\nCK_PR_FENCE(store_load, CK_DMB_SY)\nCK_PR_FENCE(load, CK_DMB_LD)\nCK_PR_FENCE(load_store, CK_DMB_SY)\nCK_PR_FENCE(memory, CK_DMB_SY)\nCK_PR_FENCE(acquire, CK_DMB_SY)\nCK_PR_FENCE(release, CK_DMB_SY)\nCK_PR_FENCE(acqrel, CK_DMB_SY)\nCK_PR_FENCE(lock, CK_DMB_SY)\nCK_PR_FENCE(unlock, CK_DMB_SY)\n\n#undef CK_PR_FENCE\n\n#undef CK_DMB_SI\n#undef CK_DMB_LD\n#undef CK_DMB_ST\n\n#define CK_PR_LOAD(S, M, T, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tlong r = 0;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %w0, [%1];\"\t\t\\\n\t\t\t\t\t: \"=r\" (r)\t\t\\\n\t\t\t\t\t: \"r\"  (target)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn ((T)r);\t\t\t\t\t\\\n\t}\n#define CK_PR_LOAD_64(S, M, T, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tlong r = 0;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %0, [%1];\"\t\t\\\n\t\t\t\t\t: \"=r\" (r)\t\t\\\n\t\t\t\t\t: \"r\"  (target)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn ((T)r);\t\t\t\t\t\\\n\t}\n\n\nCK_PR_LOAD_64(ptr, void, void *, \"ldr\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, I)\n#define CK_PR_LOAD_S_64(S, T, I) CK_PR_LOAD_64(S, T, T, I)\n\nCK_PR_LOAD_S_64(64, uint64_t, \"ldr\")\nCK_PR_LOAD_S(32, uint32_t, \"ldr\")\nCK_PR_LOAD_S(16, uint16_t, \"ldrh\")\nCK_PR_LOAD_S(8, uint8_t, \"ldrb\")\nCK_PR_LOAD_S(uint, unsigned int, \"ldr\")\nCK_PR_LOAD_S(int, int, \"ldr\")\nCK_PR_LOAD_S(short, short, \"ldrh\")\nCK_PR_LOAD_S(char, char, \"ldrb\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_LOAD_S_64(double, double, \"ldr\")\n#endif\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD_S_64\n#undef CK_PR_LOAD\n#undef CK_PR_LAOD_64\n\n#define CK_PR_STORE(S, M, T, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %w1, [%0]\"\t\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"r\" (target),\t\t\\\n\t\t\t\t\t  \"r\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n#define CK_PR_STORE_64(S, M, T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, [%0]\"\t\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"r\" (target),\t\t\\\n\t\t\t\t\t  \"r\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE_64(ptr, void, const void *, \"str\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, I)\n#define CK_PR_STORE_S_64(S, T, I) CK_PR_STORE_64(S, T, T, I)\n\nCK_PR_STORE_S_64(64, uint64_t, \"str\")\nCK_PR_STORE_S(32, uint32_t, \"str\")\nCK_PR_STORE_S(16, uint16_t, \"strh\")\nCK_PR_STORE_S(8, uint8_t, \"strb\")\nCK_PR_STORE_S(uint, unsigned int, \"str\")\nCK_PR_STORE_S(int, int, \"str\")\nCK_PR_STORE_S(short, short, \"strh\")\nCK_PR_STORE_S(char, char, \"strb\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_STORE_S_64(double, double, \"str\")\n#endif\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE_S_64\n#undef CK_PR_STORE\n#undef CK_PR_STORE_64\n\n#ifdef CK_MD_LSE_ENABLE\n#include \"ck_pr_lse.h\"\n#else\n#include \"ck_pr_llsc.h\"\n#endif\n\n/*\n * ck_pr_neg_*() functions can only be implemented via LL/SC, as there are no\n * LSE alternatives.\n */\n#define CK_PR_NEG(N, M, T, W, R)\t\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_neg_##N(M *target)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                T previous = 0;\t\t\t\t\t\\\n                T tmp = 0;\t\t\t\t\t\\\n                __asm__ __volatile__(\"1:\"\t\t\t\\\n                                     \"ldxr\" W \" %\" R \"0, [%2];\"\t\\\n                                     \"neg %\" R \"0, %\" R \"0;\"\t\\\n                                     \"stxr\" W \" %w1, %\" R \"0, [%2];\"\t\\\n                                     \"cbnz %w1, 1b;\"\t\t\\\n                                        : \"=&r\" (previous),\t\\\n                                          \"=&r\" (tmp)\t\t\\\n                                        : \"r\"   (target)\t\\\n                                        : \"memory\", \"cc\");\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\nCK_PR_NEG(ptr, void, void *, \"\", \"\")\nCK_PR_NEG(64, uint64_t, uint64_t, \"\", \"\")\n\n#define CK_PR_NEG_S(S, T, W)\t\t\t\t\t\\\n        CK_PR_NEG(S, T, T, W, \"w\")\t\t\t\t\\\n\nCK_PR_NEG_S(32, uint32_t, \"\")\nCK_PR_NEG_S(uint, unsigned int, \"\")\nCK_PR_NEG_S(int, int, \"\")\nCK_PR_NEG_S(16, uint16_t, \"h\")\nCK_PR_NEG_S(8, uint8_t, \"b\")\nCK_PR_NEG_S(short, short, \"h\")\nCK_PR_NEG_S(char, char, \"b\")\n\n#undef CK_PR_NEG_S\n#undef CK_PR_NEG\n\n#endif /* CK_PR_AARCH64_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/aarch64/ck_pr_llsc.h",
    "content": "/*\n * Copyright 2009-2016 Samy Al Bahra.\n * Copyright 2013-2016 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_AARCH64_LLSC_H\n#define CK_PR_AARCH64_LLSC_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\nCK_CC_INLINE static bool\nck_pr_cas_64_2_value(uint64_t target[2], uint64_t compare[2], uint64_t set[2], uint64_t value[2])\n{\n        uint64_t tmp1, tmp2;\n\n        __asm__ __volatile__(\"1:\"\n                             \"ldxp %0, %1, [%4];\"\n                             \"mov %2, %0;\"\n                             \"mov %3, %1;\"\n                             \"eor %0, %0, %5;\"\n                             \"eor %1, %1, %6;\"\n                             \"orr %1, %0, %1;\"\n                             \"mov %w0, #0;\"\n                             \"cbnz %1, 2f;\"\n                             \"stxp %w0, %7, %8, [%4];\"\n                             \"cbnz %w0, 1b;\"\n                             \"mov %w0, #1;\"\n                             \"2:\"\n                             : \"=&r\" (tmp1), \"=&r\" (tmp2), \"=&r\" (value[0]), \"=&r\" (value[1])\n                             : \"r\" (target), \"r\" (compare[0]), \"r\" (compare[1]), \"r\" (set[0]), \"r\" (set[1])\n                             : \"cc\", \"memory\");\n\n        return (tmp1);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2_value(void *target, void *compare, void *set, void *value)\n{\n        return (ck_pr_cas_64_2_value(CK_CPP_CAST(uint64_t *, target),\n                                   CK_CPP_CAST(uint64_t *, compare),\n                                   CK_CPP_CAST(uint64_t *, set),\n                                   CK_CPP_CAST(uint64_t *, value)));\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_64_2(uint64_t target[2], uint64_t compare[2], uint64_t set[2])\n{\n        uint64_t tmp1, tmp2;\n\n        __asm__ __volatile__(\"1:\"\n                             \"ldxp %0, %1, [%2];\"\n                             \"eor %0, %0, %3;\"\n                             \"eor %1, %1, %4;\"\n                             \"orr %1, %0, %1;\"\n                             \"mov %w0, #0;\"\n                             \"cbnz %1, 2f;\"\n                             \"stxp %w0, %5, %6, [%2];\"\n                             \"cbnz %w0, 1b;\"\n                             \"mov %w0, #1;\"\n                             \"2:\"\n                             : \"=&r\" (tmp1), \"=&r\" (tmp2)\n                             : \"r\" (target), \"r\" (compare[0]), \"r\" (compare[1]), \"r\" (set[0]), \"r\" (set[1])\n                             : \"cc\", \"memory\");\n\n        return (tmp1);\n}\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2(void *target, void *compare, void *set)\n{\n        return (ck_pr_cas_64_2(CK_CPP_CAST(uint64_t *, target),\n                             CK_CPP_CAST(uint64_t *, compare),\n                             CK_CPP_CAST(uint64_t *, set)));\n}\n\n\n#define CK_PR_CAS(N, M, T, W, R)\t\t\t\t\t\\\n        CK_CC_INLINE static bool\t\t\t\t\t\\\n        ck_pr_cas_##N##_value(M *target, T compare, T set, M *value)\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\t\\\n                T tmp;\t\t\t\t\t\t\t\\\n                __asm__ __volatile__(\"1:\"\t\t\t\t\\\n                                     \"ldxr\" W \" %\" R \"0, [%2];\"\t\t\\\n                                     \"cmp  %\" R \"0, %\" R \"4;\"\t\t\\\n                                     \"b.ne 2f;\"\t\t\t\t\\\n                                     \"stxr\" W \" %w1, %\" R \"3, [%2];\"\t\\\n                                     \"cbnz %w1, 1b;\"\t\t\t\\\n                                     \"2:\"\t\t\t\t\\\n                    : \"=&r\" (previous),\t\t\t\t\t\\\n                    \"=&r\" (tmp)\t\t\t\t\t\t\\\n                    : \"r\"   (target),\t\t\t\t\t\\\n                    \"r\"   (set),\t\t\t\t\t\\\n                    \"r\"   (compare)\t\t\t\t\t\\\n                    : \"memory\", \"cc\");\t\t\t\t\t\\\n                *(T *)value = previous;\t\t\t\t\t\\\n                return (previous == compare);\t\t\t\t\\\n        }\t\t\t\t\t\t\t\t\\\n        CK_CC_INLINE static bool\t\t\t\t\t\\\n        ck_pr_cas_##N(M *target, T compare, T set)\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\t\\\n                T tmp;\t\t\t\t\t\t\t\\\n                __asm__ __volatile__(\t\t\t\t\t\\\n                                     \"1:\"\t\t\t\t\\\n                                     \"ldxr\" W \" %\" R \"0, [%2];\"\t\t\\\n                                     \"cmp  %\" R \"0, %\" R \"4;\"\t\t\\\n                                     \"b.ne 2f;\"\t\t\t\t\\\n                                     \"stxr\" W \" %w1, %\" R \"3, [%2];\"\t\\\n                                     \"cbnz %w1, 1b;\"\t\t\t\\\n                                     \"2:\"\t\t\t\t\\\n                    : \"=&r\" (previous),\t\t\t\t\t\\\n                    \"=&r\" (tmp)\t\t\t\t\t\t\\\n                    : \"r\"   (target),\t\t\t\t\t\\\n                    \"r\"   (set),\t\t\t\t\t\\\n                    \"r\"   (compare)\t\t\t\t\t\\\n                    : \"memory\", \"cc\");\t\t\t\t\t\\\n                return (previous == compare);\t\t\t\t\\\n        }\n\nCK_PR_CAS(ptr, void, void *, \"\", \"\")\n\n#define CK_PR_CAS_S(N, M, W, R)\tCK_PR_CAS(N, M, M, W, R)\nCK_PR_CAS_S(64, uint64_t, \"\", \"\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_CAS_S(double, double, \"\", \"\")\n#endif\nCK_PR_CAS_S(32, uint32_t, \"\", \"w\")\nCK_PR_CAS_S(uint, unsigned int, \"\", \"w\")\nCK_PR_CAS_S(int, int, \"\", \"w\")\nCK_PR_CAS_S(16, uint16_t, \"h\", \"w\")\nCK_PR_CAS_S(8, uint8_t, \"b\", \"w\")\nCK_PR_CAS_S(short, short, \"h\", \"w\")\nCK_PR_CAS_S(char, char, \"b\", \"w\")\n\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n#define CK_PR_FAS(N, M, T, W, R)\t\t\t\t\\\n        CK_CC_INLINE static T\t\t\t\t\t\\\n        ck_pr_fas_##N(M *target, T v)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\\\n                T tmp;\t\t\t\t\t\t\\\n                __asm__ __volatile__(\"1:\"\t\t\t\\\n                                     \"ldxr\" W \" %\" R \"0, [%2];\"\t\\\n                                     \"stxr\" W \" %w1, %\" R \"3, [%2];\"\\\n                                     \"cbnz %w1, 1b;\"\t\t\\\n                                        : \"=&r\" (previous),\t\\\n                                          \"=&r\" (tmp) \t\t\\\n                                        : \"r\"   (target),\t\\\n                                          \"r\"   (v)\t\t\\\n                                        : \"memory\", \"cc\");\t\\\n                return (previous);\t\t\t\t\\\n        }\n\nCK_PR_FAS(64, uint64_t, uint64_t, \"\", \"\")\nCK_PR_FAS(32, uint32_t, uint32_t, \"\", \"w\")\nCK_PR_FAS(ptr, void, void *, \"\", \"\")\nCK_PR_FAS(int, int, int, \"\", \"w\")\nCK_PR_FAS(uint, unsigned int, unsigned int, \"\", \"w\")\nCK_PR_FAS(16, uint16_t, uint16_t, \"h\", \"w\")\nCK_PR_FAS(8, uint8_t, uint8_t, \"b\", \"w\")\nCK_PR_FAS(short, short, short, \"h\", \"w\")\nCK_PR_FAS(char, char, char, \"b\", \"w\")\n\n\n#undef CK_PR_FAS\n\n#define CK_PR_UNARY(O, N, M, T, I, W, R)\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_##O##_##N(M *target)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                T previous = 0;\t\t\t\t\t\\\n                T tmp = 0;\t\t\t\t\t\\\n                __asm__ __volatile__(\"1:\"\t\t\t\\\n                                     \"ldxr\" W \" %\" R \"0, [%2];\"\t\\\n                                      I \";\"\t\t\t\\\n                                     \"stxr\" W \" %w1, %\" R \"0, [%2];\"\t\\\n                                     \"cbnz %w1, 1b;\"\t\t\\\n                                        : \"=&r\" (previous),\t\\\n                                          \"=&r\" (tmp)\t\t\\\n                                        : \"r\"   (target)\t\\\n                                        : \"memory\", \"cc\");\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\nCK_PR_UNARY(inc, ptr, void, void *, \"add %0, %0, #1\", \"\", \"\")\nCK_PR_UNARY(dec, ptr, void, void *, \"sub %0, %0, #1\", \"\", \"\")\nCK_PR_UNARY(not, ptr, void, void *, \"mvn %0, %0\", \"\", \"\")\nCK_PR_UNARY(inc, 64, uint64_t, uint64_t, \"add %0, %0, #1\", \"\", \"\")\nCK_PR_UNARY(dec, 64, uint64_t, uint64_t, \"sub %0, %0, #1\", \"\", \"\")\nCK_PR_UNARY(not, 64, uint64_t, uint64_t, \"mvn %0, %0\", \"\", \"\")\n\n#define CK_PR_UNARY_S(S, T, W)\t\t\t\t\t\\\n        CK_PR_UNARY(inc, S, T, T, \"add %w0, %w0, #1\", W, \"w\")\t\\\n        CK_PR_UNARY(dec, S, T, T, \"sub %w0, %w0, #1\", W, \"w\")\t\\\n        CK_PR_UNARY(not, S, T, T, \"mvn %w0, %w0\", W, \"w\")\t\\\n\nCK_PR_UNARY_S(32, uint32_t, \"\")\nCK_PR_UNARY_S(uint, unsigned int, \"\")\nCK_PR_UNARY_S(int, int, \"\")\nCK_PR_UNARY_S(16, uint16_t, \"h\")\nCK_PR_UNARY_S(8, uint8_t, \"b\")\nCK_PR_UNARY_S(short, short, \"h\")\nCK_PR_UNARY_S(char, char, \"b\")\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\n#define CK_PR_BINARY(O, N, M, T, I, W, R)\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_##O##_##N(M *target, T delta)\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\\\n                T tmp;\t\t\t\t\t\t\\\n                __asm__ __volatile__(\"1:\"\t\t\t\\\n                                     \"ldxr\" W \" %\" R \"0, [%2];\"\\\n                                      I \" %\" R \"0, %\" R \"0, %\" R \"3;\"\t\\\n                                     \"stxr\" W \" %w1, %\" R \"0, [%2];\"\t\\\n                                     \"cbnz %w1, 1b;\"\t\t\\\n                                        : \"=&r\" (previous),\t\\\n                                          \"=&r\" (tmp)\t\t\\\n                                        : \"r\"   (target),\t\\\n                                          \"r\"   (delta)\t\t\\\n                                        : \"memory\", \"cc\");\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\nCK_PR_BINARY(and, ptr, void, uintptr_t, \"and\", \"\", \"\")\nCK_PR_BINARY(add, ptr, void, uintptr_t, \"add\", \"\", \"\")\nCK_PR_BINARY(or, ptr, void, uintptr_t, \"orr\", \"\", \"\")\nCK_PR_BINARY(sub, ptr, void, uintptr_t, \"sub\", \"\", \"\")\nCK_PR_BINARY(xor, ptr, void, uintptr_t, \"eor\", \"\", \"\")\nCK_PR_BINARY(and, 64, uint64_t, uint64_t, \"and\", \"\", \"\")\nCK_PR_BINARY(add, 64, uint64_t, uint64_t, \"add\", \"\", \"\")\nCK_PR_BINARY(or, 64, uint64_t, uint64_t, \"orr\", \"\", \"\")\nCK_PR_BINARY(sub, 64, uint64_t, uint64_t, \"sub\", \"\", \"\")\nCK_PR_BINARY(xor, 64, uint64_t, uint64_t, \"eor\", \"\", \"\")\n\n#define CK_PR_BINARY_S(S, T, W)\t\t\t\t\\\n        CK_PR_BINARY(and, S, T, T, \"and\", W, \"w\")\t\\\n        CK_PR_BINARY(add, S, T, T, \"add\", W, \"w\")\t\\\n        CK_PR_BINARY(or, S, T, T, \"orr\", W, \"w\")\t\\\n        CK_PR_BINARY(sub, S, T, T, \"sub\", W, \"w\")\t\\\n        CK_PR_BINARY(xor, S, T, T, \"eor\", W, \"w\")\n\nCK_PR_BINARY_S(32, uint32_t, \"\")\nCK_PR_BINARY_S(uint, unsigned int, \"\")\nCK_PR_BINARY_S(int, int, \"\")\nCK_PR_BINARY_S(16, uint16_t, \"h\")\nCK_PR_BINARY_S(8, uint8_t, \"b\")\nCK_PR_BINARY_S(short, short, \"h\")\nCK_PR_BINARY_S(char, char, \"b\")\n\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\nCK_CC_INLINE static void *\nck_pr_faa_ptr(void *target, uintptr_t delta)\n{\n        uintptr_t previous, r, tmp;\n\n        __asm__ __volatile__(\"1:\"\n                             \"ldxr %0, [%3];\"\n                             \"add %1, %4, %0;\"\n                             \"stxr %w2, %1, [%3];\"\n                             \"cbnz %w2, 1b;\"\n                                : \"=&r\" (previous),\n                                  \"=&r\" (r),\n                                  \"=&r\" (tmp)\n                                : \"r\"   (target),\n                                  \"r\"   (delta)\n                                : \"memory\", \"cc\");\n\n        return (void *)(previous);\n}\n\nCK_CC_INLINE static uint64_t\nck_pr_faa_64(uint64_t *target, uint64_t delta)\n{\n        uint64_t previous, r, tmp;\n\n        __asm__ __volatile__(\"1:\"\n                             \"ldxr %0, [%3];\"\n                             \"add %1, %4, %0;\"\n                             \"stxr %w2, %1, [%3];\"\n                             \"cbnz %w2, 1b;\"\n                                : \"=&r\" (previous),\n                                  \"=&r\" (r),\n                                  \"=&r\" (tmp)\n                                : \"r\"   (target),\n                                  \"r\"   (delta)\n                                : \"memory\", \"cc\");\n\n        return (previous);\n}\n\n#define CK_PR_FAA(S, T, W)\t\t\t\t\t\t\\\n        CK_CC_INLINE static T\t\t\t\t\t\t\\\n        ck_pr_faa_##S(T *target, T delta)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous, r, tmp;\t\t\t\t\t\\\n                __asm__ __volatile__(\"1:\"\t\t\t\t\\\n                                     \"ldxr\" W \" %w0, [%3];\"\t\t\\\n                                     \"add %w1, %w4, %w0;\"\t\t\\\n                                     \"stxr\" W \" %w2, %w1, [%3];\"\t\\\n                                     \"cbnz %w2, 1b;\"\t\t\t\\\n                                        : \"=&r\" (previous),\t\t\\\n                                          \"=&r\" (r),\t\t\t\\\n                                          \"=&r\" (tmp)\t\t\t\\\n                                        : \"r\"   (target),\t\t\\\n                                          \"r\"   (delta)\t\t\t\\\n                                        : \"memory\", \"cc\");\t\t\\\n                return (previous);\t\t\t\t\t\\\n        }\n\nCK_PR_FAA(32, uint32_t, \"\")\nCK_PR_FAA(uint, unsigned int, \"\")\nCK_PR_FAA(int, int, \"\")\nCK_PR_FAA(16, uint16_t, \"h\")\nCK_PR_FAA(8, uint8_t, \"b\")\nCK_PR_FAA(short, short, \"h\")\nCK_PR_FAA(char, char, \"b\")\n\n#undef CK_PR_FAA\n\n#endif /* CK_PR_AARCH64_LLSC_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/aarch64/ck_pr_lse.h",
    "content": "/*\n * Copyright 2009-2016 Samy Al Bahra.\n * Copyright 2013-2016 Olivier Houchard.\n * Copyright 2016 Alexey Kopytov.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_AARCH64_LSE_H\n#define CK_PR_AARCH64_LSE_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\nCK_CC_INLINE static bool\nck_pr_cas_64_2_value(uint64_t target[2], uint64_t compare[2], uint64_t set[2], uint64_t value[2])\n{\n        uint64_t tmp1;\n        uint64_t tmp2;\n        register uint64_t x0 __asm__ (\"x0\") = compare[0];\n        register uint64_t x1 __asm__ (\"x1\") = compare[1];\n        register uint64_t x2 __asm__ (\"x2\") = set[0];\n        register uint64_t x3 __asm__ (\"x3\") = set[1];\n\n        __asm__ __volatile__(\"casp %0, %1, %4, %5, [%6];\"\n                             \"eor %2, %0, %7;\"\n                             \"eor %3, %1, %8;\"\n                             \"orr %2, %2, %3;\"\n                             : \"+&r\" (x0), \"+&r\" (x1), \"=&r\" (tmp1), \"=&r\" (tmp2)\n                             : \"r\" (x2), \"r\" (x3), \"r\" (target), \"r\" (compare[0]), \"r\" (compare[1])\n                             : \"memory\");\n\n        value[0] = x0;\n        value[1] = x1;\n\n        return (!!tmp1);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2_value(void *target, void *compare, void *set, void *value)\n{\n        return (ck_pr_cas_64_2_value(CK_CPP_CAST(uint64_t *, target),\n                                   CK_CPP_CAST(uint64_t *, compare),\n                                   CK_CPP_CAST(uint64_t *, set),\n                                   CK_CPP_CAST(uint64_t *, value)));\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_64_2(uint64_t target[2], uint64_t compare[2], uint64_t set[2])\n{\n        register uint64_t x0 __asm__ (\"x0\") = compare[0];\n        register uint64_t x1 __asm__ (\"x1\") = compare[1];\n        register uint64_t x2 __asm__ (\"x2\") = set[0];\n        register uint64_t x3 __asm__ (\"x3\") = set[1];\n\n        __asm__ __volatile__(\"casp %0, %1, %2, %3, [%4];\"\n                             \"eor %0, %0, %5;\"\n                             \"eor %1, %1, %6;\"\n                             \"orr %0, %0, %1;\"\n                             : \"+&r\" (x0), \"+&r\" (x1)\n                             : \"r\" (x2), \"r\" (x3), \"r\" (target), \"r\" (compare[0]), \"r\" (compare[1])\n                             : \"memory\");\n\n        return (!!x0);\n}\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2(void *target, void *compare, void *set)\n{\n        return (ck_pr_cas_64_2(CK_CPP_CAST(uint64_t *, target),\n                             CK_CPP_CAST(uint64_t *, compare),\n                             CK_CPP_CAST(uint64_t *, set)));\n}\n\n\n#define CK_PR_CAS(N, M, T, W, R)\t\t\t\t\t\\\n        CK_CC_INLINE static bool\t\t\t\t\t\\\n        ck_pr_cas_##N##_value(M *target, T compare, T set, M *value)\t\\\n        {\t\t\t\t\t\t\t\t\\\n                  *(T *)value = compare;\t\t\t\t\\\n                __asm__ __volatile__(\t\t\t\t\t\\\n                                     \"cas\" W \" %\" R \"0, %\" R \"2, [%1];\"\t\\\n                    : \"+&r\" (*(T *)value)\t\t\t\t\\\n                    : \"r\"   (target),\t\t\t\t\t\\\n                    \"r\"   (set)\t\t\t\t\t\t\\\n                    : \"memory\");\t\t\t\t\t\\\n                return (*(T *)value == compare);                        \\\n        }\t\t\t\t\t\t\t\t\\\n        CK_CC_INLINE static bool\t\t\t\t\t\\\n        ck_pr_cas_##N(M *target, T compare, T set)\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous = compare;\t\t\t\t\t\\\n                __asm__ __volatile__(\t\t\t\t\t\\\n                                     \"cas\" W \" %\" R \"0, %\" R \"2, [%1];\"\t\\\n                    : \"+&r\" (previous)\t\t\t\t\t\\\n                    : \"r\"   (target),\t\t\t\t\t\\\n                    \"r\"   (set)\t\t\t\t\t\t\\\n                    : \"memory\");\t\t\t\t\t\\\n                return (previous == compare);   \t\t\t\\\n        }\n\nCK_PR_CAS(ptr, void, void *, \"\", \"\")\n\n#define CK_PR_CAS_S(N, M, W, R)\tCK_PR_CAS(N, M, M, W, R)\nCK_PR_CAS_S(64, uint64_t, \"\", \"\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_CAS_S(double, double, \"\", \"\")\n#endif\nCK_PR_CAS_S(32, uint32_t, \"\", \"w\")\nCK_PR_CAS_S(uint, unsigned int, \"\", \"w\")\nCK_PR_CAS_S(int, int, \"\", \"w\")\nCK_PR_CAS_S(16, uint16_t, \"h\", \"w\")\nCK_PR_CAS_S(8, uint8_t, \"b\", \"w\")\nCK_PR_CAS_S(short, short, \"h\", \"w\")\nCK_PR_CAS_S(char, char, \"b\", \"w\")\n\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n#define CK_PR_FAS(N, M, T, W, R)\t\t\t\t\t\\\n        CK_CC_INLINE static T\t\t\t\t\t\t\\\n        ck_pr_fas_##N(M *target, T v)\t\t\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\t\\\n                __asm__ __volatile__(\t\t\t\t\t\\\n                                     \"swp\" W \" %\" R \"2, %\" R \"0, [%1];\"\t\\\n                                        : \"=&r\" (previous)\t\t\\\n                                        : \"r\"   (target),\t\t\\\n                                          \"r\"   (v)\t\t\t\\\n                                        : \"memory\");\t\t\t\\\n                return (previous);\t\t\t\t\t\\\n        }\n\nCK_PR_FAS(64, uint64_t, uint64_t, \"\", \"\")\nCK_PR_FAS(32, uint32_t, uint32_t, \"\", \"w\")\nCK_PR_FAS(ptr, void, void *, \"\", \"\")\nCK_PR_FAS(int, int, int, \"\", \"w\")\nCK_PR_FAS(uint, unsigned int, unsigned int, \"\", \"w\")\nCK_PR_FAS(16, uint16_t, uint16_t, \"h\", \"w\")\nCK_PR_FAS(8, uint8_t, uint8_t, \"b\", \"w\")\nCK_PR_FAS(short, short, short, \"h\", \"w\")\nCK_PR_FAS(char, char, char, \"b\", \"w\")\n\n\n#undef CK_PR_FAS\n\n#define CK_PR_UNARY(O, N, M, T, I, W, R, S)\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_##O##_##N(M *target)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                __asm__ __volatile__(I \";\"\t\t\t\\\n                                     \"st\" S W \" \" R \"0, [%0];\"\t\\\n                                        :\t\t\t\\\n                                        : \"r\"   (target)\t\\\n                                        : \"x0\", \"memory\");\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\nCK_PR_UNARY(inc, ptr, void, void *, \"mov x0, 1\", \"\", \"x\", \"add\")\nCK_PR_UNARY(dec, ptr, void, void *, \"mov x0, -1\", \"\", \"x\", \"add\")\nCK_PR_UNARY(not, ptr, void, void *, \"mov x0, -1\", \"\", \"x\", \"eor\")\nCK_PR_UNARY(inc, 64, uint64_t, uint64_t, \"mov x0, 1\", \"\", \"x\", \"add\")\nCK_PR_UNARY(dec, 64, uint64_t, uint64_t, \"mov x0, -1\", \"\", \"x\", \"add\")\nCK_PR_UNARY(not, 64, uint64_t, uint64_t, \"mov x0, -1\", \"\", \"x\", \"eor\")\n\n#define CK_PR_UNARY_S(S, T, W)\t\t\t\t\t\\\n        CK_PR_UNARY(inc, S, T, T, \"mov w0, 1\", W, \"w\", \"add\")\t\\\n        CK_PR_UNARY(dec, S, T, T, \"mov w0, -1\", W, \"w\", \"add\")\t\\\n        CK_PR_UNARY(not, S, T, T, \"mov w0, -1\", W, \"w\", \"eor\")\t\\\n\nCK_PR_UNARY_S(32, uint32_t, \"\")\nCK_PR_UNARY_S(uint, unsigned int, \"\")\nCK_PR_UNARY_S(int, int, \"\")\nCK_PR_UNARY_S(16, uint16_t, \"h\")\nCK_PR_UNARY_S(8, uint8_t, \"b\")\nCK_PR_UNARY_S(short, short, \"h\")\nCK_PR_UNARY_S(char, char, \"b\")\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\n#define CK_PR_BINARY(O, N, M, T, S, W, R, I)\t\t\t\\\n        CK_CC_INLINE static void\t\t\t\t\\\n        ck_pr_##O##_##N(M *target, T delta)\t\t\t\\\n        {\t\t\t\t\t\t\t\\\n                __asm__ __volatile__(I \";\"\t\t\t\\\n                                     \"st\" S W \" %\" R \"0, [%1];\"\t\\\n                                        : \"+&r\" (delta)\t\t\\\n                                        : \"r\"   (target)\t\\\n                                        : \"memory\");\t\t\\\n                return;\t\t\t\t\t\t\\\n        }\n\nCK_PR_BINARY(and, ptr, void, uintptr_t, \"clr\", \"\", \"\", \"mvn %0, %0\")\nCK_PR_BINARY(add, ptr, void, uintptr_t, \"add\", \"\", \"\", \"\")\nCK_PR_BINARY(or, ptr, void, uintptr_t, \"set\", \"\", \"\", \"\")\nCK_PR_BINARY(sub, ptr, void, uintptr_t, \"add\", \"\", \"\", \"neg %0, %0\")\nCK_PR_BINARY(xor, ptr, void, uintptr_t, \"eor\", \"\", \"\", \"\")\nCK_PR_BINARY(and, 64, uint64_t, uint64_t, \"clr\", \"\", \"\", \"mvn %0, %0\")\nCK_PR_BINARY(add, 64, uint64_t, uint64_t, \"add\", \"\", \"\", \"\")\nCK_PR_BINARY(or, 64, uint64_t, uint64_t, \"set\", \"\", \"\", \"\")\nCK_PR_BINARY(sub, 64, uint64_t, uint64_t, \"add\", \"\", \"\", \"neg %0, %0\")\nCK_PR_BINARY(xor, 64, uint64_t, uint64_t, \"eor\", \"\", \"\", \"\")\n\n#define CK_PR_BINARY_S(S, T, W)\t\t\t\t\t\t\\\n        CK_PR_BINARY(and, S, T, T, \"clr\", W, \"w\", \"mvn %w0, %w0\")\t\\\n        CK_PR_BINARY(add, S, T, T, \"add\", W, \"w\", \"\")\t\t\t\\\n        CK_PR_BINARY(or, S, T, T, \"set\", W, \"w\", \"\")\t\t\t\\\n        CK_PR_BINARY(sub, S, T, T, \"add\", W, \"w\", \"neg %w0, %w0\")\t\\\n        CK_PR_BINARY(xor, S, T, T, \"eor\", W, \"w\", \"\")\n\nCK_PR_BINARY_S(32, uint32_t, \"\")\nCK_PR_BINARY_S(uint, unsigned int, \"\")\nCK_PR_BINARY_S(int, int, \"\")\nCK_PR_BINARY_S(16, uint16_t, \"h\")\nCK_PR_BINARY_S(8, uint8_t, \"b\")\nCK_PR_BINARY_S(short, short, \"h\")\nCK_PR_BINARY_S(char, char, \"b\")\n\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\nCK_CC_INLINE static void *\nck_pr_faa_ptr(void *target, uintptr_t delta)\n{\n        uintptr_t previous;\n\n        __asm__ __volatile__(\n                             \"ldadd %2, %0, [%1];\"\n                                : \"=r\" (previous)\n                                : \"r\"   (target),\n                                  \"r\"   (delta)\n                                : \"memory\");\n\n        return (void *)(previous);\n}\n\nCK_CC_INLINE static uint64_t\nck_pr_faa_64(uint64_t *target, uint64_t delta)\n{\n        uint64_t previous;\n\n        __asm__ __volatile__(\n                             \"ldadd %2, %0, [%1];\"\n                                : \"=r\" (previous)\n                                : \"r\"   (target),\n                                  \"r\"   (delta)\n                                : \"memory\");\n\n        return (previous);\n}\n\n#define CK_PR_FAA(S, T, W)\t\t\t\t\t\t\\\n        CK_CC_INLINE static T\t\t\t\t\t\t\\\n        ck_pr_faa_##S(T *target, T delta)\t\t\t\t\\\n        {\t\t\t\t\t\t\t\t\\\n                T previous;\t\t\t\t\t\t\\\n                __asm__ __volatile__(\t\t\t\t\t\\\n                                     \"ldadd\" W \" %w2, %w0, [%1];\"\t\\\n                                        : \"=r\" (previous)\t\t\\\n                                        : \"r\"   (target),\t\t\\\n                                          \"r\"   (delta)\t\t\t\\\n                                        : \"memory\");\t\t\t\\\n                return (previous);\t\t\t\t\t\\\n        }\n\nCK_PR_FAA(32, uint32_t, \"\")\nCK_PR_FAA(uint, unsigned int, \"\")\nCK_PR_FAA(int, int, \"\")\nCK_PR_FAA(16, uint16_t, \"h\")\nCK_PR_FAA(8, uint8_t, \"b\")\nCK_PR_FAA(short, short, \"h\")\nCK_PR_FAA(char, char, \"b\")\n\n#undef CK_PR_FAA\n\n#endif /* CK_PR_AARCH64_LSE_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/arm/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_16\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_8\n#define CK_F_PR_ADD_CHAR\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_SHORT\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_16\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_8\n#define CK_F_PR_AND_CHAR\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_SHORT\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_BARRIER\n#define CK_F_PR_CAS_16\n#define CK_F_PR_CAS_16_VALUE\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_DOUBLE\n#define CK_F_PR_CAS_DOUBLE_VALUE\n#endif\n#define CK_F_PR_CAS_8\n#define CK_F_PR_CAS_8_VALUE\n#define CK_F_PR_CAS_CHAR\n#define CK_F_PR_CAS_CHAR_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n#define CK_F_PR_CAS_PTR_2\n#define CK_F_PR_CAS_PTR_2_VALUE\n#endif\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_SHORT\n#define CK_F_PR_CAS_SHORT_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_16\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_8\n#define CK_F_PR_DEC_CHAR\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_SHORT\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_FAA_16\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_8\n#define CK_F_PR_FAA_CHAR\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_SHORT\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_16\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_8\n#define CK_F_PR_FAS_CHAR\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_SHORT\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FENCE_ATOMIC\n#define CK_F_PR_FENCE_ATOMIC_LOAD\n#define CK_F_PR_FENCE_ATOMIC_STORE\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_ATOMIC\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_LOAD_STORE\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STORE_ATOMIC\n#define CK_F_PR_FENCE_STORE_LOAD\n#define CK_F_PR_FENCE_STRICT_ATOMIC\n#define CK_F_PR_FENCE_STRICT_ATOMIC_LOAD\n#define CK_F_PR_FENCE_STRICT_ATOMIC_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_ATOMIC\n#define CK_F_PR_FENCE_STRICT_LOAD_STORE\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_FENCE_STRICT_STORE_ATOMIC\n#define CK_F_PR_FENCE_STRICT_STORE_LOAD\n#define CK_F_PR_INC_16\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_8\n#define CK_F_PR_INC_CHAR\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_SHORT\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_DOUBLE\n#endif\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_SHORT\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_NEG_16\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_8\n#define CK_F_PR_NEG_CHAR\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_SHORT\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NOT_16\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_8\n#define CK_F_PR_NOT_CHAR\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_SHORT\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_16\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_8\n#define CK_F_PR_OR_CHAR\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_SHORT\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_DOUBLE\n#endif\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_SHORT\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_16\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_8\n#define CK_F_PR_SUB_CHAR\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_SHORT\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_16\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_8\n#define CK_F_PR_XOR_CHAR\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_SHORT\n#define CK_F_PR_XOR_UINT\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/arm/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2013-2015 Olivier Houchard.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_ARM_H\n#define CK_PR_ARM_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Minimum interface requirement met.\n */\n#define CK_F_PR\n\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\n\t__asm__ __volatile__(\"\" ::: \"memory\");\n\treturn;\n}\n\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n#define CK_ISB __asm __volatile(\"isb\" : : \"r\" (0) : \"memory\")\n#define CK_DMB __asm __volatile(\"dmb\" : : \"r\" (0) : \"memory\")\n#define CK_DSB __asm __volatile(\"dsb\" : : \"r\" (0) : \"memory\")\n/* FreeBSD's toolchain doesn't accept dmb st, so use the opcode instead */\n#ifdef __FreeBSD__\n#define CK_DMB_ST __asm __volatile(\".word 0xf57ff05e\" : : \"r\" (0) : \"memory\")\n#else\n#define CK_DMB_ST __asm __volatile(\"dmb st\" : : \"r\" (0) : \"memory\")\n#endif /* __FreeBSD__ */\n#else\n/* armv6 doesn't have dsb/dmb/isb, and no way to wait only for stores */\n#define CK_ISB \\\n    __asm __volatile(\"mcr p15, 0, %0, c7, c5, 4\" : : \"r\" (0) : \"memory\")\n#define CK_DSB \\\n    __asm __volatile(\"mcr p15, 0, %0, c7, c10, 4\" : : \"r\" (0) : \"memory\")\n#define CK_DMB  \\\n    __asm __volatile(\"mcr p15, 0, %0, c7, c10, 5\" : : \"r\" (0) : \"memory\")\n#define CK_DMB_ST CK_DMB\n#endif\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\tI;\t\t\t\t\t\\\n\t}\n\nCK_PR_FENCE(atomic, CK_DMB_ST)\nCK_PR_FENCE(atomic_store, CK_DMB_ST)\nCK_PR_FENCE(atomic_load, CK_DMB_ST)\nCK_PR_FENCE(store_atomic, CK_DMB_ST)\nCK_PR_FENCE(load_atomic, CK_DMB)\nCK_PR_FENCE(store, CK_DMB_ST)\nCK_PR_FENCE(store_load, CK_DMB)\nCK_PR_FENCE(load, CK_DMB)\nCK_PR_FENCE(load_store, CK_DMB)\nCK_PR_FENCE(memory, CK_DMB)\nCK_PR_FENCE(acquire, CK_DMB)\nCK_PR_FENCE(release, CK_DMB)\nCK_PR_FENCE(acqrel, CK_DMB)\nCK_PR_FENCE(lock, CK_DMB)\nCK_PR_FENCE(unlock, CK_DMB)\n\n#undef CK_PR_FENCE\n\n#undef CK_ISB\n#undef CK_DSB\n#undef CK_DMB\n#undef CK_DMB_ST\n\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tlong r = 0;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %0, [%1];\"\t\t\\\n\t\t\t\t\t: \"=r\" (r)\t\t\\\n\t\t\t\t\t: \"r\"  (target)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn ((T)r);\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, uint32_t, \"ldr\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(32, uint32_t, \"ldr\")\nCK_PR_LOAD_S(16, uint16_t, \"ldrh\")\nCK_PR_LOAD_S(8, uint8_t, \"ldrb\")\nCK_PR_LOAD_S(uint, unsigned int, \"ldr\")\nCK_PR_LOAD_S(int, int, \"ldr\")\nCK_PR_LOAD_S(short, short, \"ldrh\")\nCK_PR_LOAD_S(char, char, \"ldrb\")\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n\n#define CK_PR_DOUBLE_LOAD(T, N) \t\t\\\nCK_CC_INLINE static T\t\t\t\t\\\nck_pr_md_load_##N(const T *target)\t\t\\\n{\t\t\t\t\t\t\\\n\tregister T ret;\t\t\t\t\\\n\t\t\t\t\t\t\\\n\t__asm __volatile(\"ldrexd %0, [%1]\" \t\\\n\t    : \"=&r\" (ret)\t\t\t\\\n\t    : \"r\" (target)\t\t\t\\\n\t    : \"memory\", \"cc\");\t\t\t\\\n\treturn (ret);\t\t\t\t\\\n}\t\t\t\t\t\n\nCK_PR_DOUBLE_LOAD(uint64_t, 64)\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_DOUBLE_LOAD(double, double)\n#endif\n#undef CK_PR_DOUBLE_LOAD\n#endif\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, [%0]\"\t\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"r\" (target),\t\t\\\n\t\t\t\t\t  \"r\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE(ptr, void, const void *, uint32_t, \"str\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)\n\nCK_PR_STORE_S(32, uint32_t, \"str\")\nCK_PR_STORE_S(16, uint16_t, \"strh\")\nCK_PR_STORE_S(8, uint8_t, \"strb\")\nCK_PR_STORE_S(uint, unsigned int, \"str\")\nCK_PR_STORE_S(int, int, \"str\")\nCK_PR_STORE_S(short, short, \"strh\")\nCK_PR_STORE_S(char, char, \"strb\")\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE\n\n#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__)\n\n#define CK_PR_DOUBLE_STORE(T, N)\t\t\t\t\\\nCK_CC_INLINE static void\t\t\t\t\t\\\nck_pr_md_store_##N(const T *target, T value)\t\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\tT tmp;\t\t\t\t\t\t\t\\\n\tuint32_t flag;\t\t\t\t\t\t\\\n\t__asm __volatile(\"1: \t\t\\n\"\t\t\t\\\n\t    \t\t \"ldrexd\t%0, [%2]\\n\"\t\t\\\n\t\t\t \"strexd\t%1, %3, [%2]\\n\"\t\t\\\n\t\t\t \"teq\t\t%1, #0\\n\"\t\t\\\n\t\t\t \"it ne\t\t\\n\"\t\t\t\\\n\t\t\t \"bne\t\t1b\\n\"\t\t\t\\\n\t\t\t\t: \"=&r\" (tmp), \"=&r\" (flag)\t\\\n\t\t\t\t: \"r\" (target), \"r\" (value)\t\\\n\t\t\t\t: \"memory\", \"cc\");\t\t\\\n}\n\nCK_PR_DOUBLE_STORE(uint64_t, 64)\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_DOUBLE_STORE(double, double)\n#endif\n\n#undef CK_PR_DOUBLE_STORE\n\n#define CK_PR_DOUBLE_CAS_VALUE(T, N)\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\t\\\nck_pr_cas_##N##_value(T *target, T compare, T set, T *value)\t\\\n{\t\t\t\t\t\t\t\t\\\n        T previous;\t\t\t\t\t\t\\\n        int tmp;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t     \"ldrexd %0, [%4];\"\t\t\t\\\n\t\t\t     \"cmp    %Q0, %Q2;\"\t\t\t\\\n\t\t\t     \"ittt eq;\"\t\t\t\t\\\n\t\t\t     \"cmpeq  %R0, %R2;\"\t\t\t\\\n\t\t\t     \"strexdeq %1, %3, [%4];\"\t\t\\\n\t\t\t     \"cmpeq  %1, #1;\"\t\t\t\\\n\t\t\t     \"beq 1b;\"\t\t\t\t\\\n\t\t\t\t:\"=&r\" (previous), \"=&r\" (tmp)\t\\\n\t\t\t\t: \"r\" (compare), \"r\" (set) ,\t\\\n\t\t\t\t  \"r\"(target)\t\t\t\\\n\t\t\t\t: \"memory\", \"cc\");\t\t\\\n        *value = previous;\t\t\t\t\t\\\n\treturn (*value == compare);\t\t\t\t\\\n}\n\nCK_PR_DOUBLE_CAS_VALUE(uint64_t, 64)\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_DOUBLE_CAS_VALUE(double, double)\n#endif\n\n#undef CK_PR_DOUBLE_CAS_VALUE\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2_value(void *target, void *compare, void *set, void *value)\n{\n\tuint32_t *_compare = CK_CPP_CAST(uint32_t *, compare);\n\tuint32_t *_set = CK_CPP_CAST(uint32_t *, set);\n\tuint64_t __compare = ((uint64_t)_compare[0]) | ((uint64_t)_compare[1] << 32);\n\tuint64_t __set = ((uint64_t)_set[0]) | ((uint64_t)_set[1] << 32);\n\n\treturn (ck_pr_cas_64_value(CK_CPP_CAST(uint64_t *, target),\n\t\t\t\t   __compare,\n\t\t\t\t   __set,\n\t\t\t\t   CK_CPP_CAST(uint64_t *, value)));\n}\n\n#define CK_PR_DOUBLE_CAS(T, N)  \t\t\\\nCK_CC_INLINE static bool\t\t\t\\\nck_pr_cas_##N(T *target, T compare, T set)\t\\\n{\t\t\t\t\t\t\\\n\tint ret;\t\t\t\t\\\n        T tmp;\t\t\t\t\t\\\n\t\t\t\t\t\t\\\n\t__asm__ __volatile__(\"1:\"\t\t\\\n\t\t\t     \"mov %0, #0;\"\t\\\n\t\t\t     \"ldrexd %1, [%4];\"\t\\\n\t\t\t     \"cmp    %Q1, %Q2;\"\t\\\n\t\t\t     \"itttt eq;\"\t\\\n\t\t\t     \"cmpeq  %R1, %R2;\"\t\\\n\t\t\t     \"strexdeq %1, %3, [%4];\" \\\n\t\t\t     \"moveq %0, #1;\"\t\\\n\t\t\t     \"cmpeq  %1, #1;\"\t\\\n\t\t\t     \"beq 1b;\"\t\t\\\n\t\t\t     : \"=&r\" (ret), \"=&r\" (tmp) \\\n\t\t\t     : \"r\" (compare), \"r\" (set) , \\\n\t\t\t       \"r\"(target)\t\\\n\t\t\t     : \"memory\", \"cc\");\t\\\n\t\t\t\t\t\t\\\n\treturn (ret);\t\t\t\t\\\n}\n\nCK_PR_DOUBLE_CAS(uint64_t, 64)\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_DOUBLE_CAS(double, double)\n#endif\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2(void *target, void *compare, void *set)\n{\n\tuint32_t *_compare = CK_CPP_CAST(uint32_t *, compare);\n\tuint32_t *_set = CK_CPP_CAST(uint32_t *, set);\n\tuint64_t __compare = ((uint64_t)_compare[0]) | ((uint64_t)_compare[1] << 32);\n\tuint64_t __set = ((uint64_t)_set[0]) | ((uint64_t)_set[1] << 32);\n\treturn (ck_pr_cas_64(CK_CPP_CAST(uint64_t *, target),\n\t\t\t     __compare,\n\t\t\t     __set));\n}\n\n#endif\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_value(void *target, void *compare, void *set, void *value)\n{\n\tvoid *previous, *tmp;\n\t__asm__ __volatile__(\"1:\"\n\t\t\t     \"ldrex %0, [%2];\"\n\t\t\t     \"cmp   %0, %4;\"\n\t\t\t     \"itt eq;\"\n\t\t\t     \"strexeq %1, %3, [%2];\"\n\t\t\t     \"cmpeq   %1, #1;\"\n\t\t\t     \"beq   1b;\"\n\t\t\t  \t: \"=&r\" (previous),\n\t\t\t\t  \"=&r\" (tmp)\n\t\t  \t\t: \"r\"   (target),\n\t\t\t\t  \"r\"   (set),\n\t\t\t\t  \"r\"   (compare)\n\t\t\t\t: \"memory\", \"cc\");\n\t*(void **)value = previous;\n\treturn (previous == compare);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr(void *target, void *compare, void *set)\n{\n\tvoid *previous, *tmp;\n\t__asm__ __volatile__(\"1:\"\n\t\t\t     \"ldrex %0, [%2];\"\n\t\t\t     \"cmp   %0, %4;\"\n\t\t\t     \"itt eq;\"\n\t\t\t     \"strexeq %1, %3, [%2];\"\n\t\t\t     \"cmpeq   %1, #1;\"\n\t\t\t     \"beq   1b;\"\n\t\t\t  \t: \"=&r\" (previous),\n\t\t\t\t  \"=&r\" (tmp)\n\t\t  \t\t: \"r\"   (target),\n\t\t\t\t  \"r\"   (set),\n\t\t\t\t  \"r\"   (compare)\n\t\t\t\t: \"memory\", \"cc\");\n\treturn (previous == compare);\n}\n\n#define CK_PR_CAS(N, T, W)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N##_value(T *target, T compare, T set, T *value)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous = 0, tmp = 0;\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"ldrex\" W \" %0, [%2];\"\t\t\\\n\t\t\t\t     \"cmp   %0, %4;\"\t\t\t\\\n\t\t\t\t     \"itt eq;\"\t\t\t\t\\\n\t\t\t\t     \"strex\" W \"eq %1, %3, [%2];\"\t\\\n\t\t    \t\t     \"cmpeq   %1, #1;\"\t\t\t\\\n\t\t\t\t     \"beq   1b;\"\t\t\t\\\n\t\t\t/* \t\t\t\t\t\t\\\n\t\t\t * Using \"+&\" instead of \"=&\" to avoid bogus\t\\\n\t\t\t * clang warnings.\t\t\t\t\\\n\t\t\t */\t\t\t\t\t\t\\\n\t\t\t\t\t: \"+&r\" (previous),\t\t\\\n\t\t    \t\t\t  \"+&r\" (tmp)\t\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (set),\t\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\t*value = previous; \t\t\t\t\t\\\n\t\treturn (previous == compare);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N(T *target, T compare, T set)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous = 0, tmp = 0;\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"ldrex\" W \" %0, [%2];\"\t\t\\\n\t\t\t\t     \"cmp   %0, %4;\"\t\t\t\\\n\t\t\t\t     \"itt eq;\"\t\t\t\t\\\n\t\t\t\t     \"strex\" W \"eq %1, %3, [%2];\"\t\\\n\t\t\t\t     \"cmpeq   %1, #1;\"\t\t\t\\\n\t\t\t\t     \"beq   1b;\"\t\t\t\\\n\t\t\t\t\t: \"+&r\" (previous),\t\t\\\n\t\t    \t\t\t  \"+&r\" (tmp)\t\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (set),\t\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (previous == compare);\t\t\t\t\\\n\t}\n\nCK_PR_CAS(32, uint32_t, \"\")\nCK_PR_CAS(uint, unsigned int, \"\")\nCK_PR_CAS(int, int, \"\")\nCK_PR_CAS(16, uint16_t, \"h\")\nCK_PR_CAS(8, uint8_t, \"b\")\nCK_PR_CAS(short, short, \"h\")\nCK_PR_CAS(char, char, \"b\")\n\n\n#undef CK_PR_CAS\n\n#define CK_PR_FAS(N, M, T, W)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_fas_##N(M *target, T v)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous = 0;\t\t\t\t\t\\\n\t\tT tmp = 0;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"ldrex\" W \" %0, [%2];\"\t\\\n\t\t\t\t     \"strex\" W \" %1, %3, [%2];\"\t\\\n\t\t    \t\t     \"cmp %1, #0;\"\t\t\\\n\t\t\t\t     \"bne 1b;\"\t\t\t\\\n\t\t\t\t\t: \"+&r\" (previous),\t\\\n\t\t    \t\t\t  \"+&r\" (tmp) \t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\\\n\t\t\t\t\t  \"r\"   (v)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn (previous);\t\t\t\t\\\n\t}\n\nCK_PR_FAS(32, uint32_t, uint32_t, \"\")\nCK_PR_FAS(ptr, void, void *, \"\")\nCK_PR_FAS(int, int, int, \"\")\nCK_PR_FAS(uint, unsigned int, unsigned int, \"\")\nCK_PR_FAS(16, uint16_t, uint16_t, \"h\")\nCK_PR_FAS(8, uint8_t, uint8_t, \"b\")\nCK_PR_FAS(short, short, short, \"h\")\nCK_PR_FAS(char, char, char, \"b\")\n\n\n#undef CK_PR_FAS\n\n#define CK_PR_UNARY(O, N, M, T, I, W)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##O##_##N(M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous = 0;\t\t\t\t\t\\\n\t\tT tmp = 0;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"ldrex\" W \" %0, [%2];\"\t\\\n\t\t\t\t      I \";\"\t\t\t\\\n\t\t\t\t     \"strex\" W \" %1, %0, [%2];\"\t\\\n\t\t    \t\t     \"cmp   %1, #0;\"\t\t\\\n\t\t\t\t     \"bne   1b;\"\t\t\\\n\t\t\t\t\t: \"+&r\" (previous),\t\\\n\t\t    \t\t\t  \"+&r\" (tmp)\t\t\\\n\t\t\t\t\t: \"r\"   (target)\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_UNARY(inc, ptr, void, void *, \"add %0, %0, #1\", \"\")\nCK_PR_UNARY(dec, ptr, void, void *, \"sub %0, %0, #1\", \"\")\nCK_PR_UNARY(not, ptr, void, void *, \"mvn %0, %0\", \"\")\nCK_PR_UNARY(neg, ptr, void, void *, \"neg %0, %0\", \"\")\n\n#define CK_PR_UNARY_S(S, T, W)\t\t\t\t\t\\\n\tCK_PR_UNARY(inc, S, T, T, \"add %0, %0, #1\", W)\t\t\\\n\tCK_PR_UNARY(dec, S, T, T, \"sub %0, %0, #1\", W)\t\t\\\n\tCK_PR_UNARY(not, S, T, T, \"mvn %0, %0\", W)\t\t\\\n\tCK_PR_UNARY(neg, S, T, T, \"neg %0, %0\", W)\t\t\\\n\nCK_PR_UNARY_S(32, uint32_t, \"\")\nCK_PR_UNARY_S(uint, unsigned int, \"\")\nCK_PR_UNARY_S(int, int, \"\")\nCK_PR_UNARY_S(16, uint16_t, \"h\")\nCK_PR_UNARY_S(8, uint8_t, \"b\")\nCK_PR_UNARY_S(short, short, \"h\")\nCK_PR_UNARY_S(char, char, \"b\")\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\n#define CK_PR_BINARY(O, N, M, T, I, W)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##O##_##N(M *target, T delta)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous = 0;\t\t\t\t\t\\\n\t\tT tmp = 0;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"ldrex\" W \" %0, [%2];\"\t\\\n\t\t\t\t      I \" %0, %0, %3;\"\t\t\\\n\t\t\t\t     \"strex\" W \" %1, %0, [%2];\"\t\\\n\t\t    \t\t     \"cmp %1, #0;\"\t\t\\\n\t\t\t\t     \"bne 1b;\"\t\t\t\\\n\t\t\t\t\t: \"+&r\" (previous),\t\\\n\t\t    \t\t\t  \"+&r\" (tmp)\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\\\n\t\t\t\t\t  \"r\"   (delta)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_BINARY(and, ptr, void, uintptr_t, \"and\", \"\")\nCK_PR_BINARY(add, ptr, void, uintptr_t, \"add\", \"\")\nCK_PR_BINARY(or, ptr, void, uintptr_t, \"orr\", \"\")\nCK_PR_BINARY(sub, ptr, void, uintptr_t, \"sub\", \"\")\nCK_PR_BINARY(xor, ptr, void, uintptr_t, \"eor\", \"\")\n\n#define CK_PR_BINARY_S(S, T, W)\t\t\t\\\n\tCK_PR_BINARY(and, S, T, T, \"and\", W)\t\\\n\tCK_PR_BINARY(add, S, T, T, \"add\", W)\t\\\n\tCK_PR_BINARY(or, S, T, T, \"orr\", W)\t\\\n\tCK_PR_BINARY(sub, S, T, T, \"sub\", W)\t\\\n\tCK_PR_BINARY(xor, S, T, T, \"eor\", W)\n\nCK_PR_BINARY_S(32, uint32_t, \"\")\nCK_PR_BINARY_S(uint, unsigned int, \"\")\nCK_PR_BINARY_S(int, int, \"\")\nCK_PR_BINARY_S(16, uint16_t, \"h\")\nCK_PR_BINARY_S(8, uint8_t, \"b\")\nCK_PR_BINARY_S(short, short, \"h\")\nCK_PR_BINARY_S(char, char, \"b\")\n\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\nCK_CC_INLINE static void *\nck_pr_faa_ptr(void *target, uintptr_t delta)\n{\n\tuintptr_t previous, r, tmp;\n\n\t__asm__ __volatile__(\"1:\"\n\t\t\t     \"ldrex %0, [%3];\"\n\t\t\t     \"add %1, %4, %0;\"\n\t\t\t     \"strex %2, %1, [%3];\"\n\t\t\t     \"cmp %2, #0;\"\n\t\t\t     \"bne  1b;\"\n\t\t\t\t: \"=&r\" (previous),\n\t\t\t\t  \"=&r\" (r),\n\t\t\t\t  \"=&r\" (tmp)\n\t\t\t\t: \"r\"   (target),\n\t\t\t\t  \"r\"   (delta)\n\t\t\t\t: \"memory\", \"cc\");\n\n\treturn (void *)(previous);\n}\n\n#define CK_PR_FAA(S, T, W)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_faa_##S(T *target, T delta)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous = 0, r = 0, tmp = 0;\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"ldrex\" W \" %0, [%3];\"\t\t\\\n\t\t\t\t     \"add %1, %4, %0;\"\t\t\t\\\n\t\t\t\t     \"strex\" W \" %2, %1, [%3];\"\t\t\\\n\t\t    \t\t     \"cmp %2, #0;\"\t\t\t\\\n\t\t\t\t     \"bne  1b;\"\t\t\t\t\\\n\t\t\t\t\t: \"+&r\" (previous),\t\t\\\n\t\t\t\t\t  \"+&r\" (r),\t\t\t\\\n\t\t    \t\t\t  \"+&r\" (tmp)\t\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (delta)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (previous);\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(32, uint32_t, \"\")\nCK_PR_FAA(uint, unsigned int, \"\")\nCK_PR_FAA(int, int, \"\")\nCK_PR_FAA(16, uint16_t, \"h\")\nCK_PR_FAA(8, uint8_t, \"b\")\nCK_PR_FAA(short, short, \"h\")\nCK_PR_FAA(char, char, \"b\")\n\n#undef CK_PR_FAA\n\n#endif /* CK_PR_ARM_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ck_cc.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2014 Paul Khuong.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_GCC_CC_H\n#define CK_GCC_CC_H\n\n#include <ck_md.h>\n\n#ifdef __SUNPRO_C\n#define CK_CC_UNUSED\n#define CK_CC_USED\n#define CK_CC_IMM\n#define CK_CC_IMM_U32\n#else\n#define CK_CC_UNUSED __attribute__((unused))\n#define CK_CC_USED   __attribute__((used))\n#define CK_CC_IMM \"i\"\n#if defined(__x86_64__) || defined(__x86__)\n#define CK_CC_IMM_U32 \"Z\"\n#define CK_CC_IMM_S32 \"e\"\n#else\n#define CK_CC_IMM_U32 CK_CC_IMM\n#define CK_CC_IMM_S32 CK_CC_IMM\n#endif /* __x86_64__ || __x86__ */\n#endif\n\n#ifdef __OPTIMIZE__\n#define CK_CC_INLINE CK_CC_UNUSED inline\n#else\n#define CK_CC_INLINE CK_CC_UNUSED\n#endif\n\n#define CK_CC_FORCE_INLINE CK_CC_UNUSED __attribute__((always_inline)) inline\n#define CK_CC_RESTRICT __restrict__\n\n/*\n * Packed attribute.\n */\n#define CK_CC_PACKED __attribute__((packed))\n\n/*\n * Weak reference.\n */\n#define CK_CC_WEAKREF __attribute__((weakref))\n\n/*\n * Alignment attribute.\n */\n#define CK_CC_ALIGN(B) __attribute__((aligned(B)))\n\n/*\n * Cache align.\n */\n#define CK_CC_CACHELINE CK_CC_ALIGN(CK_MD_CACHELINE)\n\n/*\n * These are functions which should be avoided.\n */\n#ifdef __freestanding__\n#pragma GCC poison malloc free\n#endif\n\n/*\n * Branch execution hints.\n */\n#define CK_CC_LIKELY(x) (__builtin_expect(!!(x), 1))\n#define CK_CC_UNLIKELY(x) (__builtin_expect(!!(x), 0))\n\n/*\n * Some compilers are overly strict regarding aliasing semantics.\n * Unfortunately, in many cases it makes more sense to pay aliasing\n * cost rather than overly expensive register spillage.\n */\n#define CK_CC_ALIASED __attribute__((__may_alias__))\n\n/*\n * Compile-time typeof\n */\n#define CK_CC_TYPEOF(X, DEFAULT) __typeof__(X)\n\n/*\n * Portability wrappers for bitwise ops.\n */\n\n#define CK_F_CC_FFS\n#define CK_F_CC_CLZ\n#define CK_F_CC_CTZ\n#define CK_F_CC_POPCOUNT\n\nCK_CC_INLINE static int\nck_cc_ffs(unsigned int x)\n{\n\n\treturn __builtin_ffs(x);\n}\n\nCK_CC_INLINE static int\nck_cc_clz(unsigned int x)\n{\n\n\treturn __builtin_clz(x);\n}\n\nCK_CC_INLINE static int\nck_cc_ctz(unsigned int x)\n{\n\n\treturn __builtin_ctz(x);\n}\n\nCK_CC_INLINE static int\nck_cc_popcount(unsigned int x)\n{\n\n\treturn __builtin_popcount(x);\n}\n\n#endif /* CK_GCC_CC_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_16\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_64\n#define CK_F_PR_ADD_8\n#define CK_F_PR_ADD_CHAR\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_16\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_64\n#define CK_F_PR_AND_8\n#define CK_F_PR_AND_CHAR\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_CAS_16\n#define CK_F_PR_CAS_16_VALUE\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_8\n#define CK_F_PR_CAS_8_VALUE\n#define CK_F_PR_CAS_CHAR\n#define CK_F_PR_CAS_CHAR_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_16\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_64\n#define CK_F_PR_DEC_8\n#define CK_F_PR_DEC_CHAR\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_FAA_16\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_64\n#define CK_F_PR_FAA_8\n#define CK_F_PR_FAA_CHAR\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_INC_16\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_64\n#define CK_F_PR_INC_8\n#define CK_F_PR_INC_CHAR\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_OR_16\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_64\n#define CK_F_PR_OR_8\n#define CK_F_PR_OR_CHAR\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_16\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_64\n#define CK_F_PR_SUB_8\n#define CK_F_PR_SUB_CHAR\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_16\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_64\n#define CK_F_PR_XOR_8\n#define CK_F_PR_XOR_CHAR\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_UINT\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ck_pr.h",
    "content": "/*\n * Copyright 2010 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_GCC_H\n#define CK_PR_GCC_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n\nCK_CC_INLINE static void\nck_pr_barrier(void)\n{\n\n\t__asm__ __volatile__(\"\" ::: \"memory\");\n\treturn;\n}\n\n#ifndef CK_F_PR\n#define CK_F_PR\n\n#include <ck_stdbool.h>\n#include <ck_stdint.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n#define CK_PR_ACCESS(x) (*(volatile __typeof__(x) *)&(x))\n\n#define CK_PR_LOAD(S, M, T)\t\t \t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\\\n\t\tr = CK_PR_ACCESS(*(const T *)target);\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\\\n\t\treturn (r);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\\\n\t\tCK_PR_ACCESS(*(T *)target) = v;\t\t\t\\\n\t\tck_pr_barrier();\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_CC_INLINE static void *\nck_pr_md_load_ptr(const void *target)\n{\n\tvoid *r;\n\n\tck_pr_barrier();\n\tr = CK_CC_DECONST_PTR(CK_PR_ACCESS(target));\n\tck_pr_barrier();\n\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_pr_md_store_ptr(void *target, const void *v)\n{\n\n\tck_pr_barrier();\n\tCK_PR_ACCESS(target) = CK_CC_DECONST_PTR(v);\n\tck_pr_barrier();\n\treturn;\n}\n\n#define CK_PR_LOAD_S(S, T) CK_PR_LOAD(S, T, T)\n\nCK_PR_LOAD_S(char, char)\nCK_PR_LOAD_S(uint, unsigned int)\nCK_PR_LOAD_S(int, int)\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_LOAD_S(double, double)\n#endif\nCK_PR_LOAD_S(64, uint64_t)\nCK_PR_LOAD_S(32, uint32_t)\nCK_PR_LOAD_S(16, uint16_t)\nCK_PR_LOAD_S(8,  uint8_t)\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\n\tck_pr_barrier();\n}\n\n/*\n * Load and store fences are equivalent to full fences in the GCC port.\n */\n#define CK_PR_FENCE(T)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__sync_synchronize();\t\t\t\\\n\t}\n\nCK_PR_FENCE(atomic)\nCK_PR_FENCE(atomic_atomic)\nCK_PR_FENCE(atomic_load)\nCK_PR_FENCE(atomic_store)\nCK_PR_FENCE(store_atomic)\nCK_PR_FENCE(load_atomic)\nCK_PR_FENCE(load)\nCK_PR_FENCE(load_load)\nCK_PR_FENCE(load_store)\nCK_PR_FENCE(store)\nCK_PR_FENCE(store_store)\nCK_PR_FENCE(store_load)\nCK_PR_FENCE(memory)\nCK_PR_FENCE(acquire)\nCK_PR_FENCE(release)\nCK_PR_FENCE(acqrel)\nCK_PR_FENCE(lock)\nCK_PR_FENCE(unlock)\n\n#undef CK_PR_FENCE\n\n/*\n * Atomic compare and swap.\n */\n#define CK_PR_CAS(S, M, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_pr_cas_##S(M *target, T compare, T set)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tbool z;\t\t\t\t\t\t\t\t\\\n\t\tz = __sync_bool_compare_and_swap((T *)target, compare, set);\t\\\n\t\treturn z;\t\t\t\t\t\t\t\\\n\t}\n\nCK_PR_CAS(ptr, void, void *)\n\n#define CK_PR_CAS_S(S, T) CK_PR_CAS(S, T, T)\n\nCK_PR_CAS_S(char, char)\nCK_PR_CAS_S(int, int)\nCK_PR_CAS_S(uint, unsigned int)\nCK_PR_CAS_S(64, uint64_t)\nCK_PR_CAS_S(32, uint32_t)\nCK_PR_CAS_S(16, uint16_t)\nCK_PR_CAS_S(8,  uint8_t)\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n/*\n * Compare and swap, set *v to old value of target.\n */\nCK_CC_INLINE static bool\nck_pr_cas_ptr_value(void *target, void *compare, void *set, void *v)\n{\n\tset = __sync_val_compare_and_swap((void **)target, compare, set);\n\t*(void **)v = set;\n\treturn (set == compare);\n}\n\n#define CK_PR_CAS_O(S, T)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##S##_value(T *target, T compare, T set, T *v)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tset = __sync_val_compare_and_swap(target, compare, set);\\\n\t\t*v = set;\t\t\t\t\t\t\\\n\t\treturn (set == compare);\t\t\t\t\\\n\t}\n\nCK_PR_CAS_O(char, char)\nCK_PR_CAS_O(int, int)\nCK_PR_CAS_O(uint, unsigned int)\nCK_PR_CAS_O(64, uint64_t)\nCK_PR_CAS_O(32, uint32_t)\nCK_PR_CAS_O(16, uint16_t)\nCK_PR_CAS_O(8,  uint8_t)\n\n#undef CK_PR_CAS_O\n\n/*\n * Atomic fetch-and-add operations.\n */\n#define CK_PR_FAA(S, M, T)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_faa_##S(M *target, T d)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\td = __sync_fetch_and_add((T *)target, d);\t\\\n\t\treturn (d);\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(ptr, void, void *)\n\n#define CK_PR_FAA_S(S, T) CK_PR_FAA(S, T, T)\n\nCK_PR_FAA_S(char, char)\nCK_PR_FAA_S(uint, unsigned int)\nCK_PR_FAA_S(int, int)\nCK_PR_FAA_S(64, uint64_t)\nCK_PR_FAA_S(32, uint32_t)\nCK_PR_FAA_S(16, uint16_t)\nCK_PR_FAA_S(8,  uint8_t)\n\n#undef CK_PR_FAA_S\n#undef CK_PR_FAA\n\n/*\n * Atomic store-only binary operations.\n */\n#define CK_PR_BINARY(K, S, M, T)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##K##_##S(M *target, T d)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\td = __sync_fetch_and_##K((T *)target, d);\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BINARY_S(K, S, T) CK_PR_BINARY(K, S, T, T)\n\n#define CK_PR_GENERATE(K)\t\t\t\\\n\tCK_PR_BINARY(K, ptr, void, void *)\t\\\n\tCK_PR_BINARY_S(K, char, char)\t\t\\\n\tCK_PR_BINARY_S(K, int, int)\t\t\\\n\tCK_PR_BINARY_S(K, uint, unsigned int)\t\\\n\tCK_PR_BINARY_S(K, 64, uint64_t)\t\t\\\n\tCK_PR_BINARY_S(K, 32, uint32_t)\t\t\\\n\tCK_PR_BINARY_S(K, 16, uint16_t)\t\t\\\n\tCK_PR_BINARY_S(K, 8, uint8_t)\n\nCK_PR_GENERATE(add)\nCK_PR_GENERATE(sub)\nCK_PR_GENERATE(and)\nCK_PR_GENERATE(or)\nCK_PR_GENERATE(xor)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\n#define CK_PR_UNARY(S, M, T)\t\t\t\\\n\tCK_CC_INLINE static void\t\t\\\n\tck_pr_inc_##S(M *target)\t\t\\\n\t{\t\t\t\t\t\\\n\t\tck_pr_add_##S(target, (T)1);\t\\\n\t\treturn;\t\t\t\t\\\n\t}\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\\\n\tck_pr_dec_##S(M *target)\t\t\\\n\t{\t\t\t\t\t\\\n\t\tck_pr_sub_##S(target, (T)1);\t\\\n\t\treturn;\t\t\t\t\\\n\t}\n\n#define CK_PR_UNARY_S(S, M) CK_PR_UNARY(S, M, M)\n\nCK_PR_UNARY(ptr, void, void *)\nCK_PR_UNARY_S(char, char)\nCK_PR_UNARY_S(int, int)\nCK_PR_UNARY_S(uint, unsigned int)\nCK_PR_UNARY_S(64, uint64_t)\nCK_PR_UNARY_S(32, uint32_t)\nCK_PR_UNARY_S(16, uint16_t)\nCK_PR_UNARY_S(8, uint8_t)\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n#endif /* !CK_F_PR */\n#endif /* CK_PR_GCC_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ppc/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_DEPENDS\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_SHORT\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_SHORT\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_UINT\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ppc/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2012 João Fernandes.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_PPC_H\n#define CK_PR_PPC_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Minimum interface requirement met.\n */\n#define CK_F_PR\n\n/*\n * This bounces the hardware thread from low to medium\n * priority. I am unsure of the benefits of this approach\n * but it is used by the Linux kernel.\n */\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\n\t__asm__ __volatile__(\"or 1, 1, 1;\"\n\t\t\t     \"or 2, 2, 2;\" ::: \"memory\");\n\treturn;\n}\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I ::: \"memory\");   \\\n\t}\n\nCK_PR_FENCE(atomic, \"lwsync\")\nCK_PR_FENCE(atomic_store, \"lwsync\")\nCK_PR_FENCE(atomic_load, \"sync\")\nCK_PR_FENCE(store_atomic, \"lwsync\")\nCK_PR_FENCE(load_atomic, \"lwsync\")\nCK_PR_FENCE(store, \"lwsync\")\nCK_PR_FENCE(store_load, \"sync\")\nCK_PR_FENCE(load, \"lwsync\")\nCK_PR_FENCE(load_store, \"lwsync\")\nCK_PR_FENCE(memory, \"sync\")\nCK_PR_FENCE(acquire, \"lwsync\")\nCK_PR_FENCE(release, \"lwsync\")\nCK_PR_FENCE(acqrel, \"lwsync\")\nCK_PR_FENCE(lock, \"lwsync\")\nCK_PR_FENCE(unlock, \"lwsync\")\n\n#undef CK_PR_FENCE\n\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \"%U1%X1 %0, %1\"\t\t\t\\\n\t\t\t\t\t: \"=r\" (r)\t\t\t\\\n\t\t\t\t\t: \"m\"  (*(const C *)target)\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\treturn (r);\t\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, uint32_t, \"lwz\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(32, uint32_t, \"lwz\")\nCK_PR_LOAD_S(16, uint16_t, \"lhz\")\nCK_PR_LOAD_S(8, uint8_t, \"lbz\")\nCK_PR_LOAD_S(uint, unsigned int, \"lwz\")\nCK_PR_LOAD_S(int, int, \"lwz\")\nCK_PR_LOAD_S(short, short, \"lhz\")\nCK_PR_LOAD_S(char, char, \"lbz\")\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \"%U0%X0 %1, %0\"\t\t\\\n\t\t\t\t\t: \"=m\" (*(C *)target)\t\\\n\t\t\t\t\t: \"r\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE(ptr, void, const void *, uint32_t, \"stw\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)\n\nCK_PR_STORE_S(32, uint32_t, \"stw\")\nCK_PR_STORE_S(16, uint16_t, \"sth\")\nCK_PR_STORE_S(8, uint8_t, \"stb\")\nCK_PR_STORE_S(uint, unsigned int, \"stw\")\nCK_PR_STORE_S(int, int, \"stw\")\nCK_PR_STORE_S(short, short, \"sth\")\nCK_PR_STORE_S(char, char, \"stb\")\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE\n\n#define CK_PR_CAS(N, T, M)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N##_value(M *target, T compare, T set, M *value)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"lwarx %0, 0, %1;\"\t\t\t\\\n\t\t\t\t     \"cmpw  0, %0, %3;\"\t\t\t\\\n\t\t\t\t     \"bne-  2f;\"\t\t\t\\\n\t\t\t\t     \"stwcx. %2, 0, %1;\"\t\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\t\\\n\t\t\t\t     \"2:\"\t\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (set),\t\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\t*(T *)value = previous; \t\t\t\t\\\n\t\treturn (previous == compare);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N(M *target, T compare, T set)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"lwarx %0, 0, %1;\"\t\t\t\\\n\t\t\t\t     \"cmpw  0, %0, %3;\"\t\t\t\\\n\t\t\t\t     \"bne-  2f;\"\t\t\t\\\n\t\t\t\t     \"stwcx. %2, 0, %1;\"\t\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\t\\\n\t\t\t\t     \"2:\"\t\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (set),\t\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (previous == compare);\t\t\t\t\\\n\t}\n\nCK_PR_CAS(ptr, void *, void)\n#define CK_PR_CAS_S(a, b) CK_PR_CAS(a, b, b)\nCK_PR_CAS_S(32, uint32_t)\nCK_PR_CAS_S(uint, unsigned int)\nCK_PR_CAS_S(int, int)\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n#define CK_PR_FAS(N, M, T, W)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_fas_##N(M *target, T v)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %1;\"\t\\\n\t\t\t\t     \"st\" W \"cx. %2, 0, %1;\"\t\\\n\t\t\t\t     \"bne- 1b;\"\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\\\n\t\t\t\t\t: \"r\"   (target),\t\\\n\t\t\t\t\t  \"r\"   (v)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn (previous);\t\t\t\t\\\n\t}\n\nCK_PR_FAS(32, uint32_t, uint32_t, \"w\")\nCK_PR_FAS(ptr, void, void *, \"w\")\nCK_PR_FAS(int, int, int, \"w\")\nCK_PR_FAS(uint, unsigned int, unsigned int, \"w\")\n\n#undef CK_PR_FAS\n\n#define CK_PR_UNARY(O, N, M, T, I, W)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##O##_##N(M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %1;\"\t\\\n\t\t\t\t      I \";\"\t\t\t\\\n\t\t\t\t     \"st\" W \"cx. %0, 0, %1;\"\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\\\n\t\t\t\t\t: \"r\"   (target)\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_UNARY(inc, ptr, void, void *, \"addic %0, %0, 1\", \"w\")\nCK_PR_UNARY(dec, ptr, void, void *, \"addic %0, %0, -1\", \"w\")\nCK_PR_UNARY(not, ptr, void, void *, \"not %0, %0\", \"w\")\nCK_PR_UNARY(neg, ptr, void, void *, \"neg %0, %0\", \"w\")\n\n#define CK_PR_UNARY_S(S, T, W)\t\t\t\t\t\\\n\tCK_PR_UNARY(inc, S, T, T, \"addic %0, %0, 1\", W)\t\t\\\n\tCK_PR_UNARY(dec, S, T, T, \"addic %0, %0, -1\", W)\t\\\n\tCK_PR_UNARY(not, S, T, T, \"not %0, %0\", W)\t\t\\\n\tCK_PR_UNARY(neg, S, T, T, \"neg %0, %0\", W)\n\nCK_PR_UNARY_S(32, uint32_t, \"w\")\nCK_PR_UNARY_S(uint, unsigned int, \"w\")\nCK_PR_UNARY_S(int, int, \"w\")\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\n#define CK_PR_BINARY(O, N, M, T, I, W)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##O##_##N(M *target, T delta)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %1;\"\t\\\n\t\t\t\t      I \" %0, %2, %0;\"\t\t\\\n\t\t\t\t     \"st\" W \"cx. %0, 0, %1;\"\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\\\n\t\t\t\t\t: \"r\"   (target),\t\\\n\t\t\t\t\t  \"r\"   (delta)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_BINARY(and, ptr, void, uintptr_t, \"and\", \"w\")\nCK_PR_BINARY(add, ptr, void, uintptr_t, \"add\", \"w\")\nCK_PR_BINARY(or, ptr, void, uintptr_t, \"or\", \"w\")\nCK_PR_BINARY(sub, ptr, void, uintptr_t, \"sub\", \"w\")\nCK_PR_BINARY(xor, ptr, void, uintptr_t, \"xor\", \"w\")\n\n#define CK_PR_BINARY_S(S, T, W)\t\t\t\\\n\tCK_PR_BINARY(and, S, T, T, \"and\", W)\t\\\n\tCK_PR_BINARY(add, S, T, T, \"add\", W)\t\\\n\tCK_PR_BINARY(or, S, T, T, \"or\", W)\t\\\n\tCK_PR_BINARY(sub, S, T, T, \"subf\", W)\t\\\n\tCK_PR_BINARY(xor, S, T, T, \"xor\", W)\n\nCK_PR_BINARY_S(32, uint32_t, \"w\")\nCK_PR_BINARY_S(uint, unsigned int, \"w\")\nCK_PR_BINARY_S(int, int, \"w\")\n\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\nCK_CC_INLINE static void *\nck_pr_faa_ptr(void *target, uintptr_t delta)\n{\n\tuintptr_t previous, r;\n\n\t__asm__ __volatile__(\"1:\"\n\t\t\t     \"lwarx %0, 0, %2;\"\n\t\t\t     \"add %1, %3, %0;\"\n\t\t\t     \"stwcx. %1, 0, %2;\"\n\t\t\t     \"bne-  1b;\"\n\t\t\t\t: \"=&r\" (previous),\n\t\t\t\t  \"=&r\" (r)\n\t\t\t\t: \"r\"   (target),\n\t\t\t\t  \"r\"   (delta)\n\t\t\t\t: \"memory\", \"cc\");\n\n\treturn (void *)(previous);\n}\n\n#define CK_PR_FAA(S, T, W)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_faa_##S(T *target, T delta)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous, r;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %2;\"\t\t\\\n\t\t\t\t     \"add %1, %3, %0;\"\t\t\t\\\n\t\t\t\t     \"st\" W \"cx. %1, 0, %2;\"\t\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous),\t\t\\\n\t\t\t\t\t  \"=&r\" (r)\t\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (delta)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (previous);\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(32, uint32_t, \"w\")\nCK_PR_FAA(uint, unsigned int, \"w\")\nCK_PR_FAA(int, int, \"w\")\n\n#undef CK_PR_FAA\n\n#endif /* CK_PR_PPC_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ppc64/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_64\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_64\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_64\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_64\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_64\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FAS_DOUBLE\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_DEPENDS\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_64\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_DOUBLE\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_SHORT\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_64\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_64\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_64\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_DOUBLE\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_SHORT\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_64\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_64\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_UINT\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/ppc64/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_PPC64_H\n#define CK_PR_PPC64_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Minimum interface requirement met.\n */\n#define CK_F_PR\n\n/*\n * This bounces the hardware thread from low to medium\n * priority. I am unsure of the benefits of this approach\n * but it is used by the Linux kernel.\n */\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\n\t__asm__ __volatile__(\"or 1, 1, 1;\"\n\t\t\t     \"or 2, 2, 2;\" ::: \"memory\");\n\treturn;\n}\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I ::: \"memory\");   \\\n\t}\n\n/*\n * These are derived from:\n *     http://www.ibm.com/developerworks/systems/articles/powerpc.html\n */\nCK_PR_FENCE(atomic, \"lwsync\")\nCK_PR_FENCE(atomic_store, \"lwsync\")\nCK_PR_FENCE(atomic_load, \"sync\")\nCK_PR_FENCE(store_atomic, \"lwsync\")\nCK_PR_FENCE(load_atomic, \"lwsync\")\nCK_PR_FENCE(store, \"lwsync\")\nCK_PR_FENCE(store_load, \"sync\")\nCK_PR_FENCE(load, \"lwsync\")\nCK_PR_FENCE(load_store, \"lwsync\")\nCK_PR_FENCE(memory, \"sync\")\nCK_PR_FENCE(acquire, \"lwsync\")\nCK_PR_FENCE(release, \"lwsync\")\nCK_PR_FENCE(acqrel, \"lwsync\")\nCK_PR_FENCE(lock, \"lwsync\")\nCK_PR_FENCE(unlock, \"lwsync\")\n\n#undef CK_PR_FENCE\n\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \"%U1%X1 %0, %1\"\t\t\t\\\n\t\t\t\t\t: \"=r\" (r)\t\t\t\\\n\t\t\t\t\t: \"m\"  (*(const C *)target)\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\treturn (r);\t\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, uint64_t, \"ld\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(64, uint64_t, \"ld\")\nCK_PR_LOAD_S(32, uint32_t, \"lwz\")\nCK_PR_LOAD_S(16, uint16_t, \"lhz\")\nCK_PR_LOAD_S(8, uint8_t, \"lbz\")\nCK_PR_LOAD_S(uint, unsigned int, \"lwz\")\nCK_PR_LOAD_S(int, int, \"lwz\")\nCK_PR_LOAD_S(short, short, \"lhz\")\nCK_PR_LOAD_S(char, char, \"lbz\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_LOAD_S(double, double, \"ld\")\n#endif\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \"%U0%X0 %1, %0\"\t\t\\\n\t\t\t\t\t: \"=m\" (*(C *)target)\t\\\n\t\t\t\t\t: \"r\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE(ptr, void, const void *, uint64_t, \"std\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)\n\nCK_PR_STORE_S(64, uint64_t, \"std\")\nCK_PR_STORE_S(32, uint32_t, \"stw\")\nCK_PR_STORE_S(16, uint16_t, \"sth\")\nCK_PR_STORE_S(8, uint8_t, \"stb\")\nCK_PR_STORE_S(uint, unsigned int, \"stw\")\nCK_PR_STORE_S(int, int, \"stw\")\nCK_PR_STORE_S(short, short, \"sth\")\nCK_PR_STORE_S(char, char, \"stb\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_STORE_S(double, double, \"std\")\n#endif\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE\n\nCK_CC_INLINE static bool\nck_pr_cas_64_value(uint64_t *target, uint64_t compare, uint64_t set, uint64_t *value)\n{\n\tuint64_t previous;\n\n        __asm__ __volatile__(\"1:\"\n\t\t\t     \"ldarx %0, 0, %1;\"\n\t\t\t     \"cmpd  0, %0, %3;\"\n\t\t\t     \"bne-  2f;\"\n\t\t\t     \"stdcx. %2, 0, %1;\"\n\t\t\t     \"bne-  1b;\"\n\t\t\t     \"2:\"\n                                : \"=&r\" (previous)\n                                : \"r\"   (target),\n\t\t\t\t  \"r\"   (set),\n                                  \"r\"   (compare)\n                                : \"memory\", \"cc\");\n\n        *value = previous;\n        return (previous == compare);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_value(void *target, void *compare, void *set, void *value)\n{\n\tvoid *previous;\n\n        __asm__ __volatile__(\"1:\"\n\t\t\t     \"ldarx %0, 0, %1;\"\n\t\t\t     \"cmpd  0, %0, %3;\"\n\t\t\t     \"bne-  2f;\"\n\t\t\t     \"stdcx. %2, 0, %1;\"\n\t\t\t     \"bne-  1b;\"\n\t\t\t     \"2:\"\n                                : \"=&r\" (previous)\n                                : \"r\"   (target),\n\t\t\t\t  \"r\"   (set),\n                                  \"r\"   (compare)\n                                : \"memory\", \"cc\");\n\n        ck_pr_md_store_ptr(value, previous);\n        return (previous == compare);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_64(uint64_t *target, uint64_t compare, uint64_t set)\n{\n\tuint64_t previous;\n\n        __asm__ __volatile__(\"1:\"\n\t\t\t     \"ldarx %0, 0, %1;\"\n\t\t\t     \"cmpd  0, %0, %3;\"\n\t\t\t     \"bne-  2f;\"\n\t\t\t     \"stdcx. %2, 0, %1;\"\n\t\t\t     \"bne-  1b;\"\n\t\t\t     \"2:\"\n                                : \"=&r\" (previous)\n                                : \"r\"   (target),\n\t\t\t\t  \"r\"   (set),\n                                  \"r\"   (compare)\n                                : \"memory\", \"cc\");\n\n        return (previous == compare);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr(void *target, void *compare, void *set)\n{\n\tvoid *previous;\n\n        __asm__ __volatile__(\"1:\"\n\t\t\t     \"ldarx %0, 0, %1;\"\n\t\t\t     \"cmpd  0, %0, %3;\"\n\t\t\t     \"bne-  2f;\"\n\t\t\t     \"stdcx. %2, 0, %1;\"\n\t\t\t     \"bne-  1b;\"\n\t\t\t     \"2:\"\n                                : \"=&r\" (previous)\n                                : \"r\"   (target),\n\t\t\t\t  \"r\"   (set),\n                                  \"r\"   (compare)\n                                : \"memory\", \"cc\");\n\n        return (previous == compare);\n}\n\n#define CK_PR_CAS(N, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N##_value(T *target, T compare, T set, T *value)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"lwarx %0, 0, %1;\"\t\t\t\\\n\t\t\t\t     \"cmpw  0, %0, %3;\"\t\t\t\\\n\t\t\t\t     \"bne-  2f;\"\t\t\t\\\n\t\t\t\t     \"stwcx. %2, 0, %1;\"\t\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\t\\\n\t\t\t\t     \"2:\"\t\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (set),\t\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\t*value = previous; \t\t\t\t\t\\\n\t\treturn (previous == compare);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N(T *target, T compare, T set)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"lwarx %0, 0, %1;\"\t\t\t\\\n\t\t\t\t     \"cmpw  0, %0, %3;\"\t\t\t\\\n\t\t\t\t     \"bne-  2f;\"\t\t\t\\\n\t\t\t\t     \"stwcx. %2, 0, %1;\"\t\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\t\\\n\t\t\t\t     \"2:\"\t\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (set),\t\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (previous == compare);\t\t\t\t\\\n\t}\n\nCK_PR_CAS(32, uint32_t)\nCK_PR_CAS(uint, unsigned int)\nCK_PR_CAS(int, int)\n\n#undef CK_PR_CAS\n\n#define CK_PR_FAS(N, M, T, W)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_fas_##N(M *target, T v)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %1;\"\t\\\n\t\t\t\t     \"st\" W \"cx. %2, 0, %1;\"\t\\\n\t\t\t\t     \"bne- 1b;\"\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\\\n\t\t\t\t\t: \"r\"   (target),\t\\\n\t\t\t\t\t  \"r\"   (v)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn (previous);\t\t\t\t\\\n\t}\n\nCK_PR_FAS(64, uint64_t, uint64_t, \"d\")\nCK_PR_FAS(32, uint32_t, uint32_t, \"w\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_FAS(double, double, double, \"d\")\n#endif\nCK_PR_FAS(ptr, void, void *, \"d\")\nCK_PR_FAS(int, int, int, \"w\")\nCK_PR_FAS(uint, unsigned int, unsigned int, \"w\")\n\n#undef CK_PR_FAS\n\n#define CK_PR_UNARY(O, N, M, T, I, W)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##O##_##N(M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %1;\"\t\\\n\t\t\t\t      I \";\"\t\t\t\\\n\t\t\t\t     \"st\" W \"cx. %0, 0, %1;\"\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\\\n\t\t\t\t\t: \"r\"   (target)\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_UNARY(inc, ptr, void, void *, \"addic %0, %0, 1\", \"d\")\nCK_PR_UNARY(dec, ptr, void, void *, \"addic %0, %0, -1\", \"d\")\nCK_PR_UNARY(not, ptr, void, void *, \"not %0, %0\", \"d\")\nCK_PR_UNARY(neg, ptr, void, void *, \"neg %0, %0\", \"d\")\n\n#define CK_PR_UNARY_S(S, T, W)\t\t\t\t\t\\\n\tCK_PR_UNARY(inc, S, T, T, \"addic %0, %0, 1\", W)\t\t\\\n\tCK_PR_UNARY(dec, S, T, T, \"addic %0, %0, -1\", W)\t\\\n\tCK_PR_UNARY(not, S, T, T, \"not %0, %0\", W)\t\t\\\n\tCK_PR_UNARY(neg, S, T, T, \"neg %0, %0\", W)\n\nCK_PR_UNARY_S(64, uint64_t, \"d\")\nCK_PR_UNARY_S(32, uint32_t, \"w\")\nCK_PR_UNARY_S(uint, unsigned int, \"w\")\nCK_PR_UNARY_S(int, int, \"w\")\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\n#define CK_PR_BINARY(O, N, M, T, I, W)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##O##_##N(M *target, T delta)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %1;\"\t\\\n\t\t\t\t      I \" %0, %2, %0;\"\t\t\\\n\t\t\t\t     \"st\" W \"cx. %0, 0, %1;\"\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\\\n\t\t\t\t\t: \"=&r\" (previous)\t\\\n\t\t\t\t\t: \"r\"   (target),\t\\\n\t\t\t\t\t  \"r\"   (delta)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_BINARY(and, ptr, void, uintptr_t, \"and\", \"d\")\nCK_PR_BINARY(add, ptr, void, uintptr_t, \"add\", \"d\")\nCK_PR_BINARY(or, ptr, void, uintptr_t, \"or\", \"d\")\nCK_PR_BINARY(sub, ptr, void, uintptr_t, \"sub\", \"d\")\nCK_PR_BINARY(xor, ptr, void, uintptr_t, \"xor\", \"d\")\n\n#define CK_PR_BINARY_S(S, T, W)\t\t\t\\\n\tCK_PR_BINARY(and, S, T, T, \"and\", W)\t\\\n\tCK_PR_BINARY(add, S, T, T, \"add\", W)\t\\\n\tCK_PR_BINARY(or, S, T, T, \"or\", W)\t\\\n\tCK_PR_BINARY(sub, S, T, T, \"subf\", W)\t\\\n\tCK_PR_BINARY(xor, S, T, T, \"xor\", W)\n\nCK_PR_BINARY_S(64, uint64_t, \"d\")\nCK_PR_BINARY_S(32, uint32_t, \"w\")\nCK_PR_BINARY_S(uint, unsigned int, \"w\")\nCK_PR_BINARY_S(int, int, \"w\")\n\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\nCK_CC_INLINE static void *\nck_pr_faa_ptr(void *target, uintptr_t delta)\n{\n\tuintptr_t previous, r;\n\n\t__asm__ __volatile__(\"1:\"\n\t\t\t     \"ldarx %0, 0, %2;\"\n\t\t\t     \"add %1, %3, %0;\"\n\t\t\t     \"stdcx. %1, 0, %2;\"\n\t\t\t     \"bne-  1b;\"\n\t\t\t\t: \"=&r\" (previous),\n\t\t\t\t  \"=&r\" (r)\n\t\t\t\t: \"r\"   (target),\n\t\t\t\t  \"r\"   (delta)\n\t\t\t\t: \"memory\", \"cc\");\n\n\treturn (void *)(previous);\n}\n\n#define CK_PR_FAA(S, T, W)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_faa_##S(T *target, T delta)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous, r;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"1:\"\t\t\t\t\\\n\t\t\t\t     \"l\" W \"arx %0, 0, %2;\"\t\t\\\n\t\t\t\t     \"add %1, %3, %0;\"\t\t\t\\\n\t\t\t\t     \"st\" W \"cx. %1, 0, %2;\"\t\t\\\n\t\t\t\t     \"bne-  1b;\"\t\t\t\\\n\t\t\t\t\t: \"=&r\" (previous),\t\t\\\n\t\t\t\t\t  \"=&r\" (r)\t\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (delta)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (previous);\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(64, uint64_t, \"d\")\nCK_PR_FAA(32, uint32_t, \"w\")\nCK_PR_FAA(uint, unsigned int, \"w\")\nCK_PR_FAA(int, int, \"w\")\n\n#undef CK_PR_FAA\n\n#endif /* CK_PR_PPC64_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/s390x/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_64\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_64\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_64\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_64\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_64\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FAS_DOUBLE\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_DEPENDS\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_64\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_DOUBLE\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_SHORT\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_64\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_64\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_64\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_DOUBLE\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_SHORT\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_64\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_64\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_UINT\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/s390x/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2017 Neale Ferguson\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_S390X_H\n#define CK_PR_S390X_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Minimum interface requirement met.\n */\n#define CK_F_PR\n\n/*\n * This bounces the hardware thread from low to medium\n * priority. I am unsure of the benefits of this approach\n * but it is used by the Linux kernel.\n */\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\t__sync_synchronize();\n\treturn;\n}\n\n#define CK_PR_FENCE(T)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__sync_synchronize();\t\t\t\\\n\t}\n\n/*\n * These are derived from:\n *     http://www.ibm.com/developerworks/systems/articles/powerpc.html\n */\nCK_PR_FENCE(atomic)\nCK_PR_FENCE(atomic_store)\nCK_PR_FENCE(atomic_load)\nCK_PR_FENCE(store_atomic)\nCK_PR_FENCE(load_atomic)\nCK_PR_FENCE(store)\nCK_PR_FENCE(store_load)\nCK_PR_FENCE(load)\nCK_PR_FENCE(load_store)\nCK_PR_FENCE(memory)\nCK_PR_FENCE(acquire)\nCK_PR_FENCE(release)\nCK_PR_FENCE(acqrel)\nCK_PR_FENCE(lock)\nCK_PR_FENCE(unlock)\n\n#undef CK_PR_FENCE\n\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \"\\t%0, %1\\n\"\t\t\t\\\n\t\t\t\t\t: \"=r\" (r)\t\t\t\\\n\t\t\t\t\t: \"Q\"  (*(const C *)target)\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\treturn (r);\t\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, uint64_t, \"lg\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(64, uint64_t, \"lg\")\nCK_PR_LOAD_S(32, uint32_t, \"llgf\")\nCK_PR_LOAD_S(16, uint16_t, \"llgh\")\nCK_PR_LOAD_S(8, uint8_t, \"llgc\")\nCK_PR_LOAD_S(uint, unsigned int, \"llgf\")\nCK_PR_LOAD_S(int, int, \"llgf\")\nCK_PR_LOAD_S(short, short, \"lgh\")\nCK_PR_LOAD_S(char, char, \"lgb\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_CC_INLINE static double\nck_pr_md_load_double(const double *target)\n{\n\tdouble r;\n\t__asm__ __volatile__(\"ld  %0, %1\\n\"\n\t\t\t\t: \"=f\" (r)\n\t\t\t\t: \"Q\"  (*(const double *)target)   \n\t\t\t\t: \"memory\");\n\treturn (r);\t\t\t\n}\n#endif\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \"\\t%1, %0\\n\"\t\t\\\n\t\t\t\t\t: \"=Q\" (*(C *)target)\t\\\n\t\t\t\t\t: \"r\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE(ptr, void, const void *, uint64_t, \"stg\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)\n\nCK_PR_STORE_S(64, uint64_t, \"stg\")\nCK_PR_STORE_S(32, uint32_t, \"st\")\nCK_PR_STORE_S(16, uint16_t, \"sth\")\nCK_PR_STORE_S(8, uint8_t, \"stc\")\nCK_PR_STORE_S(uint, unsigned int, \"st\")\nCK_PR_STORE_S(int, int, \"st\")\nCK_PR_STORE_S(short, short, \"sth\")\nCK_PR_STORE_S(char, char, \"stc\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_CC_INLINE static void\nck_pr_md_store_double(double *target, double v)\n{\n\t__asm__ __volatile__(\" std  %1, %0\\n\"\n\t\t\t\t: \"=Q\" (*(double *)target)   \n\t\t\t\t: \"f\"  (v)\n\t\t\t\t: \"0\", \"memory\");\n}\n#endif\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE\n\nCK_CC_INLINE static bool\nck_pr_cas_64_value(uint64_t *target, uint64_t compare, uint64_t set, uint64_t *value)\n{\n\t*value = __sync_val_compare_and_swap(target,compare,set);\n        return (*value == compare);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_value(void *target, void *compare, void *set, void *value)\n{\n\tuintptr_t previous;\n\n\tprevious = __sync_val_compare_and_swap((uintptr_t *) target,\n\t\t\t\t\t       (uintptr_t) compare,\n\t\t\t\t\t       (uintptr_t) set);\n\t*((uintptr_t *) value) = previous;\n        return (previous == (uintptr_t) compare);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_64(uint64_t *target, uint64_t compare, uint64_t set)\n{\n\treturn(__sync_bool_compare_and_swap(target,compare,set));\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr(void *target, void *compare, void *set)\n{\n\treturn(__sync_bool_compare_and_swap((uintptr_t *) target,\n\t\t\t\t\t    (uintptr_t) compare,\n\t\t\t\t\t    (uintptr_t) set));\n}\n\n#define CK_PR_CAS(N, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N##_value(T *target, T compare, T set, T *value)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t*value = __sync_val_compare_and_swap(target,\t\t\\\n\t\t\t\t\t\t     compare,\t\t\\\n\t\t\t\t\t\t     set);\t\t\\\n\t\treturn(*value == compare);\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N(T *target, T compare, T set)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\treturn(__sync_bool_compare_and_swap(target,\t\t\\\n\t\t\t\t\t\t   compare,\t\t\\\n\t\t\t\t\t\t   set));\t\t\\\n\t}\n\nCK_PR_CAS(32, uint32_t)\nCK_PR_CAS(uint, unsigned int)\nCK_PR_CAS(int, int)\n\n#undef CK_PR_CAS\n\nCK_CC_INLINE static void *\nck_pr_fas_ptr(void *target, void *v)\n{\n\treturn((void *)__atomic_exchange_n((uintptr_t *) target, (uintptr_t) v, __ATOMIC_ACQUIRE));\n}\n\n#define CK_PR_FAS(N, M, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\t\\\n\tck_pr_fas_##N(M *target, T v)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\treturn(__atomic_exchange_n(target, v, __ATOMIC_ACQUIRE));\t\\\n\t}\n\nCK_PR_FAS(64, uint64_t, uint64_t)\nCK_PR_FAS(32, uint32_t, uint32_t)\nCK_PR_FAS(int, int, int)\nCK_PR_FAS(uint, unsigned int, unsigned int)\n\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_CC_INLINE static double\nck_pr_fas_double(double *target, double *v)\n{\n\tdouble previous;\n\n\t__asm__ __volatile__ (\"\t   lg   1,%2\\n\"\n\t\t\t      \"0:  lg\t0,%1\\n\"\n\t\t\t      \"    csg\t0,1,%1\\n\"\n\t\t\t      \"    jnz\t0b\\n\"\n\t\t\t      \"    ldgr %0,0\\n\"\n\t\t\t      : \"=f\" (previous) \n\t\t\t      : \"Q\" (target), \"Q\" (v)\n\t\t\t      : \"0\", \"1\", \"cc\", \"memory\");\n\treturn (previous);\n}\n#endif\n\n#undef CK_PR_FAS\n\n/*\n * Atomic store-only binary operations.\n */\n#define CK_PR_BINARY(K, S, M, T)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##K##_##S(M *target, T d)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\td = __sync_fetch_and_##K((T *)target, d);\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BINARY_S(K, S, T) CK_PR_BINARY(K, S, T, T)\n\n#define CK_PR_GENERATE(K)\t\t\t\\\n\tCK_PR_BINARY(K, ptr, void, void *)\t\\\n\tCK_PR_BINARY_S(K, char, char)\t\t\\\n\tCK_PR_BINARY_S(K, int, int)\t\t\\\n\tCK_PR_BINARY_S(K, uint, unsigned int)\t\\\n\tCK_PR_BINARY_S(K, 64, uint64_t)\t\t\\\n\tCK_PR_BINARY_S(K, 32, uint32_t)\t\t\\\n\tCK_PR_BINARY_S(K, 16, uint16_t)\t\t\\\n\tCK_PR_BINARY_S(K, 8, uint8_t)\n\nCK_PR_GENERATE(add)\nCK_PR_GENERATE(sub)\nCK_PR_GENERATE(and)\nCK_PR_GENERATE(or)\nCK_PR_GENERATE(xor)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\n#define CK_PR_UNARY(S, M, T)\t\t\t\\\n\tCK_CC_INLINE static void\t\t\\\n\tck_pr_inc_##S(M *target)\t\t\\\n\t{\t\t\t\t\t\\\n\t\tck_pr_add_##S(target, (T)1);\t\\\n\t\treturn;\t\t\t\t\\\n\t}\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\\\n\tck_pr_dec_##S(M *target)\t\t\\\n\t{\t\t\t\t\t\\\n\t\tck_pr_sub_##S(target, (T)1);\t\\\n\t\treturn;\t\t\t\t\\\n\t}\n\n#define CK_PR_UNARY_X(S, M) \t  \t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_not_##S(M *target)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tM newval;\t\t\t\t\t\t\\\n\t\tdo {\t\t\t\t\t\t\t\\\n\t\t\tnewval = ~(*target);\t\t\t\t\\\n\t\t} while (!__sync_bool_compare_and_swap(target, \t\t\\\n\t\t\t\t\t\t      *target,\t\t\\\n\t\t\t\t\t\t      newval));\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_neg_##S(M *target)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tM newval;\t\t\t\t\t\t\\\n\t\tdo {\t\t\t\t\t\t\t\\\n\t\t\tnewval = -(*target);\t\t\t\t\\\n\t\t} while (!__sync_bool_compare_and_swap(target, \t\t\\\n\t\t\t\t\t\t      *target,\t\t\\\n\t\t\t\t\t\t      newval));\t\t\\\n\t}\t\t\t\t\t\t\t\t\n\n#define CK_PR_UNARY_S(S, M) CK_PR_UNARY(S, M, M) \\\n\t\t\t    CK_PR_UNARY_X(S, M)\n\nCK_PR_UNARY(ptr, void, void *)\nCK_PR_UNARY_S(char, char)\nCK_PR_UNARY_S(int, int)\nCK_PR_UNARY_S(uint, unsigned int)\nCK_PR_UNARY_S(64, uint64_t)\nCK_PR_UNARY_S(32, uint32_t)\nCK_PR_UNARY_S(16, uint16_t)\nCK_PR_UNARY_S(8, uint8_t)\n\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY\n\nCK_CC_INLINE static void *\nck_pr_faa_ptr(void *target, uintptr_t delta)\n{\n\tuintptr_t previous;\n\n\tprevious = __sync_fetch_and_add((uintptr_t *) target, delta);\n\n\treturn (void *)(previous);\n}\n\n#define CK_PR_FAA(S, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_faa_##S(T *target, T delta)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tprevious = __sync_fetch_and_add(target, delta);\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn (previous);\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(64, uint64_t)\nCK_PR_FAA(32, uint32_t)\nCK_PR_FAA(uint, unsigned int)\nCK_PR_FAA(int, int)\n\n#undef CK_PR_FAA\n\n#endif /* CK_PR_S390X_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/sparcv9/ck_f_pr.h",
    "content": "#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_DOUBLE\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_DOUBLE\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/sparcv9/ck_pr.h",
    "content": "/*\n * Copyright 2009, 2010 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_SPARCV9_H\n#define CK_PR_SPARCV9_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Minimum interface requirement met.\n */\n#define CK_F_PR\n\n/*\n * Order loads at the least.\n */\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\n\t__asm__ __volatile__(\"membar #LoadLoad\" ::: \"memory\");\n\treturn;\n}\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I ::: \"memory\");   \\\n\t}\n\n/*\n * Atomic operations are treated as both load and store\n * operations on SPARCv9.\n */\nCK_PR_FENCE(atomic, \"membar #StoreStore\")\nCK_PR_FENCE(atomic_store, \"membar #StoreStore\")\nCK_PR_FENCE(atomic_load, \"membar #StoreLoad\")\nCK_PR_FENCE(store_atomic, \"membar #StoreStore\")\nCK_PR_FENCE(load_atomic, \"membar #LoadStore\")\nCK_PR_FENCE(store, \"membar #StoreStore\")\nCK_PR_FENCE(store_load, \"membar #StoreLoad\")\nCK_PR_FENCE(load, \"membar #LoadLoad\")\nCK_PR_FENCE(load_store, \"membar #LoadStore\")\nCK_PR_FENCE(memory, \"membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad\")\nCK_PR_FENCE(acquire, \"membar #LoadLoad | #LoadStore\")\nCK_PR_FENCE(release, \"membar #LoadStore | #StoreStore\")\nCK_PR_FENCE(acqrel, \"membar #LoadLoad | #LoadStore | #StoreStore\")\nCK_PR_FENCE(lock, \"membar #LoadLoad | #LoadStore | #StoreStore | #StoreLoad\")\nCK_PR_FENCE(unlock, \"membar #LoadStore | #StoreStore\")\n\n#undef CK_PR_FENCE\n\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" [%1], %0\"\t\t\\\n\t\t\t\t\t: \"=&r\" (r)\t\t\\\n\t\t\t\t\t: \"r\"   (target)\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn (r);\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, uint64_t, \"ldx\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(64, uint64_t, \"ldx\")\nCK_PR_LOAD_S(32, uint32_t, \"lduw\")\nCK_PR_LOAD_S(uint, unsigned int, \"lduw\")\nCK_PR_LOAD_S(double, double, \"ldx\")\nCK_PR_LOAD_S(int, int, \"ldsw\")\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %0, [%1]\"\t\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"r\" (v),\t\t\\\n\t\t\t\t\t  \"r\" (target)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE(ptr, void, const void *, uint64_t, \"stx\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)\n\nCK_PR_STORE_S(8, uint8_t, \"stub\")\nCK_PR_STORE_S(64, uint64_t, \"stx\")\nCK_PR_STORE_S(32, uint32_t, \"stuw\")\nCK_PR_STORE_S(uint, unsigned int, \"stuw\")\nCK_PR_STORE_S(double, double, \"stx\")\nCK_PR_STORE_S(int, int, \"stsw\")\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE\n\nCK_CC_INLINE static bool\nck_pr_cas_64_value(uint64_t *target, uint64_t compare, uint64_t set, uint64_t *value)\n{\n\n\t__asm__ __volatile__(\"casx [%1], %2, %0\"\n\t\t\t\t: \"+&r\" (set)\n\t\t\t\t: \"r\"   (target),\n\t\t\t\t  \"r\"   (compare)\n\t\t\t\t: \"memory\");\n\n\t*value = set;\n\treturn (compare == set);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_64(uint64_t *target, uint64_t compare, uint64_t set)\n{\n\n\t__asm__ __volatile__(\"casx [%1], %2, %0\"\n\t\t\t\t: \"+&r\" (set)\n\t\t\t\t: \"r\" (target),\n\t\t\t\t  \"r\" (compare)\n\t\t\t\t: \"memory\");\n\n\treturn (compare == set);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr(void *target, void *compare, void *set)\n{\n\n\treturn ck_pr_cas_64(target, (uint64_t)compare, (uint64_t)set);\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_value(void *target, void *compare, void *set, void *previous)\n{\n\n\treturn ck_pr_cas_64_value(target, (uint64_t)compare, (uint64_t)set, previous);\n}\n\n#define CK_PR_CAS(N, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N##_value(T *target, T compare, T set, T *value)\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"cas [%1], %2, %0\"\t\t\t\\\n\t\t\t\t\t: \"+&r\" (set)\t\t\t\\\n\t\t\t\t\t: \"r\"   (target),\t\t\\\n\t\t\t\t\t  \"r\"   (compare)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\t*value = set;\t\t\t\t\t\t\\\n\t\treturn (compare == set);\t\t\t\t\\\n\t} \t\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_cas_##N(T *target, T compare, T set)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"cas [%1], %2, %0\"\t\t\t\\\n\t\t\t\t\t: \"+&r\" (set)\t\t\t\\\n\t\t\t\t\t: \"r\" (target),\t\t\t\\\n\t\t\t\t\t  \"r\" (compare)\t\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\treturn (compare == set);\t\t\t\t\\\n\t}\n\nCK_PR_CAS(32, uint32_t)\nCK_PR_CAS(uint, unsigned int)\nCK_PR_CAS(int, int)\n\n#undef CK_PR_CAS\n\n#define CK_PR_FAS(N, T)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static T \t\t\t\t\t\\\n\tck_pr_fas_##N(T *target, T update)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(\"swap [%1], %0\"\t\t\\\n\t\t\t\t\t: \"+&r\" (update)\t\\\n\t\t\t\t\t: \"r\"   (target)\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn (update);\t\t\t\t\\\n\t}\n\nCK_PR_FAS(int, int)\nCK_PR_FAS(uint, unsigned int)\nCK_PR_FAS(32, uint32_t)\n\n#undef CK_PR_FAS\n\n#endif /* CK_PR_SPARCV9_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/x86/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_16\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_8\n#define CK_F_PR_ADD_CHAR\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_16\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_8\n#define CK_F_PR_AND_CHAR\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_BTC_16\n#define CK_F_PR_BTC_32\n#define CK_F_PR_BTC_INT\n#define CK_F_PR_BTC_PTR\n#define CK_F_PR_BTC_UINT\n#define CK_F_PR_BTR_16\n#define CK_F_PR_BTR_32\n#define CK_F_PR_BTR_INT\n#define CK_F_PR_BTR_PTR\n#define CK_F_PR_BTR_UINT\n#define CK_F_PR_BTS_16\n#define CK_F_PR_BTS_32\n#define CK_F_PR_BTS_INT\n#define CK_F_PR_BTS_PTR\n#define CK_F_PR_BTS_UINT\n#define CK_F_PR_CAS_16\n#define CK_F_PR_CAS_16_VALUE\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_8\n#define CK_F_PR_CAS_8_VALUE\n#define CK_F_PR_CAS_CHAR\n#define CK_F_PR_CAS_CHAR_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_16\n#define CK_F_PR_DEC_16_ZERO\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_32_ZERO\n#define CK_F_PR_DEC_8\n#define CK_F_PR_DEC_8_ZERO\n#define CK_F_PR_DEC_CHAR\n#define CK_F_PR_DEC_CHAR_ZERO\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_INT_ZERO\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_PTR_ZERO\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_DEC_UINT_ZERO\n#define CK_F_PR_FAA_16\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_8\n#define CK_F_PR_FAA_CHAR\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_16\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_8\n#define CK_F_PR_FAS_CHAR\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_DEPENDS\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_INC_16\n#define CK_F_PR_INC_16_ZERO\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_32_ZERO\n#define CK_F_PR_INC_8\n#define CK_F_PR_INC_8_ZERO\n#define CK_F_PR_INC_CHAR\n#define CK_F_PR_INC_CHAR_ZERO\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_INT_ZERO\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_PTR_ZERO\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_INC_UINT_ZERO\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_NEG_16\n#define CK_F_PR_NEG_16_ZERO\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_32_ZERO\n#define CK_F_PR_NEG_8\n#define CK_F_PR_NEG_8_ZERO\n#define CK_F_PR_NEG_CHAR\n#define CK_F_PR_NEG_CHAR_ZERO\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_INT_ZERO\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_PTR_ZERO\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NEG_UINT_ZERO\n#define CK_F_PR_NOT_16\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_8\n#define CK_F_PR_NOT_CHAR\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_16\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_8\n#define CK_F_PR_OR_CHAR\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STALL\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_16\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_8\n#define CK_F_PR_SUB_CHAR\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_16\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_8\n#define CK_F_PR_XOR_CHAR\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_UINT\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/x86/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * Copyright 2011 Devon H. O'Dell <devon.odell@gmail.com>\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_X86_H\n#define CK_PR_X86_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_stdint.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/* Minimum requirements for the CK_PR interface are met. */\n#define CK_F_PR\n\n#ifdef CK_MD_UMP\n#define CK_PR_LOCK_PREFIX\n#else\n#define CK_PR_LOCK_PREFIX \"lock \"\n#endif\n\n/*\n * Prevent speculative execution in busy-wait loops (P4 <=)\n * or \"predefined delay\".\n */\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\t__asm__ __volatile__(\"pause\" ::: \"memory\");\n\treturn;\n}\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I ::: \"memory\");\t\\\n\t}\n\nCK_PR_FENCE(atomic, \"sfence\")\nCK_PR_FENCE(atomic_store, \"sfence\")\nCK_PR_FENCE(atomic_load, \"mfence\")\nCK_PR_FENCE(store_atomic, \"sfence\")\nCK_PR_FENCE(load_atomic, \"mfence\")\nCK_PR_FENCE(load, \"lfence\")\nCK_PR_FENCE(load_store, \"mfence\")\nCK_PR_FENCE(store, \"sfence\")\nCK_PR_FENCE(store_load, \"mfence\")\nCK_PR_FENCE(memory, \"mfence\")\nCK_PR_FENCE(release, \"mfence\")\nCK_PR_FENCE(acquire, \"mfence\")\nCK_PR_FENCE(acqrel, \"mfence\")\nCK_PR_FENCE(lock, \"mfence\")\nCK_PR_FENCE(unlock, \"mfence\")\n\n#undef CK_PR_FENCE\n\n/*\n * Atomic fetch-and-store operations.\n */\n#define CK_PR_FAS(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_fas_##S(M *target, T v)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %0, %1\"\t\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\\\n\t\t\t\t\t  \"+q\" (v)\t\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn v;\t\t\t\t\t\\\n\t}\n\nCK_PR_FAS(ptr, void, void *, char, \"xchgl\")\n\n#define CK_PR_FAS_S(S, T, I) CK_PR_FAS(S, T, T, T, I)\n\nCK_PR_FAS_S(char, char, \"xchgb\")\nCK_PR_FAS_S(uint, unsigned int, \"xchgl\")\nCK_PR_FAS_S(int, int, \"xchgl\")\nCK_PR_FAS_S(32, uint32_t, \"xchgl\")\nCK_PR_FAS_S(16, uint16_t, \"xchgw\")\nCK_PR_FAS_S(8,  uint8_t,  \"xchgb\")\n\n#undef CK_PR_FAS_S\n#undef CK_PR_FAS\n\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, %0\"\t\t\t\\\n\t\t\t\t\t: \"=q\" (r)\t\t\t\\\n\t\t\t\t\t: \"m\"  (*(const C *)target)\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\treturn (r);\t\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, char, \"movl\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(char, char, \"movb\")\nCK_PR_LOAD_S(uint, unsigned int, \"movl\")\nCK_PR_LOAD_S(int, int, \"movl\")\nCK_PR_LOAD_S(32, uint32_t, \"movl\")\nCK_PR_LOAD_S(16, uint16_t, \"movw\")\nCK_PR_LOAD_S(8,  uint8_t,  \"movb\")\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, %0\"\t\t\\\n\t\t\t\t\t: \"=m\" (*(C *)target)\t\\\n\t\t\t\t\t: CK_CC_IMM \"q\" (v)\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE(ptr, void, const void *, char, \"movl\")\n\n#define CK_PR_STORE_S(S, T, I) CK_PR_STORE(S, T, T, T, I)\n\nCK_PR_STORE_S(char, char, \"movb\")\nCK_PR_STORE_S(uint, unsigned int, \"movl\")\nCK_PR_STORE_S(int, int, \"movl\")\nCK_PR_STORE_S(32, uint32_t, \"movl\")\nCK_PR_STORE_S(16, uint16_t, \"movw\")\nCK_PR_STORE_S(8,  uint8_t, \"movb\")\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE\n\n/*\n * Atomic fetch-and-add operations.\n */\n#define CK_PR_FAA(S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_faa_##S(M *target, T d)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %1, %0\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\t\\\n\t\t\t\t\t  \"+q\" (d)\t\t\t\\\n\t\t\t\t\t:\t\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (d);\t\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(ptr, void, uintptr_t, char, \"xaddl\")\n\n#define CK_PR_FAA_S(S, T, I) CK_PR_FAA(S, T, T, T, I)\n\nCK_PR_FAA_S(char, char, \"xaddb\")\nCK_PR_FAA_S(uint, unsigned int, \"xaddl\")\nCK_PR_FAA_S(int, int, \"xaddl\")\nCK_PR_FAA_S(32, uint32_t, \"xaddl\")\nCK_PR_FAA_S(16, uint16_t, \"xaddw\")\nCK_PR_FAA_S(8,  uint8_t,  \"xaddb\")\n\n#undef CK_PR_FAA_S\n#undef CK_PR_FAA\n\n/*\n * Atomic store-only unary operations.\n */\n#define CK_PR_UNARY(K, S, T, C, I)\t\t\t\t\\\n\tCK_PR_UNARY_R(K, S, T, C, I)\t\t\t\t\\\n\tCK_PR_UNARY_V(K, S, T, C, I)\n\n#define CK_PR_UNARY_R(K, S, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##K##_##S(T *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %0\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target)\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_UNARY_V(K, S, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S##_zero(T *target, bool *r)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %0; setz %1\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\t\\\n\t\t\t\t\t  \"=m\" (*r)\t\t\t\\\n\t\t\t\t\t:\t\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n\n#define CK_PR_UNARY_S(K, S, T, I) CK_PR_UNARY(K, S, T, T, I)\n\n#define CK_PR_GENERATE(K)\t\t\t\t\\\n\tCK_PR_UNARY(K, ptr, void, char, #K \"l\") \t\\\n\tCK_PR_UNARY_S(K, char, char, #K \"b\")\t\t\\\n\tCK_PR_UNARY_S(K, int, int, #K \"l\")\t\t\\\n\tCK_PR_UNARY_S(K, uint, unsigned int, #K \"l\")\t\\\n\tCK_PR_UNARY_S(K, 32, uint32_t, #K \"l\")\t\t\\\n\tCK_PR_UNARY_S(K, 16, uint16_t, #K \"w\")\t\t\\\n\tCK_PR_UNARY_S(K, 8, uint8_t, #K \"b\")\n\nCK_PR_GENERATE(inc)\nCK_PR_GENERATE(dec)\nCK_PR_GENERATE(neg)\n\n/* not does not affect condition flags. */\n#undef CK_PR_UNARY_V\n#define CK_PR_UNARY_V(a, b, c, d, e)\nCK_PR_GENERATE(not)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY_V\n#undef CK_PR_UNARY_R\n#undef CK_PR_UNARY\n\n/*\n * Atomic store-only binary operations.\n */\n#define CK_PR_BINARY(K, S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S(M *target, T d)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %1, %0\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target)\t\t\\\n\t\t\t\t\t: CK_CC_IMM \"q\" (d)\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BINARY_S(K, S, T, I) CK_PR_BINARY(K, S, T, T, T, I)\n\n#define CK_PR_GENERATE(K)\t\t\t\t\t\\\n\tCK_PR_BINARY(K, ptr, void, uintptr_t, char, #K \"l\")\t\\\n\tCK_PR_BINARY_S(K, char, char, #K \"b\")\t\t\t\\\n\tCK_PR_BINARY_S(K, int, int, #K \"l\")\t\t\t\\\n\tCK_PR_BINARY_S(K, uint, unsigned int, #K \"l\")\t\t\\\n\tCK_PR_BINARY_S(K, 32, uint32_t, #K \"l\")\t\t\t\\\n\tCK_PR_BINARY_S(K, 16, uint16_t, #K \"w\")\t\t\t\\\n\tCK_PR_BINARY_S(K, 8, uint8_t, #K \"b\")\n\nCK_PR_GENERATE(add)\nCK_PR_GENERATE(sub)\nCK_PR_GENERATE(and)\nCK_PR_GENERATE(or)\nCK_PR_GENERATE(xor)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\n/*\n * Atomic compare and swap.\n */\n#define CK_PR_CAS(S, M, T, C, I)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_pr_cas_##S(M *target, T compare, T set)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tbool z;\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %2, %0; setz %1\"\t\\\n\t\t\t\t\t: \"+m\"  (*(C *)target),\t\t\t\\\n\t\t\t\t\t  \"=a\"  (z)\t\t\t\t\\\n\t\t\t\t\t: \"q\"   (set),\t\t\t\t\\\n\t\t\t\t\t  \"a\"   (compare)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\t\\\n\t\treturn z;\t\t\t\t\t\t\t\\\n\t}\n\nCK_PR_CAS(ptr, void, void *, char, \"cmpxchgl\")\n\n#define CK_PR_CAS_S(S, T, I) CK_PR_CAS(S, T, T, T, I)\n\nCK_PR_CAS_S(char, char, \"cmpxchgb\")\nCK_PR_CAS_S(int, int, \"cmpxchgl\")\nCK_PR_CAS_S(uint, unsigned int, \"cmpxchgl\")\nCK_PR_CAS_S(32, uint32_t, \"cmpxchgl\")\nCK_PR_CAS_S(16, uint16_t, \"cmpxchgw\")\nCK_PR_CAS_S(8,  uint8_t,  \"cmpxchgb\")\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n/*\n * Compare and swap, set *v to old value of target.\n */\n#define CK_PR_CAS_O(S, M, T, C, I, R)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_pr_cas_##S##_value(M *target, T compare, T set, M *v)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tbool z;\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX \"cmpxchg\" I \" %3, %0;\"\t\\\n\t\t\t\t     \"mov %% \" R \", %2;\"\t\t\t\\\n\t\t\t\t     \"setz %1;\"\t\t\t\t\t\\\n\t\t\t\t\t: \"+m\"  (*(C *)target),\t\t\t\\\n\t\t\t\t\t  \"=a\"  (z),\t\t\t\t\\\n\t\t\t\t\t  \"=m\"  (*(C *)v)\t\t\t\\\n\t\t\t\t\t: \"q\"   (set),\t\t\t\t\\\n\t\t\t\t\t  \"a\"   (compare)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\t\\\n\t\treturn (bool)z;\t\t\t\t\t\t\t\\\n\t}\n\nCK_PR_CAS_O(ptr, void, void *, char, \"l\", \"eax\")\n\n#define CK_PR_CAS_O_S(S, T, I, R)\t\\\n\tCK_PR_CAS_O(S, T, T, T, I, R)\n\nCK_PR_CAS_O_S(char, char, \"b\", \"al\")\nCK_PR_CAS_O_S(int, int, \"l\", \"eax\")\nCK_PR_CAS_O_S(uint, unsigned int, \"l\", \"eax\")\nCK_PR_CAS_O_S(32, uint32_t, \"l\", \"eax\")\nCK_PR_CAS_O_S(16, uint16_t, \"w\", \"ax\")\nCK_PR_CAS_O_S(8,  uint8_t,  \"b\", \"al\")\n\n#undef CK_PR_CAS_O_S\n#undef CK_PR_CAS_O\n\n/*\n * Atomic bit test operations.\n */\n#define CK_PR_BT(K, S, T, P, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_##K##_##S(T *target, unsigned int b)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tbool c;\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \"; setc %1\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\t\\\n\t\t\t\t\t  \"=q\" (c)\t\t\t\\\n\t\t\t\t\t: \"q\"  ((P)b)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (bool)c;\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BT_S(K, S, T, I) CK_PR_BT(K, S, T, T, T, I)\n\n#define CK_PR_GENERATE(K)\t\t\t\t\t\\\n\tCK_PR_BT(K, ptr, void, uint32_t, char, #K \"l %2, %0\")\t\\\n\tCK_PR_BT_S(K, uint, unsigned int, #K \"l %2, %0\")\t\\\n\tCK_PR_BT_S(K, int, int, #K \"l %2, %0\")\t\t\t\\\n\tCK_PR_BT_S(K, 32, uint32_t, #K \"l %2, %0\")\t\t\\\n\tCK_PR_BT_S(K, 16, uint16_t, #K \"w %w2, %0\")\n\nCK_PR_GENERATE(btc)\nCK_PR_GENERATE(bts)\nCK_PR_GENERATE(btr)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BT\n\n#endif /* CK_PR_X86_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/x86_64/ck_f_pr.h",
    "content": "/* DO NOT EDIT. This is auto-generated from feature.sh */\n#define CK_F_PR_ADD_16\n#define CK_F_PR_ADD_32\n#define CK_F_PR_ADD_64\n#define CK_F_PR_ADD_8\n#define CK_F_PR_ADD_CHAR\n#define CK_F_PR_ADD_INT\n#define CK_F_PR_ADD_PTR\n#define CK_F_PR_ADD_UINT\n#define CK_F_PR_AND_16\n#define CK_F_PR_AND_32\n#define CK_F_PR_AND_64\n#define CK_F_PR_AND_8\n#define CK_F_PR_AND_CHAR\n#define CK_F_PR_AND_INT\n#define CK_F_PR_AND_PTR\n#define CK_F_PR_AND_UINT\n#define CK_F_PR_BTC_16\n#define CK_F_PR_BTC_32\n#define CK_F_PR_BTC_64\n#define CK_F_PR_BTC_INT\n#define CK_F_PR_BTC_PTR\n#define CK_F_PR_BTC_UINT\n#define CK_F_PR_BTR_16\n#define CK_F_PR_BTR_32\n#define CK_F_PR_BTR_64\n#define CK_F_PR_BTR_INT\n#define CK_F_PR_BTR_PTR\n#define CK_F_PR_BTR_UINT\n#define CK_F_PR_BTS_16\n#define CK_F_PR_BTS_32\n#define CK_F_PR_BTS_64\n#define CK_F_PR_BTS_INT\n#define CK_F_PR_BTS_PTR\n#define CK_F_PR_BTS_UINT\n#define CK_F_PR_CAS_16\n#define CK_F_PR_CAS_16_8\n#define CK_F_PR_CAS_16_8_VALUE\n#define CK_F_PR_CAS_16_VALUE\n#define CK_F_PR_CAS_32\n#define CK_F_PR_CAS_32_4\n#define CK_F_PR_CAS_32_4_VALUE\n#define CK_F_PR_CAS_32_VALUE\n#define CK_F_PR_CAS_64\n#define CK_F_PR_CAS_64_2\n#define CK_F_PR_CAS_64_2_VALUE\n#define CK_F_PR_CAS_64_VALUE\n#define CK_F_PR_CAS_8\n#define CK_F_PR_CAS_8_16\n#define CK_F_PR_CAS_8_16_VALUE\n#define CK_F_PR_CAS_8_VALUE\n#define CK_F_PR_CAS_CHAR\n#define CK_F_PR_CAS_CHAR_16\n#define CK_F_PR_CAS_CHAR_16_VALUE\n#define CK_F_PR_CAS_CHAR_VALUE\n#define CK_F_PR_CAS_INT\n#define CK_F_PR_CAS_INT_4\n#define CK_F_PR_CAS_INT_4_VALUE\n#define CK_F_PR_CAS_INT_VALUE\n#define CK_F_PR_CAS_PTR\n#define CK_F_PR_CAS_PTR_2\n#define CK_F_PR_CAS_PTR_2_VALUE\n#define CK_F_PR_CAS_PTR_VALUE\n#define CK_F_PR_CAS_DOUBLE\n#define CK_F_PR_CAS_DOUBLE_2\n#define CK_F_PR_CAS_DOUBLE_VALUE\n#define CK_F_PR_CAS_UINT\n#define CK_F_PR_CAS_UINT_4\n#define CK_F_PR_CAS_UINT_4_VALUE\n#define CK_F_PR_CAS_UINT_VALUE\n#define CK_F_PR_DEC_16\n#define CK_F_PR_DEC_16_ZERO\n#define CK_F_PR_DEC_32\n#define CK_F_PR_DEC_32_ZERO\n#define CK_F_PR_DEC_64\n#define CK_F_PR_DEC_64_ZERO\n#define CK_F_PR_DEC_8\n#define CK_F_PR_DEC_8_ZERO\n#define CK_F_PR_DEC_CHAR\n#define CK_F_PR_DEC_CHAR_ZERO\n#define CK_F_PR_DEC_INT\n#define CK_F_PR_DEC_INT_ZERO\n#define CK_F_PR_DEC_PTR\n#define CK_F_PR_DEC_PTR_ZERO\n#define CK_F_PR_DEC_UINT\n#define CK_F_PR_DEC_UINT_ZERO\n#define CK_F_PR_FAA_16\n#define CK_F_PR_FAA_32\n#define CK_F_PR_FAA_64\n#define CK_F_PR_FAA_8\n#define CK_F_PR_FAA_CHAR\n#define CK_F_PR_FAA_INT\n#define CK_F_PR_FAA_PTR\n#define CK_F_PR_FAA_UINT\n#define CK_F_PR_FAS_16\n#define CK_F_PR_FAS_32\n#define CK_F_PR_FAS_64\n#define CK_F_PR_FAS_8\n#define CK_F_PR_FAS_CHAR\n#define CK_F_PR_FAS_INT\n#define CK_F_PR_FAS_PTR\n#define CK_F_PR_FAS_UINT\n#define CK_F_PR_FAS_DOUBLE\n#define CK_F_PR_FENCE_LOAD\n#define CK_F_PR_FENCE_LOAD_DEPENDS\n#define CK_F_PR_FENCE_MEMORY\n#define CK_F_PR_FENCE_STORE\n#define CK_F_PR_FENCE_STRICT_LOAD\n#define CK_F_PR_FENCE_STRICT_LOAD_DEPENDS\n#define CK_F_PR_FENCE_STRICT_MEMORY\n#define CK_F_PR_FENCE_STRICT_STORE\n#define CK_F_PR_INC_16\n#define CK_F_PR_INC_16_ZERO\n#define CK_F_PR_INC_32\n#define CK_F_PR_INC_32_ZERO\n#define CK_F_PR_INC_64\n#define CK_F_PR_INC_64_ZERO\n#define CK_F_PR_INC_8\n#define CK_F_PR_INC_8_ZERO\n#define CK_F_PR_INC_CHAR\n#define CK_F_PR_INC_CHAR_ZERO\n#define CK_F_PR_INC_INT\n#define CK_F_PR_INC_INT_ZERO\n#define CK_F_PR_INC_PTR\n#define CK_F_PR_INC_PTR_ZERO\n#define CK_F_PR_INC_UINT\n#define CK_F_PR_INC_UINT_ZERO\n#define CK_F_PR_LOAD_16\n#define CK_F_PR_LOAD_16_8\n#define CK_F_PR_LOAD_32\n#define CK_F_PR_LOAD_32_4\n#define CK_F_PR_LOAD_64\n#define CK_F_PR_LOAD_64_2\n#define CK_F_PR_LOAD_8\n#define CK_F_PR_LOAD_8_16\n#define CK_F_PR_LOAD_CHAR\n#define CK_F_PR_LOAD_CHAR_16\n#define CK_F_PR_LOAD_INT\n#define CK_F_PR_LOAD_INT_4\n#define CK_F_PR_LOAD_PTR\n#define CK_F_PR_LOAD_PTR_2\n#define CK_F_PR_LOAD_DOUBLE\n#define CK_F_PR_LOAD_UINT\n#define CK_F_PR_LOAD_UINT_4\n#define CK_F_PR_NEG_16\n#define CK_F_PR_NEG_16_ZERO\n#define CK_F_PR_NEG_32\n#define CK_F_PR_NEG_32_ZERO\n#define CK_F_PR_NEG_64\n#define CK_F_PR_NEG_64_ZERO\n#define CK_F_PR_NEG_8\n#define CK_F_PR_NEG_8_ZERO\n#define CK_F_PR_NEG_CHAR\n#define CK_F_PR_NEG_CHAR_ZERO\n#define CK_F_PR_NEG_INT\n#define CK_F_PR_NEG_INT_ZERO\n#define CK_F_PR_NEG_PTR\n#define CK_F_PR_NEG_PTR_ZERO\n#define CK_F_PR_NEG_UINT\n#define CK_F_PR_NEG_UINT_ZERO\n#define CK_F_PR_NOT_16\n#define CK_F_PR_NOT_32\n#define CK_F_PR_NOT_64\n#define CK_F_PR_NOT_8\n#define CK_F_PR_NOT_CHAR\n#define CK_F_PR_NOT_INT\n#define CK_F_PR_NOT_PTR\n#define CK_F_PR_NOT_UINT\n#define CK_F_PR_OR_16\n#define CK_F_PR_OR_32\n#define CK_F_PR_OR_64\n#define CK_F_PR_OR_8\n#define CK_F_PR_OR_CHAR\n#define CK_F_PR_OR_INT\n#define CK_F_PR_OR_PTR\n#define CK_F_PR_OR_UINT\n#define CK_F_PR_STORE_16\n#define CK_F_PR_STORE_32\n#define CK_F_PR_STORE_64\n#define CK_F_PR_STORE_8\n#define CK_F_PR_STORE_CHAR\n#define CK_F_PR_STORE_INT\n#define CK_F_PR_STORE_DOUBLE\n#define CK_F_PR_STORE_PTR\n#define CK_F_PR_STORE_UINT\n#define CK_F_PR_SUB_16\n#define CK_F_PR_SUB_32\n#define CK_F_PR_SUB_64\n#define CK_F_PR_SUB_8\n#define CK_F_PR_SUB_CHAR\n#define CK_F_PR_SUB_INT\n#define CK_F_PR_SUB_PTR\n#define CK_F_PR_SUB_UINT\n#define CK_F_PR_XOR_16\n#define CK_F_PR_XOR_32\n#define CK_F_PR_XOR_64\n#define CK_F_PR_XOR_8\n#define CK_F_PR_XOR_CHAR\n#define CK_F_PR_XOR_INT\n#define CK_F_PR_XOR_PTR\n#define CK_F_PR_XOR_UINT\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/x86_64/ck_pr.h",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_PR_X86_64_H\n#define CK_PR_X86_64_H\n\n#ifndef CK_PR_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_stdint.h>\n\n/*\n * The following represent supported atomic operations.\n * These operations may be emulated.\n */\n#include \"ck_f_pr.h\"\n\n/*\n * Support for TSX extensions.\n */\n#ifdef CK_MD_RTM_ENABLE\n#include \"ck_pr_rtm.h\"\n#endif\n\n/* Minimum requirements for the CK_PR interface are met. */\n#define CK_F_PR\n\n#ifdef CK_MD_UMP\n#define CK_PR_LOCK_PREFIX\n#else\n#define CK_PR_LOCK_PREFIX \"lock \"\n#endif\n\n/*\n * Prevent speculative execution in busy-wait loops (P4 <=)\n * or \"predefined delay\".\n */\nCK_CC_INLINE static void\nck_pr_stall(void)\n{\n\t__asm__ __volatile__(\"pause\" ::: \"memory\");\n\treturn;\n}\n\n#define CK_PR_FENCE(T, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\\\n\tck_pr_fence_strict_##T(void)\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I ::: \"memory\");\t\\\n\t}\n\nCK_PR_FENCE(atomic, \"sfence\")\nCK_PR_FENCE(atomic_store, \"sfence\")\nCK_PR_FENCE(atomic_load, \"mfence\")\nCK_PR_FENCE(store_atomic, \"sfence\")\nCK_PR_FENCE(load_atomic, \"mfence\")\nCK_PR_FENCE(load, \"lfence\")\nCK_PR_FENCE(load_store, \"mfence\")\nCK_PR_FENCE(store, \"sfence\")\nCK_PR_FENCE(store_load, \"mfence\")\nCK_PR_FENCE(memory, \"mfence\")\nCK_PR_FENCE(release, \"mfence\")\nCK_PR_FENCE(acquire, \"mfence\")\nCK_PR_FENCE(acqrel, \"mfence\")\nCK_PR_FENCE(lock, \"mfence\")\nCK_PR_FENCE(unlock, \"mfence\")\n\n#undef CK_PR_FENCE\n\n/*\n * Read for ownership. Older compilers will generate the 32-bit\n * 3DNow! variant which is binary compatible with x86-64 variant\n * of prefetchw.\n */\n#ifndef CK_F_PR_RFO\n#define CK_F_PR_RFO\nCK_CC_INLINE static void\nck_pr_rfo(const void *m)\n{\n\n\t__asm__ __volatile__(\"prefetchw (%0)\"\n\t    :\n\t    : \"r\" (m)\n\t    : \"memory\");\n\n\treturn;\n}\n#endif /* CK_F_PR_RFO */\n\n/*\n * Atomic fetch-and-store operations.\n */\n#define CK_PR_FAS(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_fas_##S(M *target, T v)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %0, %1\"\t\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\\\n\t\t\t\t\t  \"+q\" (v)\t\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn v;\t\t\t\t\t\\\n\t}\n\nCK_PR_FAS(ptr, void, void *, char, \"xchgq\")\n\n#define CK_PR_FAS_S(S, T, I) CK_PR_FAS(S, T, T, T, I)\n\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_FAS_S(double, double, \"xchgq\")\n#endif\nCK_PR_FAS_S(char, char, \"xchgb\")\nCK_PR_FAS_S(uint, unsigned int, \"xchgl\")\nCK_PR_FAS_S(int, int, \"xchgl\")\nCK_PR_FAS_S(64, uint64_t, \"xchgq\")\nCK_PR_FAS_S(32, uint32_t, \"xchgl\")\nCK_PR_FAS_S(16, uint16_t, \"xchgw\")\nCK_PR_FAS_S(8,  uint8_t,  \"xchgb\")\n\n#undef CK_PR_FAS_S\n#undef CK_PR_FAS\n\n/*\n * Atomic load-from-memory operations.\n */\n#define CK_PR_LOAD(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\\\n\tck_pr_md_load_##S(const M *target)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tT r;\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, %0\"\t\t\\\n\t\t    : \"=q\" (r)\t\t\t\t\t\\\n\t\t    : \"m\"  (*(const C *)target)\t\t\t\\\n\t\t    : \"memory\");\t\t\t\t\\\n\t\treturn (r);\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD(ptr, void, void *, char, \"movq\")\n\n#define CK_PR_LOAD_S(S, T, I) CK_PR_LOAD(S, T, T, T, I)\n\nCK_PR_LOAD_S(char, char, \"movb\")\nCK_PR_LOAD_S(uint, unsigned int, \"movl\")\nCK_PR_LOAD_S(int, int, \"movl\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_LOAD_S(double, double, \"movq\")\n#endif\nCK_PR_LOAD_S(64, uint64_t, \"movq\")\nCK_PR_LOAD_S(32, uint32_t, \"movl\")\nCK_PR_LOAD_S(16, uint16_t, \"movw\")\nCK_PR_LOAD_S(8,  uint8_t,  \"movb\")\n\n#undef CK_PR_LOAD_S\n#undef CK_PR_LOAD\n\nCK_CC_INLINE static void\nck_pr_load_64_2(const uint64_t target[2], uint64_t v[2])\n{\n\t__asm__ __volatile__(\"movq %%rdx, %%rcx;\"\n\t\t\t     \"movq %%rax, %%rbx;\"\n\t\t\t     CK_PR_LOCK_PREFIX \"cmpxchg16b %2;\"\n\t\t\t\t: \"=a\" (v[0]),\n\t\t\t\t  \"=d\" (v[1])\n\t\t\t\t: \"m\" (*(const uint64_t *)target)\n\t\t\t\t: \"rbx\", \"rcx\", \"memory\", \"cc\");\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_pr_load_ptr_2(const void *t, void *v)\n{\n\tck_pr_load_64_2(CK_CPP_CAST(const uint64_t *, t),\n\t\t\tCK_CPP_CAST(uint64_t *, v));\n\treturn;\n}\n\n#define CK_PR_LOAD_2(S, W, T)\t\t\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\t\\\n\tck_pr_md_load_##S##_##W(const T t[2], T v[2])\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_load_64_2((const uint64_t *)(const void *)t,\t\t\\\n\t\t\t\t(uint64_t *)(void *)v);\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\\\n\t}\n\nCK_PR_LOAD_2(char, 16, char)\nCK_PR_LOAD_2(int, 4, int)\nCK_PR_LOAD_2(uint, 4, unsigned int)\nCK_PR_LOAD_2(32, 4, uint32_t)\nCK_PR_LOAD_2(16, 8, uint16_t)\nCK_PR_LOAD_2(8, 16, uint8_t)\n\n#undef CK_PR_LOAD_2\n\n/*\n * Atomic store-to-memory operations.\n */\n#define CK_PR_STORE_IMM(S, M, T, C, I, K)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, %0\"\t\t\t\\\n\t\t\t\t\t: \"=m\" (*(C *)target)\t\t\\\n\t\t\t\t\t: K \"q\" (v)\t\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_STORE(S, M, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_md_store_##S(M *target, T v)\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(I \" %1, %0\"\t\t\\\n\t\t\t\t\t: \"=m\" (*(C *)target)\t\\\n\t\t\t\t\t: \"q\" (v)\t\t\\\n\t\t\t\t\t: \"memory\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\nCK_PR_STORE_IMM(ptr, void, const void *, char, \"movq\", CK_CC_IMM_U32)\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_STORE(double, double, double, double, \"movq\")\n#endif\n\n#define CK_PR_STORE_S(S, T, I, K) CK_PR_STORE_IMM(S, T, T, T, I, K)\n\nCK_PR_STORE_S(char, char, \"movb\", CK_CC_IMM_S32)\nCK_PR_STORE_S(int, int, \"movl\", CK_CC_IMM_S32)\nCK_PR_STORE_S(uint, unsigned int, \"movl\", CK_CC_IMM_U32)\nCK_PR_STORE_S(64, uint64_t, \"movq\", CK_CC_IMM_U32)\nCK_PR_STORE_S(32, uint32_t, \"movl\", CK_CC_IMM_U32)\nCK_PR_STORE_S(16, uint16_t, \"movw\", CK_CC_IMM_U32)\nCK_PR_STORE_S(8,  uint8_t, \"movb\", CK_CC_IMM_U32)\n\n#undef CK_PR_STORE_S\n#undef CK_PR_STORE_IMM\n#undef CK_PR_STORE\n\n/*\n * Atomic fetch-and-add operations.\n */\n#define CK_PR_FAA(S, M, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static T\t\t\t\t\t\t\\\n\tck_pr_faa_##S(M *target, T d)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %1, %0\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\t\\\n\t\t\t\t\t  \"+q\" (d)\t\t\t\\\n\t\t\t\t\t:\t\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn (d);\t\t\t\t\t\t\\\n\t}\n\nCK_PR_FAA(ptr, void, uintptr_t, char, \"xaddq\")\n\n#define CK_PR_FAA_S(S, T, I) CK_PR_FAA(S, T, T, T, I)\n\nCK_PR_FAA_S(char, char, \"xaddb\")\nCK_PR_FAA_S(uint, unsigned int, \"xaddl\")\nCK_PR_FAA_S(int, int, \"xaddl\")\nCK_PR_FAA_S(64, uint64_t, \"xaddq\")\nCK_PR_FAA_S(32, uint32_t, \"xaddl\")\nCK_PR_FAA_S(16, uint16_t, \"xaddw\")\nCK_PR_FAA_S(8,  uint8_t,  \"xaddb\")\n\n#undef CK_PR_FAA_S\n#undef CK_PR_FAA\n\n/*\n * Atomic store-only unary operations.\n */\n#define CK_PR_UNARY(K, S, T, C, I)\t\t\t\t\\\n\tCK_PR_UNARY_R(K, S, T, C, I)\t\t\t\t\\\n\tCK_PR_UNARY_V(K, S, T, C, I)\n\n#define CK_PR_UNARY_R(K, S, T, C, I)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\\\n\tck_pr_##K##_##S(T *target)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %0\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target)\t\\\n\t\t\t\t\t:\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_UNARY_V(K, S, T, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S##_zero(T *target, bool *r)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %0; setz %1\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\t\\\n\t\t\t\t\t  \"=m\" (*r)\t\t\t\\\n\t\t\t\t\t:\t\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n\n#define CK_PR_UNARY_S(K, S, T, I) CK_PR_UNARY(K, S, T, T, I)\n\n#define CK_PR_GENERATE(K)\t\t\t\t\\\n\tCK_PR_UNARY(K, ptr, void, char, #K \"q\") \t\\\n\tCK_PR_UNARY_S(K, char, char, #K \"b\")\t\t\\\n\tCK_PR_UNARY_S(K, int, int, #K \"l\")\t\t\\\n\tCK_PR_UNARY_S(K, uint, unsigned int, #K \"l\")\t\\\n\tCK_PR_UNARY_S(K, 64, uint64_t, #K \"q\")\t\t\\\n\tCK_PR_UNARY_S(K, 32, uint32_t, #K \"l\")\t\t\\\n\tCK_PR_UNARY_S(K, 16, uint16_t, #K \"w\")\t\t\\\n\tCK_PR_UNARY_S(K, 8, uint8_t, #K \"b\")\n\nCK_PR_GENERATE(inc)\nCK_PR_GENERATE(dec)\nCK_PR_GENERATE(neg)\n\n/* not does not affect condition flags. */\n#undef CK_PR_UNARY_V\n#define CK_PR_UNARY_V(a, b, c, d, e)\nCK_PR_GENERATE(not)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_UNARY_S\n#undef CK_PR_UNARY_V\n#undef CK_PR_UNARY_R\n#undef CK_PR_UNARY\n\n/*\n * Atomic store-only binary operations.\n */\n#define CK_PR_BINARY(K, S, M, T, C, I, O)\t\t\t\t\\\n\tCK_CC_INLINE static void\t\t\t\t\t\\\n\tck_pr_##K##_##S(M *target, T d)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %1, %0\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target)\t\t\\\n\t\t\t\t\t: O \"q\" (d)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BINARY_S(K, S, T, I, O) CK_PR_BINARY(K, S, T, T, T, I, O)\n\n#define CK_PR_GENERATE(K)\t\t\t\t\t\t\t\\\n\tCK_PR_BINARY(K, ptr, void, uintptr_t, char, #K \"q\", CK_CC_IMM_U32)\t\\\n\tCK_PR_BINARY_S(K, char, char, #K \"b\", CK_CC_IMM_S32)\t\t\t\\\n\tCK_PR_BINARY_S(K, int, int, #K \"l\", CK_CC_IMM_S32)\t\t\t\\\n\tCK_PR_BINARY_S(K, uint, unsigned int, #K \"l\", CK_CC_IMM_U32)\t\t\\\n\tCK_PR_BINARY_S(K, 64, uint64_t, #K \"q\", CK_CC_IMM_U32)\t\t\t\\\n\tCK_PR_BINARY_S(K, 32, uint32_t, #K \"l\", CK_CC_IMM_U32)\t\t\t\\\n\tCK_PR_BINARY_S(K, 16, uint16_t, #K \"w\", CK_CC_IMM_U32)\t\t\t\\\n\tCK_PR_BINARY_S(K, 8, uint8_t, #K \"b\", CK_CC_IMM_U32)\n\nCK_PR_GENERATE(add)\nCK_PR_GENERATE(sub)\nCK_PR_GENERATE(and)\nCK_PR_GENERATE(or)\nCK_PR_GENERATE(xor)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BINARY_S\n#undef CK_PR_BINARY\n\n/*\n * Atomic compare and swap.\n */\n#define CK_PR_CAS(S, M, T, C, I)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_pr_cas_##S(M *target, T compare, T set)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tbool z;\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \" %2, %0; setz %1\"\t\\\n\t\t\t\t\t: \"+m\"  (*(C *)target),\t\t\t\\\n\t\t\t\t\t  \"=a\"  (z)\t\t\t\t\\\n\t\t\t\t\t: \"q\"   (set),\t\t\t\t\\\n\t\t\t\t\t  \"a\"   (compare)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\t\\\n\t\treturn z;\t\t\t\t\t\t\t\\\n\t}\n\nCK_PR_CAS(ptr, void, void *, char, \"cmpxchgq\")\n\n#define CK_PR_CAS_S(S, T, I) CK_PR_CAS(S, T, T, T, I)\n\nCK_PR_CAS_S(char, char, \"cmpxchgb\")\nCK_PR_CAS_S(int, int, \"cmpxchgl\")\nCK_PR_CAS_S(uint, unsigned int, \"cmpxchgl\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_CAS_S(double, double, \"cmpxchgq\")\n#endif\nCK_PR_CAS_S(64, uint64_t, \"cmpxchgq\")\nCK_PR_CAS_S(32, uint32_t, \"cmpxchgl\")\nCK_PR_CAS_S(16, uint16_t, \"cmpxchgw\")\nCK_PR_CAS_S(8,  uint8_t,  \"cmpxchgb\")\n\n#undef CK_PR_CAS_S\n#undef CK_PR_CAS\n\n/*\n * Compare and swap, set *v to old value of target.\n */\n#define CK_PR_CAS_O(S, M, T, C, I, R)\t\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\t\\\n\tck_pr_cas_##S##_value(M *target, T compare, T set, M *v)\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tbool z;\t\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX \"cmpxchg\" I \" %3, %0;\"\t\\\n\t\t\t\t     \"mov %% \" R \", %2;\"\t\t\t\\\n\t\t\t\t     \"setz %1;\"\t\t\t\t\t\\\n\t\t\t\t\t: \"+m\"  (*(C *)target),\t\t\t\\\n\t\t\t\t\t  \"=a\"  (z),\t\t\t\t\\\n\t\t\t\t\t  \"=m\"  (*(C *)v)\t\t\t\\\n\t\t\t\t\t: \"q\"   (set),\t\t\t\t\\\n\t\t\t\t\t  \"a\"   (compare)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\t\\\n\t\treturn z;\t\t\t\t\t\t\t\\\n\t}\n\nCK_PR_CAS_O(ptr, void, void *, char, \"q\", \"rax\")\n\n#define CK_PR_CAS_O_S(S, T, I, R)\t\\\n\tCK_PR_CAS_O(S, T, T, T, I, R)\n\nCK_PR_CAS_O_S(char, char, \"b\", \"al\")\nCK_PR_CAS_O_S(int, int, \"l\", \"eax\")\nCK_PR_CAS_O_S(uint, unsigned int, \"l\", \"eax\")\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_CAS_O_S(double, double, \"q\", \"rax\")\n#endif\nCK_PR_CAS_O_S(64, uint64_t, \"q\", \"rax\")\nCK_PR_CAS_O_S(32, uint32_t, \"l\", \"eax\")\nCK_PR_CAS_O_S(16, uint16_t, \"w\", \"ax\")\nCK_PR_CAS_O_S(8,  uint8_t,  \"b\", \"al\")\n\n#undef CK_PR_CAS_O_S\n#undef CK_PR_CAS_O\n\n/*\n * Contrary to C-interface, alignment requirements are that of uint64_t[2].\n */\nCK_CC_INLINE static bool\nck_pr_cas_64_2(uint64_t target[2], uint64_t compare[2], uint64_t set[2])\n{\n\tbool z;\n\n\t__asm__ __volatile__(\"movq 0(%4), %%rax;\"\n\t\t\t     \"movq 8(%4), %%rdx;\"\n\t\t\t     CK_PR_LOCK_PREFIX \"cmpxchg16b %0; setz %1\"\n\t\t\t\t: \"+m\" (*target),\n\t\t\t\t  \"=q\" (z)\n\t\t\t\t: \"b\"  (set[0]),\n\t\t\t\t  \"c\"  (set[1]),\n\t\t\t\t  \"q\"  (compare)\n\t\t\t\t: \"memory\", \"cc\", \"%rax\", \"%rdx\");\n\treturn z;\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2(void *t, void *c, void *s)\n{\n\treturn ck_pr_cas_64_2(CK_CPP_CAST(uint64_t *, t),\n\t\t\t      CK_CPP_CAST(uint64_t *, c),\n\t\t\t      CK_CPP_CAST(uint64_t *, s));\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_64_2_value(uint64_t target[2],\n\t\t     uint64_t compare[2],\n\t\t     uint64_t set[2],\n\t\t     uint64_t v[2])\n{\n\tbool z;\n\n\t__asm__ __volatile__(CK_PR_LOCK_PREFIX \"cmpxchg16b %0;\"\n\t\t\t     \"setz %3\"\n\t\t\t\t: \"+m\" (*target),\n\t\t\t\t  \"=a\" (v[0]),\n\t\t\t\t  \"=d\" (v[1]),\n\t\t\t\t  \"=q\" (z)\n\t\t\t\t: \"a\" (compare[0]),\n\t\t\t\t  \"d\" (compare[1]),\n\t\t\t\t  \"b\" (set[0]),\n\t\t\t\t  \"c\" (set[1])\n\t\t\t\t: \"memory\", \"cc\");\n\treturn z;\n}\n\nCK_CC_INLINE static bool\nck_pr_cas_ptr_2_value(void *t, void *c, void *s, void *v)\n{\n\treturn ck_pr_cas_64_2_value(CK_CPP_CAST(uint64_t *,t),\n\t\t\t\t    CK_CPP_CAST(uint64_t *,c),\n\t\t\t\t    CK_CPP_CAST(uint64_t *,s),\n\t\t\t\t    CK_CPP_CAST(uint64_t *,v));\n}\n\n#define CK_PR_CAS_V(S, W, T)\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\t\\\nck_pr_cas_##S##_##W(T t[W], T c[W], T s[W])\t\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\treturn ck_pr_cas_64_2((uint64_t *)(void *)t,\t\t\\\n\t\t\t      (uint64_t *)(void *)c,\t\t\\\n\t\t\t      (uint64_t *)(void *)s);\t\t\\\n}\t\t\t\t\t\t\t\t\\\nCK_CC_INLINE static bool\t\t\t\t\t\\\nck_pr_cas_##S##_##W##_value(T *t, T c[W], T s[W], T *v)\t\t\\\n{\t\t\t\t\t\t\t\t\\\n\treturn ck_pr_cas_64_2_value((uint64_t *)(void *)t,\t\\\n\t\t\t\t    (uint64_t *)(void *)c,\t\\\n\t\t\t\t    (uint64_t *)(void *)s,\t\\\n\t\t\t\t    (uint64_t *)(void *)v);\t\\\n}\n\n#ifndef CK_PR_DISABLE_DOUBLE\nCK_PR_CAS_V(double, 2, double)\n#endif\nCK_PR_CAS_V(char, 16, char)\nCK_PR_CAS_V(int, 4, int)\nCK_PR_CAS_V(uint, 4, unsigned int)\nCK_PR_CAS_V(32, 4, uint32_t)\nCK_PR_CAS_V(16, 8, uint16_t)\nCK_PR_CAS_V(8, 16, uint8_t)\n\n#undef CK_PR_CAS_V\n\n/*\n * Atomic bit test operations.\n */\n#define CK_PR_BT(K, S, T, P, C, I)\t\t\t\t\t\\\n\tCK_CC_INLINE static bool\t\t\t\t\t\\\n\tck_pr_##K##_##S(T *target, unsigned int b)\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tbool c;\t\t\t\t\t\t\t\\\n\t\t__asm__ __volatile__(CK_PR_LOCK_PREFIX I \"; setc %1\"\t\\\n\t\t\t\t\t: \"+m\" (*(C *)target),\t\t\\\n\t\t\t\t\t  \"=q\" (c)\t\t\t\\\n\t\t\t\t\t: \"q\"  ((P)b)\t\t\t\\\n\t\t\t\t\t: \"memory\", \"cc\");\t\t\\\n\t\treturn c;\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BT_S(K, S, T, I) CK_PR_BT(K, S, T, T, T, I)\n\n#define CK_PR_GENERATE(K)\t\t\t\t\t\\\n\tCK_PR_BT(K, ptr, void, uint64_t, char, #K \"q %2, %0\")\t\\\n\tCK_PR_BT_S(K, uint, unsigned int, #K \"l %2, %0\")\t\\\n\tCK_PR_BT_S(K, int, int, #K \"l %2, %0\")\t\t\t\\\n\tCK_PR_BT_S(K, 64, uint64_t, #K \"q %2, %0\")\t\t\\\n\tCK_PR_BT_S(K, 32, uint32_t, #K \"l %2, %0\")\t\t\\\n\tCK_PR_BT_S(K, 16, uint16_t, #K \"w %w2, %0\")\n\nCK_PR_GENERATE(btc)\nCK_PR_GENERATE(bts)\nCK_PR_GENERATE(btr)\n\n#undef CK_PR_GENERATE\n#undef CK_PR_BT\n\n#endif /* CK_PR_X86_64_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/gcc/x86_64/ck_pr_rtm.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * Copyright (c) 2012,2013 Intel Corporation\n * Author: Andi Kleen\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that: (1) source code distributions\n * retain the above copyright notice and this paragraph in its entirety, (2)\n * distributions including binary code include the above copyright notice and\n * this paragraph in its entirety in the documentation or other materials\n * provided with the distribution\n *\n * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED\n * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF\n * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n#ifndef CK_PR_X86_64_RTM_H\n#define CK_PR_X86_64_RTM_H\n\n#ifndef CK_PR_X86_64_H\n#error Do not include this file directly, use ck_pr.h\n#endif\n\n#define CK_F_PR_RTM\n\n#include <ck_cc.h>\n#include <ck_stdbool.h>\n\n#define CK_PR_RTM_STARTED\t(~0U)\n#define CK_PR_RTM_EXPLICIT\t(1 << 0)\n#define CK_PR_RTM_RETRY\t\t(1 << 1)\n#define CK_PR_RTM_CONFLICT\t(1 << 2)\n#define CK_PR_RTM_CAPACITY\t(1 << 3)\n#define CK_PR_RTM_DEBUG\t\t(1 << 4)\n#define CK_PR_RTM_NESTED\t(1 << 5)\n#define CK_PR_RTM_CODE(x)\t(((x) >> 24) & 0xFF)\n\nCK_CC_INLINE static unsigned int\nck_pr_rtm_begin(void)\n{\n\tunsigned int r = CK_PR_RTM_STARTED;\n\n\t__asm__ __volatile__(\".byte 0xc7,0xf8;\"\n\t\t\t     \".long 0;\"\n\t\t\t\t: \"+a\" (r)\n\t\t\t\t:\n\t\t\t\t: \"memory\");\n\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_pr_rtm_end(void)\n{\n\n\t__asm__ __volatile__(\".byte 0x0f,0x01,0xd5\" ::: \"memory\");\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_pr_rtm_abort(const unsigned int status)\n{\n\n\t__asm__ __volatile__(\".byte 0xc6,0xf8,%P0\" :: \"i\" (status) : \"memory\");\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_pr_rtm_test(void)\n{\n\tbool r;\n\n\t__asm__ __volatile__(\".byte 0x0f,0x01,0xd6;\"\n\t\t\t     \"setnz %0\"\n\t\t\t\t: \"=r\" (r)\n\t\t\t\t:\n\t\t\t\t: \"memory\");\n\n\treturn r;\n}\n\n#endif /* CK_PR_X86_64_RTM_H */\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/anderson.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_ANDERSON_H\n#define CK_SPINLOCK_ANDERSON_H\n\n#include <ck_cc.h>\n#include <ck_limits.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_F_SPINLOCK_ANDERSON\n#define CK_F_SPINLOCK_ANDERSON\n/*\n * This is an implementation of Anderson's array-based queuing lock.\n */\nstruct ck_spinlock_anderson_thread {\n\tunsigned int locked;\n\tunsigned int position;\n};\ntypedef struct ck_spinlock_anderson_thread ck_spinlock_anderson_thread_t;\n\nstruct ck_spinlock_anderson {\n\tstruct ck_spinlock_anderson_thread *slots;\n\tunsigned int count;\n\tunsigned int wrap;\n\tunsigned int mask;\n\tchar pad[CK_MD_CACHELINE - sizeof(unsigned int) * 3 - sizeof(void *)];\n\tunsigned int next;\n};\ntypedef struct ck_spinlock_anderson ck_spinlock_anderson_t;\n\nCK_CC_INLINE static void\nck_spinlock_anderson_init(struct ck_spinlock_anderson *lock,\n    struct ck_spinlock_anderson_thread *slots,\n    unsigned int count)\n{\n\tunsigned int i;\n\n\tslots[0].locked = false;\n\tslots[0].position = 0;\n\tfor (i = 1; i < count; i++) {\n\t\tslots[i].locked = true;\n\t\tslots[i].position = i;\n\t}\n\n\tlock->slots = slots;\n\tlock->count = count;\n\tlock->mask = count - 1;\n\tlock->next = 0;\n\n\t/*\n\t * If the number of threads is not a power of two then compute\n\t * appropriate wrap-around value in the case of next slot counter\n\t * overflow.\n\t */\n\tif (count & (count - 1))\n\t\tlock->wrap = (UINT_MAX % count) + 1;\n\telse\n\t\tlock->wrap = 0;\n\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_anderson_locked(struct ck_spinlock_anderson *lock)\n{\n\tunsigned int position;\n\tbool r;\n\n\tposition = ck_pr_load_uint(&lock->next) & lock->mask;\n\tr = ck_pr_load_uint(&lock->slots[position].locked);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_anderson_lock(struct ck_spinlock_anderson *lock,\n    struct ck_spinlock_anderson_thread **slot)\n{\n\tunsigned int position, next;\n\tunsigned int count = lock->count;\n\n\t/*\n\t * If count is not a power of 2, then it is possible for an overflow\n\t * to reallocate beginning slots to more than one thread. To avoid this\n\t * use a compare-and-swap.\n\t */\n\tif (lock->wrap != 0) {\n\t\tposition = ck_pr_load_uint(&lock->next);\n\n\t\tdo {\n\t\t\tif (position == UINT_MAX)\n\t\t\t\tnext = lock->wrap;\n\t\t\telse\n\t\t\t\tnext = position + 1;\n\t\t} while (ck_pr_cas_uint_value(&lock->next, position,\n\t\t\t\t\t      next, &position) == false);\n\n\t\tposition %= count;\n\t} else {\n\t\tposition = ck_pr_faa_uint(&lock->next, 1);\n\t\tposition &= lock->mask;\n\t}\n\n\t/* Serialize with respect to previous thread's store. */\n\tck_pr_fence_load();\n\n\t/*\n\t * Spin until slot is marked as unlocked. First slot is initialized to\n\t * false.\n\t */\n\twhile (ck_pr_load_uint(&lock->slots[position].locked) == true)\n\t\tck_pr_stall();\n\n\t/* Prepare slot for potential re-use by another thread. */\n\tck_pr_store_uint(&lock->slots[position].locked, true);\n\tck_pr_fence_lock();\n\n\t*slot = lock->slots + position;\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_anderson_unlock(struct ck_spinlock_anderson *lock,\n    struct ck_spinlock_anderson_thread *slot)\n{\n\tunsigned int position;\n\n\tck_pr_fence_unlock();\n\n\t/* Mark next slot as available. */\n\tif (lock->wrap == 0)\n\t\tposition = (slot->position + 1) & lock->mask;\n\telse\n\t\tposition = (slot->position + 1) % lock->count;\n\n\tck_pr_store_uint(&lock->slots[position].locked, false);\n\treturn;\n}\n#endif /* CK_F_SPINLOCK_ANDERSON */\n#endif /* CK_SPINLOCK_ANDERSON_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/cas.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_CAS_H\n#define CK_SPINLOCK_CAS_H\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_elide.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_F_SPINLOCK_CAS\n#define CK_F_SPINLOCK_CAS\n/*\n * This is a simple CACAS (TATAS) spinlock implementation.\n */\nstruct ck_spinlock_cas {\n\tunsigned int value;\n};\ntypedef struct ck_spinlock_cas ck_spinlock_cas_t;\n\n#define CK_SPINLOCK_CAS_INITIALIZER {false}\n\nCK_CC_INLINE static void\nck_spinlock_cas_init(struct ck_spinlock_cas *lock)\n{\n\n\tlock->value = false;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_cas_trylock(struct ck_spinlock_cas *lock)\n{\n\tunsigned int value;\n\n\tvalue = ck_pr_fas_uint(&lock->value, true);\n\tck_pr_fence_lock();\n\treturn !value;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_cas_locked(struct ck_spinlock_cas *lock)\n{\n\tbool r = ck_pr_load_uint(&lock->value);\n\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_cas_lock(struct ck_spinlock_cas *lock)\n{\n\n\twhile (ck_pr_cas_uint(&lock->value, false, true) == false) {\n\t\twhile (ck_pr_load_uint(&lock->value) == true)\n\t\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_cas_lock_eb(struct ck_spinlock_cas *lock)\n{\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\n\twhile (ck_pr_cas_uint(&lock->value, false, true) == false)\n\t\tck_backoff_eb(&backoff);\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_cas_unlock(struct ck_spinlock_cas *lock)\n{\n\n\t/* Set lock state to unlocked. */\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&lock->value, false);\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_spinlock_cas, ck_spinlock_cas_t,\n    ck_spinlock_cas_locked, ck_spinlock_cas_lock,\n    ck_spinlock_cas_locked, ck_spinlock_cas_unlock)\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_cas, ck_spinlock_cas_t,\n    ck_spinlock_cas_locked, ck_spinlock_cas_trylock)\n\n#endif /* CK_F_SPINLOCK_CAS */\n#endif /* CK_SPINLOCK_CAS_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/clh.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_CLH_H\n#define CK_SPINLOCK_CLH_H\n\n#include <ck_cc.h>\n#include <ck_limits.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\n#ifndef CK_F_SPINLOCK_CLH\n#define CK_F_SPINLOCK_CLH\n\nstruct ck_spinlock_clh {\n\tunsigned int wait;\n\tstruct ck_spinlock_clh *previous;\n};\ntypedef struct ck_spinlock_clh ck_spinlock_clh_t;\n\nCK_CC_INLINE static void\nck_spinlock_clh_init(struct ck_spinlock_clh **lock, struct ck_spinlock_clh *unowned)\n{\n\n\tunowned->previous = NULL;\n\tunowned->wait = false;\n\t*lock = unowned;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_clh_locked(struct ck_spinlock_clh **queue)\n{\n\tstruct ck_spinlock_clh *head;\n\tbool r;\n\n\thead = ck_pr_load_ptr(queue);\n\tr = ck_pr_load_uint(&head->wait);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_clh_lock(struct ck_spinlock_clh **queue, struct ck_spinlock_clh *thread)\n{\n\tstruct ck_spinlock_clh *previous;\n\n\t/* Indicate to the next thread on queue that they will have to block. */\n\tthread->wait = true;\n\tck_pr_fence_store_atomic();\n\n\t/*\n\t * Mark current request as last request. Save reference to previous\n\t * request.\n\t */\n\tprevious = ck_pr_fas_ptr(queue, thread);\n\tthread->previous = previous;\n\n\t/* Wait until previous thread is done with lock. */\n\tck_pr_fence_load();\n\twhile (ck_pr_load_uint(&previous->wait) == true)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_clh_unlock(struct ck_spinlock_clh **thread)\n{\n\tstruct ck_spinlock_clh *previous;\n\n\t/*\n\t * If there are waiters, they are spinning on the current node wait\n\t * flag. The flag is cleared so that the successor may complete an\n\t * acquisition. If the caller is pre-empted then the predecessor field\n\t * may be updated by a successor's lock operation. In order to avoid\n\t * this, save a copy of the predecessor before setting the flag.\n\t */\n\tprevious = thread[0]->previous;\n\n\t/*\n\t * We have to pay this cost anyways, use it as a compiler barrier too.\n\t */\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&(*thread)->wait, false);\n\n\t/*\n\t * Predecessor is guaranteed not to be spinning on previous request,\n\t * so update caller to use previous structure. This allows successor\n\t * all the time in the world to successfully read updated wait flag.\n\t */\n\t*thread = previous;\n\treturn;\n}\n#endif /* CK_F_SPINLOCK_CLH */\n#endif /* CK_SPINLOCK_CLH_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/dec.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_DEC_H\n#define CK_SPINLOCK_DEC_H\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_elide.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_F_SPINLOCK_DEC\n#define CK_F_SPINLOCK_DEC\n/*\n * This is similar to the CACAS lock but makes use of an atomic decrement\n * operation to check if the lock value was decremented to 0 from 1. The\n * idea is that a decrement operation is cheaper than a compare-and-swap.\n */\nstruct ck_spinlock_dec {\n\tunsigned int value;\n};\ntypedef struct ck_spinlock_dec ck_spinlock_dec_t;\n\n#define CK_SPINLOCK_DEC_INITIALIZER\t{1}\n\nCK_CC_INLINE static void\nck_spinlock_dec_init(struct ck_spinlock_dec *lock)\n{\n\n\tlock->value = 1;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_dec_trylock(struct ck_spinlock_dec *lock)\n{\n\tunsigned int value;\n\n\tvalue = ck_pr_fas_uint(&lock->value, 0);\n\tck_pr_fence_lock();\n\treturn value == 1;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_dec_locked(struct ck_spinlock_dec *lock)\n{\n\tbool r;\n\n\tr = ck_pr_load_uint(&lock->value) != 1;\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_dec_lock(struct ck_spinlock_dec *lock)\n{\n\tbool r;\n\n\tfor (;;) {\n\t\t/*\n\t\t * Only one thread is guaranteed to decrement lock to 0.\n\t\t * Overflow must be protected against. No more than\n\t\t * UINT_MAX lock requests can happen while the lock is held.\n\t\t */\n\t\tck_pr_dec_uint_zero(&lock->value, &r);\n\t\tif (r == true)\n\t\t\tbreak;\n\n\t\t/* Load value without generating write cycles. */\n\t\twhile (ck_pr_load_uint(&lock->value) != 1)\n\t\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_dec_lock_eb(struct ck_spinlock_dec *lock)\n{\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\tbool r;\n\n\tfor (;;) {\n\t\tck_pr_dec_uint_zero(&lock->value, &r);\n\t\tif (r == true)\n\t\t\tbreak;\n\n\t\twhile (ck_pr_load_uint(&lock->value) != 1)\n\t\t\tck_backoff_eb(&backoff);\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_dec_unlock(struct ck_spinlock_dec *lock)\n{\n\n\tck_pr_fence_unlock();\n\n\t/*\n\t * Unconditionally set lock value to 1 so someone can decrement lock\n\t * to 0.\n\t */\n\tck_pr_store_uint(&lock->value, 1);\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_spinlock_dec, ck_spinlock_dec_t,\n    ck_spinlock_dec_locked, ck_spinlock_dec_lock,\n    ck_spinlock_dec_locked, ck_spinlock_dec_unlock)\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_dec, ck_spinlock_dec_t,\n    ck_spinlock_dec_locked, ck_spinlock_dec_trylock)\n\n#endif /* CK_F_SPINLOCK_DEC */\n#endif /* CK_SPINLOCK_DEC_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/fas.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_FAS_H\n#define CK_SPINLOCK_FAS_H\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_elide.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_F_SPINLOCK_FAS\n#define CK_F_SPINLOCK_FAS\n\nstruct ck_spinlock_fas {\n\tunsigned int value;\n};\ntypedef struct ck_spinlock_fas ck_spinlock_fas_t;\n\n#define CK_SPINLOCK_FAS_INITIALIZER {false}\n\nCK_CC_INLINE static void\nck_spinlock_fas_init(struct ck_spinlock_fas *lock)\n{\n\n\tlock->value = false;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_fas_trylock(struct ck_spinlock_fas *lock)\n{\n\tbool value;\n\n\tvalue = ck_pr_fas_uint(&lock->value, true);\n\tck_pr_fence_lock();\n\n\treturn !value;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_fas_locked(struct ck_spinlock_fas *lock)\n{\n\tbool r;\n\n\tr = ck_pr_load_uint(&lock->value);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_fas_lock(struct ck_spinlock_fas *lock)\n{\n\n\twhile (ck_pr_fas_uint(&lock->value, true) == true) {\n\t\twhile (ck_pr_load_uint(&lock->value) == true)\n\t\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_fas_lock_eb(struct ck_spinlock_fas *lock)\n{\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\n\twhile (ck_pr_fas_uint(&lock->value, true) == true)\n\t\tck_backoff_eb(&backoff);\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_fas_unlock(struct ck_spinlock_fas *lock)\n{\n\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&lock->value, false);\n\treturn;\n}\n\nCK_ELIDE_PROTOTYPE(ck_spinlock_fas, ck_spinlock_fas_t,\n    ck_spinlock_fas_locked, ck_spinlock_fas_lock,\n    ck_spinlock_fas_locked, ck_spinlock_fas_unlock)\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_fas, ck_spinlock_fas_t,\n    ck_spinlock_fas_locked, ck_spinlock_fas_trylock)\n\n#endif /* CK_F_SPINLOCK_FAS */\n#endif /* CK_SPINLOCK_FAS_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/hclh.h",
    "content": "/*\n * Copyright 2013-2015 Olivier Houchard\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_HCLH_H\n#define CK_SPINLOCK_HCLH_H\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\n#ifndef CK_F_SPINLOCK_HCLH\n#define CK_F_SPINLOCK_HCLH\nstruct ck_spinlock_hclh {\n\tunsigned int wait;\n\tunsigned int splice;\n\tint cluster_id;\n\tstruct ck_spinlock_hclh *previous;\n};\ntypedef struct ck_spinlock_hclh ck_spinlock_hclh_t;\n\nCK_CC_INLINE static void\nck_spinlock_hclh_init(struct ck_spinlock_hclh **lock,\n    struct ck_spinlock_hclh *unowned,\n    int cluster_id)\n{\n\n\tunowned->previous = NULL;\n\tunowned->wait = false;\n\tunowned->splice = false;\n\tunowned->cluster_id = cluster_id;\n\t*lock = unowned;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_hclh_locked(struct ck_spinlock_hclh **queue)\n{\n\tstruct ck_spinlock_hclh *head;\n\tbool r;\n\n\thead = ck_pr_load_ptr(queue);\n\tr = ck_pr_load_uint(&head->wait);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_hclh_lock(struct ck_spinlock_hclh **glob_queue,\n    struct ck_spinlock_hclh **local_queue,\n    struct ck_spinlock_hclh *thread)\n{\n\tstruct ck_spinlock_hclh *previous, *local_tail;\n\n\t/* Indicate to the next thread on queue that they will have to block. */\n\tthread->wait = true;\n\tthread->splice = false;\n\tthread->cluster_id = (*local_queue)->cluster_id;\n\n\t/* Serialize with respect to update of local queue. */\n\tck_pr_fence_store_atomic();\n\n\t/* Mark current request as last request. Save reference to previous request. */\n\tprevious = ck_pr_fas_ptr(local_queue, thread);\n\tthread->previous = previous;\n\n\t/* Wait until previous thread from the local queue is done with lock. */\n\tck_pr_fence_load();\n\tif (previous->previous != NULL &&\n\t    previous->cluster_id == thread->cluster_id) {\n\t\twhile (ck_pr_load_uint(&previous->wait) == true)\n\t\t\tck_pr_stall();\n\n\t\t/* We're head of the global queue, we're done */\n\t\tif (ck_pr_load_uint(&previous->splice) == false)\n\t\t\treturn;\n\t}\n\n\t/* Now we need to splice the local queue into the global queue. */\n\tlocal_tail = ck_pr_load_ptr(local_queue);\n\tprevious = ck_pr_fas_ptr(glob_queue, local_tail);\n\n\tck_pr_store_uint(&local_tail->splice, true);\n\n\t/* Wait until previous thread from the global queue is done with lock. */\n\twhile (ck_pr_load_uint(&previous->wait) == true)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_hclh_unlock(struct ck_spinlock_hclh **thread)\n{\n\tstruct ck_spinlock_hclh *previous;\n\n\t/*\n\t * If there are waiters, they are spinning on the current node wait\n\t * flag. The flag is cleared so that the successor may complete an\n\t * acquisition. If the caller is pre-empted then the predecessor field\n\t * may be updated by a successor's lock operation. In order to avoid\n\t * this, save a copy of the predecessor before setting the flag.\n\t */\n\tprevious = thread[0]->previous;\n\n\t/* We have to pay this cost anyways, use it as a compiler barrier too. */\n\tck_pr_fence_unlock();\n\tck_pr_store_uint(&(*thread)->wait, false);\n\n\t/*\n\t * Predecessor is guaranteed not to be spinning on previous request,\n\t * so update caller to use previous structure. This allows successor\n\t * all the time in the world to successfully read updated wait flag.\n\t */\n\t*thread = previous;\n\treturn;\n}\n#endif /* CK_F_SPINLOCK_HCLH */\n#endif /* CK_SPINLOCK_HCLH_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/mcs.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_MCS_H\n#define CK_SPINLOCK_MCS_H\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n\n#ifndef CK_F_SPINLOCK_MCS\n#define CK_F_SPINLOCK_MCS\n\nstruct ck_spinlock_mcs {\n\tunsigned int locked;\n\tstruct ck_spinlock_mcs *next;\n};\ntypedef struct ck_spinlock_mcs * ck_spinlock_mcs_t;\ntypedef struct ck_spinlock_mcs ck_spinlock_mcs_context_t;\n\n#define CK_SPINLOCK_MCS_INITIALIZER\t    (NULL)\n\nCK_CC_INLINE static void\nck_spinlock_mcs_init(struct ck_spinlock_mcs **queue)\n{\n\n\t*queue = NULL;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_mcs_trylock(struct ck_spinlock_mcs **queue,\n    struct ck_spinlock_mcs *node)\n{\n\tbool r;\n\n\tnode->locked = true;\n\tnode->next = NULL;\n\tck_pr_fence_store_atomic();\n\n\tr = ck_pr_cas_ptr(queue, NULL, node);\n\tck_pr_fence_lock();\n\treturn r;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_mcs_locked(struct ck_spinlock_mcs **queue)\n{\n\tbool r;\n\n\tr = ck_pr_load_ptr(queue) != NULL;\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_mcs_lock(struct ck_spinlock_mcs **queue,\n    struct ck_spinlock_mcs *node)\n{\n\tstruct ck_spinlock_mcs *previous;\n\n\t/*\n\t * In the case that there is a successor, let them know they must\n\t * wait for us to unlock.\n\t */\n\tnode->locked = true;\n\tnode->next = NULL;\n\tck_pr_fence_store_atomic();\n\n\t/*\n\t * Swap current tail with current lock request. If the swap operation\n\t * returns NULL, it means the queue was empty. If the queue was empty,\n\t * then the operation is complete.\n\t */\n\tprevious = ck_pr_fas_ptr(queue, node);\n\tif (previous != NULL) {\n\t\t/*\n\t\t * Let the previous lock holder know that we are waiting on\n\t\t * them.\n\t\t */\n\t\tck_pr_store_ptr(&previous->next, node);\n\t\twhile (ck_pr_load_uint(&node->locked) == true)\n\t\t\tck_pr_stall();\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_mcs_unlock(struct ck_spinlock_mcs **queue,\n    struct ck_spinlock_mcs *node)\n{\n\tstruct ck_spinlock_mcs *next;\n\n\tck_pr_fence_unlock();\n\n\tnext = ck_pr_load_ptr(&node->next);\n\tif (next == NULL) {\n\t\t/*\n\t\t * If there is no request following us then it is a possibilty\n\t\t * that we are the current tail. In this case, we may just\n\t\t * mark the spinlock queue as empty.\n\t\t */\n\t\tif (ck_pr_load_ptr(queue) == node &&\n\t\t    ck_pr_cas_ptr(queue, node, NULL) == true) {\n\t\t\treturn;\n\t\t}\n\n\t\t/*\n\t\t * If the node is not the current tail then a lock operation\n\t\t * is in-progress. In this case, busy-wait until the queue is\n\t\t * in a consistent state to wake up the incoming lock\n\t\t * request.\n\t\t */\n\t\tfor (;;) {\n\t\t\tnext = ck_pr_load_ptr(&node->next);\n\t\t\tif (next != NULL)\n\t\t\t\tbreak;\n\n\t\t\tck_pr_stall();\n\t\t}\n\t}\n\n\t/* Allow the next lock operation to complete. */\n\tck_pr_store_uint(&next->locked, false);\n\treturn;\n}\n#endif /* CK_F_SPINLOCK_MCS */\n#endif /* CK_SPINLOCK_MCS_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/include/spinlock/ticket.h",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_SPINLOCK_TICKET_H\n#define CK_SPINLOCK_TICKET_H\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_elide.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\n#ifndef CK_F_SPINLOCK_TICKET\n#define CK_F_SPINLOCK_TICKET\n/*\n * If 16-bit or 32-bit increment is supported, implement support for\n * trylock functionality on availability of 32-bit or 64-bit fetch-and-add\n * and compare-and-swap. This code path is only applied to x86*.\n */\n#if defined(CK_MD_TSO) && (defined(__x86__) || defined(__x86_64__))\n#if defined(CK_F_PR_FAA_32) && defined(CK_F_PR_INC_16) && defined(CK_F_PR_CAS_32)\n#define CK_SPINLOCK_TICKET_TYPE\t\tuint32_t\n#define CK_SPINLOCK_TICKET_TYPE_BASE\tuint16_t\n#define CK_SPINLOCK_TICKET_INC(x)\tck_pr_inc_16(x)\n#define CK_SPINLOCK_TICKET_CAS(x, y, z) ck_pr_cas_32(x, y, z)\n#define CK_SPINLOCK_TICKET_FAA(x, y)\tck_pr_faa_32(x, y)\n#define CK_SPINLOCK_TICKET_LOAD(x)\tck_pr_load_32(x)\n#define CK_SPINLOCK_TICKET_INCREMENT\t(0x00010000UL)\n#define CK_SPINLOCK_TICKET_MASK\t\t(0xFFFFUL)\n#define CK_SPINLOCK_TICKET_SHIFT\t(16)\n#elif defined(CK_F_PR_FAA_64) && defined(CK_F_PR_INC_32) && defined(CK_F_PR_CAS_64)\n#define CK_SPINLOCK_TICKET_TYPE\t\tuint64_t\n#define CK_SPINLOCK_TICKET_TYPE_BASE\tuint32_t\n#define CK_SPINLOCK_TICKET_INC(x)\tck_pr_inc_32(x)\n#define CK_SPINLOCK_TICKET_CAS(x, y, z) ck_pr_cas_64(x, y, z)\n#define CK_SPINLOCK_TICKET_FAA(x, y)\tck_pr_faa_64(x, y)\n#define CK_SPINLOCK_TICKET_LOAD(x)\tck_pr_load_64(x)\n#define CK_SPINLOCK_TICKET_INCREMENT\t(0x0000000100000000ULL)\n#define CK_SPINLOCK_TICKET_MASK\t\t(0xFFFFFFFFULL)\n#define CK_SPINLOCK_TICKET_SHIFT\t(32)\n#endif\n#endif /* CK_MD_TSO */\n\n#if defined(CK_SPINLOCK_TICKET_TYPE)\n#define CK_F_SPINLOCK_TICKET_TRYLOCK\n\nstruct ck_spinlock_ticket {\n\tCK_SPINLOCK_TICKET_TYPE value;\n};\ntypedef struct ck_spinlock_ticket ck_spinlock_ticket_t;\n#define CK_SPINLOCK_TICKET_INITIALIZER { .value = 0 }\n\nCK_CC_INLINE static void\nck_spinlock_ticket_init(struct ck_spinlock_ticket *ticket)\n{\n\n\tticket->value = 0;\n\tck_pr_barrier();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_ticket_locked(struct ck_spinlock_ticket *ticket)\n{\n\tCK_SPINLOCK_TICKET_TYPE request, position;\n\n\trequest = CK_SPINLOCK_TICKET_LOAD(&ticket->value);\n\tposition = request & CK_SPINLOCK_TICKET_MASK;\n\trequest >>= CK_SPINLOCK_TICKET_SHIFT;\n\n\tck_pr_fence_acquire();\n\treturn request != position;\n}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_lock(struct ck_spinlock_ticket *ticket)\n{\n\tCK_SPINLOCK_TICKET_TYPE request, position;\n\n\t/* Get our ticket number and set next ticket number. */\n\trequest = CK_SPINLOCK_TICKET_FAA(&ticket->value,\n\t    CK_SPINLOCK_TICKET_INCREMENT);\n\n\tposition = request & CK_SPINLOCK_TICKET_MASK;\n\trequest >>= CK_SPINLOCK_TICKET_SHIFT;\n\n\twhile (request != position) {\n\t\tck_pr_stall();\n\t\tposition = CK_SPINLOCK_TICKET_LOAD(&ticket->value) &\n\t\t    CK_SPINLOCK_TICKET_MASK;\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket *ticket, unsigned int c)\n{\n\tCK_SPINLOCK_TICKET_TYPE request, position;\n\tck_backoff_t backoff;\n\n\t/* Get our ticket number and set next ticket number. */\n\trequest = CK_SPINLOCK_TICKET_FAA(&ticket->value,\n\t    CK_SPINLOCK_TICKET_INCREMENT);\n\n\tposition = request & CK_SPINLOCK_TICKET_MASK;\n\trequest >>= CK_SPINLOCK_TICKET_SHIFT;\n\n\twhile (request != position) {\n\t\tck_pr_stall();\n\t\tposition = CK_SPINLOCK_TICKET_LOAD(&ticket->value) &\n\t\t    CK_SPINLOCK_TICKET_MASK;\n\n\t\tbackoff = (request - position) & CK_SPINLOCK_TICKET_MASK;\n\t\tbackoff <<= c;\n\t\tck_backoff_eb(&backoff);\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_ticket_trylock(struct ck_spinlock_ticket *ticket)\n{\n\tCK_SPINLOCK_TICKET_TYPE snapshot, request, position;\n\n\tsnapshot = CK_SPINLOCK_TICKET_LOAD(&ticket->value);\n\tposition = snapshot & CK_SPINLOCK_TICKET_MASK;\n\trequest = snapshot >> CK_SPINLOCK_TICKET_SHIFT;\n\n\tif (position != request)\n\t\treturn false;\n\n\tif (CK_SPINLOCK_TICKET_CAS(&ticket->value,\n\t    snapshot, snapshot + CK_SPINLOCK_TICKET_INCREMENT) == false) {\n\t\treturn false;\n\t}\n\n\tck_pr_fence_lock();\n\treturn true;\n}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_unlock(struct ck_spinlock_ticket *ticket)\n{\n\n\tck_pr_fence_unlock();\n\tCK_SPINLOCK_TICKET_INC((CK_SPINLOCK_TICKET_TYPE_BASE *)(void *)&ticket->value);\n\treturn;\n}\n\n#undef CK_SPINLOCK_TICKET_TYPE\n#undef CK_SPINLOCK_TICKET_TYPE_BASE\n#undef CK_SPINLOCK_TICKET_INC\n#undef CK_SPINLOCK_TICKET_FAA\n#undef CK_SPINLOCK_TICKET_LOAD\n#undef CK_SPINLOCK_TICKET_INCREMENT\n#undef CK_SPINLOCK_TICKET_MASK\n#undef CK_SPINLOCK_TICKET_SHIFT\n#else\n/*\n * MESI benefits from cacheline padding between next and current. This avoids\n * invalidation of current from the cache due to incoming lock requests.\n */\nstruct ck_spinlock_ticket {\n\tunsigned int next;\n\tunsigned int position;\n};\ntypedef struct ck_spinlock_ticket ck_spinlock_ticket_t;\n\n#define CK_SPINLOCK_TICKET_INITIALIZER {.next = 0, .position = 0}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_init(struct ck_spinlock_ticket *ticket)\n{\n\n\tticket->next = 0;\n\tticket->position = 0;\n\tck_pr_barrier();\n\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_spinlock_ticket_locked(struct ck_spinlock_ticket *ticket)\n{\n\tbool r;\n\n\tr = ck_pr_load_uint(&ticket->position) !=\n\t    ck_pr_load_uint(&ticket->next);\n\tck_pr_fence_acquire();\n\treturn r;\n}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_lock(struct ck_spinlock_ticket *ticket)\n{\n\tunsigned int request;\n\n\t/* Get our ticket number and set next ticket number. */\n\trequest = ck_pr_faa_uint(&ticket->next, 1);\n\n\t/*\n\t * Busy-wait until our ticket number is current.\n\t * We can get away without a fence here assuming\n\t * our position counter does not overflow.\n\t */\n\twhile (ck_pr_load_uint(&ticket->position) != request)\n\t\tck_pr_stall();\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_lock_pb(struct ck_spinlock_ticket *ticket, unsigned int c)\n{\n\tck_backoff_t backoff;\n\tunsigned int request, position;\n\n\trequest = ck_pr_faa_uint(&ticket->next, 1);\n\n\tfor (;;) {\n\t\tposition = ck_pr_load_uint(&ticket->position);\n\t\tif (position == request)\n\t\t\tbreak;\n\n\t\tbackoff = request - position;\n\t\tbackoff <<= c;\n\n\t\t/*\n\t\t * Ideally, back-off from generating cache traffic for at least\n\t\t * the amount of time necessary for the number of pending lock\n\t\t * acquisition and relinquish operations (assuming an empty\n\t\t * critical section).\n\t\t */\n\t\tck_backoff_eb(&backoff);\n\t}\n\n\tck_pr_fence_lock();\n\treturn;\n}\n\nCK_CC_INLINE static void\nck_spinlock_ticket_unlock(struct ck_spinlock_ticket *ticket)\n{\n\tunsigned int update;\n\n\tck_pr_fence_unlock();\n\n\t/*\n\t * Update current ticket value so next lock request can proceed.\n\t * Overflow behavior is assumed to be roll-over, in which case,\n\t * it is only an issue if there are 2^32 pending lock requests.\n\t */\n\tupdate = ck_pr_load_uint(&ticket->position);\n\tck_pr_store_uint(&ticket->position, update + 1);\n\treturn;\n}\n#endif /* !CK_F_SPINLOCK_TICKET_TRYLOCK */\n\nCK_ELIDE_PROTOTYPE(ck_spinlock_ticket, ck_spinlock_ticket_t,\n    ck_spinlock_ticket_locked, ck_spinlock_ticket_lock,\n    ck_spinlock_ticket_locked, ck_spinlock_ticket_unlock)\n\nCK_ELIDE_TRYLOCK_PROTOTYPE(ck_spinlock_ticket, ck_spinlock_ticket_t,\n    ck_spinlock_ticket_locked, ck_spinlock_ticket_trylock)\n\n#endif /* CK_F_SPINLOCK_TICKET */\n#endif /* CK_SPINLOCK_TICKET_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/Makefile.unsupported",
    "content": ".PHONY: all clean check\n\nall:\n\t@echo Regressions are currently unsupported for out-of-source builds\n\nclean: all\n\ncheck: all\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_array/validate/serial.c",
    "content": "#include <ck_array.h>\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATION\n#define ITERATION 128\n#endif\n\nstatic void\nmy_free(void *p, size_t m, bool d)\n{\n\n\t(void)m;\n\t(void)d;\n\n\tfree(p);\n\treturn;\n}\n\nstatic void *\nmy_malloc(size_t b)\n{\n\n\treturn malloc(b);\n}\n\nstatic void *\nmy_realloc(void *r, size_t a, size_t b, bool d)\n{\n\n\t(void)a;\n\t(void)d;\n\n\treturn realloc(r, b);\n}\n\nint\nmain(void)\n{\n\tvoid *r;\n\tuintptr_t i;\n\tck_array_t array;\n\tck_array_iterator_t iterator;\n\tstruct ck_malloc m = {\n\t\t.malloc = my_malloc,\n\t\t.free = NULL,\n\t\t.realloc = my_realloc\n\t};\n\n\tif (ck_array_init(&array, CK_ARRAY_MODE_SPMC, &m, 4) == true)\n\t\tck_error(\"ck_array_init with NULL free succeeded\\n\");\n\n\tm.free = my_free;\n\tif (ck_array_init(&array, CK_ARRAY_MODE_SPMC, &m, 4) == false)\n\t\tck_error(\"ck_array_init\\n\");\n\n\tfor (i = 0; i < ITERATION; i++) {\n\t\tif (ck_array_put(&array, (void *)i) == false)\n\t\t\tck_error(\"ck_error_put\\n\");\n\n\t\tif (ck_array_remove(&array, (void *)i) == false)\n\t\t\tck_error(\"ck_error_remove after put\\n\");\n\t}\n\n\ti = 0; CK_ARRAY_FOREACH(&array, &iterator, &r) i++;\n\tif (i != 0)\n\t\tck_error(\"Non-empty array after put -> remove workload.\\n\");\n\n\tck_array_commit(&array);\n\n\ti = 0; CK_ARRAY_FOREACH(&array, &iterator, &r) i++;\n\tif (i != 0)\n\t\tck_error(\"Non-empty array after put -> remove -> commit workload.\\n\");\n\n\tfor (i = 0; i < ITERATION; i++) {\n\t\tif (ck_array_put(&array, (void *)i) == false)\n\t\t\tck_error(\"ck_error_put\\n\");\n\t}\n\n\ti = 0; CK_ARRAY_FOREACH(&array, &iterator, &r) i++;\n\tif (i != 0)\n\t\tck_error(\"Non-empty array after put workload.\\n\");\n\n\tfor (i = 0; i < ITERATION; i++) {\n\t\tif (ck_array_remove(&array, (void *)i) == false)\n\t\t\tck_error(\"ck_error_remove after put\\n\");\n\t}\n\n\ti = 0; CK_ARRAY_FOREACH(&array, &iterator, &r) i++;\n\tif (i != 0)\n\t\tck_error(\"Non-empty array after put -> remove workload.\\n\");\n\n\tck_array_commit(&array);\n\n\ti = 0; CK_ARRAY_FOREACH(&array, &iterator, &r) i++;\n\tif (i != 0)\n\t\tck_error(\"Non-empty array after put -> remove -> commit workload.\\n\");\n\n\tfor (i = 0; i < ITERATION; i++) {\n\t\tif (ck_array_put(&array, (void *)i) == false)\n\t\t\tck_error(\"ck_error_put\\n\");\n\t}\n\n\tck_array_commit(&array);\n\n\ti = 0;\n\tCK_ARRAY_FOREACH(&array, &iterator, &r) {\n\t\ti++;\n\t}\n\n\tif (i != ITERATION)\n\t\tck_error(\"Incorrect item count in iteration\\n\");\n\n\tck_array_remove(&array, (void *)(uintptr_t)0);\n\tck_array_remove(&array, (void *)(uintptr_t)1);\n\tck_array_commit(&array);\n\ti = 0; CK_ARRAY_FOREACH(&array, &iterator, &r) i++;\n\tif (i != ITERATION - 2 || ck_array_length(&array) != ITERATION - 2)\n\t\tck_error(\"Incorrect item count in iteration after remove\\n\");\n\n\tif (ck_array_put_unique(&array, (void *)UINTPTR_MAX) != 0)\n\t\tck_error(\"Unique value put failed.\\n\");\n\n\tif (ck_array_put_unique(&array, (void *)(uintptr_t)4) != 1)\n\t\tck_error(\"put of 4 not detected as non-unique.\\n\");\n\n\tif (ck_array_put_unique(&array, (void *)UINTPTR_MAX) != 1)\n\t\tck_error(\"put of UINTPTR_MAX not detected as non-unique.\\n\");\n\n\tck_array_commit(&array);\n\ti = 0;\n\tCK_ARRAY_FOREACH(&array, &iterator, &r) {\n\t\ti++;\n\t}\n\tif (i != ITERATION - 1 || ck_array_length(&array) != ITERATION - 1)\n\t\tck_error(\"Incorrect item count in iteration after unique put\\n\");\n\n\tif (ck_array_initialized(&array) == false)\n\t\tck_error(\"Error, expected array to be initialized.\\n\");\n\n\tfor (i = 0; i < ITERATION * 4; i++) {\n\t\tck_array_remove(&array, (void *)i);\n\t}\n\n\tfor (i = 0; i < ITERATION * 16; i++) {\n\t\tck_array_put(&array, (void *)i);\n\t}\n\n\tck_array_commit(&array);\n\n\tfor (i = 0; i < ITERATION * 128; i++) {\n\t\tck_array_put(&array, (void *)i);\n\t\tif (ck_array_put_unique(&array, (void *)i) != 1)\n\t\t\tck_error(\"put_unique for non-unique value should fail.\\n\");\n\t}\n\n\tfor (i = 0; i < ITERATION * 64; i++) {\n\t\tbool f = ck_array_remove(&array, (void *)i);\n\n\t\tif (f == false && i < ITERATION * 144)\n\t\t\tck_error(\"Remove failed for existing entry.\\n\");\n\n\t\tif (f == true && i > ITERATION * 144)\n\t\t\tck_error(\"Remove succeeded for non-existing entry.\\n\");\n\t}\n\n\tck_array_commit(&array);\n\tck_array_deinit(&array, false);\n\n\tif (ck_array_initialized(&array) == true)\n\t\tck_error(\"Error, expected array to be uninitialized.\\n\");\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_backoff/validate/validate.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n\n#include <ck_backoff.h>\n#include \"../../common.h\"\n\nint\nmain(void)\n{\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\tconst ck_backoff_t ceiling = CK_BACKOFF_CEILING + 1;\n\tunsigned int i = 0;\n\n\tfprintf(stderr, \"Ceiling is: %u (%#x)\\n\", CK_BACKOFF_CEILING, CK_BACKOFF_CEILING);\n\n\tfor (;;) {\n\t\tck_backoff_t previous = backoff;\n\t\tck_backoff_eb(&backoff);\n\n\t\tprintf(\"EB %u\\n\", backoff);\n\t\tif (previous == ceiling) {\n\t\t\tif (backoff != ceiling)\n\t\t\t\tck_error(\"[C] GB: expected %u, got %u\\n\", ceiling, backoff);\n\n\t\t\tif (i++ >= 1)\n\t\t\t\tbreak;\n\t\t} else if (previous != backoff >> 1) {\n\t\t\tck_error(\"[N] GB: expected %u (%u), got %u\\n\", previous << 1, previous, backoff);\n\t\t}\n\t}\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_barrier/benchmark/throughput.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <pthread.h>\n#include <unistd.h>\n#include <ck_stdint.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include <ck_pr.h>\n#include <ck_barrier.h>\n\n#include \"../../common.h\"\n\n#if defined(CK_F_PR_INC_64) && defined(CK_F_PR_LOAD_64)\nstatic int done = 0;\nstatic struct affinity a;\nstatic int nthr;\nstatic int tid;\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstruct counter {\n\tuint64_t value;\n} CK_CC_CACHELINE;\nstruct counter *counters;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tck_barrier_centralized_state_t state = CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\tint id;\n\n\tid = ck_pr_faa_int(&tid, 1);\n\taff_iterate(&a);\n\n\twhile (ck_pr_load_int(&done) == 0) {\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tck_pr_inc_64(&counters[id].value);\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tuint64_t count;\n\tint i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Correct usage: <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n        if (nthr <= 0) {\n                ck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n        }\n\n        threads = malloc(sizeof(pthread_t) * nthr);\n        if (threads == NULL) {\n                ck_error(\"ERROR: Could not allocate thread structures\\n\");\n        }\n\n\tcounters = calloc(sizeof(struct counter), nthr);\n\tif (counters == NULL) {\n\t\tck_error(\"ERROR: Could not allocate counters\\n\");\n\t}\n\n        a.delta = atoi(argv[2]);\n\n        fprintf(stderr, \"Creating threads (barrier)...\");\n        for (i = 0; i < nthr; ++i) {\n                if (pthread_create(&threads[i], NULL, thread, NULL)) {\n                        ck_error(\"ERROR: Could not create thread %d\\n\", i);\n                }\n        }\n        fprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\n\tcount = 0;\n\tck_pr_store_int(&done, 1);\n\tfor (i = 0; i < nthr; ++i)\n\t\tcount += ck_pr_load_64(&counters[i].value);\n\tprintf(\"%d %16\" PRIu64 \"\\n\", nthr, count);\n\n\treturn (0);\n}\n#else\nint\nmain(void)\n{\n\n\tfputs(\"Unsupported.\", stderr);\n\treturn 0;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_barrier/validate/barrier_centralized.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_barrier.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 5000000\n#endif\n\n#ifndef ENTRIES\n#define ENTRIES 512\n#endif\n\nstatic struct affinity a;\nstatic int nthr;\nstatic int counters[ENTRIES];\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstatic int barrier_wait;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tck_barrier_centralized_state_t state = CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\tint j, counter;\n\tint i = 0;\n\n\taff_iterate(&a);\n\n\tck_pr_inc_int(&barrier_wait);\n\twhile (ck_pr_load_int(&barrier_wait) != nthr)\n\t\tck_pr_stall();\n\n\tfor (j = 0; j < ITERATE; j++) {\n\t\ti = j++ & (ENTRIES - 1);\n\t\tck_pr_inc_int(&counters[i]);\n\t\tck_barrier_centralized(&barrier, &state, nthr);\n\t\tcounter = ck_pr_load_int(&counters[i]);\n\t\tif (counter != nthr * (j / ENTRIES + 1)) {\n\t\t\tck_error(\"FAILED [%d:%d]: %d != %d\\n\", i, j - 1, counter, nthr);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tint i;\n\n\tif (argc < 3) {\n\t\tck_error(\"Usage: correct <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tfprintf(stderr, \"Creating threads (barrier)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_barrier/validate/barrier_combining.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_barrier.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 5000000\n#endif\n\n#ifndef ENTRIES\n#define ENTRIES 512\n#endif\n\nstatic struct affinity a;\nstatic int nthr;\nstatic int ngroups;\nstatic int counters[ENTRIES];\nstatic ck_barrier_combining_t barrier;\nstatic int barrier_wait;\n\nstatic void *\nthread(void *group)\n{\n\tck_barrier_combining_state_t state = CK_BARRIER_COMBINING_STATE_INITIALIZER;\n\tint j, counter;\n\tint i = 0;\n\n\taff_iterate(&a);\n\n\tck_pr_inc_int(&barrier_wait);\n\twhile (ck_pr_load_int(&barrier_wait) != (nthr * ngroups))\n\t\tck_pr_stall();\n\n\tfor (j = 0; j < ITERATE; j++) {\n\t\ti = j++ & (ENTRIES - 1);\n\t\tck_pr_inc_int(&counters[i]);\n\t\tck_barrier_combining(&barrier, group, &state);\n\t\tcounter = ck_pr_load_int(&counters[i]);\n\t\tif (counter != nthr * ngroups * (j / ENTRIES + 1)) {\n\t\t\tck_error(\"FAILED [%d:%d]: %d != %d\\n\", i, j - 1, counter, nthr * ngroups);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tck_barrier_combining_group_t *groupings;\n\tck_barrier_combining_group_t *init_root;\n\tint i;\n\n\tinit_root = malloc(sizeof(ck_barrier_combining_group_t));\n\tif (init_root == NULL) {\n\t\tck_error(\"ERROR: Could not allocate initial barrier structure\\n\");\n\t}\n\tck_barrier_combining_init(&barrier, init_root);\n\n\tif (argc < 4) {\n\t\tck_error(\"Usage: correct <total groups> <threads per group> <affinity delta>\\n\");\n\t}\n\n\tngroups = atoi(argv[1]);\n\tif (ngroups <= 0) {\n\t\tck_error(\"ERROR: Number of groups must be greater than 0\\n\");\n\t}\n\n\tnthr = atoi(argv[2]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tgroupings = malloc(sizeof(ck_barrier_combining_group_t) * ngroups);\n\tif (groupings == NULL) {\n\t\tck_error(\"Could not allocate thread barrier grouping structures\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr * ngroups);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[3]);\n\n\tfor (i = 0; i < ngroups; i++)\n\t\tck_barrier_combining_group_init(&barrier, groupings + i, nthr);\n\n\tfprintf(stderr, \"Creating threads (barrier)...\");\n\tfor (i = 0; i < (nthr * ngroups); i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, groupings + (i % ngroups))) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < (nthr * ngroups); i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_barrier/validate/barrier_dissemination.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_barrier.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 5000000\n#endif\n\n#ifndef ENTRIES\n#define ENTRIES 512\n#endif\n\nstatic struct affinity a;\nstatic int nthr;\nstatic int counters[ENTRIES];\nstatic int barrier_wait;\n\nstatic void *\nthread(void *b)\n{\n\tck_barrier_dissemination_t *barrier = b;\n\tck_barrier_dissemination_state_t state;\n\tint j, k, counter;\n\tint i = 0;\n\n\taff_iterate(&a);\n\tck_barrier_dissemination_subscribe(barrier, &state);\n\n\tck_pr_inc_int(&barrier_wait);\n\twhile (ck_pr_load_int(&barrier_wait) != nthr)\n\t\tck_pr_stall();\n\n\tfor (j = 0, k = 0; j < ITERATE; j++, k++) {\n\t\ti = j++ & (ENTRIES - 1);\n\t\tck_pr_inc_int(&counters[i]);\n\t\tck_barrier_dissemination(barrier, &state);\n\t\tcounter = ck_pr_load_int(&counters[i]);\n\t\tif (counter != nthr * (j / ENTRIES + 1)) {\n\t\t\tck_error(\"FAILED [%d:%d]: %d != %d\\n\", i, j - 1, counter, nthr);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tck_barrier_dissemination_t *barrier;\n\tck_barrier_dissemination_flag_t **barrier_internal;\n\tpthread_t *threads;\n\tint i, size;\n\n\tif (argc < 3) {\n\t\tck_error(\"Usage: correct <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tbarrier = malloc(sizeof(ck_barrier_dissemination_t) * nthr);\n\tif (barrier == NULL) {\n\t\tck_error(\"ERROR: Could not allocate barrier structures\\n\");\n\t}\n\n\tbarrier_internal = malloc(sizeof(ck_barrier_dissemination_flag_t *) * nthr);\n\tif (barrier_internal == NULL) {\n\t\tck_error(\"ERROR: Could not allocate barrier structures\\n\");\n\t}\n\n\tsize = ck_barrier_dissemination_size(nthr);\n\tfor (i = 0; i < nthr; ++i) {\n\t\tbarrier_internal[i] = malloc(sizeof(ck_barrier_dissemination_flag_t) * size);\n\t\tif (barrier_internal[i] == NULL) {\n\t\t\tck_error(\"ERROR: Could not allocate barrier structures\\n\");\n\t\t}\n\t}\n\tck_barrier_dissemination_init(barrier, barrier_internal, nthr);\n\n\tfprintf(stderr, \"Creating threads (barrier)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, barrier)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_barrier/validate/barrier_mcs.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_barrier.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 5000000\n#endif\n\n#ifndef ENTRIES\n#define ENTRIES 512\n#endif\n\nstatic struct affinity a;\nstatic int nthr;\nstatic int counters[ENTRIES];\nstatic int barrier_wait;\n\nstatic void *\nthread(void *b)\n{\n\tck_barrier_mcs_t *barrier = b;\n\tck_barrier_mcs_state_t state;\n\tint j, counter;\n\tint i = 0;\n\n\taff_iterate(&a);\n\n\tck_barrier_mcs_subscribe(barrier, &state);\n\n\tck_pr_inc_int(&barrier_wait);\n\twhile (ck_pr_load_int(&barrier_wait) != nthr)\n\t\tck_pr_stall();\n\n\tfor (j = 0; j < ITERATE; j++) {\n\t\ti = j++ & (ENTRIES - 1);\n\t\tck_pr_inc_int(&counters[i]);\n\t\tck_barrier_mcs(barrier, &state);\n\t\tcounter = ck_pr_load_int(&counters[i]);\n\t\tif (counter != nthr * (j / ENTRIES + 1)) {\n\t\t\tck_error(\"FAILED [%d:%d]: %d != %d\\n\", i, j - 1, counter, nthr);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tck_barrier_mcs_t *barrier;\n\tint i;\n\n\tif (argc < 3) {\n\t\tck_error(\"Usage: correct <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\tbarrier = malloc(sizeof(ck_barrier_mcs_t) * nthr);\n\tif (barrier == NULL) {\n\t\tck_error(\"ERROR: Could not allocate barrier structures\\n\");\n\t}\n\tck_barrier_mcs_init(barrier, nthr);\n\n\ta.delta = atoi(argv[2]);\n\n\tfprintf(stderr, \"Creating threads (barrier)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, barrier)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_barrier/validate/barrier_tournament.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_barrier.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 5000000\n#endif\n\n#ifndef ENTRIES\n#define ENTRIES 512\n#endif\n\nstatic struct affinity a;\nstatic int nthr;\nstatic int counters[ENTRIES];\nstatic int barrier_wait;\nstatic ck_barrier_tournament_t barrier;\n\nstatic void *\nthread(CK_CC_UNUSED void *unused)\n{\n\tck_barrier_tournament_state_t state;\n\tint j, counter;\n\tint i = 0;\n\n\taff_iterate(&a);\n\tck_barrier_tournament_subscribe(&barrier, &state);\n\n\tck_pr_inc_int(&barrier_wait);\n\twhile (ck_pr_load_int(&barrier_wait) != nthr)\n\t\tck_pr_stall();\n\n\tfor (j = 0; j < ITERATE; j++) {\n\t\ti = j++ & (ENTRIES - 1);\n\t\tck_pr_inc_int(&counters[i]);\n\t\tck_barrier_tournament(&barrier, &state);\n\t\tcounter = ck_pr_load_int(&counters[i]);\n\t\tif (counter != nthr * (j / ENTRIES + 1)) {\n\t\t\tck_error(\"FAILED [%d:%d]: %d != %d\\n\", i, j - 1, counter, nthr);\n\t\t}\n\t}\n\n\tck_pr_inc_int(&barrier_wait);\n\twhile (ck_pr_load_int(&barrier_wait) != nthr * 2)\n\t\tck_pr_stall();\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tck_barrier_tournament_round_t **rounds;\n\tint i;\n\tunsigned int size;\n\n\tif (argc < 3) {\n\t\tck_error(\"Usage: correct <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\ta.delta = atoi(argv[2]);\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\trounds = malloc(sizeof(ck_barrier_tournament_round_t *) * nthr);\n\tif (rounds == NULL) {\n\t\tck_error(\"ERROR: Could not allocate barrier structures\\n\");\n\t}\n\n\tsize = ck_barrier_tournament_size(nthr);\n\tfor (i = 0; i < nthr; ++i) {\n\t\trounds[i] = malloc(sizeof(ck_barrier_tournament_round_t) * size);\n\t\tif (rounds[i] == NULL) {\n\t\t\tck_error(\"ERROR: Could not allocate barrier structures\\n\");\n\t\t}\n\t}\n\n\tck_barrier_tournament_init(&barrier, rounds, nthr);\n\n\tfprintf(stderr, \"Creating threads (barrier)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_bitmap/validate/serial.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * Copyright 2012-2014 AppNexus, Inc.\n * Copyright 2012 Shreyas Prasad.\n * Copyright 2014 Paul Khuong.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_bitmap.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"../../common.h\"\n\n#ifndef STATIC_LENGTH\n#define STATIC_LENGTH 256\n#endif\n\nstatic unsigned int length = 256;\nstatic ck_bitmap_t *g_bits;\n\nstatic void\ncheck_iteration(ck_bitmap_t *bits, unsigned int len, bool initial)\n{\n\tck_bitmap_iterator_t iter;\n\tunsigned int i = 0, j;\n\n\tlen += 1;\n\tif (initial == true) {\n\t\tif (bits == g_bits)\n\t\t\tlen = length;\n\t\telse\n\t\t\tlen = STATIC_LENGTH;\n\t}\n\n\tck_bitmap_iterator_init(&iter, bits);\n\tfor (j = 0; ck_bitmap_next(bits, &iter, &i) == true; j++) {\n\t\tif (i == j)\n\t\t\tcontinue;\n\n\t\tck_error(\"[4] ERROR: Expected bit %u, got bit %u\\n\", j, i);\n\t}\n\n\tif (j != len) {\n\t\tck_error(\"[5] ERROR: Expected length %u, got length %u\\n\", len, j);\n\t}\n\n\treturn;\n}\n\nstatic void\ntest(ck_bitmap_t *bits, unsigned int n_length, bool initial)\n{\n\tbool r;\n\tunsigned int i;\n\tCK_BITMAP_INSTANCE(8) u;\n\n\tCK_BITMAP_INIT(&u, 8, false);\n\tCK_BITMAP_SET(&u, 1);\n\tCK_BITMAP_SET(&u, 4);\n\n\tfor (i = 0; i < n_length; i++) {\n\t\tif (ck_bitmap_test(bits, i) == !initial) {\n\t\t\tck_error(\"[0] ERROR [%u]: Expected %u got %u\\n\", i,\n\t\t\t\tinitial, !initial);\n\t\t}\n\t}\n\n\tfor (i = 0; i < n_length; i++) {\n\t\tck_bitmap_set(bits, i);\n\t\tif (ck_bitmap_test(bits, i) == false) {\n\t\t\tck_error(\"[1] ERROR: Expected bit to be set: %u\\n\", i);\n\t\t}\n\n\t\tck_bitmap_reset(bits, i);\n\t\tif (ck_bitmap_test(bits, i) == true) {\n\t\t\tck_error(\"[2] ERROR: Expected bit to be cleared: %u\\n\", i);\n\t\t}\n\n\t\tr = ck_bitmap_bts(bits, i);\n\t\tif (r == true) {\n\t\t\tck_error(\"[3] ERROR: Expected bit to be cleared before 1st bts: %u\\n\", i);\n\t\t}\n\t\tif (ck_bitmap_test(bits, i) == false) {\n\t\t\tck_error(\"[4] ERROR: Expected bit to be set: %u\\n\", i);\n\t\t}\n\t\tr = ck_bitmap_bts(bits, i);\n\t\tif (r == false) {\n\t\t\tck_error(\"[5] ERROR: Expected bit to be set before 2nd bts: %u\\n\", i);\n\t\t}\n\t\tif (ck_bitmap_test(bits, i) == false) {\n\t\t\tck_error(\"[6] ERROR: Expected bit to be set: %u\\n\", i);\n\t\t}\n\n\t\tck_bitmap_reset(bits, i);\n\t\tif (ck_bitmap_test(bits, i) == true) {\n\t\t\tck_error(\"[7] ERROR: Expected bit to be cleared: %u\\n\", i);\n\t\t}\n\n\t\tck_bitmap_set(bits, i);\n\t\tif (ck_bitmap_test(bits, i) == false) {\n\t\t\tck_error(\"[8] ERROR: Expected bit to be set: %u\\n\", i);\n\t\t}\n\n\t\tcheck_iteration(bits, i, initial);\n\t}\n\n\tfor (i = 0; i < n_length; i++) {\n\t\tif (ck_bitmap_test(bits, i) == false) {\n\t\t\tck_error(\"[9] ERROR: Expected bit to be set: %u\\n\", i);\n\t\t}\n\t}\n\n\tck_bitmap_clear(bits);\n\n\tfor (i = 0; i < n_length; i++) {\n\t\tif (ck_bitmap_test(bits, i) == true) {\n\t\t\tck_error(\"[10] ERROR: Expected bit to be reset: %u\\n\", i);\n\t\t}\n\t}\n\n\tck_bitmap_union(bits, CK_BITMAP(&u));\n\tif (ck_bitmap_test(bits, 1) == false ||\n\t    ck_bitmap_test(bits, 4) == false) {\n\t\tck_error(\"ERROR: Expected union semantics.\\n\");\n\t}\n\n\treturn;\n}\n\nstatic void\ntest_init(bool init)\n{\n\tck_bitmap_t *bitmap;\n\tsize_t bytes;\n\tunsigned int i;\n\n\tbytes = ck_bitmap_size(length);\n\tbitmap = malloc(bytes);\n\tmemset(bitmap, random(), bytes);\n\n\tck_bitmap_init(bitmap, length, init);\n\n\tif (ck_bitmap_bits(bitmap) != length) {\n\t\tck_error(\"ERROR: Expected length %u got %u\\n\",\n\t\t    length, ck_bitmap_bits(bitmap));\n\t}\n\n\tfor (i = 0; i < length; i++) {\n\t\tif (ck_bitmap_test(bitmap, i) != init) {\n\t\t\tck_error(\"ERROR: Expected bit %i at index %u, got %i\\n\",\n\t\t\t    (int)init, i, (int)(!init));\n\t\t}\n\t}\n\n\tfree(bitmap);\n}\n\nstatic ck_bitmap_t *\nrandom_init(void)\n{\n\tck_bitmap_t *bitmap;\n\tunsigned int i;\n\n\tbitmap = malloc(ck_bitmap_size(length));\n\tck_bitmap_init(bitmap, length, false);\n\n\tfor (i = 0; i < length; i++) {\n\t\tif (random() & 1) {\n\t\t\tck_bitmap_set(bitmap, i);\n\t\t}\n\t}\n\n\treturn bitmap;\n}\n\nstatic ck_bitmap_t *\ncopy(const ck_bitmap_t *src)\n{\n\tck_bitmap_t *bitmap;\n\tsize_t bytes = ck_bitmap_size(ck_bitmap_bits(src));\n\n\tbitmap = malloc(bytes);\n\tmemcpy(bitmap, src, bytes);\n\treturn bitmap;\n}\n\nstatic void\ntest_counts(const ck_bitmap_t *x, const ck_bitmap_t *y)\n{\n\tunsigned int count = 0;\n\tunsigned int count_intersect = 0;\n\tunsigned int i;\n\n\tfor (i = 0; i <= length * 2; i++) {\n\t\tunsigned actual_limit = i;\n\t\tunsigned int r;\n\t\tbool check;\n\n\t\tif (actual_limit > ck_bitmap_bits(x))\n\t\t\tactual_limit = ck_bitmap_bits(x);\n\n\t\tcheck = ck_bitmap_empty(x, i);\n\t\tif (check != (count == 0)) {\n\t\t\tck_error(\"ck_bitmap_empty(%u): got %i expected %i\\n\",\n\t\t\t    i, (int)check, (int)(count == 0));\n\t\t}\n\n\t\tcheck = ck_bitmap_full(x, i);\n\t\tif (check != (count == actual_limit)) {\n\t\t\tck_error(\"ck_bitmap_full(%u): got %i expected %i\\n\",\n\t\t\t    i, (int)check, (int)(count == i));\n\t\t}\n\n\t\tr = ck_bitmap_count(x, i);\n\t\tif (r != count) {\n\t\t\tck_error(\"ck_bitmap_count(%u): got %u expected %u\\n\",\n\t\t\t    i, r, count);\n\t\t}\n\n\t\tr = ck_bitmap_count_intersect(x, y, i);\n\t\tif (r != count_intersect) {\n\t\t\tck_error(\"ck_bitmap_count_intersect(%u): got %u expected %u\\n\",\n\t\t\t    i, r, count_intersect);\n\t\t}\n\n\t\tif (i < length) {\n\t\t\tcount += ck_bitmap_test(x, i);\n\t\t\tcount_intersect += ck_bitmap_test(x, i) & ck_bitmap_test(y, i);\n\t\t}\n\t}\n}\n\nstatic void\nrandom_test(unsigned int seed)\n{\n\tck_bitmap_t *x, *x_copy, *y;\n\tunsigned int i;\n\n\tsrandom(seed);\n\n\ttest_init(false);\n\ttest_init(true);\n\n\tx = random_init();\n\ty = random_init();\n\n#define TEST(routine, expected) do {\t\t\t\t\t\\\n\t\tx_copy = copy(x);\t\t\t\t\t\\\n\t\troutine(x_copy, y);\t\t\t\t\t\\\n\t\tfor (i = 0; i < length; i++) {\t\t\t\t\\\n\t\t\tbool xi = ck_bitmap_test(x, i);\t\t\t\\\n\t\t\tbool yi = ck_bitmap_test(y, i);\t\t\t\\\n\t\t\tbool ri = ck_bitmap_test(x_copy, i);\t\t\\\n\t\t\tbool wanted = expected(xi, yi);\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (ri != wanted) {\t\t\t\t\\\n\t\t\t\tck_error(\"In \" #routine \" at %u: \"\t\\\n\t\t\t\t    \"got %i expected %i\\n\",\t\t\\\n\t\t\t\t    i, ri, wanted);\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\tfree(x_copy);\t\t\t\t\t\t\\\n\t} while (0)\n\n#define OR(x, y) (x | y)\n#define AND(x, y) (x & y)\n#define ANDC2(x, y) (x & (~y))\n\n\tTEST(ck_bitmap_union, OR);\n\tTEST(ck_bitmap_intersection, AND);\n\tTEST(ck_bitmap_intersection_negate, ANDC2);\n\n#undef ANDC2\n#undef AND\n#undef OR\n#undef TEST\n\n\ttest_counts(x, y);\n\n\tfor (i = 0; i < 4; i++) {\n\t\tck_bitmap_init(x, length, i & 1);\n\t\tck_bitmap_init(y, length, i >> 1);\n\t\ttest_counts(x, y);\n\t}\n\n\tfree(y);\n\tfree(x);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int bytes, base;\n\tsize_t i, j;\n\n\tif (argc >= 2) {\n\t\tlength = atoi(argv[1]);\n\t}\n\n\tbase = ck_bitmap_base(length);\n\tbytes = ck_bitmap_size(length);\n\tfprintf(stderr, \"Configuration: %u bytes\\n\",\n\t    bytes);\n\n\tg_bits = malloc(bytes);\n\tmemset(g_bits->map, 0xFF, base);\n\tck_bitmap_init(g_bits, length, false);\n\ttest(g_bits, length, false);\n\n\tmemset(g_bits->map, 0x00, base);\n\tck_bitmap_init(g_bits, length, true);\n\ttest(g_bits, length, true);\n\n\tck_bitmap_test(g_bits, length - 1);\n\n\tCK_BITMAP_INSTANCE(STATIC_LENGTH) sb;\n\tfprintf(stderr, \"Static configuration: %zu bytes\\n\",\n\t    sizeof(sb));\n\tmemset(CK_BITMAP_BUFFER(&sb), 0xFF, ck_bitmap_base(STATIC_LENGTH));\n\tCK_BITMAP_INIT(&sb, STATIC_LENGTH, false);\n\ttest(CK_BITMAP(&sb), STATIC_LENGTH, false);\n\tmemset(CK_BITMAP_BUFFER(&sb), 0x00, ck_bitmap_base(STATIC_LENGTH));\n\tCK_BITMAP_INIT(&sb, STATIC_LENGTH, true);\n\ttest(CK_BITMAP(&sb), STATIC_LENGTH, true);\n\n\tCK_BITMAP_CLEAR(&sb);\n\tif (CK_BITMAP_TEST(&sb, 1) == true) {\n\t\tck_error(\"ERROR: Expected bit to be reset.\\n\");\n\t}\n\n\tCK_BITMAP_SET(&sb, 1);\n\tif (CK_BITMAP_TEST(&sb, 1) == false) {\n\t\tck_error(\"ERROR: Expected bit to be set.\\n\");\n\t}\n\n\tCK_BITMAP_RESET(&sb, 1);\n\tif (CK_BITMAP_TEST(&sb, 1) == true) {\n\t\tck_error(\"ERROR: Expected bit to be reset.\\n\");\n\t}\n\n\tfor (i = 0; i < 4 * sizeof(unsigned int) * CHAR_BIT; i++) {\n\t\tlength = i;\n\t\tfor (j = 0; j < 10; j++) {\n\t\t\trandom_test(i * 10 + j);\n\t\t}\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_brlock/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_brlock.h>\n#include <ck_rwlock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_brlock_t brlock = CK_BRLOCK_INITIALIZER;\n\tck_brlock_reader_t r[8];\n\tck_rwlock_t naive;\n\n\tfor (i = 0; i < sizeof(r) / sizeof(*r); i++)\n\t\tck_brlock_read_register(&brlock, &r[i]);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_brlock_write_lock(&brlock);\n\t\tck_brlock_write_unlock(&brlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_brlock_write_lock(&brlock);\n\t\tck_brlock_write_unlock(&brlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"WRITE: brlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tck_rwlock_init(&naive);\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_write_lock(&naive);\n\t\tck_rwlock_write_unlock(&naive);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_write_lock(&naive);\n\t\tck_rwlock_write_unlock(&naive);\n\t}\n\te_b = rdtsc();\n\tprintf(\"WRITE: naive    %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_brlock_read_lock(&brlock, &r[0]);\n\t\tck_brlock_read_unlock(&r[0]);\n\t}\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_brlock_read_lock(&brlock, &r[0]);\n\t\tck_brlock_read_unlock(&r[0]);\n\t}\n\te_b = rdtsc();\n\tprintf(\"READ:  brlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_read_lock(&naive);\n\t\tck_rwlock_read_unlock(&naive);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_read_lock(&naive);\n\t\tck_rwlock_read_unlock(&naive);\n\t}\n\te_b = rdtsc();\n\tprintf(\"READ:  naive    %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_brlock/benchmark/throughput.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_brlock.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic int barrier;\nstatic int threads;\nstatic unsigned int flag CK_CC_CACHELINE;\nstatic ck_brlock_t brlock = CK_BRLOCK_INITIALIZER;\nstatic struct affinity affinity;\n\nstatic void *\nthread_brlock(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tck_brlock_reader_t r;\n\tuint64_t *value = pun;\n\n\tif (aff_iterate(&affinity) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_brlock_read_register(&brlock, &r);\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\tck_brlock_read_lock(&brlock, &r);\n\t\tck_brlock_read_unlock(&r);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint t;\n\tpthread_t *p;\n\tuint64_t *latency;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: throughput <delta> <threads>\\n\");\n\t}\n\n\tthreads = atoi(argv[2]);\n\tif (threads <= 0) {\n\t\tck_error(\"ERROR: Threads must be a value > 0.\\n\");\n\t}\n\n\tp = malloc(sizeof(pthread_t) * threads);\n\tif (p == NULL) {\n\t\tck_error(\"ERROR: Failed to initialize thread.\\n\");\n\t}\n\n\tlatency = malloc(sizeof(uint64_t) * threads);\n\tif (latency == NULL) {\n\t\tck_error(\"ERROR: Failed to create latency buffer.\\n\");\n\t}\n\n\taffinity.delta = atoi(argv[1]);\n\taffinity.request = 0;\n\n\tfprintf(stderr, \"Creating threads (brlock)...\");\n\tfor (t = 0; t < threads; t++) {\n\t\tif (pthread_create(&p[t], NULL, thread_brlock, latency + t) != 0) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", t);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&flag, 1);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (t = 0; t < threads; t++)\n\t\tpthread_join(p[t], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (t = 1; t <= threads; t++)\n\t\tprintf(\"%10u %20\" PRIu64 \"\\n\", t, latency[t - 1]);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_brlock/validate/validate.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_brlock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstatic struct affinity a;\nstatic unsigned int locked = 0;\nstatic int nthr;\nstatic ck_brlock_t lock = CK_BRLOCK_INITIALIZER;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tck_brlock_reader_t r;\n\tint i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tck_brlock_read_register(&lock, &r);\n\n\twhile (i--) {\n\t\tck_brlock_write_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_brlock_write_unlock(&lock);\n\n\t\tck_brlock_read_lock(&lock, &r);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_brlock_read_unlock(&r);\n\t}\n\n\tck_brlock_read_unregister(&lock, &r);\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tint i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: validate <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tfprintf(stderr, \"Creating threads (mutual exclusion)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_bytelock/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_bytelock.h>\n#include <ck_rwlock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_bytelock_t bytelock = CK_BYTELOCK_INITIALIZER;\n\tck_rwlock_t naive;\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_bytelock_write_lock(&bytelock, 1);\n\t\tck_bytelock_write_unlock(&bytelock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_bytelock_write_lock(&bytelock, 1);\n\t\tck_bytelock_write_unlock(&bytelock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"WRITE: bytelock %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tck_rwlock_init(&naive);\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_write_lock(&naive);\n\t\tck_rwlock_write_unlock(&naive);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_write_lock(&naive);\n\t\tck_rwlock_write_unlock(&naive);\n\t}\n\te_b = rdtsc();\n\tprintf(\"WRITE: naive    %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_bytelock_read_lock(&bytelock, 1);\n\t\tck_bytelock_read_unlock(&bytelock, 1);\n\t}\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_bytelock_read_lock(&bytelock, 1);\n\t\tck_bytelock_read_unlock(&bytelock, 1);\n\t}\n\te_b = rdtsc();\n\tprintf(\"READ:  bytelock %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_read_lock(&naive);\n\t\tck_rwlock_read_unlock(&naive);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_read_lock(&naive);\n\t\tck_rwlock_read_unlock(&naive);\n\t}\n\te_b = rdtsc();\n\tprintf(\"READ:  naive    %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_bytelock/validate/validate.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_bytelock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 5000000\n#endif\n\nstruct block {\n\tunsigned int tid;\n};\n\nstatic struct affinity a;\nstatic unsigned int locked = 0;\nstatic int nthr;\nstatic ck_bytelock_t lock CK_CC_CACHELINE = CK_BYTELOCK_INITIALIZER;\n\nstatic void *\nthread(void *null)\n{\n\tstruct block *context = null;\n\tint i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tif (context->tid == (unsigned int)nthr - 1)\n\t\tcontext->tid = sizeof(lock.readers) + 1;\n\n\twhile (i--) {\n\t\tck_bytelock_write_lock(&lock, context->tid);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_bytelock_write_unlock(&lock);\n\n\t\tck_bytelock_read_lock(&lock, context->tid);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_bytelock_read_unlock(&lock, context->tid);\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tstruct block *context;\n\tint i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: correct <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\tcontext = malloc(sizeof(struct block) * nthr);\n\tif (context == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread contexts\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tfprintf(stderr, \"Creating threads (mutual exclusion)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tcontext[i].tid = i + 1;\n\t\tif (pthread_create(&threads[i], NULL, thread, context + i)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_cohort/benchmark/ck_cohort.c",
    "content": "#include \"../ck_cohort.h\"\n\n#include <ck_cohort.h>\n#ifdef THROUGHPUT\n#include \"../../ck_spinlock/benchmark/throughput.h\"\n#elif defined(LATENCY)\n#include \"../../ck_spinlock/benchmark/latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_cohort/benchmark/throughput.c",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copyright 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_cohort.h>\n#include <ck_md.h>\n#include <ck_spinlock.h>\n\n#include \"../../common.h\"\n\n#define max(x, y) (((x) > (y)) ? (x) : (y))\n\nstatic struct affinity a;\nstatic unsigned int ready;\n\nstruct counters {\n\tuint64_t value;\n} CK_CC_CACHELINE;\n\nstatic struct counters *count;\nstatic uint64_t nthr;\nstatic unsigned int n_cohorts;\nstatic unsigned int barrier;\nstatic int critical CK_CC_CACHELINE;\n\nstatic void\nck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\n\t(void)context;\n\tck_spinlock_fas_lock(lock);\n\treturn;\n}\n\nstatic void\nck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\n\t(void)context;\n\tck_spinlock_fas_unlock(lock);\n\treturn;\n}\n\nstatic bool\nck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\n\t(void)context;\n\treturn ck_spinlock_fas_locked(lock);\n}\n\nCK_COHORT_PROTOTYPE(basic,\n    ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,\n    ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)\n\nstruct cohort_record {\n\tCK_COHORT_INSTANCE(basic) cohort;\n} CK_CC_CACHELINE;\nstatic struct cohort_record *cohorts;\n\nstatic ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;\n\nstruct block {\n\tunsigned int tid;\n};\n\nstatic void *\nfairness(void *null)\n{\n\tstruct block *context = null;\n\tunsigned int i = context->tid;\n\tvolatile int j;\n\tlong int base;\n\tunsigned int core;\n\tCK_COHORT_INSTANCE(basic) *cohort;\n\n\n\tif (aff_iterate_core(&a, &core)) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tcohort = &((cohorts + (core / (int)(a.delta)) % n_cohorts)->cohort);\n\n\twhile (ck_pr_load_uint(&ready) == 0);\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) != nthr);\n\n\twhile (ck_pr_load_uint(&ready)) {\n\t\tCK_COHORT_LOCK(basic, cohort, NULL, NULL);\n\n\t\tcount[i].value++;\n\t\tif (critical) {\n\t\t\tbase = common_lrand48() % critical;\n\t\t\tfor (j = 0; j < base; j++);\n\t\t}\n\n\t\tCK_COHORT_UNLOCK(basic, cohort, NULL, NULL);\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tuint64_t v, d;\n\tunsigned int i;\n\tpthread_t *threads;\n\tstruct block *context;\n\tck_spinlock_t *local_lock;\n\n\tif (argc != 5) {\n\t\tck_error(\"Usage: ck_cohort <number of cohorts> <threads per cohort> \"\n\t\t\t\"<affinity delta> <critical section>\\n\");\n\t}\n\n\tn_cohorts = atoi(argv[1]);\n\tif (n_cohorts <= 0) {\n\t\tck_error(\"ERROR: Number of cohorts must be greater than 0\\n\");\n\t}\n\n\tnthr = n_cohorts * atoi(argv[2]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tcritical = atoi(argv[4]);\n\tif (critical < 0) {\n\t\tck_error(\"ERROR: critical section cannot be negative\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\tcohorts = malloc(sizeof(struct cohort_record) * n_cohorts);\n\tif (cohorts == NULL) {\n\t\tck_error(\"ERROR: Could not allocate cohort structures\\n\");\n\t}\n\n\tcontext = malloc(sizeof(struct block) * nthr);\n\tif (context == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread contexts\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\ta.request = 0;\n\n\tcount = malloc(sizeof(*count) * nthr);\n\tif (count == NULL) {\n\t\tck_error(\"ERROR: Could not create acquisition buffer\\n\");\n\t}\n\tmemset(count, 0, sizeof(*count) * nthr);\n\n\tfprintf(stderr, \"Creating cohorts...\");\n\tfor (i = 0 ; i < n_cohorts ; i++) {\n\t\tlocal_lock = malloc(max(CK_MD_CACHELINE, sizeof(ck_spinlock_t)));\n\t\tif (local_lock == NULL) {\n\t\t\tck_error(\"ERROR: Could not allocate local lock\\n\");\n\t\t}\n\t\tCK_COHORT_INIT(basic, &((cohorts + i)->cohort), &global_lock, local_lock,\n\t\t    CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\t\tlocal_lock = NULL;\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Creating threads (fairness)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tcontext[i].tid = i;\n\t\tif (pthread_create(&threads[i], NULL, fairness, context + i)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tck_pr_store_uint(&ready, 1);\n\tcommon_sleep(10);\n\tck_pr_store_uint(&ready, 0);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (i = 0, v = 0; i < nthr; i++) {\n\t\tprintf(\"%d %15\" PRIu64 \"\\n\", i, count[i].value);\n\t\tv += count[i].value;\n\t}\n\n\tprintf(\"\\n# total       : %15\" PRIu64 \"\\n\", v);\n\tprintf(\"# throughput  : %15\" PRIu64 \" a/s\\n\", (v /= nthr) / 10);\n\n\tfor (i = 0, d = 0; i < nthr; i++)\n\t\td += (count[i].value - v) * (count[i].value - v);\n\n\tprintf(\"# average     : %15\" PRIu64 \"\\n\", v);\n\tprintf(\"# deviation   : %.2f (%.2f%%)\\n\\n\", sqrt(d / nthr), (sqrt(d / nthr) / v) * 100.00);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_cohort/ck_cohort.h",
    "content": "#define LOCK_NAME \"ck_cohort\"\n#define LOCK_DEFINE\t\t\t\t\t\t\t\t\t\\\n\tstatic ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\t\t\\\n\tstatic ck_spinlock_fas_t local_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\\\n\tck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t(void)context;\t\t\t\t\t\t\t\t\\\n\t\tck_spinlock_fas_lock(lock);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\\\n\tck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t(void)context;\t\t\t\t\t\t\t\t\\\n\t\tck_spinlock_fas_unlock(lock);\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic bool\t\t\t\t\t\t\t\t\t\\\n\tck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\t(void)context;\t\t\t\t\t\t\t\t\\\n\t\treturn ck_spinlock_fas_locked(lock);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tCK_COHORT_PROTOTYPE(fas_fas,\t\t\t\t\t\t\t\\\n\t    ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,\t\\\n\t    ck_spinlock_fas_locked_with_context, ck_spinlock_fas_lock_with_context,\t\\\n\t    ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)\t\\\n\tstatic CK_COHORT_INSTANCE(fas_fas) CK_CC_CACHELINE cohort = CK_COHORT_INITIALIZER\n\n\n#define LOCK_INIT CK_COHORT_INIT(fas_fas, &cohort, &global_fas_lock, &local_fas_lock,   \\\n\tCK_COHORT_DEFAULT_LOCAL_PASS_LIMIT)\n#define LOCK CK_COHORT_LOCK(fas_fas, &cohort, NULL, NULL)\n#define UNLOCK CK_COHORT_UNLOCK(fas_fas, &cohort, NULL, NULL)\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_cohort/validate/validate.c",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copyright 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include <ck_pr.h>\n#include <ck_cohort.h>\n#include <ck_spinlock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstatic struct affinity a;\nstatic unsigned int locked;\nstatic int nthr;\nstatic ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\n\nstatic void\nck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_fas_lock(lock);\n}\n\nstatic void\nck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_fas_unlock(lock);\n}\n\nstatic bool\nck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\treturn ck_spinlock_fas_locked(lock);\n}\n\nstatic bool\nck_spinlock_fas_trylock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\treturn ck_spinlock_fas_trylock(lock);\n}\n\nCK_COHORT_TRYLOCK_PROTOTYPE(fas_fas,\n\tck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,\n\tck_spinlock_fas_locked_with_context, ck_spinlock_fas_trylock_with_context,\n\tck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context,\n\tck_spinlock_fas_locked_with_context, ck_spinlock_fas_trylock_with_context)\nstatic CK_COHORT_INSTANCE(fas_fas) *cohorts;\nstatic int n_cohorts;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tint i = ITERATE;\n\tunsigned int l;\n\tunsigned int core;\n\tCK_COHORT_INSTANCE(fas_fas) *cohort;\n\n\tif (aff_iterate_core(&a, &core)) {\n\t\t\tperror(\"ERROR: Could not affine thread\");\n\t\t\texit(EXIT_FAILURE);\n\t}\n\n\tcohort = cohorts + (core / (int)(a.delta)) % n_cohorts;\n\n\twhile (i--) {\n\n\t\tif (i & 1) {\n\t\t\tCK_COHORT_LOCK(fas_fas, cohort, NULL, NULL);\n\t\t} else {\n\t\t\twhile (CK_COHORT_TRYLOCK(fas_fas, cohort, NULL, NULL, NULL) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\t\t}\n\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_COHORT_UNLOCK(fas_fas, cohort, NULL, NULL);\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tint threads_per_cohort;\n\tck_spinlock_fas_t *local_lock;\n\tint i;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <number of cohorts> <threads per cohort> <affinity delta>\\n\");\n\t}\n\n\tn_cohorts = atoi(argv[1]);\n\tif (n_cohorts <= 0) {\n\t\tfprintf(stderr, \"setting number of cohorts per thread to 1\\n\");\n\t\tn_cohorts = 1;\n\t}\n\n\tthreads_per_cohort = atoi(argv[2]);\n\tif (threads_per_cohort <= 0) {\n\t\tck_error(\"ERROR: Threads per cohort must be greater than 0\\n\");\n\t}\n\n\tnthr = n_cohorts * threads_per_cohort;\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[3]);\n\n\tfprintf(stderr, \"Creating cohorts...\");\n\tcohorts = malloc(sizeof(CK_COHORT_INSTANCE(fas_fas)) * n_cohorts);\n\tfor (i = 0 ; i < n_cohorts ; i++) {\n\t\tlocal_lock = malloc(sizeof(ck_spinlock_fas_t));\n\t\tCK_COHORT_INIT(fas_fas, cohorts + i, &global_fas_lock, local_lock,\n\t\t    CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Creating threads...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/ck_epoch_call.c",
    "content": "/*\n * Copyright 2014 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <stdio.h>\n#include <ck_epoch.h>\n\n#include \"../../common.h\"\n\nstatic ck_epoch_t epoch;\nstatic unsigned int counter;\nstatic ck_epoch_record_t record[2];\n\nstatic void\ncb(ck_epoch_entry_t *p)\n{\n\n\t/* Test that we can reregister the callback. */\n\tif (counter == 0)\n\t\tck_epoch_call(&record[1], p, cb);\n\n\tprintf(\"Counter value: %u -> %u\\n\",\n\t    counter, counter + 1);\n\tcounter++;\n\treturn;\n}\n\nint\nmain(void)\n{\n\tck_epoch_entry_t entry;\n\tck_epoch_entry_t another;\n\n\tck_epoch_register(&epoch, &record[0], NULL);\n\tck_epoch_register(&epoch, &record[1], NULL);\n\n\tck_epoch_call(&record[1], &entry, cb);\n\tck_epoch_barrier(&record[1]);\n\tck_epoch_barrier(&record[1]);\n\n\t/* Make sure that strict works. */\n\tck_epoch_call_strict(&record[1], &entry, cb);\n\tck_epoch_call_strict(&record[1], &another, cb);\n\tck_epoch_barrier(&record[1]);\n\n\tif (counter != 4)\n\t\tck_error(\"Expected counter value 4, read %u.\\n\", counter);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/ck_epoch_poll.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <string.h>\n#include <ck_epoch.h>\n#include <ck_stack.h>\n\n#include \"../../common.h\"\n\nstatic unsigned int n_rd;\nstatic unsigned int n_wr;\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int e_barrier;\nstatic unsigned int readers;\nstatic unsigned int writers;\n\n#ifndef PAIRS_S\n#define PAIRS_S 100000\n#endif\n\n#ifndef ITERATE_S\n#define ITERATE_S 20\n#endif\n\nstruct node {\n\tunsigned int value;\n\tck_stack_entry_t stack_entry;\n\tck_epoch_entry_t epoch_entry;\n};\nstatic ck_stack_t stack = CK_STACK_INITIALIZER;\nstatic ck_epoch_t stack_epoch;\nCK_STACK_CONTAINER(struct node, stack_entry, stack_container)\nCK_EPOCH_CONTAINER(struct node, epoch_entry, epoch_container)\nstatic struct affinity a;\nstatic const char animate[] = \"-/|\\\\\";\n\nstatic void\ndestructor(ck_epoch_entry_t *p)\n{\n\tstruct node *e = epoch_container(p);\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nread_thread(void *unused CK_CC_UNUSED)\n{\n\tunsigned int j;\n\tck_epoch_record_t record CK_CC_CACHELINE;\n\tck_stack_entry_t *cursor, *n;\n\n\tck_epoch_register(&stack_epoch, &record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\twhile (CK_STACK_ISEMPTY(&stack) == true) {\n\t\tif (ck_pr_load_uint(&readers) != 0)\n\t\t\tbreak;\n\n\t\tck_pr_stall();\n\t}\n\n\tj = 0;\n\tfor (;;) {\n\t\tck_epoch_begin(&record, NULL);\n\t\tCK_STACK_FOREACH(&stack, cursor) {\n\t\t\tif (cursor == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tn = CK_STACK_NEXT(cursor);\n\t\t\tj += ck_pr_load_ptr(&n) != NULL;\n\t\t}\n\t\tck_epoch_end(&record, NULL);\n\n\t\tif (j != 0 && ck_pr_load_uint(&readers) == 0)\n\t\t\tck_pr_store_uint(&readers, 1);\n\n\t\tif (CK_STACK_ISEMPTY(&stack) == true &&\n\t\t    ck_pr_load_uint(&e_barrier) != 0)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads);\n\n\tfprintf(stderr, \"[R] Observed entries: %u\\n\", j);\n\treturn (NULL);\n}\n\nstatic void *\nwrite_thread(void *unused CK_CC_UNUSED)\n{\n\tstruct node **entry, *e;\n\tunsigned int i, j, tid;\n\tck_epoch_record_t record;\n\tck_stack_entry_t *s;\n\n\tck_epoch_register(&stack_epoch, &record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\ttid = ck_pr_faa_uint(&writers, 1);\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\tentry = malloc(sizeof(struct node *) * PAIRS_S);\n\tif (entry == NULL) {\n\t\tck_error(\"Failed allocation.\\n\");\n\t}\n\n\tfor (j = 0; j < ITERATE_S; j++) {\n\t\tfor (i = 0; i < PAIRS_S; i++) {\n\t\t\tentry[i] = malloc(sizeof(struct node));\n\t\t\tif (entry == NULL) {\n\t\t\t\tck_error(\"Failed individual allocation\\n\");\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < PAIRS_S; i++) {\n\t\t\tck_stack_push_upmc(&stack, &entry[i]->stack_entry);\n\t\t}\n\n\t\twhile (ck_pr_load_uint(&readers) == 0)\n\t\t\tck_pr_stall();\n\n\t\tif (tid == 0) {\n\t\t\tfprintf(stderr, \"\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b[W] %2.2f: %c\",\n\t\t\t    (double)j / ITERATE_S, animate[i % strlen(animate)]);\n\t\t}\n\n\t\tfor (i = 0; i < PAIRS_S; i++) {\n\t\t\tck_epoch_begin(&record, NULL);\n\t\t\ts = ck_stack_pop_upmc(&stack);\n\t\t\te = stack_container(s);\n\t\t\tck_epoch_end(&record, NULL);\n\n\t\t\tck_epoch_call(&record, &e->epoch_entry, destructor);\n\t\t\tck_epoch_poll(&record);\n\t\t}\n\t}\n\n\tck_epoch_barrier(&record);\n\n\tif (tid == 0) {\n\t\tfprintf(stderr, \"\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b\\b[W] Peak: %u (%2.2f%%)\\n    Reclamations: %u\\n\\n\",\n\t\t\trecord.n_peak,\n\t\t\t(double)record.n_peak / ((double)PAIRS_S * ITERATE_S) * 100,\n\t\t\trecord.n_dispatch);\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads);\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <#readers> <#writers> <affinity delta>\\n\");\n\t}\n\n\tn_rd = atoi(argv[1]);\n\tn_wr = atoi(argv[2]);\n\tn_threads = n_wr + n_rd;\n\n\ta.delta = atoi(argv[3]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\tck_epoch_init(&stack_epoch);\n\n\tfor (i = 0; i < n_rd; i++)\n\t\tpthread_create(threads + i, NULL, read_thread, NULL);\n\n\tdo {\n\t\tpthread_create(threads + i, NULL, write_thread, NULL);\n\t} while (++i < n_wr + n_rd);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/ck_epoch_section.c",
    "content": "/*\n * Copyright 2015 John Esmet.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <pthread.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <string.h>\n#include <stdio.h>\n#include <time.h>\n#include <unistd.h>\n\n#include <ck_epoch.h>\n\n#include \"../../common.h\"\n\nstatic ck_epoch_t epc;\nstatic ck_epoch_record_t record, record2;\nstatic unsigned int cleanup_calls;\n\nstatic void\nsetup_test(void)\n{\n\n\tck_epoch_init(&epc);\n\tck_epoch_register(&epc, &record, NULL);\n\tck_epoch_register(&epc, &record2, NULL);\n\tcleanup_calls = 0;\n\n\treturn;\n}\n\nstatic void\nteardown_test(void)\n{\n\n\tmemset(&epc, 0, sizeof(ck_epoch_t));\n\tck_epoch_unregister(&record);\n\tmemset(&record, 0, sizeof(ck_epoch_record_t));\n\tmemset(&record2, 0, sizeof(ck_epoch_record_t));\n\tcleanup_calls = 0;\n\n\treturn;\n}\n\nstatic void\ncleanup(ck_epoch_entry_t *e)\n{\n\t(void) e;\n\n\tcleanup_calls++;\n\n\treturn;\n}\n\nstatic void\ntest_simple_read_section(void)\n{\n\tck_epoch_entry_t entry;\n\tck_epoch_section_t section;\n\n\tmemset(&entry, 0, sizeof(ck_epoch_entry_t));\n\tsetup_test();\n\n\tck_epoch_begin(&record, &section);\n\tck_epoch_call(&record, &entry, cleanup);\n\tassert(cleanup_calls == 0);\n\tif (ck_epoch_end(&record, &section) == false)\n\t\tck_error(\"expected no more sections\");\n\tck_epoch_barrier(&record);\n\tassert(cleanup_calls == 1);\n\n\tteardown_test();\n\treturn;\n}\n\nstatic void\ntest_nested_read_section(void)\n{\n\tck_epoch_entry_t entry1, entry2;\n\tck_epoch_section_t section1, section2;\n\n\tmemset(&entry1, 0, sizeof(ck_epoch_entry_t));\n\tmemset(&entry2, 0, sizeof(ck_epoch_entry_t));\n\tsetup_test();\n\n\tck_epoch_begin(&record, &section1);\n\tck_epoch_call(&record, &entry1, cleanup);\n\tassert(cleanup_calls == 0);\n\n\tck_epoch_begin(&record, &section2);\n\tck_epoch_call(&record, &entry2, cleanup);\n\tassert(cleanup_calls == 0);\n\n\tck_epoch_end(&record, &section2);\n\tassert(cleanup_calls == 0);\n\n\tck_epoch_end(&record, &section1);\n\tassert(cleanup_calls == 0);\n\n\tck_epoch_barrier(&record);\n\tassert(cleanup_calls == 2);\n\n\tteardown_test();\n\treturn;\n}\n\nstruct obj {\n\tck_epoch_entry_t entry;\n\tunsigned int destroyed;\n};\n\nstatic void *\nbarrier_work(void *arg)\n{\n\tunsigned int *run;\n\n\trun = (unsigned int *)arg;\n\twhile (ck_pr_load_uint(run) != 0) {\n\t\t/*\n\t\t * Need to use record2, as record is local\n\t\t * to the test thread.\n\t\t */\n\t\tck_epoch_barrier(&record2);\n\t\tusleep(5 * 1000);\n\t}\n\n\treturn NULL;\n}\n\nstatic void *\nreader_work(void *arg)\n{\n\tck_epoch_record_t local_record;\n\tck_epoch_section_t section;\n\tstruct obj *o;\n\n\tck_epoch_register(&epc, &local_record, NULL);\n\n\to = (struct obj *)arg;\n\n\t/*\n\t * Begin a read section. The calling thread has an open read section,\n\t * so the object should not be destroyed for the lifetime of this\n\t * thread.\n\t */\n\tck_epoch_begin(&local_record, &section);\n\tusleep((common_rand() % 100) * 1000);\n\tassert(ck_pr_load_uint(&o->destroyed) == 0);\n\tck_epoch_end(&local_record, &section);\n\n\tck_epoch_unregister(&local_record);\n\n\treturn NULL;\n}\n\nstatic void\nobj_destroy(ck_epoch_entry_t *e)\n{\n\tstruct obj *o;\n\n\to = (struct obj *)e;\n\tck_pr_fas_uint(&o->destroyed, 1);\n\n\treturn;\n}\n\nstatic void\ntest_single_reader_with_barrier_thread(void)\n{\n\tconst int num_sections = 10;\n\tstruct obj o;\n\tunsigned int run;\n\tpthread_t thread;\n\tck_epoch_section_t sections[num_sections];\n\tint shuffled[num_sections];\n\n\trun = 1;\n\tmemset(&o, 0, sizeof(struct obj));\n\tcommon_srand(time(NULL));\n\tsetup_test();\n\n\tif (pthread_create(&thread, NULL, barrier_work, &run) != 0) {\n\t\tabort();\n\t}\n\n\t/* Start a bunch of sections. */\n\tfor (int i = 0; i < num_sections; i++) {\n\t\tck_epoch_begin(&record, &sections[i]);\n\t\tshuffled[i] = i;\n\t\tif (i == num_sections / 2) {\n\t\t\tusleep(1 * 1000);\n\t\t}\n\t}\n\n\t/* Generate a shuffle. */\n\tfor (int i = num_sections - 1; i >= 0; i--) {\n\t\tint k = common_rand() % (i + 1);\n\t\tint tmp = shuffled[k];\n\t\tshuffled[k] = shuffled[i];\n\t\tshuffled[i] = tmp;\n\t}\n\n\tck_epoch_call(&record, &o.entry, obj_destroy);\n\n\t/* Close the sections in shuffle-order. */\n\tfor (int i = 0; i < num_sections; i++) {\n\t\tck_epoch_end(&record, &sections[shuffled[i]]);\n\t\tif (i != num_sections - 1) {\n\t\t\tassert(ck_pr_load_uint(&o.destroyed) == 0);\n\t\t\tusleep(3 * 1000);\n\t\t}\n\t}\n\n\tck_pr_store_uint(&run, 0);\n\tif (pthread_join(thread, NULL) != 0) {\n\t\tabort();\n\t}\n\n\tck_epoch_barrier(&record);\n\tassert(ck_pr_load_uint(&o.destroyed) == 1);\n\n\tteardown_test();\n\n\treturn;\n}\n\nstatic void\ntest_multiple_readers_with_barrier_thread(void)\n{\n\tconst int num_readers = 10;\n\tstruct obj o;\n\tunsigned int run;\n\tck_epoch_section_t section;\n\tpthread_t threads[num_readers + 1];\n\n\trun = 1;\n\tmemset(&o, 0, sizeof(struct obj));\n\tmemset(&section, 0, sizeof(ck_epoch_section_t));\n\tcommon_srand(time(NULL));\n\tsetup_test();\n\n\t/* Create a thread to call barrier() while we create reader threads.\n\t * Each barrier will attempt to move the global epoch forward so\n\t * it will make the read section code coverage more interesting. */\n\tif (pthread_create(&threads[num_readers], NULL,\n\t    barrier_work, &run) != 0) {\n\t\tabort();\n\t}\n\n\tck_epoch_begin(&record, &section);\n\tck_epoch_call(&record, &o.entry, obj_destroy);\n\n\tfor (int i = 0; i < num_readers; i++) {\n\t\tif (pthread_create(&threads[i], NULL, reader_work, &o) != 0) {\n\t\t\tabort();\n\t\t}\n\t}\n\n\tck_epoch_end(&record, &section);\n\n\tck_pr_store_uint(&run, 0);\n\tif (pthread_join(threads[num_readers], NULL) != 0) {\n\t\tabort();\n\t}\n\n\t/* After the barrier, the object should be destroyed and readers\n\t * should return. */\n\tfor (int i = 0; i < num_readers; i++) {\n\t\tif (pthread_join(threads[i], NULL) != 0) {\n\t\t\tabort();\n\t\t}\n\t}\n\n\tteardown_test();\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\ttest_simple_read_section();\n\ttest_nested_read_section();\n\ttest_single_reader_with_barrier_thread();\n\ttest_multiple_readers_with_barrier_thread();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/ck_epoch_section_2.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <string.h>\n#include <ck_epoch.h>\n#include <ck_stack.h>\n\n#include \"../../common.h\"\n\nstatic unsigned int n_rd;\nstatic unsigned int n_wr;\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int leave;\n\n#ifndef PAIRS_S\n#define PAIRS_S 10000\n#endif\n\n#ifndef CK_EPOCH_T_DEPTH\n#define CK_EPOCH_T_DEPTH\t8\n#endif\n\nstatic ck_epoch_t epoch;\nstatic struct affinity a;\n\nstatic void *\nread_thread(void *unused CK_CC_UNUSED)\n{\n\tck_epoch_record_t *record;\n\tunsigned long long i = 0;\n\n\trecord = malloc(sizeof *record);\n\tassert(record != NULL);\n\tck_epoch_register(&epoch, record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\tfor (;;) {\n\t\tck_epoch_section_t section[2];\n\t\tck_epoch_section_t junk[CK_EPOCH_T_DEPTH];\n\t\tunsigned int j;\n\n\t\tck_epoch_begin(record, &section[0]);\n\n\t\tfor (j = 0; j < CK_EPOCH_T_DEPTH; j++)\n\t\t\tck_epoch_begin(record, &junk[j]);\n\t\tfor (j = 0; j < CK_EPOCH_T_DEPTH; j++)\n\t\t\tck_epoch_end(record, &junk[j]);\n\n\t\tif (i > 0)\n\t\t\tck_epoch_end(record, &section[1]);\n\n\t\t/* Wait for the next synchronize operation. */\n\t\twhile ((ck_pr_load_uint(&epoch.epoch) & 1) ==\n\t\t    section[0].bucket) {\n\t\t\ti++;\n\n\t\t\tif (!(i % 10000000)) {\n\t\t\t\tfprintf(stderr, \"%u %u %u\\n\",\n\t\t\t\t    ck_pr_load_uint(&epoch.epoch),\n\t\t\t\t    section[0].bucket, record->epoch);\n\t\t\t}\n\n\t\t\twhile ((ck_pr_load_uint(&epoch.epoch) & 1) ==\n\t\t\t    section[0].bucket) {\n\t\t\t\tif (ck_pr_load_uint(&leave) == 1)\n\t\t\t\t\tbreak;\n\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\t\t}\n\n\t\tck_epoch_begin(record, &section[1]);\n\n\t\tassert(section[0].bucket != section[1].bucket);\n\t\tck_epoch_end(record, &section[0]);\n\n\t\tassert(ck_pr_load_uint(&record->active) > 0);\n\n\t\tif (ck_pr_load_uint(&leave) == 1) {\n\t\t\tck_epoch_end(record, &section[1]);\n\t\t\tbreak;\n\t\t}\n\n\t\ti++;\n\t}\n\n\treturn NULL;\n}\n\nstatic void *\nwrite_thread(void *unused CK_CC_UNUSED)\n{\n\tck_epoch_record_t record;\n\tunsigned long iterations = 0;\n\n\tck_epoch_register(&epoch, &record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\tfor (;;) {\n\t\tif (!(iterations % 1048575))\n\t\t\tfprintf(stderr, \".\");\n\n\t\tck_epoch_synchronize(&record);\n\t\titerations++;\n\n\t\tif (ck_pr_load_uint(&leave) == 1)\n\t\t\tbreak;\n\t}\n\n\tfprintf(stderr, \"%lu iterations\\n\", iterations);\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <#readers> <#writers> <affinity delta>\\n\");\n\t}\n\n\tn_rd = atoi(argv[1]);\n\tn_wr = atoi(argv[2]);\n\tn_threads = n_wr + n_rd;\n\n\ta.delta = atoi(argv[3]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\tck_epoch_init(&epoch);\n\n\tfor (i = 0; i < n_rd; i++)\n\t\tpthread_create(threads + i, NULL, read_thread, NULL);\n\n\tdo {\n\t\tpthread_create(threads + i, NULL, write_thread, NULL);\n\t} while (++i < n_wr + n_rd);\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&leave, 1);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/ck_epoch_synchronize.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <string.h>\n#include <ck_epoch.h>\n#include <ck_stack.h>\n\n#include \"../../common.h\"\n\nstatic unsigned int n_rd;\nstatic unsigned int n_wr;\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int e_barrier;\nstatic unsigned int readers;\nstatic unsigned int writers;\n\n#ifndef PAIRS_S\n#define PAIRS_S 10000\n#endif\n\n#ifndef ITERATE_S\n#define ITERATE_S 20\n#endif\n\nstruct node {\n\tunsigned int value;\n\tck_stack_entry_t stack_entry;\n\tck_epoch_entry_t epoch_entry;\n};\nstatic ck_stack_t stack = CK_STACK_INITIALIZER;\nstatic ck_epoch_t stack_epoch;\nCK_STACK_CONTAINER(struct node, stack_entry, stack_container)\nCK_EPOCH_CONTAINER(struct node, epoch_entry, epoch_container)\nstatic struct affinity a;\nstatic const char animate[] = \"-/|\\\\\";\n\nstatic void\ndestructor(ck_epoch_entry_t *p)\n{\n\tstruct node *e = epoch_container(p);\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nread_thread(void *unused CK_CC_UNUSED)\n{\n\tunsigned int j;\n\tck_epoch_record_t record CK_CC_CACHELINE;\n\tck_stack_entry_t *cursor;\n\tck_stack_entry_t *n;\n\tunsigned int i;\n\n\tck_epoch_register(&stack_epoch, &record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\twhile (CK_STACK_ISEMPTY(&stack) == true) {\n\t\tif (ck_pr_load_uint(&readers) != 0)\n\t\t\tbreak;\n\n\t\tck_pr_stall();\n\t}\n\n\tj = 0;\n\tfor (;;) {\n\t\ti = 0;\n\n\t\tck_epoch_begin(&record, NULL);\n\t\tCK_STACK_FOREACH(&stack, cursor) {\n\t\t\tif (cursor == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tn = CK_STACK_NEXT(cursor);\n\t\t\tj += ck_pr_load_ptr(&n) != NULL;\n\n\t\t\tif (i++ > 4098)\n\t\t\t\tbreak;\n\t\t}\n\t\tck_epoch_end(&record, NULL);\n\n\t\tif (j != 0 && ck_pr_load_uint(&readers) == 0)\n\t\t\tck_pr_store_uint(&readers, 1);\n\n\t\tif (CK_STACK_ISEMPTY(&stack) == true &&\n\t\t    ck_pr_load_uint(&e_barrier) != 0)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads);\n\n\tfprintf(stderr, \"[R] Observed entries: %u\\n\", j);\n\treturn (NULL);\n}\n\nstatic void *\nwrite_thread(void *unused CK_CC_UNUSED)\n{\n\tstruct node **entry, *e;\n\tunsigned int i, j, tid;\n\tck_epoch_record_t record;\n\tck_stack_entry_t *s;\n\n\tck_epoch_register(&stack_epoch, &record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\ttid = ck_pr_faa_uint(&writers, 1);\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\tentry = malloc(sizeof(struct node *) * PAIRS_S);\n\tif (entry == NULL) {\n\t\tck_error(\"Failed allocation.\\n\");\n\t}\n\n\tfor (j = 0; j < ITERATE_S; j++) {\n\t\tfor (i = 0; i < PAIRS_S; i++) {\n\t\t\tentry[i] = malloc(sizeof(struct node));\n\t\t\tif (entry == NULL) {\n\t\t\t\tck_error(\"Failed individual allocation\\n\");\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < PAIRS_S; i++) {\n\t\t\tck_stack_push_upmc(&stack, &entry[i]->stack_entry);\n\t\t}\n\n\t\twhile (ck_pr_load_uint(&readers) == 0)\n\t\t\tck_pr_stall();\n\n\t\tfor (i = 0; i < PAIRS_S; i++) {\n\t\t\tck_epoch_begin(&record, NULL);\n\t\t\ts = ck_stack_pop_upmc(&stack);\n\t\t\te = stack_container(s);\n\t\t\tck_epoch_end(&record, NULL);\n\n\t\t\tif (i & 1) {\n\t\t\t\tck_epoch_synchronize(&record);\n\t\t\t\tck_epoch_reclaim(&record);\n\t\t\t\tck_epoch_call(&record, &e->epoch_entry, destructor);\n\t\t\t} else {\n\t\t\t\tck_epoch_barrier(&record);\n\t\t\t\tdestructor(&e->epoch_entry);\n\t\t\t}\n\n\t\t\tif (tid == 0 && (i % 16384) == 0) {\n\t\t\t\tfprintf(stderr, \"[W] %2.2f: %c\\n\",\n\t\t\t\t    (double)j / ITERATE_S, animate[i % strlen(animate)]);\n\t\t\t}\n\t\t}\n\t}\n\n\tck_epoch_synchronize(&record);\n\n\tif (tid == 0) {\n\t\tfprintf(stderr, \"[W] Peak: %u (%2.2f%%)\\n    Reclamations: %u\\n\\n\",\n\t\t\trecord.n_peak,\n\t\t\t(double)record.n_peak / ((double)PAIRS_S * ITERATE_S) * 100,\n\t\t\trecord.n_dispatch);\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads);\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <#readers> <#writers> <affinity delta>\\n\");\n\t}\n\n\tn_rd = atoi(argv[1]);\n\tn_wr = atoi(argv[2]);\n\tn_threads = n_wr + n_rd;\n\n\ta.delta = atoi(argv[3]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\tck_epoch_init(&stack_epoch);\n\n\tfor (i = 0; i < n_rd; i++)\n\t\tpthread_create(threads + i, NULL, read_thread, NULL);\n\n\tdo {\n\t\tpthread_create(threads + i, NULL, write_thread, NULL);\n\t} while (++i < n_wr + n_rd);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/ck_stack.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <ck_epoch.h>\n#include <ck_stack.h>\n\n#include \"../../common.h\"\n\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int e_barrier;\n\n#ifndef PAIRS\n#define PAIRS 5000000\n#endif\n\nstruct node {\n\tunsigned int value;\n\tck_epoch_entry_t epoch_entry;\n\tck_stack_entry_t stack_entry;\n};\nstatic ck_stack_t stack = {NULL, NULL};\nstatic ck_epoch_t stack_epoch;\nCK_STACK_CONTAINER(struct node, stack_entry, stack_container)\nCK_EPOCH_CONTAINER(struct node, epoch_entry, epoch_container)\nstatic struct affinity a;\n\nstatic void\ndestructor(ck_epoch_entry_t *p)\n{\n\tstruct node *e = epoch_container(p);\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nthread(void *unused CK_CC_UNUSED)\n{\n\tstruct node **entry, *e;\n\tck_epoch_record_t record;\n\tck_stack_entry_t *s;\n\tunsigned long smr = 0;\n\tunsigned int i;\n\n\tck_epoch_register(&stack_epoch, &record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tentry = malloc(sizeof(struct node *) * PAIRS);\n\tif (entry == NULL) {\n\t\tck_error(\"Failed allocation.\\n\");\n\t}\n\n\tfor (i = 0; i < PAIRS; i++) {\n\t\tentry[i] = malloc(sizeof(struct node));\n\t\tif (entry == NULL) {\n\t\t\tck_error(\"Failed individual allocation\\n\");\n\t\t}\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\tfor (i = 0; i < PAIRS; i++) {\n\t\tck_epoch_begin(&record, NULL);\n\t\tck_stack_push_upmc(&stack, &entry[i]->stack_entry);\n\t\ts = ck_stack_pop_upmc(&stack);\n\t\tck_epoch_end(&record, NULL);\n\n\t\te = stack_container(s);\n\t\tck_epoch_call(&record, &e->epoch_entry, destructor);\n\t\tsmr += ck_epoch_poll(&record) == false;\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads);\n\n\tfprintf(stderr, \"Deferrals: %lu (%2.2f)\\n\", smr, (double)smr / PAIRS);\n\tfprintf(stderr, \"Peak: %u (%2.2f%%), %u pending\\nReclamations: %u\\n\\n\",\n\t\t\trecord.n_peak,\n\t\t\t(double)record.n_peak / PAIRS * 100,\n\t\t\trecord.n_pending,\n\t\t\trecord.n_dispatch);\n\n\tck_epoch_barrier(&record);\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < (n_threads << 1));\n\n\tif (record.n_pending != 0) {\n\t\tck_error(\"ERROR: %u pending, expecting none.\\n\",\n\t\t\t\trecord.n_pending);\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: stack <threads> <affinity delta>\\n\");\n\t}\n\n\tn_threads = atoi(argv[1]);\n\ta.delta = atoi(argv[2]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\n\tck_epoch_init(&stack_epoch);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_create(threads + i, NULL, thread, NULL);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_epoch/validate/torture.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <inttypes.h>\n#include <stdbool.h>\n#include <string.h>\n#include <ck_epoch.h>\n#include <ck_stack.h>\n\n#include \"../../common.h\"\n\nstatic unsigned int n_rd;\nstatic unsigned int n_wr;\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int leave;\nstatic unsigned int first;\n\nstruct {\n\tunsigned int value;\n} valid CK_CC_CACHELINE = { 1 };\n\nstruct {\n\tunsigned int value;\n} invalid CK_CC_CACHELINE;\n\n#ifndef PAIRS_S\n#define PAIRS_S 10000\n#endif\n\n#ifndef CK_EPOCH_T_DEPTH\n#define CK_EPOCH_T_DEPTH\t8\n#endif\n\nstatic ck_epoch_t epoch;\nstatic struct affinity a;\n\nstatic void\ntest(struct ck_epoch_record *record)\n{\n\tunsigned int j[3];\n\tunsigned int b, c;\n\tconst unsigned int r = 100;\n\tsize_t i;\n\n\tfor (i = 0; i < 8; i++) {\n\t\tck_epoch_begin(record, NULL);\n\t\tc = ck_pr_load_uint(&invalid.value);\n\t\tck_pr_fence_load();\n\t\tb = ck_pr_load_uint(&valid.value);\n\t\tck_test(c > b, \"Invalid value: %u > %u\\n\", c, b);\n\t\tck_epoch_end(record, NULL);\n\t}\n\n\tck_epoch_begin(record, NULL);\n\n\t/* This implies no early load of epoch occurs. */\n\tj[0] = record->epoch;\n\n\n\t/* We should observe up to one epoch migration. */\n\tdo {\n\t\tck_pr_fence_load();\n\t\tj[1] = ck_pr_load_uint(&epoch.epoch);\n\n\t\tif (ck_pr_load_uint(&leave) == 1) {\n\t\t\tck_epoch_end(record, NULL);\n\t\t\treturn;\n\t\t}\n\t} while (j[1] == j[0]);\n\n\t/* No more epoch migrations should occur */\n\tfor (i = 0; i < r; i++) {\n\t\tck_pr_fence_strict_load();\n\t\tj[2] = ck_pr_load_uint(&epoch.epoch);\n\n\t\tck_test(j[2] != j[1], \"Inconsistency detected: %u %u %u\\n\",\n\t\t    j[0], j[1], j[2]);\n\t}\n\n\tck_epoch_end(record, NULL);\n\treturn;\n}\n\nstatic void *\nread_thread(void *unused CK_CC_UNUSED)\n{\n\tck_epoch_record_t *record;\n\n\trecord = malloc(sizeof *record);\n\tassert(record != NULL);\n\tck_epoch_register(&epoch, record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n\tdo {\n\t\ttest(record);\n\t\ttest(record);\n\t\ttest(record);\n\t\ttest(record);\n\t} while (ck_pr_load_uint(&leave) == 0);\n\n\tck_pr_dec_uint(&n_rd);\n\n\treturn NULL;\n}\n\nstatic void *\nwrite_thread(void *unused CK_CC_UNUSED)\n{\n\tck_epoch_record_t *record;\n\tunsigned long iterations = 0;\n\tbool c = ck_pr_faa_uint(&first, 1);\n\tuint64_t ac = 0;\n\n\trecord = malloc(sizeof *record);\n\tassert(record != NULL);\n\tck_epoch_register(&epoch, record, NULL);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads);\n\n#define CK_EPOCH_S\tdo {\t\t\\\n\tuint64_t _s = rdtsc();\t\t\\\n\tck_epoch_synchronize(record);\t\\\n\tac += rdtsc() - _s;\t\t\\\n} while (0)\n\n\tdo {\n\t\t/*\n\t\t * A thread should never observe invalid.value > valid.value.\n\t\t * inside a protected section. Only\n\t\t * invalid.value <= valid.value is valid.\n\t\t */\n\t\tif (!c) ck_pr_store_uint(&valid.value, 1);\n\t\tCK_EPOCH_S;\n\t\tif (!c) ck_pr_store_uint(&invalid.value, 1);\n\n\t\tck_pr_fence_store();\n\t\tif (!c) ck_pr_store_uint(&valid.value, 2);\n\t\tCK_EPOCH_S;\n\t\tif (!c) ck_pr_store_uint(&invalid.value, 2);\n\n\t\tck_pr_fence_store();\n\t\tif (!c) ck_pr_store_uint(&valid.value, 3);\n\t\tCK_EPOCH_S;\n\t\tif (!c) ck_pr_store_uint(&invalid.value, 3);\n\n\t\tck_pr_fence_store();\n\t\tif (!c) ck_pr_store_uint(&valid.value, 4);\n\t\tCK_EPOCH_S;\n\t\tif (!c) ck_pr_store_uint(&invalid.value, 4);\n\n\t\tCK_EPOCH_S;\n\t\tif (!c) ck_pr_store_uint(&invalid.value, 0);\n\t\tCK_EPOCH_S;\n\n\t\titerations += 6;\n\t} while (ck_pr_load_uint(&leave) == 0 &&\n\t\t ck_pr_load_uint(&n_rd) > 0);\n\n\tfprintf(stderr, \"%lu iterations\\n\", iterations);\n\tfprintf(stderr, \"%\" PRIu64 \" average latency\\n\", ac / iterations);\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <#readers> <#writers> <affinity delta>\\n\");\n\t}\n\n\tn_rd = atoi(argv[1]);\n\tn_wr = atoi(argv[2]);\n\tn_threads = n_wr + n_rd;\n\n\ta.delta = atoi(argv[3]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\tck_epoch_init(&epoch);\n\n\tfor (i = 0; i < n_rd; i++)\n\t\tpthread_create(threads + i, NULL, read_thread, NULL);\n\n\tdo {\n\t\tpthread_create(threads + i, NULL, write_thread, NULL);\n\t} while (++i < n_wr + n_rd);\n\n\tcommon_sleep(30);\n\tck_pr_store_uint(&leave, 1);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_fifo/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_fifo.h>\n#include <ck_spinlock.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#ifndef ENTRIES\n#define ENTRIES 4096\n#endif\n\n#ifndef STEPS\n#define STEPS 40000\n#endif\n\nint\nmain(void)\n{\n\tck_spinlock_fas_t mutex = CK_SPINLOCK_FAS_INITIALIZER;\n\tvoid *r;\n\tuint64_t s, e, a;\n\tunsigned int i;\n\tunsigned int j;\n\n#if   defined(CK_F_FIFO_SPSC)\n\tck_fifo_spsc_t spsc_fifo;\n\tck_fifo_spsc_entry_t spsc_entry[ENTRIES];\n\tck_fifo_spsc_entry_t spsc_stub;\n#endif\n\n#if defined(CK_F_FIFO_MPMC)\n\tck_fifo_mpmc_t mpmc_fifo;\n\tck_fifo_mpmc_entry_t mpmc_entry[ENTRIES];\n\tck_fifo_mpmc_entry_t mpmc_stub;\n\tck_fifo_mpmc_entry_t *garbage;\n#endif\n\n#ifdef CK_F_FIFO_SPSC\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_fifo_spsc_init(&spsc_fifo, &spsc_stub);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++) {\n\t\t\tck_spinlock_fas_lock(&mutex);\n\t\t\tck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL);\n\t\t\tck_spinlock_fas_unlock(&mutex);\n\t\t}\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"    spinlock_enqueue: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry)));\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_fifo_spsc_init(&spsc_fifo, &spsc_stub);\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++) {\n\t\t\tck_spinlock_fas_lock(&mutex);\n\t\t\tck_fifo_spsc_dequeue(&spsc_fifo, &r);\n\t\t\tck_spinlock_fas_unlock(&mutex);\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\"    spinlock_dequeue: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry)));\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_fifo_spsc_init(&spsc_fifo, &spsc_stub);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_fifo_spsc_enqueue: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry)));\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_fifo_spsc_init(&spsc_fifo, &spsc_stub);\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_spsc_enqueue(&spsc_fifo, spsc_entry + j, NULL);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_spsc_dequeue(&spsc_fifo, &r);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_fifo_spsc_dequeue: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(spsc_entry) / sizeof(*spsc_entry)));\n#endif\n\n#ifdef CK_F_FIFO_MPMC\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_fifo_mpmc_init(&mpmc_fifo, &mpmc_stub);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_mpmc_enqueue(&mpmc_fifo, mpmc_entry + j, NULL);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_fifo_mpmc_enqueue: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(mpmc_entry) / sizeof(*mpmc_entry)));\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_fifo_mpmc_init(&mpmc_fifo, &mpmc_stub);\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_mpmc_enqueue(&mpmc_fifo, mpmc_entry + j, NULL);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_fifo_mpmc_dequeue(&mpmc_fifo, &r, &garbage);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_fifo_mpmc_dequeue: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(mpmc_entry) / sizeof(*mpmc_entry)));\n#endif\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_fifo/validate/ck_fifo_mpmc.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <ck_fifo.h>\n\n#include \"../../common.h\"\n\n#ifdef CK_F_FIFO_MPMC\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n};\n\nstruct entry {\n\tint tid;\n\tint value;\n};\n\nstatic int nthr;\n\n#ifdef CK_F_FIFO_MPMC\nstatic ck_fifo_mpmc_t fifo CK_CC_CACHELINE;\n#endif\n\nstatic struct affinity a;\nstatic int size;\nstatic unsigned int barrier;\n\nstatic void *\ntest(void *c)\n{\n#ifdef CK_F_FIFO_MPMC\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tck_fifo_mpmc_entry_t *fifo_entry, *garbage;\n\tint i, j;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < (unsigned int)nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tfifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t));\n\t\t\tentry = malloc(sizeof(struct entry));\n\t\t\tentry->tid = context->tid;\n\t\t\tck_fifo_mpmc_enqueue(&fifo, fifo_entry, entry);\n\t\t\tif (ck_fifo_mpmc_dequeue(&fifo, &entry, &garbage) == false) {\n\t\t\t\tck_error(\"ERROR [%u] Queue should never be empty.\\n\", context->tid);\n\t\t\t}\n\n\t\t\tif (entry->tid < 0 || entry->tid >= nthr) {\n\t\t\t\tck_error(\"ERROR [%u] Incorrect value in entry.\\n\", entry->tid);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tfifo_entry = malloc(sizeof(ck_fifo_mpmc_entry_t));\n\t\t\tentry = malloc(sizeof(struct entry));\n\t\t\tentry->tid = context->tid;\n\t\t\twhile (ck_fifo_mpmc_tryenqueue(&fifo, fifo_entry, entry) == false)\n\t\t\t\tck_pr_stall();\n\n\t\t\twhile (ck_fifo_mpmc_trydequeue(&fifo, &entry, &garbage) == false)\n\t\t\t\tck_pr_stall();\n\n\t\t\tif (entry->tid < 0 || entry->tid >= nthr) {\n\t\t\t\tck_error(\"ERROR [%u] Incorrect value in entry when using try interface.\\n\", entry->tid);\n\t\t\t}\n\t\t}\n\t}\n#endif\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tstruct context *context;\n\tck_fifo_mpmc_entry_t *garbage;\n\tpthread_t *thread;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size > 0);\n\n\tcontext = malloc(sizeof(*context) * nthr);\n\tassert(context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tck_fifo_mpmc_init(&fifo, malloc(sizeof(ck_fifo_mpmc_entry_t)));\n\tck_fifo_mpmc_deinit(&fifo, &garbage);\n\tif (garbage == NULL)\n\t\tck_error(\"ERROR: Expected non-NULL stub node on deinit.\\n\");\n\tfree(garbage);\n\tck_fifo_mpmc_init(&fifo, malloc(sizeof(ck_fifo_mpmc_entry_t)));\n\n\tfor (i = 0; i < nthr; i++) {\n\t\tcontext[i].tid = i;\n\t\tr = pthread_create(thread + i, NULL, test, context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn (0);\n}\n#else\nint\nmain(void)\n{\n\tfprintf(stderr, \"Unsupported.\\n\");\n\treturn 0;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_fifo/validate/ck_fifo_mpmc_iterator.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_fifo.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#ifdef CK_F_FIFO_MPMC\nstruct example {\n\tint x;\n};\n\nstatic ck_fifo_mpmc_t mpmc_fifo;\n\nint\nmain(void)\n{\n\tint i, length = 3;\n\tstruct example *examples;\n\tck_fifo_mpmc_entry_t *stub, *entries, *entry, *next;\n\n\tstub = malloc(sizeof(ck_fifo_mpmc_entry_t));\n\tif (stub == NULL)\n\t\texit(EXIT_FAILURE);\n\n\tck_fifo_mpmc_init(&mpmc_fifo, stub);\n\n\tentries = malloc(sizeof(ck_fifo_mpmc_entry_t) * length);\n\tif (entries == NULL)\n\t\texit(EXIT_FAILURE);\n\n\texamples = malloc(sizeof(struct example) * length);\n\t/* Need these for this unit test. */\n\tif (examples == NULL)\n\t\texit(EXIT_FAILURE);\n\n\tfor (i = 0; i < length; ++i) {\n\t\texamples[i].x = i;\n\t\tck_fifo_mpmc_enqueue(&mpmc_fifo, entries + i, examples + i);\n\t}\n\n\tputs(\"Testing CK_FIFO_MPMC_FOREACH.\");\n\tCK_FIFO_MPMC_FOREACH(&mpmc_fifo, entry) {\n\t\tprintf(\"Next value in fifo: %d\\n\", ((struct example *)entry->value)->x);\n\t}\n\n\tputs(\"Testing CK_FIFO_MPMC_FOREACH_SAFE.\");\n\tCK_FIFO_MPMC_FOREACH_SAFE(&mpmc_fifo, entry, next) {\n\t\tif (entry->next.pointer != next)\n\t\t\texit(EXIT_FAILURE);\n\t\tprintf(\"Next value in fifo: %d\\n\", ((struct example *)entry->value)->x);\n\t}\n\n\tfree(examples);\n\tfree(entries);\n\tfree(stub);\n\n\treturn (0);\n}\n#else\nint\nmain(void)\n{\n\treturn (0);\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_fifo/validate/ck_fifo_spsc.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n\n#include <ck_fifo.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n};\n\nstruct entry {\n\tint tid;\n\tint value;\n};\n\nstatic int nthr;\nstatic ck_fifo_spsc_t *fifo;\nstatic struct affinity a;\nstatic int size;\nstatic unsigned int barrier;\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tck_fifo_spsc_entry_t *fifo_entry;\n\tint i, j;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n#ifdef DEBUG\n\tfprintf(stderr, \"%p %u: %u -> %u\\n\", fifo+context->tid, context->tid, context->previous, context->tid);\n#endif\n\n\tif (context->tid == 0) {\n\t\tstruct entry *entries;\n\n\t\tentries = malloc(sizeof(struct entry) * size);\n\t\tassert(entries != NULL);\n\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tentries[i].value = i;\n\t\t\tentries[i].tid = 0;\n\n\t\t\tfifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t));\n\t\t\tck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entries + i);\n\t\t}\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < (unsigned int)nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\twhile (ck_fifo_spsc_dequeue(fifo + context->previous, &entry) == false);\n\t\t\tif (context->previous != (unsigned int)entry->tid) {\n\t\t\t\tck_error(\"T [%u:%p] %u != %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tif (entry->value != j) {\n\t\t\t\tck_error(\"V [%u:%p] %u != %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->value, j);\n\t\t\t}\n\n\t\t\tentry->tid = context->tid;\n\t\t\tfifo_entry = ck_fifo_spsc_recycle(fifo + context->tid);\n\t\t\tif (fifo_entry == NULL)\n\t\t\t\tfifo_entry = malloc(sizeof(ck_fifo_spsc_entry_t));\n\n\t\t\tck_fifo_spsc_enqueue(fifo + context->tid, fifo_entry, entry);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tstruct context *context;\n\tpthread_t *thread;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size > 0);\n\n\tfifo = malloc(sizeof(ck_fifo_spsc_t) * nthr);\n\tassert(fifo);\n\n\tcontext = malloc(sizeof(*context) * nthr);\n\tassert(context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tfor (i = 0; i < nthr; i++) {\n\t\tck_fifo_spsc_entry_t *garbage;\n\n\t\tcontext[i].tid = i;\n\t\tif (i == 0) {\n\t\t\tcontext[i].previous = nthr - 1;\n\t\t\tcontext[i].next = i + 1;\n\t\t} else if (i == nthr - 1) {\n\t\t\tcontext[i].next = 0;\n\t\t\tcontext[i].previous = i - 1;\n\t\t} else {\n\t\t\tcontext[i].next = i + 1;\n\t\t\tcontext[i].previous = i - 1;\n\t\t}\n\n\t\tck_fifo_spsc_init(fifo + i, malloc(sizeof(ck_fifo_spsc_entry_t)));\n\t\tck_fifo_spsc_deinit(fifo + i, &garbage);\n\t\tif (garbage == NULL)\n\t\t\tck_error(\"ERROR: Expected non-NULL stub node on deinit.\\n\");\n\n\t\tfree(garbage);\n\t\tck_fifo_spsc_init(fifo + i, malloc(sizeof(ck_fifo_spsc_entry_t)));\n\t\tr = pthread_create(thread + i, NULL, test, context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_fifo/validate/ck_fifo_spsc_iterator.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_fifo.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n\nstruct example {\n\tint x;\n};\n\nstatic ck_fifo_spsc_t spsc_fifo;\n\nint\nmain(void)\n{\n\tint i, length = 3;\n\tstruct example *examples;\n\tck_fifo_spsc_entry_t *stub, *entries, *entry, *next;\n\n\tstub = malloc(sizeof(ck_fifo_spsc_entry_t));\n\tif (stub == NULL)\n\t\texit(EXIT_FAILURE);\n\n\tck_fifo_spsc_init(&spsc_fifo, stub);\n\n\tentries = malloc(sizeof(ck_fifo_spsc_entry_t) * length);\n\tif (entries == NULL)\n\t\texit(EXIT_FAILURE);\n\n\texamples = malloc(sizeof(struct example) * length);\n\t/* Need these for this unit test. */\n\tif (examples == NULL)\n\t\texit(EXIT_FAILURE);\n\n\tfor (i = 0; i < length; ++i) {\n\t\texamples[i].x = i;\n\t\tck_fifo_spsc_enqueue(&spsc_fifo, entries + i, examples + i);\n\t}\n\n\tputs(\"Testing CK_FIFO_SPSC_FOREACH.\");\n\tCK_FIFO_SPSC_FOREACH(&spsc_fifo, entry) {\n\t\tprintf(\"Next value in fifo: %d\\n\", ((struct example *)entry->value)->x);\n\t}\n\n\tputs(\"Testing CK_FIFO_SPSC_FOREACH_SAFE.\");\n\tCK_FIFO_SPSC_FOREACH_SAFE(&spsc_fifo, entry, next) {\n\t\tif (entry->next != next)\n\t\t\texit(EXIT_FAILURE);\n\t\tprintf(\"Next value in fifo: %d\\n\", ((struct example *)entry->value)->x);\n\t}\n\n\tfree(examples);\n\tfree(entries);\n\tfree(stub);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/benchmark/fifo_latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_hp.h>\n#include <ck_hp_fifo.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../../common.h\"\n\n#ifndef ENTRIES\n#define ENTRIES 4096\n#endif\n\n#ifndef STEPS\n#define STEPS 40000\n#endif\n\nstatic ck_hp_fifo_t fifo;\nstatic ck_hp_t fifo_hp;\n\nint\nmain(void)\n{\n\tvoid *r;\n\tuint64_t s, e, a;\n\tunsigned int i;\n\tunsigned int j;\n\tck_hp_fifo_entry_t hp_entry[ENTRIES];\n\tck_hp_fifo_entry_t hp_stub;\n\tck_hp_record_t record;\n\n\tck_hp_init(&fifo_hp, CK_HP_FIFO_SLOTS_COUNT, 1000000, NULL);\n\n\tr = malloc(CK_HP_FIFO_SLOTS_SIZE);\n\tif (r == NULL) {\n\t\tck_error(\"ERROR: Failed to allocate slots.\\n\");\n\t}\n\tck_hp_register(&fifo_hp, &record, r);\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_hp_fifo_init(&fifo, &hp_stub);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_hp_fifo_enqueue_mpmc(&record, &fifo, hp_entry + j, NULL);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_hp_fifo_enqueue_mpmc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_hp_fifo_init(&fifo, &hp_stub);\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_hp_fifo_enqueue_mpmc(&record, &fifo, hp_entry + j, NULL);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_hp_fifo_dequeue_mpmc(&record, &fifo, &r);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_hp_fifo_dequeue_mpmc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/benchmark/stack_latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_hp.h>\n#include <ck_hp_stack.h>\n#include <ck_stack.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../../common.h\"\n\n#ifndef ENTRIES\n#define ENTRIES 4096\n#endif\n\n#ifndef STEPS\n#define STEPS 40000\n#endif\n\nstatic ck_stack_t stack;\nstatic ck_hp_t stack_hp;\n\nint\nmain(void)\n{\n\tck_hp_record_t record;\n\tck_stack_entry_t entry[ENTRIES];\n\tuint64_t s, e, a;\n\tunsigned int i;\n\tunsigned int j;\n\tvoid *r;\n\n\tck_hp_init(&stack_hp, CK_HP_STACK_SLOTS_COUNT, 1000000, NULL);\n\tr = malloc(CK_HP_STACK_SLOTS_SIZE);\n\tif (r == NULL) {\n\t\tck_error(\"ERROR: Failed to allocate slots.\\n\");\n\t}\n\tck_hp_register(&stack_hp, &record, (void *)r);\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_hp_stack_push_mpmc(&stack, entry + j);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_hp_stack_push_mpmc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_hp_stack_push_mpmc(&stack, entry + j);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++) {\n\t\t\tr = ck_hp_stack_pop_mpmc(&record, &stack);\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\" ck_hp_stack_pop_mpmc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/validate/ck_hp_fifo.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <ck_hp_fifo.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n};\n\nstruct entry {\n\tint tid;\n\tint value;\n};\n\nstatic ck_hp_fifo_t fifo;\nstatic ck_hp_t fifo_hp;\nstatic int nthr;\n\nstatic struct affinity a;\nstatic int size;\nstatic unsigned int barrier;\nstatic unsigned int e_barrier;\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tck_hp_fifo_entry_t *fifo_entry;\n\tck_hp_record_t record;\n\tint i, j;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tck_hp_register(&fifo_hp, &record, malloc(sizeof(void *) * 2));\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < (unsigned int)nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tfifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));\n\t\t\tentry = malloc(sizeof(struct entry));\n\t\t\tentry->tid = context->tid;\n\t\t\tck_hp_fifo_enqueue_mpmc(&record, &fifo, fifo_entry, entry);\n\n\t\t\tck_pr_barrier();\n\n\t\t\tfifo_entry = ck_hp_fifo_dequeue_mpmc(&record, &fifo, &entry);\n\t\t\tif (fifo_entry == NULL) {\n\t\t\t\tck_error(\"ERROR [%u] Queue should never be empty.\\n\", context->tid);\n\t\t\t}\n\n\t\t\tck_pr_barrier();\n\n\t\t\tif (entry->tid < 0 || entry->tid >= nthr) {\n\t\t\t\tck_error(\"ERROR [%u] Incorrect value in entry.\\n\", entry->tid);\n\t\t\t}\n\n\t\t\tck_hp_free(&record, &fifo_entry->hazard, fifo_entry, fifo_entry);\n\t\t}\n\t}\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tfifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));\n\t\t\tentry = malloc(sizeof(struct entry));\n\t\t\tentry->tid = context->tid;\n\n\t\t\twhile (ck_hp_fifo_tryenqueue_mpmc(&record, &fifo, fifo_entry, entry) == false)\n\t\t\t\tck_pr_stall();\n\n\t\t\twhile (fifo_entry = ck_hp_fifo_trydequeue_mpmc(&record, &fifo, &entry), fifo_entry == NULL)\n\t\t\t\tck_pr_stall();\n\n\t\t\tif (entry->tid < 0 || entry->tid >= nthr) {\n\t\t\t\tck_error(\"ERROR [%u] Incorrect value in entry.\\n\", entry->tid);\n\t\t\t}\n\n\t\t\tck_hp_free(&record, &fifo_entry->hazard, fifo_entry, fifo_entry);\n\t\t}\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < (unsigned int)nthr);\n\n\treturn (NULL);\n}\n\nstatic void\ndestructor(void *p)\n{\n\n\tfree(p);\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tstruct context *context;\n\tpthread_t *thread;\n\tint threshold;\n\n\tif (argc != 5) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size> <threshold>\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size > 0);\n\n\tthreshold = atoi(argv[4]);\n\tassert(threshold > 0);\n\n\tcontext = malloc(sizeof(*context) * nthr);\n\tassert(context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tck_hp_init(&fifo_hp, 2, threshold, destructor);\n\tck_hp_fifo_init(&fifo, malloc(sizeof(ck_hp_fifo_entry_t)));\n\n\tck_hp_fifo_entry_t *entry;\n\tck_hp_fifo_deinit(&fifo, &entry);\n\n\tif (entry == NULL)\n\t\tck_error(\"ERROR: Expected non-NULL stub node.\\n\");\n\n\tfree(entry);\n\tck_hp_fifo_init(&fifo, malloc(sizeof(ck_hp_fifo_entry_t)));\n\n\tfor (i = 0; i < nthr; i++) {\n\t\tcontext[i].tid = i;\n\t\tr = pthread_create(thread + i, NULL, test, context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/validate/ck_hp_fifo_donner.c",
    "content": "/*\n * Copyright 2012 Hendrik Donner\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_hp.h>\n#include <ck_hp_fifo.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <sys/time.h>\n#include <assert.h>\n#include \"../../common.h\"\n\n/* FIFO queue */\nstatic ck_hp_fifo_t fifo;\n\n/* Hazard pointer global */\nstatic ck_hp_t fifo_hp;\n\n/* thread local element count */\nstatic unsigned long *count;\n\nstatic unsigned long thread_count;\n\nstatic unsigned int start_barrier;\nstatic unsigned int end_barrier;\n\n/* destructor for FIFO queue */\nstatic void\ndestructor(void *p)\n{\n\n\tfree(p);\n\treturn;\n}\n\n/* entry struct for FIFO queue entries */\nstruct entry {\n\tunsigned long value;\n};\n\n/* function for thread */\nstatic void *\nqueue_50_50(void *elements)\n{\n        struct entry *entry;\n        ck_hp_fifo_entry_t *fifo_entry;\n\tck_hp_record_t *record;\n\tvoid *slots;\n        unsigned long j, element_count = *(unsigned long *)elements;\n\tunsigned int seed;\n\n\trecord = malloc(sizeof(ck_hp_record_t));\n\tassert(record);\n\n\tslots = malloc(CK_HP_FIFO_SLOTS_SIZE);\n\tassert(slots);\n\n        /* different seed for each thread */\n\tseed = 1337; /*(unsigned int) pthread_self(); */\n\n        /*\n         * This subscribes the thread to the fifo_hp state using the thread-owned\n         * record.\n         * FIFO queue needs 2 hazard pointers.\n         */\n        ck_hp_register(&fifo_hp, record, slots);\n\n\t/* start barrier */\n\tck_pr_inc_uint(&start_barrier);\n\twhile (ck_pr_load_uint(&start_barrier) < thread_count + 1)\n\t\tck_pr_stall();\n\n\t/* 50/50 enqueue-dequeue */\n\tfor(j = 0; j < element_count; j++) {\n\t\t/* rand_r with thread local state should be thread safe */\n\t\tif( 50 < (1+(int) (100.0*common_rand_r(&seed)/(RAND_MAX+1.0)))) {\n\t\t\t/* This is the container for the enqueued data. */\n        \t\tfifo_entry = malloc(sizeof(ck_hp_fifo_entry_t));\n\n        \t\tif (fifo_entry == NULL) {\n        \t        \texit(EXIT_FAILURE);\n\t\t\t}\n\n        \t\t/* This is the data. */\n        \t\tentry = malloc(sizeof(struct entry));\n        \t\tif (entry != NULL) {\n        \t        \tentry->value = j;\n\t\t\t}\n\n        \t       /*\n        \t \t* Enqueue the value of the pointer entry into FIFO queue using the\n        \t \t* container fifo_entry.\n        \t \t*/\n        \t\tck_hp_fifo_enqueue_mpmc(record, &fifo, fifo_entry, entry);\n\t\t} else {\n\t\t\t/*\n        \t\t * ck_hp_fifo_dequeue_mpmc will return a pointer to the first unused node and store\n        \t\t * the value of the first pointer in the FIFO queue in entry.\n        \t\t */\n  \t\t      \tfifo_entry = ck_hp_fifo_dequeue_mpmc(record, &fifo, &entry);\n        \t\tif (fifo_entry != NULL) {\n               \t\t \t/*\n               \t\t \t * Safely reclaim memory associated with fifo_entry.\n                \t\t * This inserts garbage into a local list. Once the list (plist) reaches\n      \t\t\t       \t * a length of 100, ck_hp_free will attempt to reclaim all references\n                \t\t * to objects on the list.\n        \t\t       \t */\n                \t\tck_hp_free(record, &fifo_entry->hazard, fifo_entry, fifo_entry);\n        \t\t}\n\t\t}\n\t}\n\n\t/* end barrier */\n\tck_pr_inc_uint(&end_barrier);\n\twhile (ck_pr_load_uint(&end_barrier) < thread_count + 1)\n\t\tck_pr_stall();\n\n       \treturn NULL;\n}\n\nint\nmain(int argc, char** argv)\n{\n        ck_hp_fifo_entry_t *stub;\n        unsigned long element_count, i;\n\tpthread_t *thr;\n\n        if (argc != 3) {\n        \tck_error(\"Usage: cktest <thread_count> <element_count>\\n\");\n        }\n\n        /* Get element count from argument */\n        element_count = atoi(argv[2]);\n\n\t/* Get element count from argument */\n        thread_count = atoi(argv[1]);\n\n\t/* pthread handles */\n\tthr = malloc(sizeof(pthread_t) * thread_count);\n\n\t/* array for local operation count */\n\tcount = malloc(sizeof(unsigned long *) * thread_count);\n\n        /*\n         * Initialize global hazard pointer safe memory reclamation to execute free()\n         * when a fifo_entry is safe to be deleted.\n         * Hazard pointer scan routine will be called when the thread local intern plist's\n         * size exceed 100 entries.\n         */\n\n\t/* FIFO queue needs 2 hazard pointers */\n\tck_hp_init(&fifo_hp, CK_HP_FIFO_SLOTS_COUNT, 100, destructor);\n\n        /* The FIFO requires one stub entry on initialization. */\n        stub = malloc(sizeof(ck_hp_fifo_entry_t));\n\n        /* Behavior is undefined if stub is NULL. */\n        if (stub == NULL) {\n                exit(EXIT_FAILURE);\n\t}\n\n        /* This is called once to initialize the fifo. */\n        ck_hp_fifo_init(&fifo, stub);\n\n\t/* Create threads */\n\tfor (i = 0; i < thread_count; i++) {\n\t\tcount[i] = (element_count + i) / thread_count;\n\t\tif (pthread_create(&thr[i], NULL, queue_50_50, (void *) &count[i]) != 0) {\n                \texit(EXIT_FAILURE);\n                }\n\t}\n\n\t/* start barrier */\n\tck_pr_inc_uint(&start_barrier);\n\twhile (ck_pr_load_uint(&start_barrier) < thread_count + 1);\n\n\t/* end barrier */\n\tck_pr_inc_uint(&end_barrier);\n\twhile (ck_pr_load_uint(&end_barrier) < thread_count + 1);\n\n\t/* Join threads */\n\tfor (i = 0; i < thread_count; i++)\n\t\tpthread_join(thr[i], NULL);\n\n        return 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/validate/ck_hp_stack.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <ck_hp.h>\n#include <ck_stack.h>\n#include <ck_hp_stack.h>\n\n#include \"../../common.h\"\n\nstatic unsigned int threshold;\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int e_barrier;\n\n#ifndef PAIRS\n#define PAIRS 5000000\n#endif\n\nstruct node {\n\tunsigned int value;\n\tck_hp_hazard_t hazard;\n\tck_stack_entry_t stack_entry;\n};\nstatic ck_stack_t stack = {NULL, NULL};\nstatic ck_hp_t stack_hp;\nCK_STACK_CONTAINER(struct node, stack_entry, stack_container)\nstatic struct affinity a;\n\nstatic void *\nthread(void *unused CK_CC_UNUSED)\n{\n\tstruct node **entry, *e;\n\tunsigned int i;\n\tck_hp_record_t record;\n\tvoid **pointers;\n\tck_stack_entry_t *s;\n\n\tunused = NULL;\n\tpointers = malloc(sizeof(void *));\n\tck_hp_register(&stack_hp, &record, pointers);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tentry = malloc(sizeof(struct node *) * PAIRS);\n\tif (entry == NULL) {\n\t\tck_error(\"Failed allocation.\\n\");\n\t}\n\n\tfor (i = 0; i < PAIRS; i++) {\n\t\tentry[i] = malloc(sizeof(struct node));\n\t\tif (entry == NULL) {\n\t\t\tck_error(\"Failed individual allocation\\n\");\n\t\t}\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads)\n\t\tck_pr_stall();\n\n\tfor (i = 0; i < PAIRS; i++) {\n\t\tck_hp_stack_push_mpmc(&stack, &entry[i]->stack_entry);\n\t\ts = ck_hp_stack_pop_mpmc(&record, &stack);\n\t\te = stack_container(s);\n\t\tck_hp_free(&record, &e->hazard, e, s);\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads)\n\t\tck_pr_stall();\n\n        fprintf(stderr, \"Peak: %u (%2.2f%%)\\nReclamations: %\" PRIu64 \"\\n\\n\",\n                record.n_peak,\n\t\t(double)record.n_peak / PAIRS * 100,\n\t\trecord.n_reclamations);\n\n\tck_hp_clear(&record);\n\tck_hp_purge(&record);\n\n        ck_pr_inc_uint(&e_barrier);\n        while (ck_pr_load_uint(&e_barrier) < (n_threads << 1));\n\n        if (record.n_pending != 0) {\n                ck_error(\"ERROR: %u pending, expecting none.\\n\",\n                                record.n_pending);\n        }\n\n\treturn (NULL);\n}\n\nstatic void\ndestructor(void *p)\n{\n\n\tfree(p);\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <threads> <threshold> <delta>\\n\");\n\t}\n\n\tn_threads = atoi(argv[1]);\n\tthreshold = atoi(argv[2]);\n\ta.delta = atoi(argv[3]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\n\tck_hp_init(&stack_hp, 1, threshold, destructor);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_create(threads + i, NULL, thread, NULL);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/validate/nbds_haz_test.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * This is a unit test similar to the implementation in John Dybnis's nbds\n * test.\n */\n\n#include <assert.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdbool.h>\n#include <stddef.h>\n#include <ck_hp.h>\n\n#include \"../../common.h\"\n\n#define STACK_CONTAINER(T, M, N) CK_CC_CONTAINER(stack_entry_t, T, M, N)\n\nstruct stack_entry {\n\tstruct stack_entry *next;\n} CK_CC_ALIGN(8);\ntypedef struct stack_entry stack_entry_t;\n\nstruct stack {\n\tstruct stack_entry *head;\n\tchar *generation;\n} CK_CC_PACKED CK_CC_ALIGN(16);\ntypedef struct stack hp_stack_t;\n\nstatic unsigned int threshold;\nstatic unsigned int n_threads;\nstatic unsigned int barrier;\nstatic unsigned int e_barrier;\nstatic unsigned int global_tid;\nstatic unsigned int pops;\nstatic unsigned int pushs;\n\n#ifndef PAIRS\n#define PAIRS 1000000\n#endif\n\nstruct node {\n\tunsigned int value;\n\tck_hp_hazard_t hazard;\n\tstack_entry_t stack_entry;\n};\nhp_stack_t stack = {NULL, NULL};\nck_hp_t stack_hp;\n\nSTACK_CONTAINER(struct node, stack_entry, stack_container)\nstatic struct affinity a;\n\n/*\n * Stack producer operation safe for multiple unique producers and multiple consumers.\n */\nCK_CC_INLINE static void\nstack_push_mpmc(struct stack *target, struct stack_entry *entry)\n{\n\tstruct stack_entry *lstack;\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\n\tlstack = ck_pr_load_ptr(&target->head);\n\tck_pr_store_ptr(&entry->next, lstack);\n\tck_pr_fence_store();\n\n\twhile (ck_pr_cas_ptr_value(&target->head, lstack, entry, &lstack) == false) {\n\t\tck_pr_store_ptr(&entry->next, lstack);\n\t\tck_pr_fence_store();\n\t\tck_backoff_eb(&backoff);\n\t}\n\n\treturn;\n}\n\n/*\n * Stack consumer operation safe for multiple unique producers and multiple consumers.\n */\nCK_CC_INLINE static struct stack_entry *\nstack_pop_mpmc(ck_hp_record_t *record, struct stack *target)\n{\n\tstruct stack_entry *entry;\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\n\tdo {\n\t\tentry = ck_pr_load_ptr(&target->head);\n\t\tif (entry == NULL)\n\t\t\treturn (NULL);\n\n\t\tck_hp_set_fence(record, 0, entry);\n\t} while (entry != ck_pr_load_ptr(&target->head));\n\n\twhile (ck_pr_cas_ptr_value(&target->head, entry, entry->next, &entry) == false) {\n\t\tif (ck_pr_load_ptr(&entry) == NULL)\n\t\t\tbreak;\n\n\t\tck_hp_set_fence(record, 0, entry);\n\t\tif (entry != ck_pr_load_ptr(&target->head))\n\t\t\tcontinue;\n\n\t\tck_backoff_eb(&backoff);\n\t}\n\n\treturn (entry);\n}\n\nstatic void *\nthread(void *unused CK_CC_UNUSED)\n{\n\tstruct node *entry, *e;\n\tunsigned int i;\n\tck_hp_record_t record;\n\tvoid **pointers;\n\tstack_entry_t *s;\n\tunsigned int tid = ck_pr_faa_uint(&global_tid, 1) + 1;\n\tunsigned int r = (unsigned int)(tid + 1) * 0x5bd1e995;\n\n\tunused = NULL;\n\tpointers = malloc(sizeof(void *));\n\tck_hp_register(&stack_hp, &record, pointers);\n\n\tif (aff_iterate(&a)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) < n_threads)\n\t\tck_pr_stall();\n\n\tfor (i = 0; i < PAIRS; i++) {\n\t\tr ^= r << 6; r ^= r >> 21; r ^= r << 7;\n\n\t\tif (r & 0x1000) {\n\t\t\tentry = malloc(sizeof(struct node));\n\t\t\tassert(entry);\n\t\t\tstack_push_mpmc(&stack, &entry->stack_entry);\n\t\t\tck_pr_inc_uint(&pushs);\n\t\t} else {\n\t\t\ts = stack_pop_mpmc(&record, &stack);\n\t\t\tif (s == NULL)\n\t\t\t\tcontinue;\n\n\t\t\te = stack_container(s);\n\t\t\tck_hp_free(&record, &e->hazard, e, s);\n\t\t\tck_pr_inc_uint(&pops);\n\t\t}\n\t}\n\n\tck_pr_inc_uint(&e_barrier);\n\twhile (ck_pr_load_uint(&e_barrier) < n_threads);\n\n\treturn (NULL);\n}\n\nstatic void\ndestructor(void *p)\n{\n\tfree(p);\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <threads> <threshold> <delta>\\n\");\n\t}\n\n\tn_threads = atoi(argv[1]);\n\tthreshold = atoi(argv[2]);\n\ta.delta = atoi(argv[3]);\n\ta.request = 0;\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\n\tck_hp_init(&stack_hp, 1, threshold, destructor);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_create(threads + i, NULL, thread, NULL);\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(threads[i], NULL);\n\n\tfprintf(stderr, \"Push: %u\\nPop: %u\\n\", pushs, pops);\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hp/validate/serial.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <stdbool.h>\n#include <stddef.h>\n#include <ck_hp.h>\n\n#include \"../../common.h\"\n\nstruct entry {\n\tunsigned int value;\n\tck_hp_hazard_t hazard;\n};\n\nstatic void\ndestructor(void *pointer)\n{\n\n\tfprintf(stderr, \"Free %p\\n\", pointer);\n\tfree(pointer);\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tck_hp_t state;\n\tck_hp_record_t record[2];\n\tvoid **pointers;\n\tstruct entry *entry, *other;\n\n\t(void)argc;\n\t(void)argv;\n\n\tck_hp_init(&state, 1, 1, destructor);\n\n\tpointers = malloc(sizeof(void *));\n\tif (pointers == NULL) {\n\t\tck_error(\"ERROR: Failed to allocate slot.\\n\");\n\t}\n\tck_hp_register(&state, &record[0], pointers);\n\tck_hp_reclaim(&record[0]);\n\n\tentry = malloc(sizeof *entry);\n\tck_hp_set(&record[0], 0, entry);\n\tck_hp_reclaim(&record[0]);\n\tck_hp_free(&record[0], &entry->hazard, entry, entry);\n\tck_hp_reclaim(&record[0]);\n\tck_hp_set(&record[0], 0, NULL);\n\tck_hp_reclaim(&record[0]);\n\n\tentry = malloc(sizeof *entry);\n\tck_hp_set(&record[0], 0, entry);\n\tck_hp_reclaim(&record[0]);\n\tck_hp_free(&record[0], &entry->hazard, entry, entry);\n\tck_hp_reclaim(&record[0]);\n\tck_hp_set(&record[0], 0, NULL);\n\tck_hp_reclaim(&record[0]);\n\n\tpointers = malloc(sizeof(void *));\n\tif (pointers == NULL) {\n\t\tck_error(\"ERROR: Failed to allocate slot.\\n\");\n\t}\n\tck_hp_register(&state, &record[1], pointers);\n\tck_hp_reclaim(&record[1]);\n\n\tentry = malloc(sizeof *entry);\n\tck_hp_set(&record[1], 0, entry);\n\tck_hp_reclaim(&record[1]);\n\tck_hp_free(&record[1], &entry->hazard, entry, entry);\n\tck_hp_reclaim(&record[1]);\n\tck_hp_set(&record[1], 0, NULL);\n\tck_hp_reclaim(&record[1]);\n\n\tprintf(\"Allocating entry and freeing in other HP record...\\n\");\n\tentry = malloc(sizeof *entry);\n\tentry->value = 42;\n\tck_hp_set(&record[0], 0, entry);\n\tck_hp_free(&record[1], &entry->hazard, entry, entry);\n\tck_pr_store_uint(&entry->value, 1);\n\n\tother = malloc(sizeof *other);\n\tother->value = 24;\n\tck_hp_set(&record[1], 0, other);\n\tck_hp_free(&record[0], &other->hazard, other, other);\n\tck_pr_store_uint(&other->value, 32);\n\tck_hp_set(&record[0], 0, NULL);\n\tck_hp_reclaim(&record[1]);\n\tck_hp_set(&record[1], 0, NULL);\n\tck_hp_reclaim(&record[0]);\n\tck_hp_reclaim(&record[1]);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hs/benchmark/apply.c",
    "content": "/*\n * Copyright 2014 Samy Al Bahra.\n * Copyright 2014 Backtrace I/O, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_hs.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n#include \"../../common.h\"\n#include \"../../../src/ck_ht_hash.h\"\n\nstatic ck_hs_t hs;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\nstatic unsigned long global_seed;\n\nstatic void *\nhs_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\n\tfree(p);\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\th = (unsigned long)MurmurHash64A(c, strlen(c), seed);\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void\nset_destroy(void)\n{\n\n\tck_hs_destroy(&hs);\n\treturn;\n}\n\nstatic void\nset_init(unsigned int size, unsigned int mode)\n{\n\n\tif (ck_hs_init(&hs, CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC | mode, hs_hash, hs_compare,\n\t    &my_allocator, size, global_seed) == false) {\n\t\tperror(\"ck_hs_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic size_t\nset_count(void)\n{\n\n\treturn ck_hs_count(&hs);\n}\n\nstatic bool\nset_reset(void)\n{\n\n\treturn ck_hs_reset(&hs);\n}\n\nstatic void *\ntest_apply(void *key, void *closure)\n{\n\n\t(void)key;\n\n\treturn closure;\n}\n\nstatic void\nrun_test(const char *file, size_t r, unsigned int size, unsigned int mode)\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, gp, agp;\n\tstruct ck_hs_stat st;\n\tchar **t;\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(file, \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\tset_init(size, mode);\n\tfor (i = 0; i < keys_length; i++) {\n\t\tunsigned long h = CK_HS_HASH(&hs, hs_hash, keys[i]);\n\n\t\tif (ck_hs_get(&hs, h, keys[i]) == false) {\n\t\t\tif (ck_hs_put(&hs, h, keys[i]) == false)\n\t\t\t\tck_error(\"ERROR: Failed get to put workload.\\n\");\n\t\t} else {\n\t\t\td++;\n\t\t}\n\t}\n\tck_hs_stat(&hs, &st);\n\n\tfprintf(stderr, \"# %zu entries stored, %u duplicates, %u probe.\\n\",\n\t    set_count(), d, st.probe_maximum);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false)\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tunsigned long h = CK_HS_HASH(&hs, hs_hash, keys[i]);\n\n\t\t\tif (ck_hs_get(&hs, h, keys[i]) == false &&\n\t\t\t    ck_hs_put(&hs, h, keys[i]) == false) {\n\t\t\t\tck_error(\"ERROR: Failed get to put workload.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tgp = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false)\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tunsigned long h = CK_HS_HASH(&hs, hs_hash, keys[i]);\n\n\t\t\tif (ck_hs_apply(&hs, h, keys[i], test_apply, (void *)keys[i]) == false)\n\t\t\t\tck_error(\"ERROR: Failed in apply workload.\\n\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tagp = a / (r * keys_length);\n\n\tfclose(fp);\n\n\tfor (i = 0; i < keys_length; i++) {\n\t\tfree(keys[i]);\n\t}\n\n\tprintf(\"Get to put: %\" PRIu64 \" ticks\\n\", gp);\n\tprintf(\"     Apply: %\" PRIu64 \" ticks\\n\", agp);\n\n\tfree(keys);\n\tkeys_length = 0;\n\tset_destroy();\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int r, size;\n\n\tcommon_srand48((long int)time(NULL));\n\tif (argc < 2) {\n\t\tck_error(\"Usage: ck_hs <dictionary> [<repetitions> <initial size>]\\n\");\n\t}\n\n\tr = 16;\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tsize = 8;\n\tif (argc >= 4)\n\t\tsize = atoi(argv[3]);\n\n\tglobal_seed = common_lrand48();\n\trun_test(argv[1], r, size, 0);\n\n\tprintf(\"\\n==============================================\\n\"\n\t    \"Delete mode\\n\"\n\t    \"==============================================\\n\");\n\trun_test(argv[1], r, size, CK_HS_MODE_DELETE);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hs/benchmark/parallel_bytestring.c",
    "content": "/*\n * Copyright 2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"../../common.h\"\n#include <ck_hs.h>\n#include \"../../../src/ck_ht_hash.h\"\n#include <assert.h>\n#include <ck_epoch.h>\n#include <ck_malloc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <unistd.h>\n\nstatic ck_hs_t hs CK_CC_CACHELINE;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\nstatic ck_epoch_t epoch_hs;\nstatic ck_epoch_record_t epoch_wr;\nstatic int n_threads;\nstatic bool next_stage;\n\nenum state {\n\tHS_STATE_STOP = 0,\n\tHS_STATE_GET,\n\tHS_STATE_STRICT_REPLACEMENT,\n\tHS_STATE_DELETION,\n\tHS_STATE_REPLACEMENT,\n\tHS_STATE_COUNT\n};\n\nstatic ck_spinlock_t mtx = CK_SPINLOCK_INITIALIZER;\nstatic struct affinity affinerator = AFFINITY_INITIALIZER;\nstatic uint64_t accumulator[HS_STATE_COUNT];\nstatic int barrier[HS_STATE_COUNT];\nstatic int state;\n\nstruct hs_epoch {\n\tck_epoch_entry_t epoch_entry;\n};\n\nCOMMON_ALARM_DECLARE_GLOBAL(hs_alarm, alarm_event, next_stage)\n\nstatic void\nalarm_handler(int s)\n{\n\n\t(void)s;\n\tnext_stage = true;\n\treturn;\n}\n\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\th = (unsigned long)MurmurHash64A(c, strlen(c), seed);\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void\nhs_destroy(ck_epoch_entry_t *e)\n{\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nhs_malloc(size_t r)\n{\n\tck_epoch_entry_t *b;\n\n\tb = malloc(sizeof(*b) + r);\n\treturn b + 1;\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\tstruct hs_epoch *e = p;\n\n\t(void)b;\n\n\tif (r == true) {\n\t\t/* Destruction requires safe memory reclamation. */\n\t\tck_epoch_call(&epoch_wr, &(--e)->epoch_entry, hs_destroy);\n\t} else {\n\t\tfree(--e);\n\t}\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nstatic void\nset_init(void)\n{\n\tunsigned int mode = CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC;\n\n#ifdef HS_DELETE\n\tmode |= CK_HS_MODE_DELETE;\n#endif\n\n\tck_epoch_init(&epoch_hs);\n\tck_epoch_register(&epoch_hs, &epoch_wr, NULL);\n\tcommon_srand48((long int)time(NULL));\n\tif (ck_hs_init(&hs, mode, hs_hash, hs_compare, &my_allocator, 65536, common_lrand48()) == false) {\n\t\tperror(\"ck_hs_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\nset_remove(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn (bool)ck_hs_remove(&hs, h, value);\n}\n\nstatic bool\nset_replace(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_set(&hs, h, value, &previous);\n}\n\nstatic bool\nset_swap(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_fas(&hs, h, value, &previous);\n}\n\nstatic void *\nset_get(const char *value)\n{\n\tunsigned long h;\n\tvoid *v;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\tv = ck_hs_get(&hs, h, value);\n\treturn v;\n}\n\nstatic bool\nset_insert(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_put(&hs, h, value);\n}\n\nstatic size_t\nset_count(void)\n{\n\n\treturn ck_hs_count(&hs);\n}\n\nstatic bool\nset_reset(void)\n{\n\n\treturn ck_hs_reset(&hs);\n}\n\nstatic void *\nreader(void *unused)\n{\n\tsize_t i;\n\tck_epoch_record_t epoch_record;\n\tint state_previous = HS_STATE_STOP;\n\tint n_state = 0;\n\tuint64_t s, j, a;\n\n\t(void)unused;\n\tif (aff_iterate(&affinerator) != 0)\n\t\tperror(\"WARNING: Failed to affine thread\");\n\n\ts = j = a = 0;\n\tck_epoch_register(&epoch_hs, &epoch_record, NULL);\n\tfor (;;) {\n\t\tj++;\n\t\tck_epoch_begin(&epoch_record, NULL);\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tchar *r;\n\n\t\t\tr = set_get(keys[i]);\n\t\t\tif (r == NULL) {\n\t\t\t\tif (n_state == HS_STATE_STRICT_REPLACEMENT) {\n\t\t\t\t\tck_error(\"ERROR: Did not find during replacement: %s\\n\", keys[i]);\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (strcmp(r, keys[i]) == 0)\n\t\t\t\tcontinue;\n\n\t\t\tck_error(\"ERROR: Found invalid value: [%s] but expected [%s]\\n\", (char *)r, keys[i]);\n\t\t}\n\t\ta += rdtsc() - s;\n\t\tck_epoch_end(&epoch_record, NULL);\n\n\t\tn_state = ck_pr_load_int(&state);\n\t\tif (n_state != state_previous) {\n\t\t\tck_spinlock_lock(&mtx);\n\t\t\taccumulator[state_previous] += a / (j * keys_length);\n\t\t\tck_spinlock_unlock(&mtx);\n\n\t\t\tck_pr_inc_int(&barrier[state_previous]);\n\t\t\twhile (ck_pr_load_int(&barrier[state_previous]) != n_threads + 1)\n\t\t\t\tck_pr_stall();\n\n\t\t\tstate_previous = n_state;\n\t\t\ts = j = a = 0;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nstatic uint64_t\nacc(size_t i)\n{\n\tuint64_t r;\n\n\tck_spinlock_lock(&mtx);\n\tr = accumulator[i];\n\tck_spinlock_unlock(&mtx);\n\n\treturn r;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j, r;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, repeated;\n\tchar **t;\n\tpthread_t *readers;\n\tdouble p_r, p_d;\n\n\tCOMMON_ALARM_DECLARE_LOCAL(hs_alarm, alarm_event)\n\n\tr = 20;\n\ts = 8;\n\tp_d = 0.5;\n\tp_r = 0.5;\n\tn_threads = CORES - 1;\n\n\tif (argc < 2) {\n\t\tck_error(\"Usage: parallel <dictionary> [<interval length> <initial size> <readers>\\n\"\n\t\t    \" <probability of replacement> <probability of deletion> <epoch threshold>]\\n\");\n\t}\n\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tif (argc >= 4)\n\t\ts = (uint64_t)atoi(argv[3]);\n\n\tif (argc >= 5) {\n\t\tn_threads = atoi(argv[4]);\n\t\tif (n_threads < 1) {\n\t\t\tck_error(\"ERROR: Number of readers must be >= 1.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 6) {\n\t\tp_r = atof(argv[5]) / 100.00;\n\t\tif (p_r < 0) {\n\t\t\tck_error(\"ERROR: Probability of replacement must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 7) {\n\t\tp_d = atof(argv[6]) / 100.00;\n\t\tif (p_d < 0) {\n\t\t\tck_error(\"ERROR: Probability of deletion must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tCOMMON_ALARM_INIT(hs_alarm, alarm_event, r)\n\n\taffinerator.delta = 1;\n\treaders = malloc(sizeof(pthread_t) * n_threads);\n\tassert(readers != NULL);\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(argv[1], \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\tset_init();\n\n\tfor (i = 0; i < (size_t)n_threads; i++) {\n\t\tif (pthread_create(&readers[i], NULL, reader, NULL) != 0) {\n\t\t\tck_error(\"ERROR: Failed to create thread %zu.\\n\", i);\n\t\t}\n\t}\n\n\tfor (i = 0; i < keys_length; i++)\n\t\td += set_insert(keys[i]) == false;\n\n\tfprintf(stderr, \" [S] %d readers, 1 writer.\\n\", n_threads);\n\tfprintf(stderr, \" [S] %zu entries stored and %u duplicates.\\n\\n\",\n\t    set_count(), d);\n\n\tfprintf(stderr, \" ,- BASIC TEST\\n\");\n\tfprintf(stderr, \" | Executing SMR test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += set_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing replacement test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing get test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (set_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\ta = 0;\n\tfprintf(stderr, \" | Executing removal test...\");\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert(keys[i]);\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing negative look-up test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_get(\"\\x50\\x03\\x04\\x05\\x06\\x10\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tck_epoch_record_t epoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\n\tfprintf(stderr, \" ,- READER CONCURRENCY\\n\");\n\tfprintf(stderr, \" | Executing reader test...\");\n\n\tck_pr_store_int(&state, HS_STATE_GET);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_STOP]) != n_threads)\n\t\tck_pr_stall();\n\tck_pr_inc_int(&barrier[HS_STATE_STOP]);\n\tcommon_sleep(r);\n\tck_pr_store_int(&state, HS_STATE_STRICT_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_GET]) != n_threads)\n\t\tck_pr_stall();\n\n\tfprintf(stderr, \"done (reader = %\" PRIu64 \" ticks)\\n\",\n\t    acc(HS_STATE_GET) / n_threads);\n\n\tfprintf(stderr, \" | Executing strict replacement test...\");\n\n\ta = repeated = 0;\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tck_pr_inc_int(&barrier[HS_STATE_GET]);\n\tfor (;;) {\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (i & 1) {\n\t\t\t\tset_replace(keys[i]);\n\t\t\t} else {\n\t\t\t\tset_swap(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tck_pr_store_int(&state, HS_STATE_DELETION);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_STRICT_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\tset_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), acc(HS_STATE_STRICT_REPLACEMENT) / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing deletion test (%.2f)...\", p_d * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HS_STATE_STRICT_REPLACEMENT]);\n\tfor (;;) {\n\t\tdouble delete;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\tset_remove(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HS_STATE_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_DELETION]) != n_threads)\n\t\tck_pr_stall();\n\n\tset_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), acc(HS_STATE_DELETION) / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing replacement test (%.2f)...\", p_r * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HS_STATE_DELETION]);\n\tfor (;;) {\n\t\tdouble delete, replace;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\tset_remove(keys[i]);\n\t\t\t} else {\n\t\t\t\tdelete = 0.0;\n\t\t\t}\n\n\t\t\tif (p_r != 0.0) {\n\t\t\t\treplace = common_drand48();\n\t\t\t\tif (replace <= p_r) {\n\t\t\t\t\tif ((i & 1) || (delete <= p_d)) {\n\t\t\t\t\t\tset_replace(keys[i]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tset_swap(keys[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HS_STATE_STOP);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\tset_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), acc(HS_STATE_REPLACEMENT) / n_threads);\n\n\tck_pr_inc_int(&barrier[HS_STATE_REPLACEMENT]);\n\tepoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hs/benchmark/serial.c",
    "content": "/*\n * Copyright 2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_hs.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n#include \"../../common.h\"\n#include \"../../../src/ck_ht_hash.h\"\n\nstatic ck_hs_t hs;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\nstatic unsigned long global_seed;\n\nstatic void *\nhs_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\n\tfree(p);\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\th = (unsigned long)MurmurHash64A(c, strlen(c), seed);\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void\nset_destroy(void)\n{\n\n\tck_hs_destroy(&hs);\n\treturn;\n}\n\nstatic void\nset_init(unsigned int size, unsigned int mode)\n{\n\n\tif (ck_hs_init(&hs, CK_HS_MODE_OBJECT | CK_HS_MODE_SPMC | mode, hs_hash, hs_compare,\n\t    &my_allocator, size, global_seed) == false) {\n\t\tperror(\"ck_hs_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\nset_remove(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_remove(&hs, h, value) != NULL;\n}\n\nstatic bool\nset_swap(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_fas(&hs, h, value, &previous);\n}\n\nstatic bool\nset_replace(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\tck_hs_set(&hs, h, value, &previous);\n\treturn previous == value;\n}\n\nstatic void *\nset_get(const char *value)\n{\n\tunsigned long h;\n\tvoid *v;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\tv = ck_hs_get(&hs, h, value);\n\treturn v;\n}\n\nstatic bool\nset_insert(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_put(&hs, h, value);\n}\n\nstatic bool\nset_insert_unique(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_HS_HASH(&hs, hs_hash, value);\n\treturn ck_hs_put_unique(&hs, h, value);\n}\n\nstatic size_t\nset_count(void)\n{\n\n\treturn ck_hs_count(&hs);\n}\n\nstatic bool\nset_reset(void)\n{\n\n\treturn ck_hs_reset(&hs);\n}\n\nstatic void\nset_gc(void)\n{\n\n\tck_hs_gc(&hs, 0, 0);\n\treturn;\n}\n\nstatic void\nset_rebuild(void)\n{\n\n\tck_hs_rebuild(&hs);\n\treturn;\n}\n\nstatic void\nkeys_shuffle(char **k)\n{\n\tsize_t i, j;\n\tchar *t;\n\n\tfor (i = keys_length; i > 1; i--) {\n\t\tj = rand() % (i - 1);\n\n\t\tif (j != i - 1) {\n\t\t\tt = k[i - 1];\n\t\t\tk[i - 1] = k[j];\n\t\t\tk[j] = t;\n\t\t}\n\t}\n\n\treturn;\n}\n\nstatic void\nrun_test(const char *file, size_t r, unsigned int size, unsigned int mode)\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, ri, si, ai, sr, rg, sg, ag, sd, ng, ss, sts, su, sgc, sb;\n\tstruct ck_hs_stat st;\n\tchar **t;\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(file, \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\tset_init(size, mode);\n\tfor (i = 0; i < keys_length; i++)\n\t\td += set_insert(keys[i]) == false;\n\tck_hs_stat(&hs, &st);\n\n\tfprintf(stderr, \"# %zu entries stored, %u duplicates, %u probe.\\n\",\n\t    set_count(), d, st.probe_maximum);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = keys_length; i > 0; i--)\n\t\t\td += set_insert(keys[i - 1]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tri = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += set_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsi = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tkeys_shuffle(keys);\n\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += set_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tai = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_swap(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tss = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsr = a / (r * keys_length);\n\n\tset_reset();\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_insert(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = keys_length; i > 0; i--) {\n\t\t\tif (set_get(keys[i - 1]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\trg = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (set_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsg = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tkeys_shuffle(keys);\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (set_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tag = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert(keys[i]);\n\t}\n\tsd = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_get(\"\\x50\\x03\\x04\\x05\\x06\\x10\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tng = a / (r * keys_length);\n\n\tset_reset();\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_insert(keys[i]);\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t}\n\tsts = a / (r * keys_length);\n\n\tset_reset();\n\n\t/* Prune duplicates. */\n\tfor (i = 0; i < keys_length; i++) {\n\t\tif (set_insert(keys[i]) == true)\n\t\t\tcontinue;\n\n\t\tfree(keys[i]);\n\t\tkeys[i] = keys[--keys_length];\n\t}\n\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert_unique(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t}\n\tsu = a / (r * keys_length);\n\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_insert_unique(keys[i]);\n\n\tfor (i = 0; i < keys_length / 2; i++)\n\t\tset_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tset_gc();\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsgc = a / r;\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tset_rebuild();\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsb = a / r;\n\n\tprintf(\"%zu \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \"\\n\",\n\t    keys_length, ri, si, ai, ss, sr, rg, sg, ag, sd, ng, sts, su, sgc, sb);\n\n\tfclose(fp);\n\n\tfor (i = 0; i < keys_length; i++) {\n\t\tfree(keys[i]);\n\t}\n\n\tfree(keys);\n\tkeys_length = 0;\n\tset_destroy();\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int r, size;\n\n\tcommon_srand48((long int)time(NULL));\n\tif (argc < 2) {\n\t\tck_error(\"Usage: ck_hs <dictionary> [<repetitions> <initial size>]\\n\");\n\t}\n\n\tr = 16;\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tsize = 8;\n\tif (argc >= 4)\n\t\tsize = atoi(argv[3]);\n\n\tglobal_seed = common_lrand48();\n\trun_test(argv[1], r, size, 0);\n\trun_test(argv[1], r, size, CK_HS_MODE_DELETE);\n\tfprintf(stderr, \"#    reverse_insertion serial_insertion random_insertion serial_swap \"\n\t    \"serial_replace reverse_get serial_get random_get serial_remove negative_get tombstone \"\n\t    \"set_unique gc rebuild\\n\\n\");\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_hs/validate/serial.c",
    "content": "/*\n * Copyright 2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_hs.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"../../common.h\"\n\nstatic void *\nhs_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\tfree(p);\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nconst char *test[] = { \"Samy\", \"Al\", \"Bahra\", \"dances\", \"in\", \"the\", \"wind.\", \"Once\",\n                       \"upon\", \"a\", \"time\", \"his\", \"gypsy\", \"ate\", \"one\", \"itsy\",\n                       \"bitsy\", \"spider.\", \"What\", \"goes\", \"up\", \"must\",\n                       \"come\", \"down.\", \"What\", \"is\", \"down\", \"stays\",\n                       \"down.\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\",\n                       \"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\" };\n\nconst char *negative = \"negative\";\n\n/* Purposefully crappy hash function. */\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\t(void)seed;\n\th = c[0];\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void *\ntest_ip(void *key, void *closure)\n{\n\tconst char *a = key;\n\tconst char *b = closure;\n\n\tif (strcmp(a, b) != 0)\n\t\tck_error(\"Mismatch: %s != %s\\n\", a, b);\n\n\treturn closure;\n}\n\nstatic void *\ntest_negative(void *key, void *closure)\n{\n\n\t(void)closure;\n\tif (key != NULL)\n\t\tck_error(\"ERROR: Apply callback expects NULL argument instead of [%s]\\n\", key);\n\n\treturn NULL;\n}\n\nstatic void *\ntest_unique(void *key, void *closure)\n{\n\n\tif (key != NULL)\n\t\tck_error(\"ERROR: Apply callback expects NULL argument instead of [%s]\\n\", key);\n\n\treturn closure;\n}\n\nstatic void *\ntest_remove(void *key, void *closure)\n{\n\n\t(void)key;\n\t(void)closure;\n\n\treturn NULL;\n}\n\nstatic void\nrun_test(unsigned int is, unsigned int ad)\n{\n\tck_hs_t hs[16];\n\tconst size_t size = sizeof(hs) / sizeof(*hs);\n\tsize_t i, j;\n\tconst char *blob = \"#blobs\";\n\tunsigned long h;\n\tck_hs_iterator_t it;\n\n\tif (ck_hs_init(&hs[0], CK_HS_MODE_SPMC | CK_HS_MODE_OBJECT | ad, hs_hash, hs_compare, &my_allocator, is, 6602834) == false)\n\t\tck_error(\"ck_hs_init\\n\");\n\n\tfor (j = 0; j < size; j++) {\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tif (ck_hs_get(&hs[j], h, test[i]) != NULL) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (i & 1) {\n\t\t\t\tif (ck_hs_put_unique(&hs[j], h, test[i]) == false)\n\t\t\t\t\tck_error(\"ERROR [%zu]: Failed to insert unique (%s)\\n\", j, test[i]);\n\t\t\t} else if (ck_hs_apply(&hs[j], h, test[i], test_unique, (void *)(uintptr_t)test[i]) == false) {\n\t\t\t\tck_error(\"ERROR: Failed to apply for insertion.\\n\");\n\t\t\t}\n\n\t\t\tif (i & 1) {\n\t\t\t\tif (ck_hs_remove(&hs[j], h, test[i]) == false)\n\t\t\t\t\tck_error(\"ERROR [%zu]: Failed to remove unique (%s)\\n\", j, test[i]);\n\t\t\t} else if (ck_hs_apply(&hs[j], h, test[i], test_remove, NULL) == false) {\n\t\t\t\tck_error(\"ERROR: Failed to remove apply.\\n\");\n\t\t\t}\n\n\t\t\tif (ck_hs_apply(&hs[j], h, test[i], test_negative, (char *)(uintptr_t)test[i]) == false)\n\t\t\t\tck_error(\"ERROR: Failed to apply.\\n\");\n\n\t\t\tbreak;\n\t\t}\n\n\t\tif (ck_hs_gc(&hs[j], 0, 0) == false)\n\t\t\tck_error(\"ERROR: Failed to GC empty set.\\n\");\n\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tck_hs_put(&hs[j], h, test[i]);\n\t\t\tif (ck_hs_put(&hs[j], h, test[i]) == true) {\n\t\t\t\tck_error(\"ERROR [%u] [1]: put must fail on collision (%s).\\n\", is, test[i]);\n\t\t\t}\n\t\t\tif (ck_hs_get(&hs[j], h, test[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: get must not fail after put\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\t/* Test iteration */\n\t\tif (j == 0) { // avoid the blob stuff as it's not in the test array\n\t\t\tck_hs_iterator_init(&it);\n\t\t\tvoid *k = NULL;\n\t\t\tint matches = 0;\n\t\t\tint entries = 0;\n\t\t\twhile(ck_hs_next(&hs[j], &it, &k)) {\n\t\t\t\tentries++;\n\t\t\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\t\t\tint x = strcmp(test[i], (char *)k);\n\t\t\t\t\tif (x == 0) {\n\t\t\t\t\t\tmatches++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (entries != matches) {\n\t\t\t\tck_error(\"Iteration must match all elements, has: %d, matched: %d [%d]\", entries, matches, is);\n\t\t\t}\n\n\t\t\t/* Now test iteration in the face of grows (spmc)*/\n\t\t\tck_hs_iterator_init(&it);\n\t\t\tk = NULL;\n\t\t\tmatches = 0;\n\t\t\tentries = 0;\n\t\t\twhile(ck_hs_next_spmc(&hs[j], &it, &k)) {\n\t\t\t\tentries++;\n\t\t\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\t\t\tint x = strcmp(test[i], (char *)k);\n\t\t\t\t\tif (x == 0) {\n\t\t\t\t\t\tmatches++;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (entries == 20) {\n\t\t\t\t\tck_hs_grow(&hs[j], 128);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (entries != matches) {\n\t\t\t\tck_error(\"After growth, iteration must match all elements, has: %d, matched: %d [%d]\", entries, matches, is);\n\t\t\t}\n\t\t}\n\n\t\t/* Test grow semantics. */\n\t\tck_hs_grow(&hs[j], 128);\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tif (ck_hs_put(&hs[j], h, test[i]) == true) {\n\t\t\t\tck_error(\"ERROR [%u] [2]: put must fail on collision.\\n\", is);\n\t\t\t}\n\n\t\t\tif (ck_hs_get(&hs[j], h, test[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: get must not fail\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\th = blob[0];\n\t\tif (ck_hs_get(&hs[j], h, blob) == NULL) {\n\t\t\tif (j > 0)\n\t\t\t\tck_error(\"ERROR [%u]: Blob must always exist after first.\\n\", is);\n\n\t\t\tif (ck_hs_put(&hs[j], h, blob) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: A unique blob put failed.\\n\", is);\n\t\t\t}\n\t\t} else {\n\t\t\tif (ck_hs_put(&hs[j], h, blob) == true) {\n\t\t\t\tck_error(\"ERROR [%u]: Duplicate blob put succeeded.\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\t/* Grow set and check get semantics. */\n\t\tck_hs_grow(&hs[j], 512);\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tif (ck_hs_get(&hs[j], h, test[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: get must not fail\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\t/* Delete and check negative membership. */\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\tvoid *r;\n\n\t\t\th = test[i][0];\n\t\t\tif (ck_hs_get(&hs[j], h, test[i]) == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tif (r = ck_hs_remove(&hs[j], h, test[i]), r == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: remove must not fail\\n\", is);\n\t\t\t}\n\n\t\t\tif (strcmp(r, test[i]) != 0) {\n\t\t\t\tck_error(\"ERROR [%u]: Removed incorrect node (%s != %s)\\n\", (char *)r, test[i], is);\n\t\t\t}\n\t\t}\n\n\t\t/* Test replacement semantics. */\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\tvoid *r;\n\t\t\tbool d;\n\n\t\t\th = test[i][0];\n\t\t\td = ck_hs_get(&hs[j], h, test[i]) != NULL;\n\t\t\tif (ck_hs_set(&hs[j], h, test[i], &r) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: Failed to set\\n\", is);\n\t\t\t}\n\n\t\t\t/* Expected replacement. */\n\t\t\tif (d == true && (r == NULL || strcmp(r, test[i]) != 0)) {\n\t\t\t\tck_error(\"ERROR [%u]: Incorrect previous value: %s != %s\\n\",\n\t\t\t\t    is, test[i], (char *)r);\n\t\t\t}\n\n\t\t\t/* Replacement should succeed. */\n\t\t\tif (ck_hs_fas(&hs[j], h, test[i], &r) == false)\n\t\t\t\tck_error(\"ERROR [%u]: ck_hs_fas must succeed.\\n\", is);\n\n\t\t\tif (strcmp(r, test[i]) != 0) {\n\t\t\t\tck_error(\"ERROR [%u]: Incorrect replaced value: %s != %s\\n\",\n\t\t\t\t    is, test[i], (char *)r);\n\t\t\t}\n\n\t\t\tif (ck_hs_fas(&hs[j], h, negative, &r) == true)\n\t\t\t\tck_error(\"ERROR [%u]: Replacement of negative should fail.\\n\", is);\n\n\t\t\tif (ck_hs_set(&hs[j], h, test[i], &r) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: Failed to set [1]\\n\", is);\n\t\t\t}\n\n\t\t\tif (strcmp(r, test[i]) != 0) {\n\t\t\t\tck_error(\"ERROR [%u]: Invalid &hs[j]: %s != %s\\n\", is, test[i], (char *)r);\n\t\t\t}\n\n\t\t\t/* Attempt in-place mutation. */\n\t\t\tif (ck_hs_apply(&hs[j], h, test[i], test_ip, (void *)(uintptr_t)test[i]) == false)\n\t\t\t\tck_error(\"ERROR [%u]: Failed to apply: %s != %s\\n\", is, (char *)r, test[i]);\n\n\t\t\td = ck_hs_get(&hs[j], h, test[i]) != NULL;\n\t\t\tif (d == false)\n\t\t\t\tck_error(\"ERROR [%u]: Expected [%s] to exist.\\n\", is, test[i]);\n\t\t}\n\n\t\tif (j == size - 1)\n\t\t\tbreak;\n\n\t\tif (ck_hs_move(&hs[j + 1], &hs[j], hs_hash, hs_compare, &my_allocator) == false)\n\t\t\tck_error(\"Failed to move hash table\");\n\n\t\tif (j & 1) {\n\t\t\tck_hs_gc(&hs[j + 1], 0, 0);\n\t\t} else {\n\t\t\tck_hs_gc(&hs[j + 1], 26, 26);\n\t\t}\n\n\t\tif (ck_hs_rebuild(&hs[j + 1]) == false)\n\t\t\tck_error(\"Failed to rebuild\");\n\t}\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\tunsigned int k;\n\n\tfor (k = 16; k <= 64; k <<= 1) {\n\t\trun_test(k, 0);\n\t\trun_test(k, CK_HS_MODE_DELETE);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ht/benchmark/parallel_bytestring.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_ht.h>\n\n\n#include <assert.h>\n#include <ck_epoch.h>\n#include <ck_malloc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\nstatic ck_ht_t ht CK_CC_CACHELINE;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\nstatic ck_epoch_t epoch_ht;\nstatic ck_epoch_record_t epoch_wr;\nstatic int n_threads;\nstatic bool next_stage;\n\nenum state {\n\tHT_STATE_STOP = 0,\n\tHT_STATE_GET,\n\tHT_STATE_STRICT_REPLACEMENT,\n\tHT_STATE_DELETION,\n\tHT_STATE_REPLACEMENT,\n\tHT_STATE_COUNT\n};\n\nstatic struct affinity affinerator = AFFINITY_INITIALIZER;\nstatic uint64_t accumulator[HT_STATE_COUNT];\nstatic ck_spinlock_t accumulator_mutex = CK_SPINLOCK_INITIALIZER;\nstatic int barrier[HT_STATE_COUNT];\nstatic int state;\n\nstruct ht_epoch {\n\tck_epoch_entry_t epoch_entry;\n};\n\nCOMMON_ALARM_DECLARE_GLOBAL(ht_alarm, alarm_event, next_stage)\n\nstatic void\nalarm_handler(int s)\n{\n\n\t(void)s;\n\tnext_stage = true;\n\treturn;\n}\n\nstatic void\nht_destroy(ck_epoch_entry_t *e)\n{\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nht_malloc(size_t r)\n{\n\tck_epoch_entry_t *b;\n\n\tb = malloc(sizeof(*b) + r);\n\treturn b + 1;\n}\n\nstatic void\nht_free(void *p, size_t b, bool r)\n{\n\tstruct ht_epoch *e = p;\n\n\t(void)b;\n\n\tif (r == true) {\n\t\t/* Destruction requires safe memory reclamation. */\n\t\tck_epoch_call(&epoch_wr, &(--e)->epoch_entry, ht_destroy);\n\t} else {\n\t\tfree(--e);\n\t}\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = ht_malloc,\n\t.free = ht_free\n};\n\nstatic void\ntable_init(void)\n{\n\tunsigned int mode = CK_HT_MODE_BYTESTRING;\n\n#ifdef HT_DELETE\n\tmode |= CK_HT_WORKLOAD_DELETE;\n#endif\n\n\tck_epoch_init(&epoch_ht);\n\tck_epoch_register(&epoch_ht, &epoch_wr, NULL);\n\tcommon_srand48((long int)time(NULL));\n\tif (ck_ht_init(&ht, mode, NULL, &my_allocator, 8, common_lrand48()) == false) {\n\t\tperror(\"ck_ht_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\ntable_remove(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_key_set(&entry, value, l);\n\treturn ck_ht_remove_spmc(&ht, h, &entry);\n}\n\nstatic bool\ntable_replace(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_set(&entry, h, value, l, \"REPLACED\");\n\treturn ck_ht_set_spmc(&ht, h, &entry);\n}\n\nstatic void *\ntable_get(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_key_set(&entry, value, l);\n\tif (ck_ht_get_spmc(&ht, h, &entry) == true)\n\t\treturn ck_ht_entry_value(&entry);\n\n\treturn NULL;\n}\n\nstatic bool\ntable_insert(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_set(&entry, h, value, l, value);\n\treturn ck_ht_put_spmc(&ht, h, &entry);\n}\n\nstatic size_t\ntable_count(void)\n{\n\n\treturn ck_ht_count(&ht);\n}\n\nstatic bool\ntable_reset(void)\n{\n\n\treturn ck_ht_reset_spmc(&ht);\n}\n\nstatic void *\nreader(void *unused)\n{\n\tsize_t i;\n\tck_epoch_record_t epoch_record;\n\tint state_previous = HT_STATE_STOP;\n\tint n_state;\n\tuint64_t s, j, a;\n\n\t(void)unused;\n\tif (aff_iterate(&affinerator) != 0)\n\t\tperror(\"WARNING: Failed to affine thread\");\n\n\ts = j = a = 0;\n\tck_epoch_register(&epoch_ht, &epoch_record, NULL);\n\tfor (;;) {\n\t\tj++;\n\t\tck_epoch_begin(&epoch_record, NULL);\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tchar *r;\n\n\t\t\tr = table_get(keys[i]);\n\t\t\tif (r == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tif (strcmp(r, \"REPLACED\") == 0)\n\t\t\t\tcontinue;\n\n\t\t\tif (strcmp(r, keys[i]) == 0)\n\t\t\t\tcontinue;\n\n\t\t\tck_error(\"ERROR: Found invalid value: [%s] but expected [%s]\\n\", r, keys[i]);\n\t\t}\n\t\ta += rdtsc() - s;\n\t\tck_epoch_end(&epoch_record, NULL);\n\n\t\tn_state = ck_pr_load_int(&state);\n\t\tif (n_state != state_previous) {\n\t\t\tck_spinlock_lock(&accumulator_mutex);\n\t\t\taccumulator[state_previous] += a / (j * keys_length);\n\t\t\tck_spinlock_unlock(&accumulator_mutex);\n\t\t\tck_pr_inc_int(&barrier[state_previous]);\n\t\t\twhile (ck_pr_load_int(&barrier[state_previous]) != n_threads + 1)\n\t\t\t\tck_pr_stall();\n\n\t\t\tstate_previous = n_state;\n\t\t\ts = j = a = 0;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j, r;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, repeated;\n\tchar **t;\n\tpthread_t *readers;\n\tdouble p_r, p_d;\n\n\tCOMMON_ALARM_DECLARE_LOCAL(ht_alarm, alarm_event)\n\n\tr = 20;\n\ts = 8;\n\tp_d = 0.5;\n\tp_r = 0.5;\n\tn_threads = CORES - 1;\n\n\tif (argc < 2) {\n\t\tck_error(\"Usage: parallel <dictionary> [<interval length> <initial size> <readers>\\n\"\n\t\t    \" <probability of replacement> <probability of deletion> <epoch threshold>]\\n\");\n\t}\n\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tif (argc >= 4)\n\t\ts = (uint64_t)atoi(argv[3]);\n\n\tif (argc >= 5) {\n\t\tn_threads = atoi(argv[4]);\n\t\tif (n_threads < 1) {\n\t\t\tck_error(\"ERROR: Number of readers must be >= 1.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 6) {\n\t\tp_r = atof(argv[5]) / 100.00;\n\t\tif (p_r < 0) {\n\t\t\tck_error(\"ERROR: Probability of replacement must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 7) {\n\t\tp_d = atof(argv[6]) / 100.00;\n\t\tif (p_d < 0) {\n\t\t\tck_error(\"ERROR: Probability of deletion must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tCOMMON_ALARM_INIT(ht_alarm, alarm_event, r)\n\n\taffinerator.delta = 1;\n\treaders = malloc(sizeof(pthread_t) * n_threads);\n\tassert(readers != NULL);\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(argv[1], \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\ttable_init();\n\n\tfor (i = 0; i < (size_t)n_threads; i++) {\n\t\tif (pthread_create(&readers[i], NULL, reader, NULL) != 0) {\n\t\t\tck_error(\"ERROR: Failed to create thread %zu.\\n\", i);\n\t\t}\n\t}\n\n\tfor (i = 0; i < keys_length; i++)\n\t\td += table_insert(keys[i]) == false;\n\n\tfprintf(stderr, \" [S] %d readers, 1 writer.\\n\", n_threads);\n\tfprintf(stderr, \" [S] %zu entries stored and %u duplicates.\\n\\n\",\n\t    table_count(), d);\n\n\tfprintf(stderr, \" ,- BASIC TEST\\n\");\n\tfprintf(stderr, \" | Executing SMR test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (table_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += table_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing replacement test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing get test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (table_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\ta = 0;\n\tfprintf(stderr, \" | Executing removal test...\");\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_insert(keys[i]);\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing negative look-up test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_get(\"\\x50\\x03\\x04\\x05\\x06\\x10\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tck_epoch_record_t epoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\n\tfprintf(stderr, \" ,- READER CONCURRENCY\\n\");\n\tfprintf(stderr, \" | Executing reader test...\");\n\n\tck_pr_store_int(&state, HT_STATE_GET);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_STOP]) != n_threads)\n\t\tck_pr_stall();\n\tck_pr_inc_int(&barrier[HT_STATE_STOP]);\n\tcommon_sleep(r);\n\tck_pr_store_int(&state, HT_STATE_STRICT_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_GET]) != n_threads)\n\t\tck_pr_stall();\n\tfprintf(stderr, \"done (reader = %\" PRIu64 \" ticks)\\n\",\n\t    accumulator[HT_STATE_GET] / n_threads);\n\n\tfprintf(stderr, \" | Executing strict replacement test...\");\n\n\ta = repeated = 0;\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tck_pr_inc_int(&barrier[HT_STATE_GET]);\n\tfor (;;) {\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tck_pr_store_int(&state, HT_STATE_DELETION);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_STRICT_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\ttable_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), accumulator[HT_STATE_STRICT_REPLACEMENT] / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing deletion test (%.2f)...\", p_d * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HT_STATE_STRICT_REPLACEMENT]);\n\tfor (;;) {\n\t\tdouble delete;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\ttable_remove(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HT_STATE_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_DELETION]) != n_threads)\n\t\tck_pr_stall();\n\n\ttable_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), accumulator[HT_STATE_DELETION] / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing replacement test (%.2f)...\", p_r * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HT_STATE_DELETION]);\n\tfor (;;) {\n\t\tdouble replace, delete;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\ttable_remove(keys[i]);\n\t\t\t}\n\t\t\tif (p_r != 0.0) {\n\t\t\t\treplace = common_drand48();\n\t\t\t\tif (replace <= p_r)\n\t\t\t\t\ttable_replace(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HT_STATE_STOP);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\ttable_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), accumulator[HT_STATE_REPLACEMENT] / n_threads);\n\n\tck_pr_inc_int(&barrier[HT_STATE_REPLACEMENT]);\n\tepoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ht/benchmark/parallel_direct.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_ht.h>\n\n#include <assert.h>\n#include <ck_epoch.h>\n#include <ck_malloc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\nstatic ck_ht_t ht CK_CC_CACHELINE;\nstatic uintptr_t *keys;\nstatic size_t keys_length = 0;\nstatic ck_epoch_t epoch_ht;\nstatic ck_epoch_record_t epoch_wr;\nstatic int n_threads;\nstatic bool next_stage;\n\nenum state {\n\tHT_STATE_STOP = 0,\n\tHT_STATE_GET,\n\tHT_STATE_STRICT_REPLACEMENT,\n\tHT_STATE_DELETION,\n\tHT_STATE_REPLACEMENT,\n\tHT_STATE_COUNT\n};\n\nstatic struct affinity affinerator = AFFINITY_INITIALIZER;\nstatic uint64_t accumulator[HT_STATE_COUNT];\nstatic ck_spinlock_t accumulator_mutex = CK_SPINLOCK_INITIALIZER;\nstatic int barrier[HT_STATE_COUNT];\nstatic int state;\n\nstruct ht_epoch {\n\tck_epoch_entry_t epoch_entry;\n};\n\nCOMMON_ALARM_DECLARE_GLOBAL(ht_alarm, alarm_event, next_stage)\n\nstatic void\nalarm_handler(int s)\n{\n\n\t(void)s;\n\tnext_stage = true;\n\treturn;\n}\n\nstatic void\nht_destroy(ck_epoch_entry_t *e)\n{\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nht_malloc(size_t r)\n{\n\tck_epoch_entry_t *b;\n\n\tb = malloc(sizeof(*b) + r);\n\treturn b + 1;\n}\n\nstatic void\nht_free(void *p, size_t b, bool r)\n{\n\tstruct ht_epoch *e = p;\n\n\t(void)b;\n\n\tif (r == true) {\n\t\t/* Destruction requires safe memory reclamation. */\n\t\tck_epoch_call(&epoch_wr, &(--e)->epoch_entry, ht_destroy);\n\t} else {\n\t\tfree(--e);\n\t}\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = ht_malloc,\n\t.free = ht_free\n};\n\nstatic void\nhash_function(ck_ht_hash_t *h, const void *key, size_t key_length, uint64_t seed)\n{\n\tconst uintptr_t *value = key;\n\n\t(void)key_length;\n\t(void)seed;\n\th->value = *value;\n\treturn;\n}\n\nstatic void\ntable_init(void)\n{\n\n\tck_epoch_init(&epoch_ht);\n\tck_epoch_register(&epoch_ht, &epoch_wr, NULL);\n\tcommon_srand48((long int)time(NULL));\n\tif (ck_ht_init(&ht, CK_HT_MODE_DIRECT, hash_function, &my_allocator, 8, common_lrand48()) == false) {\n\t\tperror(\"ck_ht_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\ntable_remove(uintptr_t value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\n\tck_ht_hash_direct(&h, &ht, value);\n\tck_ht_entry_key_set_direct(&entry, value);\n\treturn ck_ht_remove_spmc(&ht, h, &entry);\n}\n\nstatic bool\ntable_replace(uintptr_t value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\n\tck_ht_hash_direct(&h, &ht, value);\n\tck_ht_entry_set_direct(&entry, h, value, 6605241);\n\treturn ck_ht_set_spmc(&ht, h, &entry);\n}\n\nstatic uintptr_t\ntable_get(uintptr_t value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\n\tck_ht_hash_direct(&h, &ht, value);\n\tck_ht_entry_key_set_direct(&entry, value);\n\tif (ck_ht_get_spmc(&ht, h, &entry) == true)\n\t\treturn ck_ht_entry_value_direct(&entry);\n\n\treturn 0;\n}\n\nstatic bool\ntable_insert(uintptr_t value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\n\tck_ht_hash_direct(&h, &ht, value);\n\tck_ht_entry_set_direct(&entry, h, value, value);\n\treturn ck_ht_put_spmc(&ht, h, &entry);\n}\n\nstatic size_t\ntable_count(void)\n{\n\n\treturn ck_ht_count(&ht);\n}\n\nstatic bool\ntable_reset(void)\n{\n\n\treturn ck_ht_reset_spmc(&ht);\n}\n\nstatic void *\nht_reader(void *unused)\n{\n\tsize_t i;\n\tck_epoch_record_t epoch_record;\n\tint state_previous = HT_STATE_STOP;\n\tint n_state;\n\tuint64_t s, j, a;\n\n\t(void)unused;\n\tif (aff_iterate(&affinerator) != 0)\n\t\tperror(\"WARNING: Failed to affine thread\");\n\n\ts = j = a = 0;\n\tck_epoch_register(&epoch_ht, &epoch_record, NULL);\n\tfor (;;) {\n\t\tj++;\n\t\tck_epoch_begin(&epoch_record, NULL);\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tuintptr_t r;\n\n\t\t\tr = table_get(keys[i]);\n\t\t\tif (r == 0)\n\t\t\t\tcontinue;\n\n\t\t\tif (r == 6605241)\n\t\t\t\tcontinue;\n\n\t\t\tif (r == keys[i])\n\t\t\t\tcontinue;\n\n\t\t\tck_error(\"ERROR: Found invalid value: [%ju]\\n\",\n\t\t\t    (uintmax_t)r);\n\t\t}\n\t\ta += rdtsc() - s;\n\t\tck_epoch_end(&epoch_record, NULL);\n\n\t\tn_state = ck_pr_load_int(&state);\n\t\tif (n_state != state_previous) {\n\t\t\tck_spinlock_lock(&accumulator_mutex);\n\t\t\taccumulator[state_previous] += a / (j * keys_length);\n\t\t\tck_spinlock_unlock(&accumulator_mutex);\n\t\t\tck_pr_inc_int(&barrier[state_previous]);\n\t\t\twhile (ck_pr_load_int(&barrier[state_previous]) != n_threads + 1)\n\t\t\t\tck_pr_stall();\n\n\t\t\tstate_previous = n_state;\n\t\t\ts = j = a = 0;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tsize_t i, j, r;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, repeated;\n\tpthread_t *readers;\n\tdouble p_r, p_d;\n\n\tCOMMON_ALARM_DECLARE_LOCAL(ht_alarm, alarm_event)\n\n\tr = 20;\n\ts = 8;\n\tp_d = 0.5;\n\tp_r = 0.5;\n\tn_threads = CORES - 1;\n\n\tif (argc < 2) {\n\t\tfprintf(stderr, \"Usage: parallel <#entries> [<interval length> <initial size> <readers>\\n\"\n\t\t    \" <probability of replacement> <probability of deletion> <epoch threshold>]\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tif (argc >= 4)\n\t\ts = (uint64_t)atoi(argv[3]);\n\n\tif (argc >= 5) {\n\t\tn_threads = atoi(argv[4]);\n\t\tif (n_threads < 1) {\n\t\t\tck_error(\"ERROR: Number of readers must be >= 1.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 6) {\n\t\tp_r = atof(argv[5]) / 100.00;\n\t\tif (p_r < 0) {\n\t\t\tck_error(\"ERROR: Probability of replacement must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 7) {\n\t\tp_d = atof(argv[6]) / 100.00;\n\t\tif (p_d < 0) {\n\t\t\tck_error(\"ERROR: Probability of deletion must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tCOMMON_ALARM_INIT(ht_alarm, alarm_event, r)\n\n\taffinerator.delta = 1;\n\treaders = malloc(sizeof(pthread_t) * n_threads);\n\tassert(readers != NULL);\n\n\tkeys_length = (size_t)atoi(argv[1]);\n\tkeys = malloc(sizeof(uintptr_t) * keys_length);\n\tassert(keys != NULL);\n\n\ttable_init();\n\n\tfor (i = 0; i < keys_length; i++) {\n\t\tkeys[i] = (uintptr_t)common_lrand48();\n\t\twhile (keys[i] == 2)\n\t\t\tkeys[i] = (uintptr_t)common_lrand48();\n\t}\n\n\tfor (i = 0; i < (size_t)n_threads; i++) {\n\t\tif (pthread_create(&readers[i], NULL, ht_reader, NULL) != 0) {\n\t\t\tck_error(\"ERROR: Failed to create thread %zu.\\n\", i);\n\t\t}\n\t}\n\n\tfor (i = 0; i < keys_length; i++)\n\t\td += table_insert(keys[i]) == false;\n\n\tfprintf(stderr, \" [S] %zu entries stored and %u duplicates.\\n\\n\",\n\t    table_count(), d);\n\n\tfprintf(stderr, \" ,- BASIC TEST\\n\");\n\tfprintf(stderr, \" | Executing SMR test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (table_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += table_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing replacement test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing get test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (table_get(keys[i]) == 0) {\n\t\t\t\tck_error(\"ERROR: Unexpected 0 value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\ta = 0;\n\tfprintf(stderr, \" | Executing removal test...\");\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_insert(keys[i]);\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing negative look-up test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_get(2);\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tck_epoch_record_t epoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\n\tfprintf(stderr, \" ,- READER CONCURRENCY\\n\");\n\tfprintf(stderr, \" | Executing reader test...\");\n\n\tck_pr_store_int(&state, HT_STATE_GET);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_STOP]) != n_threads)\n\t\tck_pr_stall();\n\tck_pr_inc_int(&barrier[HT_STATE_STOP]);\n\tcommon_sleep(r);\n\tck_pr_store_int(&state, HT_STATE_STRICT_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_GET]) != n_threads)\n\t\tck_pr_stall();\n\tfprintf(stderr, \"done (reader = %\" PRIu64 \" ticks)\\n\",\n\t    accumulator[HT_STATE_GET] / n_threads);\n\n\tfprintf(stderr, \" | Executing strict replacement test...\");\n\n\ta = repeated = 0;\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tck_pr_inc_int(&barrier[HT_STATE_GET]);\n\tfor (;;) {\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tck_pr_store_int(&state, HT_STATE_DELETION);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_STRICT_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\ttable_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), accumulator[HT_STATE_STRICT_REPLACEMENT] / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing deletion test (%.2f)...\", p_d * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HT_STATE_STRICT_REPLACEMENT]);\n\tfor (;;) {\n\t\tdouble delete;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\ttable_remove(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HT_STATE_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_DELETION]) != n_threads)\n\t\tck_pr_stall();\n\n\ttable_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), accumulator[HT_STATE_DELETION] / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing replacement test (%.2f)...\", p_r * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HT_STATE_DELETION]);\n\tfor (;;) {\n\t\tdouble replace, delete;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\ttable_remove(keys[i]);\n\t\t\t}\n\t\t\tif (p_r != 0.0) {\n\t\t\t\treplace = common_drand48();\n\t\t\t\tif (replace <= p_r)\n\t\t\t\t\ttable_replace(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HT_STATE_STOP);\n\twhile (ck_pr_load_int(&barrier[HT_STATE_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\ttable_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), accumulator[HT_STATE_REPLACEMENT] / n_threads);\n\n\tck_pr_inc_int(&barrier[HT_STATE_REPLACEMENT]);\n\tepoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ht/benchmark/serial.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_ht.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n#include \"../../common.h\"\n\nstatic ck_ht_t ht;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\n\nstatic void *\nht_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nht_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\n\tfree(p);\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = ht_malloc,\n\t.free = ht_free\n};\n\nstatic void\ntable_init(void)\n{\n\tunsigned int mode = CK_HT_MODE_BYTESTRING;\n\n#ifdef HT_DELETE\n\tmode |= CK_HT_WORKLOAD_DELETE;\n#endif\n\n\tcommon_srand48((long int)time(NULL));\n\tif (ck_ht_init(&ht, mode, NULL, &my_allocator, 8, common_lrand48()) == false) {\n\t\tperror(\"ck_ht_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\ntable_remove(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_key_set(&entry, value, l);\n\treturn ck_ht_remove_spmc(&ht, h, &entry);\n}\n\nstatic bool\ntable_replace(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_set(&entry, h, value, l, \"REPLACED\");\n\treturn ck_ht_set_spmc(&ht, h, &entry);\n}\n\nstatic void *\ntable_get(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\tvoid *v = NULL;\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_key_set(&entry, value, l);\n\n\tif (ck_ht_get_spmc(&ht, h, &entry) == true) {\n\t\tv = ck_ht_entry_value(&entry);\n\t}\n\treturn v;\n}\n\nstatic bool\ntable_insert(const char *value)\n{\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tsize_t l = strlen(value);\n\n\tck_ht_hash(&h, &ht, value, l);\n\tck_ht_entry_set(&entry, h, value, l, \"VALUE\");\n\treturn ck_ht_put_spmc(&ht, h, &entry);\n}\n\nstatic size_t\ntable_count(void)\n{\n\n\treturn ck_ht_count(&ht);\n}\n\nstatic bool\ntable_gc(void)\n{\n\n\treturn ck_ht_gc(&ht, 0, common_lrand48());\n}\n\nstatic bool\ntable_reset(void)\n{\n\n\treturn ck_ht_reset_spmc(&ht);\n}\n\nstatic void\nkeys_shuffle(char **k)\n{\n\tsize_t i, j;\n\tchar *t;\n\n\tfor (i = keys_length; i > 1; i--) {\n\t\tj = rand() % (i - 1);\n\n\t\tif (j != i - 1) {\n\t\t\tt = k[i - 1];\n\t\t\tk[i - 1] = k[j];\n\t\t\tk[j] = t;\n\t\t}\n\t}\n\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j, r;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, ri, si, ai, sr, rg, sg, ag, sd, ng, gg;\n\tchar **t;\n\tstruct ck_ht_stat st;\n\n\tr = 20;\n\ts = 8;\n\tsrand(time(NULL));\n\n\tif (argc < 2) {\n\t\tck_error(\"Usage: ck_ht <dictionary> [<repetitions> <initial size>]\\n\");\n\t}\n\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tif (argc >= 4)\n\t\ts = (uint64_t)atoi(argv[3]);\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(argv[1], \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\ttable_init();\n\n\tfor (i = 0; i < keys_length; i++)\n\t\td += table_insert(keys[i]) == false;\n\tck_ht_stat(&ht, &st);\n\n\tfprintf(stderr, \"# %zu entries stored, %u duplicates, %\" PRIu64 \" probe.\\n\",\n\t    table_count(), d, st.probe_maximum);\n\n\tfprintf(stderr, \"#    reverse_insertion serial_insertion random_insertion serial_replace reverse_get serial_get random_get serial_remove negative_get garbage_collect\\n\\n\");\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (table_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = keys_length; i > 0; i--)\n\t\t\td += table_insert(keys[i - 1]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tri = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (table_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += table_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsi = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tkeys_shuffle(keys);\n\n\t\tif (table_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += table_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tai = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsr = a / (r * keys_length);\n\n\ttable_reset();\n\tfor (i = 0; i < keys_length; i++)\n\t\ttable_insert(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = keys_length; i > 0; i--) {\n\t\t\tif (table_get(keys[i - 1]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\trg = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (table_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsg = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tkeys_shuffle(keys);\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (table_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tag = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\ttable_insert(keys[i]);\n\t}\n\tsd = a / (r * keys_length);\n\n\tfor (i = 0; i < keys_length / 2; i++)\n\t\ttable_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\ttable_gc();\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tgg = a / r;\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\ttable_get(\"\\x50\\x03\\x04\\x05\\x06\\x10\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tng = a / (r * keys_length);\n\n\tprintf(\"%zu \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \"\\n\",\n\t    keys_length, ri, si, ai, sr, rg, sg, ag, sd, ng, gg);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ht/validate/serial.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_ht.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include \"../../common.h\"\n#include \"../../../src/ck_ht_hash.h\"\n\nstatic size_t hash_times_called = 0;\n\nstatic void *\nht_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nht_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\tfree(p);\n\treturn;\n}\n\nstatic void\nht_hash_wrapper(struct ck_ht_hash *h,\n\tconst void *key,\n\tsize_t length,\n\tuint64_t seed)\n{\n\thash_times_called++;\n\n\th->value = (unsigned long)MurmurHash64A(key, length, seed);\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = ht_malloc,\n\t.free = ht_free\n};\n\nconst char *test[] = {\"Samy\", \"Al\", \"Bahra\", \"dances\", \"in\", \"the\", \"wind.\", \"Once\",\n\t\t\t\"upon\", \"a\", \"time\", \"his\", \"gypsy\", \"ate\", \"one\", \"itsy\",\n\t\t\t    \"bitsy\", \"spider.\", \"What\", \"goes\", \"up\", \"must\",\n\t\t\t\t\"come\", \"down.\", \"What\", \"is\", \"down\", \"stays\",\n\t\t\t\t    \"down.\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\",\n\t\t\t\t\t\"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\"};\n\nstatic uintptr_t direct[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 1, 2, 3, 4, 5, 9 };\n\nconst char *negative = \"negative\";\n\nint\nmain(void)\n{\n\tsize_t i, l;\n\tck_ht_t ht;\n\tck_ht_entry_t entry;\n\tck_ht_hash_t h;\n\tck_ht_iterator_t iterator = CK_HT_ITERATOR_INITIALIZER;\n\tck_ht_entry_t *cursor;\n\tunsigned int mode = CK_HT_MODE_BYTESTRING;\n\n#ifdef HT_DELETE\n\tmode |= CK_HT_WORKLOAD_DELETE;\n#endif\n\n\tif (ck_ht_init(&ht, mode, ht_hash_wrapper, &my_allocator, 2, 6602834) == false) {\n\t\tperror(\"ck_ht_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_set(&entry, h, test[i], l, test[i]);\n\t\tck_ht_put_spmc(&ht, h, &entry);\n\t}\n\n\tl = strlen(test[0]);\n\tck_ht_hash(&h, &ht, test[0], l);\n\tck_ht_entry_set(&entry, h, test[0], l, test[0]);\n\tck_ht_put_spmc(&ht, h, &entry);\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_key_set(&entry, test[i], l);\n\t\tif (ck_ht_get_spmc(&ht, h, &entry) == false) {\n\t\t\tck_error(\"ERROR (put): Failed to find [%s]\\n\", test[i]);\n\t\t} else {\n\t\t\tvoid *k, *v;\n\n\t\t\tk = ck_ht_entry_key(&entry);\n\t\t\tv = ck_ht_entry_value(&entry);\n\n\t\t\tif (strcmp(k, test[i]) || strcmp(v, test[i])) {\n\t\t\t\tck_error(\"ERROR: Mismatch: (%s, %s) != (%s, %s)\\n\",\n\t\t\t\t    (char *)k, (char *)v, test[i], test[i]);\n\t\t\t}\n\t\t}\n\t}\n\n\tck_ht_hash(&h, &ht, negative, strlen(negative));\n\tck_ht_entry_key_set(&entry, negative, strlen(negative));\n\tif (ck_ht_get_spmc(&ht, h, &entry) == true) {\n\t\tck_error(\"ERROR: Found non-existing entry.\\n\");\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_key_set(&entry, test[i], l);\n\n\t\tif (ck_ht_get_spmc(&ht, h, &entry) == false)\n\t\t\tcontinue;\n\n\t\tif (ck_ht_remove_spmc(&ht, h, &entry) == false) {\n\t\t\tck_error(\"ERROR: Failed to delete existing entry\\n\");\n\t\t}\n\n\t\tif (ck_ht_get_spmc(&ht, h, &entry) == true)\n\t\t\tck_error(\"ERROR: Able to find [%s] after delete\\n\", test[i]);\n\n\t\tck_ht_entry_set(&entry, h, test[i], l, test[i]);\n\t\tif (ck_ht_put_spmc(&ht, h, &entry) == false)\n\t\t\tck_error(\"ERROR: Failed to insert [%s]\\n\", test[i]);\n\n\t\tif (ck_ht_remove_spmc(&ht, h, &entry) == false) {\n\t\t\tck_error(\"ERROR: Failed to delete existing entry\\n\");\n\t\t}\n\t}\n\n\tck_ht_reset_spmc(&ht);\n\tif (ck_ht_count(&ht) != 0) {\n\t\tck_error(\"ERROR: Map was not reset.\\n\");\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_set(&entry, h, test[i], l, test[i]);\n\t\tck_ht_put_spmc(&ht, h, &entry);\n\t}\n\n\tfor (i = 0; ck_ht_next(&ht, &iterator, &cursor) == true; i++);\n\tif (i != 42) {\n\t\tck_error(\"ERROR: Incorrect number of entries in table.\\n\");\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_set(&entry, h, test[i], l, test[i]);\n\t\tck_ht_set_spmc(&ht, h, &entry);\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_key_set(&entry, test[i], l);\n\t\tif (ck_ht_get_spmc(&ht, h, &entry) == false) {\n\t\t\tck_error(\"ERROR (set): Failed to find [%s]\\n\", test[i]);\n\t\t} else {\n\t\t\tvoid *k, *v;\n\n\t\t\tk = ck_ht_entry_key(&entry);\n\t\t\tv = ck_ht_entry_value(&entry);\n\n\t\t\tif (strcmp(k, test[i]) || strcmp(v, test[i])) {\n\t\t\t\tck_error(\"ERROR: Mismatch: (%s, %s) != (%s, %s)\\n\",\n\t\t\t\t    (char *)k, (char *)v, test[i], test[i]);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (ck_ht_gc(&ht, 0, 27) == false) {\n\t\tck_error(\"ck_ht_gc\\n\");\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_set(&entry, h, test[i], l, \"REPLACED\");\n\t\tck_ht_set_spmc(&ht, h, &entry);\n\n\t\tif (strcmp(test[i], \"What\") == 0)\n\t\t\tcontinue;\n\n\t\tif (strcmp(test[i], \"down.\") == 0)\n\t\t\tcontinue;\n\n\t\tif (strcmp(ck_ht_entry_value(&entry), test[i]) != 0) {\n\t\t\tck_error(\"Mismatch detected: %s, expected %s\\n\",\n\t\t\t\t(char *)ck_ht_entry_value(&entry),\n\t\t\t\ttest[i]);\n\t\t}\n\t}\n\n\tck_ht_iterator_init(&iterator);\n\twhile (ck_ht_next(&ht, &iterator, &cursor) == true) {\n\t\tif (strcmp(ck_ht_entry_value(cursor), \"REPLACED\") != 0) {\n\t\t\tck_error(\"Mismatch detected: %s, expected REPLACED\\n\",\n\t\t\t\t(char *)ck_ht_entry_value(cursor));\n\t\t}\n\t}\n\n\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\tl = strlen(test[i]);\n\t\tck_ht_hash(&h, &ht, test[i], l);\n\t\tck_ht_entry_key_set(&entry, test[i], l);\n\n\t\tif (ck_ht_get_spmc(&ht, h, &entry) == false)\n\t\t\tcontinue;\n\n\t\tif (ck_ht_remove_spmc(&ht, h, &entry) == false) {\n\t\t\tck_error(\"ERROR: Failed to delete existing entry\\n\");\n\t\t}\n\n\t\tif (ck_ht_get_spmc(&ht, h, &entry) == true)\n\t\t\tck_error(\"ERROR: Able to find [%s] after delete\\n\", test[i]);\n\n\t\tck_ht_entry_set(&entry, h, test[i], l, test[i]);\n\t\tif (ck_ht_put_spmc(&ht, h, &entry) == false)\n\t\t\tck_error(\"ERROR: Failed to insert [%s]\\n\", test[i]);\n\n\t\tif (ck_ht_remove_spmc(&ht, h, &entry) == false) {\n\t\t\tck_error(\"ERROR: Failed to delete existing entry\\n\");\n\t\t}\n\t}\n\n\tck_ht_destroy(&ht);\n\n\tif (hash_times_called == 0) {\n\t\tck_error(\"ERROR: Our hash function was not called!\\n\");\n\t}\n\n\thash_times_called = 0;\n\n\tif (ck_ht_init(&ht, CK_HT_MODE_DIRECT, ht_hash_wrapper, &my_allocator, 8, 6602834) == false) {\n\t\tperror(\"ck_ht_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tl = 0;\n\tfor (i = 0; i < sizeof(direct) / sizeof(*direct); i++) {\n\t\tck_ht_hash_direct(&h, &ht, direct[i]);\n\t\tck_ht_entry_set_direct(&entry, h, direct[i], (uintptr_t)test[i]);\n\t\tl += ck_ht_put_spmc(&ht, h, &entry) == false;\n\t}\n\n\tif (l != 7) {\n\t\tck_error(\"ERROR: Got %zu failures rather than 7\\n\", l);\n\t}\n\n\tfor (i = 0; i < sizeof(direct) / sizeof(*direct); i++) {\n\t\tck_ht_hash_direct(&h, &ht, direct[i]);\n\t\tck_ht_entry_set_direct(&entry, h, direct[i], (uintptr_t)\"REPLACED\");\n\t\tl += ck_ht_set_spmc(&ht, h, &entry) == false;\n\t}\n\n\tck_ht_iterator_init(&iterator);\n\twhile (ck_ht_next(&ht, &iterator, &cursor) == true) {\n\t\tif (strcmp(ck_ht_entry_value(cursor), \"REPLACED\") != 0) {\n\t\t\tck_error(\"Mismatch detected: %s, expected REPLACED\\n\",\n\t\t\t\t(char *)ck_ht_entry_value(cursor));\n\t\t}\n\t}\n\n\tck_ht_destroy(&ht);\n\n\tif (hash_times_called == 0) {\n\t\tck_error(\"ERROR: Our hash function was not called!\\n\");\n\t}\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pflock/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2013 John Wittrock.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHEPFISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_pflock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_pflock_t pflock = CK_PFLOCK_INITIALIZER;\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_pflock_write_lock(&pflock);\n\t\tck_pflock_write_unlock(&pflock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_pflock_write_lock(&pflock);\n\t\tck_pflock_write_unlock(&pflock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"WRITE: pflock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"READ:  pflock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pflock/benchmark/throughput.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2013 John Wittrock.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHEPFISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_pflock.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic int barrier;\nstatic int threads;\nstatic unsigned int flag CK_CC_CACHELINE;\nstatic ck_pflock_t pflock = CK_PFLOCK_INITIALIZER;\nstatic struct affinity affinity;\n\nstatic void *\nthread_pflock(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tuint64_t *value = pun;\n\n\tif (aff_iterate(&affinity) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\tck_pflock_read_lock(&pflock);\n\t\tck_pflock_read_unlock(&pflock);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint t;\n\tpthread_t *p;\n\tuint64_t *latency;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: throughput <delta> <threads>\\n\");\n\t}\n\n\tthreads = atoi(argv[2]);\n\tif (threads <= 0) {\n\t\tck_error(\"ERROR: Threads must be a value > 0.\\n\");\n\t}\n\n\tp = malloc(sizeof(pthread_t) * threads);\n\tif (p == NULL) {\n\t\tck_error(\"ERROR: Failed to initialize thread.\\n\");\n\t}\n\n\tlatency = malloc(sizeof(uint64_t) * threads);\n\tif (latency == NULL) {\n\t\tck_error(\"ERROR: Failed to create latency buffer.\\n\");\n\t}\n\n\taffinity.delta = atoi(argv[1]);\n\taffinity.request = 0;\n\n\tfprintf(stderr, \"Creating threads (pflock)...\");\n\tfor (t = 0; t < threads; t++) {\n\t\tif (pthread_create(&p[t], NULL, thread_pflock, latency + t) != 0) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", t);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&flag, 1);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (t = 0; t < threads; t++)\n\t\tpthread_join(p[t], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (t = 1; t <= threads; t++)\n\t\tprintf(\"%10u %20\" PRIu64 \"\\n\", t, latency[t - 1]);\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pflock/validate/validate.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra, John Wittrock.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_pflock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstatic struct affinity a;\nstatic unsigned int locked;\nstatic int nthr;\nstatic ck_pflock_t lock = CK_PFLOCK_INITIALIZER;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tint i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tck_pflock_write_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_pflock_write_unlock(&lock);\n\n\t\tck_pflock_read_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_pflock_read_unlock(&lock);\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tint i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: validate <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tfprintf(stderr, \"Creating threads (mutual exclusion)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/benchmark.h",
    "content": "#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n\n/* 8! = 40320, evenly divide 1 .. 8 processor workload. */\n#define WORKLOAD (40320 * 2056)\n\nstruct block {\n\tunsigned int tid;\n};\n\nstatic struct affinity a;\nstatic unsigned int ready;\nstatic uint64_t *count;\nstatic uint64_t nthr;\n\nstatic uint64_t object[2] CK_CC_CACHELINE;\n\nstatic void *\nfairness(void *null)\n{\n\tstruct block *context = null;\n\tunsigned int i = context->tid;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (ck_pr_load_uint(&ready) == 0);\n\twhile (ck_pr_load_uint(&ready)) {\n\t\tATOMIC;\n\t\tATOMIC;\n\t\tATOMIC;\n\t\tATOMIC;\n\t\tck_pr_store_64(count + i, count[i] + 1);\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tuint64_t v, d;\n\tunsigned int i;\n\tpthread_t *threads;\n\tstruct block *context;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: \" ATOMIC_STRING \" <number of threads> <affinity delta>\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tcontext = malloc(sizeof(struct block) * nthr);\n\tif (context == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread contexts\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\ta.delta = atoi(argv[2]);\n\ta.request = 0;\n\n\tcount = malloc(sizeof(uint64_t) * nthr);\n\tif (count == NULL) {\n\t\tck_error(\"ERROR: Could not create acquisition buffer\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\tmemset(count, 0, sizeof(uint64_t) * nthr);\n\n\tfprintf(stderr, \"Creating threads (fairness)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tcontext[i].tid = i;\n\t\tif (pthread_create(&threads[i], NULL, fairness, context + i)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tck_pr_store_uint(&ready, 1);\n\tcommon_sleep(10);\n\tck_pr_store_uint(&ready, 0);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (i = 0, v = 0; i < nthr; i++) {\n\t\tprintf(\"%d %15\" PRIu64 \"\\n\", i, count[i]);\n\t\tv += count[i];\n\t}\n\n\tprintf(\"\\n# total       : %15\" PRIu64 \"\\n\", v);\n\tprintf(\"# throughput  : %15\" PRIu64 \" a/s\\n\", (v /= nthr) / 10);\n\n\tfor (i = 0, d = 0; i < nthr; i++)\n\t\td += (count[i] - v) * (count[i] - v);\n\n\tprintf(\"# average     : %15\" PRIu64 \"\\n\", v);\n\tprintf(\"# deviation   : %.2f (%.2f%%)\\n\\n\", sqrt(d / nthr), (sqrt(d / nthr) / v) * 100.00);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/ck_pr_add_64.c",
    "content": "#include <ck_pr.h>\n\n#ifdef CK_F_PR_ADD_64\n#define ATOMIC ck_pr_add_64(object, 1)\n#define ATOMIC_STRING \"ck_pr_add_64\"\n#include \"benchmark.h\"\n#else\n#warning Did not find ADD_64 implementation.\n#include <stdlib.h>\n\nint\nmain(void)\n{\n\texit(EXIT_FAILURE);\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/ck_pr_cas_64.c",
    "content": "#include <ck_pr.h>\n\n#ifdef CK_F_PR_CAS_64\n#define ATOMIC ck_pr_cas_64(object, 1, 1)\n#define ATOMIC_STRING \"ck_pr_cas_64\"\n#include \"benchmark.h\"\n#else\n#warning Did not find CAS_64 implementation.\n#include <stdlib.h>\n\nint\nmain(void)\n{\n\texit(EXIT_FAILURE);\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/ck_pr_cas_64_2.c",
    "content": "#include <ck_pr.h>\n\n#ifdef CK_F_PR_CAS_64_2\n#define ATOMIC { uint64_t z[2] = {1, 2}; ck_pr_cas_64_2(object, z, z); }\n#define ATOMIC_STRING \"ck_pr_cas_64_2\"\n#include \"benchmark.h\"\n#else\n#include <stdio.h>\n#include <stdlib.h>\n\nint\nmain(void)\n{\n\tfprintf(stderr, \"Unsupported.\\n\");\n\treturn 0;\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/ck_pr_faa_64.c",
    "content": "#include <ck_pr.h>\n\n#ifdef CK_F_PR_FAA_64\n#define ATOMIC ck_pr_faa_64(object, 1)\n#define ATOMIC_STRING \"ck_pr_faa_64\"\n#include \"benchmark.h\"\n#else\n#warning Did not find FAA_64 implementation.\n#include <stdlib.h>\n\nint\nmain(void)\n{\n\texit(EXIT_FAILURE);\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/ck_pr_fas_64.c",
    "content": "#include <ck_pr.h>\n\n#ifdef CK_F_PR_FAS_64\n#define ATOMIC ck_pr_fas_64(object, 1)\n#define ATOMIC_STRING \"ck_pr_fas_64\"\n#include \"benchmark.h\"\n#else\n#warning Did not find FAS_64 implementation.\n#include <stdlib.h>\n\nint\nmain(void)\n{\n\n\treturn 0;\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/ck_pr_neg_64.c",
    "content": "#include <ck_pr.h>\n\n#ifdef CK_F_PR_NEG_64\n#define ATOMIC ck_pr_neg_64(object)\n#define ATOMIC_STRING \"ck_pr_neg_64\"\n#include \"benchmark.h\"\n#else\n#warning Did not find NEG_64 implementation.\n#include <stdlib.h>\n\nint\nmain(void)\n{\n\texit(EXIT_FAILURE);\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/benchmark/fp.c",
    "content": "#include <stdio.h>\n#include <inttypes.h>\n#include <stdint.h>\n\n#include \"../../common.h\"\n\n#ifndef IR\n#define IR 3000000\n#endif /* IR */\n\nstatic int a CK_CC_CACHELINE;\nstatic int b CK_CC_CACHELINE;\n\nint\nmain(void)\n{\n\tuint64_t s, e;\n\tunsigned int i;\n\n\ts = rdtsc();\n\tfor (i = 0; i < IR; i++) {\n\t\tck_pr_load_int(&a);\n\t\tck_pr_fence_strict_load();\n\t\tck_pr_load_int(&b);\n\t}\n\te = rdtsc();\n\tprintf(\"[A] fence_load: %\" PRIu64 \"\\n\", (e - s) / IR);\n\n\ts = rdtsc();\n\tfor (i = 0; i < IR; i++) {\n\t\tif (ck_pr_load_int(&a) == 0)\n\t\t\tck_pr_barrier();\n\t\tck_pr_fence_strict_lock();\n\t\tck_pr_load_int(&b);\n\t}\n\te = rdtsc();\n\tprintf(\"[A] fence_lock: %\" PRIu64 \"\\n\", (e - s) / IR);\n\n\ts = rdtsc();\n\tfor (i = 0; i < IR; i++) {\n\t\tck_pr_store_int(&a, 0);\n\t\tck_pr_fence_strict_store();\n\t\tck_pr_store_int(&b, 0);\n\t}\n\te = rdtsc();\n\tprintf(\"[B] fence_store: %\" PRIu64 \"\\n\", (e - s) / IR);\n\n\ts = rdtsc();\n\tfor (i = 0; i < IR; i++) {\n\t\tck_pr_store_int(&a, 0);\n\t\tck_pr_fence_strict_memory();\n\t\tck_pr_load_int(&b);\n\t}\n\te = rdtsc();\n\tprintf(\"[C] fence_memory: %\" PRIu64 \"\\n\", (e - s) / IR);\n\n\ts = rdtsc();\n\tfor (i = 0; i < IR; i++) {\n\t\tck_pr_store_int(&a, 0);\n\t\tck_pr_faa_int(&a, 0);\n\t\tck_pr_load_int(&b);\n\t}\n\te = rdtsc();\n\tprintf(\"[C] atomic: %\" PRIu64 \"\\n\", (e - s) / IR);\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_add.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_ADD_T(w, v, d)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = v;\t\t\t\t\t\t\\\n\t\tck_pr_add_##w(&t, d);\t\t\t\t\t\t\\\n\t\tif (t != (uint##w##_t)(v + d)) {\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w \"]\\n\",\\\n\t\t\t\t\t(uint##w##_t)v, d, t);\t\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_ADD_B(w)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\t\t\\\n\t\tprintf(\"ck_pr_add_\" #w \": \");\t\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\t\t\\\n\t\t\tuint##w##_t a = common_rand() % ((uint##w##_t)-1 / 2);\t\\\n\t\t\tuint##w##_t b = common_rand() % ((uint##w##_t)-1 / 2);\t\\\n\t\t\tCK_PR_ADD_T(w, a, b);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_ADD_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = -1, r = -1 & ~(uint##m##_t)(uint##w##_t)-1;\t\\\n\t\tck_pr_add_##w((uint##w##_t *)(void *)&t, 1);\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\tt = 0, r = (uint##m##_t)(uint##w##_t)-1;\t\t\t\\\n\t\tck_pr_add_##w((uint##w##_t *)(void *)&t, -1);\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_ADD_64\n\tif (m == 64) {\n#if defined(CK_F_PR_ADD_32)\n\t\tCK_PR_ADD_W(64, 32);\n#endif\n#if defined(CK_PR_ADD_16)\n\t\tCK_PR_ADD_W(64, 16);\n#endif\n#if defined(CK_PR_ADD_8)\n\t\tCK_PR_ADD_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_ADD_64 */\n\n#ifdef CK_F_PR_ADD_32\n\tif (m == 32) {\n#if defined(CK_F_PR_ADD_16)\n\t\tCK_PR_ADD_W(32, 16);\n#endif\n#if defined(CK_PR_ADD_8)\n\t\tCK_PR_ADD_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_ADD_32 */\n\n#if defined(CK_F_PR_ADD_16) && defined(CK_PR_ADD_8)\n\tif (m == 16) {\n\t\tCK_PR_ADD_W(16, 8);\n\t}\n#endif /* CK_PR_ADD_16 && CK_PR_ADD_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_ADD_64\n\tCK_PR_ADD_B(64);\n#endif\n\n#ifdef CK_F_PR_ADD_32\n\tCK_PR_ADD_B(32);\n#endif\n\n#ifdef CK_F_PR_ADD_16\n\tCK_PR_ADD_B(16);\n#endif\n\n#ifdef CK_F_PR_ADD_8\n\tCK_PR_ADD_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_and.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define BM(m, w) ((uint##m##_t)-1 << (w))\n\n#define CK_PR_AND_T(w, v, d)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = v;\t\t\t\t\t\t\\\n\t\tck_pr_and_##w(&t, d);\t\t\t\t\t\t\\\n\t\tif (t != (uint##w##_t)(v & d)) {\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w \"]\\n\",\\\n\t\t\t\t\t(uint##w##_t)v, d, t);\t\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_AND_B(w)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\\\n\t\tprintf(\"ck_pr_and_\" #w \": \");\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\\\n\t\t\tuint##w##_t a = (uint##w##_t)common_rand();\t\\\n\t\t\tuint##w##_t b = (uint##w##_t)common_rand();\t\\\n\t\t\tCK_PR_AND_T(w, a, b);\t\t\t\\\n\t\t}\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\\\n\t}\n\n#define CK_PR_AND_W(m, w)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = -1;\t\t\t\t\t\t\t\t\\\n\t\tck_pr_and_##w((uint##w##_t *)(void *)&t, 0);\t\t\t\t\t\\\n\t\tif (t != BM(m, w)) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"  FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, BM(m, w));\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_AND_64\n\tif (m == 64) {\n#if defined(CK_F_PR_AND_32)\n\t\tCK_PR_AND_W(64, 32);\n#endif\n#if defined(CK_PR_AND_16)\n\t\tCK_PR_AND_W(64, 16);\n#endif\n#if defined(CK_PR_AND_8)\n\t\tCK_PR_AND_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_AND_64 */\n\n#ifdef CK_F_PR_AND_32\n\tif (m == 32) {\n#if defined(CK_F_PR_AND_16)\n\t\tCK_PR_AND_W(32, 16);\n#endif\n#if defined(CK_PR_AND_8)\n\t\tCK_PR_AND_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_AND_32 */\n\n#if defined(CK_F_PR_AND_16) && defined(CK_PR_AND_8)\n\tif (m == 16) {\n\t\tCK_PR_AND_W(16, 8);\n\t}\n#endif /* CK_PR_AND_16 && CK_PR_AND_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_AND_64\n\tCK_PR_AND_B(64);\n#endif\n\n#ifdef CK_F_PR_AND_32\n\tCK_PR_AND_B(32);\n#endif\n\n#ifdef CK_F_PR_AND_16\n\tCK_PR_AND_B(16);\n#endif\n\n#ifdef CK_F_PR_AND_8\n\tCK_PR_AND_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_bin.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_pr.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n#define REPEAT 2000000\n\n#define TEST_BINARY(K, S, T, P, D)\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\\\n\trun_test_##K##_##S(void)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tint i, r;\t\t\t\t\t\t\\\n\t\tT serial_result = 65535;\t\t\t\t\\\n\t\tT ck_result = 65535;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tputs(\"***TESTING ck_pr_\" #K \"_\" #S \"***\");\t\t\\\n\t\tcommon_srand((unsigned int)getpid());\t\t\t\\\n\t\tfor (i = 0; i < REPEAT; ++i) {\t\t\t\t\\\n\t\t\tr = common_rand();\t\t\t\t\t\\\n\t\t\tserial_result = serial_result P r;\t\t\\\n\t\t\tck_pr_##K##_##S(&ck_result, r);\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"Value of operation \" #K \" on 2000000 \"\t\t\\\n\t\t\t\"random numbers\\n\\tusing \" #P \": %\" #D \",\\n\"\t\\\n\t\t\t\"\\tusing ck_pr_\"#K\"_\"#S\": %\" #D \"\\n\",\t\t\\\n\t\t\t\t serial_result, ck_result);\t\t\\\n\t\t(serial_result == ck_result) ? puts(\"SUCCESS.\")\t\t\\\n\t\t\t\t\t     : puts(\"FAILURE.\");\t\\\n\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\\\n\n#define GENERATE_TEST(K, P)\t\t\t\t\\\n\tTEST_BINARY(K, int, int, P, d)\t\t\t\\\n\tTEST_BINARY(K, uint, unsigned int, P, u)\t\\\n\tstatic void\t\t\t\t\t\\\n\trun_test_##K(void)\t\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\trun_test_##K##_int();\t\t\t\\\n\t\trun_test_##K##_uint();\t\t\t\\\n\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\\\n\t}\n\nGENERATE_TEST(add, +)\nGENERATE_TEST(sub, -)\nGENERATE_TEST(and, &)\nGENERATE_TEST(or, |)\nGENERATE_TEST(xor, ^)\n\n#undef GENERATE_TEST\n#undef TEST_BINARY\n\nint\nmain(void)\n{\n\trun_test_add();\n\trun_test_sub();\n\trun_test_and();\n\trun_test_or();\n\trun_test_xor();\n\n\treturn (0);\n}\n\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_btc.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n/*\n * Bit selector.\n */\n#define BM(v, b) (((v) >> (b)) & 1)\n\n#define CK_PR_BTC_T(w, v)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int j;\t\t\t\t\t\t\t\\\n\t\tuint##w##_t r = v;\t\t\t\t\t\t\\\n\t\tbool t;\t\t\t\t\t\t\t\t\\\n\t\tfor (j = 0; j < (w); j++) {\t\t\t\t\t\\\n\t\t\tt = ck_pr_btc_##w(&r, j);\t\t\t\t\\\n\t\t\tif ((t && !BM(v, j)) || ((BM(v, j) + BM(r, j)) != 1)) {\t\\\n\t\t\t\tprintf(\"FAIL [%\" PRIx##w \":%u]\\n\", r, j);\t\\\n\t\t\t\texit(EXIT_FAILURE);\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BTC_B(w)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\tuint##w##_t o;\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\\\n\t\tprintf(\"ck_pr_btc_\" #w \": \");\t\t\\\n\t\tfor (i = 0; i < R_REPEAT; i++) {\t\\\n\t\t\to = (uint##w##_t)common_rand();\t\\\n\t\t\tCK_PR_BTC_T(w, o);\t\t\\\n\t\t}\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\\\n\t}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_BTC_64\n\tCK_PR_BTC_B(64);\n#endif\n\n#ifdef CK_F_PR_BTC_32\n\tCK_PR_BTC_B(32);\n#endif\n\n#ifdef CK_F_PR_BTC_16\n\tCK_PR_BTC_B(16);\n#endif\n\n#ifdef CK_F_PR_BTC_8\n\tCK_PR_BTC_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_btr.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n/*\n * Bit selector.\n */\n#define BM(v, b) (((v) >> (b)) & 1)\n\n#define CK_PR_BTR_T(w, v)\t\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int j;\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t r = v, c = v;\t\t\t\t\t\t\t\t\\\n\t\tbool t;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (j = 0; j < (w); j++) {\t\t\t\t\t\t\t\t\\\n\t\t\tc &= (uint##w##_t)-1 ^ (1 << j);\t\t\t\t\t\t\\\n\t\t\tt = ck_pr_btr_##w(&r, j);\t\t\t\t\t\t\t\\\n\t\t\tif ((t && !BM(v, j)) || (r != c)) {\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"FAIL [%\" PRIx##w \":%u != %\" PRIx##w \":%u]\\n\", r, j, c, j);\t\\\n\t\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BTR_B(w)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\tuint##w##_t o;\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\\\n\t\tprintf(\"ck_pr_btr_\" #w \": \");\t\t\\\n\t\tfor (i = 0; i < R_REPEAT; i++) {\t\\\n\t\t\to = (uint##w##_t)common_rand();\t\\\n\t\t\tCK_PR_BTR_T(w, o);\t\t\\\n\t\t}\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\\\n\t}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_BTR_64\n\tCK_PR_BTR_B(64);\n#endif\n\n#ifdef CK_F_PR_BTR_32\n\tCK_PR_BTR_B(32);\n#endif\n\n#ifdef CK_F_PR_BTR_16\n\tCK_PR_BTR_B(16);\n#endif\n\n#ifdef CK_F_PR_BTR_8\n\tCK_PR_BTR_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_bts.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n/*\n * Bit selector.\n */\n#define BM(v, b) (((v) >> (b)) & 1)\n\n#define CK_PR_BTS_T(w, v)\t\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int j;\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t r = v, c = v;\t\t\t\t\t\t\t\t\\\n\t\tbool t;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tfor (j = 0; j < (w); j++) {\t\t\t\t\t\t\t\t\\\n\t\t\tc |= (uint##w##_t)1 << j;\t\t\t\t\t\t\t\\\n\t\t\tt = ck_pr_bts_##w(&r, j);\t\t\t\t\t\t\t\\\n\t\t\tif ((t && !BM(v, j)) || (r != c)) {\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"FAIL [%\" PRIx##w \":%u != %\" PRIx##w \":%u]\\n\", r, j, c, j);\t\\\n\t\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_BTS_B(w)\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\tuint##w##_t o;\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\\\n\t\tprintf(\"ck_pr_bts_\" #w \": \");\t\t\\\n\t\tfor (i = 0; i < R_REPEAT; i++) {\t\\\n\t\t\to = (uint##w##_t)common_rand();\t\\\n\t\t\tCK_PR_BTS_T(w, o);\t\t\\\n\t\t}\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\\\n\t}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_BTS_64\n\tCK_PR_BTS_B(64);\n#endif\n\n#ifdef CK_F_PR_BTS_32\n\tCK_PR_BTS_B(32);\n#endif\n\n#ifdef CK_F_PR_BTS_16\n\tCK_PR_BTS_B(16);\n#endif\n\n#ifdef CK_F_PR_BTS_8\n\tCK_PR_BTS_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_btx.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <stdbool.h>\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#define REPEAT 2000000\n\n#define TEST_BTX(K, S, M, T, L, P, D, R)\t\t\t\t\t\t\\\n\tstatic bool\t\t\t\t\t\t\t\t\t\\\n\ttest_##K##_##S(M *target, int offset)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tT previous;\t\t\t\t\t\t\t\t\\\n\t\tconst L change = R (0x01 << offset);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tprevious = (T)*target;\t\t\t\t\t\t\t\\\n\t\t*target = previous P change;\t\t\t\t\t\t\\\n\t\treturn ((previous >> offset) & 0x01);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\\\n\trun_test_##K##_##S(void)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tint i, offset, m;\t\t\t\t\t\t\t\\\n\t\tbool serial_t, ck_pr_t;\t\t\t\t\t\t\t\\\n\t\tT x = 65535, y = 65535;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tcommon_srand((unsigned int)getpid());\t\t\t\t\t\\\n\t\tm = sizeof(T) * 8;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tputs(\"***TESTING ck_pr_\"#K\"_\"#S\"***\");\t\t\t\t\t\\\n\t\tfor (i = 0; i < REPEAT; ++i) {\t\t\t\t\t\t\\\n\t\t\toffset = common_rand() % m;\t\t\t\t\t\t\\\n\t\t\tserial_t = test_##K##_##S(&x, offset);\t\t\t\t\\\n\t\t\tck_pr_t = ck_pr_##K##_##S(&y, offset);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (serial_t != ck_pr_t || x != y ) {\t\t\t\t\\\n\t\t\t\tprintf(\"Serial(%\"#D\") and ck_pr(%\"#D\")\"\t\t\t\\\n\t\t\t\t\t#K\"_\"#S \" do not match.\\n\"\t\t\t\\\n\t\t\t\t\t\"FAILURE.\\n\", \t\t\t\t\t\\\n\t\t\t\t\tserial_t, ck_pr_t);\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn;\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"\\tserial_\"#K\"_\"#S\": %\"#D\"\\n\"\t\t\t\t\t\\\n\t\t\t\"\\tck_pr_\"#K\"_\"#S\": %\"#D\"\\n\"\t\t\t\t\t\\\n\t\t\t\"SUCCESS.\\n\",\t\t\t\t\t\t\t\\\n\t\t\tx, y);\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define TEST_BTX_S(K, S, T, P, D, R) TEST_BTX(K, S, T, T, T, P, D, R)\n\n#define GENERATE_TEST(K, P, R)\t\t\t\t\\\n\tTEST_BTX_S(K, int, int, P, d, R)\t\t\\\n\tTEST_BTX_S(K, uint, unsigned int, P, u, R)\t\\\n\tstatic void\t\t\t\t\t\\\n\trun_test_##K(void)\t\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\trun_test_##K##_int();\t\t\t\\\n\t\trun_test_##K##_uint();\t\t\t\\\n\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\\\n\t}\n\nGENERATE_TEST(btc, ^, 0+)\nGENERATE_TEST(btr, &, ~)\nGENERATE_TEST(bts, |, 0+)\n\n#undef GENERATE_TEST\n#undef TEST_BTX_S\n#undef TEST_BTX\n\nint\nmain(void)\n{\n\trun_test_btc();\n\trun_test_btr();\n\trun_test_bts();\n\n\treturn (0);\n}\n\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_cas.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define W(w, x) (uint##w##_t)((x) & (uint##w##_t)~0)\n\n#define CK_PR_CAS_T(w, v, c, s) \t\t\t\t\t\t\t\t\t\t\\\n\t\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tuint##w##_t t = v;\t\t\t\t\t\t\t\t\t\\\n\t\t\tbool r;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tr = ck_pr_cas_##w(&t, c, s);\t\t\t\t\t\t\t\t\\\n\t\t\tif (((c == v) && (r == false)) || ((c != v) && (r == true)) ||\t\t\t\t\\\n\t\t\t\t\t((r == true) && (W(w, s) != t))) {\t\t\t\t\t\\\n\t\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \" -> %\" PRIu##w \")\"\t\t\t\t\\\n\t\t\t\t\t\" -> %\" PRIu##w \"]\\n\",\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t(uint##w##_t)(v), (uint##w##_t)(c), W(w, s), (uint##w##_t)(t));\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t}\n\n#define CK_PR_CAS_B(w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i;\t\t\t\t\t\\\n\t\tprintf(\"ck_pr_cas_\" #w \": \");\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\t\\\n\t\t\tuint##w##_t a = common_rand() % (uint##w##_t)-1;\t\\\n\t\t\tCK_PR_CAS_T(w, a, a + 1, (a - 1));\t\t\\\n\t\t\tCK_PR_CAS_T(w, a, a, (a - 1));\t\t\t\\\n\t\t\tCK_PR_CAS_T(w, a, a + 1, a);\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\t\\\n\t}\n\n#define CK_PR_CAS_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = -1, r = -1 & ~(uint##m##_t)(uint##w##_t)-1;\t\\\n\t\tck_pr_cas_##w((uint##w##_t *)(void *)&t, (uint##w##_t)t, 0);\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\",\t\\\n\t\t\t\t\t(uint##m##_t)t, (uint##m##_t)r);\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_CAS_64\n\tif (m == 64) {\n#if defined(CK_F_PR_CAS_32)\n\t\tCK_PR_CAS_W(64, 32);\n#endif\n#if defined(CK_PR_CAS_16)\n\t\tCK_PR_CAS_W(64, 16);\n#endif\n#if defined(CK_PR_CAS_8)\n\t\tCK_PR_CAS_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_CAS_64 */\n\n#ifdef CK_F_PR_CAS_32\n\tif (m == 32) {\n#if defined(CK_F_PR_CAS_16)\n\t\tCK_PR_CAS_W(32, 16);\n#endif\n#if defined(CK_PR_CAS_8)\n\t\tCK_PR_CAS_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_CAS_32 */\n\n#if defined(CK_F_PR_CAS_16) && defined(CK_PR_CAS_8)\n\tif (m == 16) {\n\t\tCK_PR_CAS_W(16, 8);\n\t}\n#endif /* CK_PR_CAS_16 && CK_PR_CAS_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_CAS_64\n\tCK_PR_CAS_B(64);\n#endif\n\n#ifdef CK_F_PR_CAS_32\n\tCK_PR_CAS_B(32);\n#endif\n\n#ifdef CK_F_PR_CAS_16\n\tCK_PR_CAS_B(16);\n#endif\n\n#ifdef CK_F_PR_CAS_8\n\tCK_PR_CAS_B(8);\n#endif\n\n#ifdef CK_F_PR_CAS_64_VALUE\n\tuint64_t a = 0xffffffffaaaaaaaa, b = 0x8888888800000000;\n\n\tprintf(\"%\" PRIx64 \" (%\" PRIx64 \") -> \", b, a);\n\tck_pr_cas_64_value(&a, a, b, &b);\n\tprintf(\"%\" PRIx64 \" (%\" PRIx64 \")\\n\", b, a);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_dec.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_DEC_T(w, v)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = v;\t\t\t\t\t\t\t\\\n\t\tck_pr_dec_##w(&t);\t\t\t\t\t\t\t\\\n\t\tif ((t != (uint##w##_t)(v - 1))) {\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" -> %\" PRIu##w \"]\\n\", (uint##w##_t)v, t);\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_DEC_B(w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\t\\\n\t\tprintf(\"ck_pr_dec_\" #w \": \");\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\t\\\n\t\t\tuint##w##_t a = common_rand() % ((uint##w##_t)-1);\t\\\n\t\t\tCK_PR_DEC_T(w, a);\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\t\\\n\t}\n\n#define CK_PR_DEC_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = 0, r = (uint##w##_t)-1;\t\t\t\t\\\n\t\tck_pr_dec_##w((uint##w##_t *)(void *)&t);\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_DEC_64\n\tif (m == 64) {\n#if defined(CK_F_PR_DEC_32)\n\t\tCK_PR_DEC_W(64, 32);\n#endif\n#if defined(CK_PR_DEC_16)\n\t\tCK_PR_DEC_W(64, 16);\n#endif\n#if defined(CK_PR_DEC_8)\n\t\tCK_PR_DEC_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_DEC_64 */\n\n#ifdef CK_F_PR_DEC_32\n\tif (m == 32) {\n#if defined(CK_F_PR_DEC_16)\n\t\tCK_PR_DEC_W(32, 16);\n#endif\n#if defined(CK_PR_DEC_8)\n\t\tCK_PR_DEC_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_DEC_32 */\n\n#if defined(CK_F_PR_DEC_16) && defined(CK_PR_DEC_8)\n\tif (m == 16) {\n\t\tCK_PR_DEC_W(16, 8);\n\t}\n#endif /* CK_PR_DEC_16 && CK_PR_DEC_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_DEC_64\n\tCK_PR_DEC_B(64);\n#endif\n\n#ifdef CK_F_PR_DEC_32\n\tCK_PR_DEC_B(32);\n#endif\n\n#ifdef CK_F_PR_DEC_16\n\tCK_PR_DEC_B(16);\n#endif\n\n#ifdef CK_F_PR_DEC_8\n\tCK_PR_DEC_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_faa.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_FAA_T(w, v, d)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t r, t = v;\t\t\t\t\t\t\\\n\t\tr = ck_pr_faa_##w(&t, d);\t\t\t\t\t\\\n\t\tif ((t != (uint##w##_t)(v + d)) || (r != v)) {\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w\t\\\n\t\t\t\t\t\" (%\" PRIu##w \")]\\n\",\t\t\t\\\n\t\t\t\t\t(uint##w##_t)v, d, t, r);\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_FAA_B(w)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\t\t\\\n\t\tprintf(\"ck_pr_faa_\" #w \": \");\t\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\t\t\\\n\t\t\tuint##w##_t a = common_rand() % ((uint##w##_t)-1 / 2);\t\\\n\t\t\tuint##w##_t b = common_rand() % ((uint##w##_t)-1 / 2);\t\\\n\t\t\tCK_PR_FAA_T(w, a, b);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_FAA_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = -1, r = -1 & ~(uint##m##_t)(uint##w##_t)-1;\t\\\n\t\tck_pr_faa_##w((uint##w##_t *)(void *)&t, 1);\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t\tt = 0, r = (uint##m##_t)(uint##w##_t)-1;\t\t\t\\\n\t\tck_pr_faa_##w((uint##w##_t *)(void *)&t, -1);\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_FAA_64\n\tif (m == 64) {\n#if defined(CK_F_PR_FAA_32)\n\t\tCK_PR_FAA_W(64, 32);\n#endif\n#if defined(CK_PR_FAA_16)\n\t\tCK_PR_FAA_W(64, 16);\n#endif\n#if defined(CK_PR_FAA_8)\n\t\tCK_PR_FAA_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_FAA_64 */\n\n#ifdef CK_F_PR_FAA_32\n\tif (m == 32) {\n#if defined(CK_F_PR_FAA_16)\n\t\tCK_PR_FAA_W(32, 16);\n#endif\n#if defined(CK_PR_FAA_8)\n\t\tCK_PR_FAA_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_FAA_32 */\n\n#if defined(CK_F_PR_FAA_16) && defined(CK_PR_FAA_8)\n\tif (m == 16) {\n\t\tCK_PR_FAA_W(16, 8);\n\t}\n#endif /* CK_PR_FAA_16 && CK_PR_FAA_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_FAA_64\n\tCK_PR_FAA_B(64);\n#endif\n\n#ifdef CK_F_PR_FAA_32\n\tCK_PR_FAA_B(32);\n#endif\n\n#ifdef CK_F_PR_FAA_16\n\tCK_PR_FAA_B(16);\n#endif\n\n#ifdef CK_F_PR_FAA_8\n\tCK_PR_FAA_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_fas.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define BM(m, w) ((uint##m##_t)(uint##w##_t)(-1))\n\n#define CK_PR_FAS_T(w, v, d)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t r, t = v;\t\t\t\t\t\t\\\n\t\tr = ck_pr_fas_##w(&t, d);\t\t\t\t\t\\\n\t\tif ((t != d) || (r != v)) {\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w\t\\\n\t\t\t\t\t\" (%\" PRIu##w \")]\\n\",\t\t\t\\\n\t\t\t\t\t(uint##w##_t)v, d, t, r);\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_FAS_B(w)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\\\n\t\tprintf(\"ck_pr_fas_\" #w \": \");\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\\\n\t\t\tuint##w##_t a = common_rand();\t\t\\\n\t\t\tuint##w##_t b = common_rand();\t\t\\\n\t\t\tCK_PR_FAS_T(w, a, b);\t\t\t\\\n\t\t}\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\\\n\t}\n\n#define CK_PR_FAS_W(m, w)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = 0;\t\t\t\t\t\t\t\\\n\t\tck_pr_fas_##w((uint##w##_t *)(void *)&t, -1);\t\t\t\t\\\n\t\tif (t != BM(m, w)) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, BM(m, w));\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_FAS_64\n\tif (m == 64) {\n#if defined(CK_F_PR_FAS_32)\n\t\tCK_PR_FAS_W(64, 32);\n#endif\n#if defined(CK_PR_FAS_16)\n\t\tCK_PR_FAS_W(64, 16);\n#endif\n#if defined(CK_PR_FAS_8)\n\t\tCK_PR_FAS_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_FAS_64 */\n\n#ifdef CK_F_PR_FAS_32\n\tif (m == 32) {\n#if defined(CK_F_PR_FAS_16)\n\t\tCK_PR_FAS_W(32, 16);\n#endif\n#if defined(CK_PR_FAS_8)\n\t\tCK_PR_FAS_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_FAS_32 */\n\n#if defined(CK_F_PR_FAS_16) && defined(CK_PR_FAS_8)\n\tif (m == 16) {\n\t\tCK_PR_FAS_W(16, 8);\n\t}\n#endif /* CK_PR_FAS_16 && CK_PR_FAS_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_FAS_64\n\tCK_PR_FAS_B(64);\n#endif\n\n#ifdef CK_F_PR_FAS_32\n\tCK_PR_FAS_B(32);\n#endif\n\n#ifdef CK_F_PR_FAS_16\n\tCK_PR_FAS_B(16);\n#endif\n\n#ifdef CK_F_PR_FAS_8\n\tCK_PR_FAS_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_fax.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#define REPEAT 2000000\n\n#define TEST_FAX_FN(S, T, M)\t\t\t\t\t\t\t\t\\\n\tstatic T\t\t\t\t\t\t\t\t\t\\\n\ttest_faa_##S(M *target, T delta)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tT previous = (T)*target;\t\t\t\t\t\t\\\n\t\t*target = (T)*target + delta;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn (previous);\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\tstatic T\t\t\t\t\t\t\t\t\t\\\n\ttest_fas_##S(M *target, T update)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tT previous = *target;\t\t\t\t\t\t\t\\\n\t\t*target = update;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn (previous);\t\t\t\t\t\t\t\\\n\t}\n\n#define TEST_FAX_FN_S(S, T) TEST_FAX_FN(S, T, T)\n\nTEST_FAX_FN_S(int, int)\nTEST_FAX_FN_S(uint, unsigned int)\n\n#undef TEST_FAX_FN_S\n#undef TEST_FAX_FN\n\n#define TEST_FAX(K, S, T, D)\t\t\t\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\\\n\trun_test_##K##_##S(void)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tint i, r;\t\t\t\t\t\t\t\t\\\n\t\tT x = 0, y = 0, x_b, y_b;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tputs(\"***TESTING ck_pr_\"#K\"_\"#S\"***\");\t\t\t\t\t\\\n\t\tcommon_srand((unsigned int)getpid());\t\t\t\t\t\\\n\t\tfor (i = 0; i < REPEAT; ++i) {\t\t\t\t\t\t\\\n\t\t\tr = common_rand();\t\t\t\t\t\t\t\\\n\t\t\tx_b = test_##K##_##S(&x, r);\t\t\t\t\t\\\n\t\t\ty_b = ck_pr_##K##_##S(&y, r);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (x_b != y_b) {\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"Serial fetch does not match ck_pr fetch.\\n\"\t\\\n\t\t\t\t\t\"\\tSerial: %\"#D\"\\n\"\t\t\t\t\\\n\t\t\t\t\t\"\\tck_pr: %\"#D\"\\n\",\t\t\t\t\\\n\t\t\t\t\tx_b, y_b);\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn;\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"Final result:\\n\"\t\t\t\t\t\t\\\n\t\t\t\"\\tSerial: %\"#D\"\\n\"\t\t\t\t\t\t\\\n\t\t\t\"\\tck_pr: %\"#D\"\\n\",\t\t\t\t\t\t\\\n\t\t\tx, y);\t\t\t\t\t\t\t\t\\\n\t\t(x == y) ? puts(\"SUCCESS.\")\t\t\t\t\t\t\\\n\t\t\t : puts(\"FAILURE.\");\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\\\n\n\n#define GENERATE_TEST(K)\t\t\t\t\\\n\tTEST_FAX(K, int, int, d)\t\t\t\\\n\tTEST_FAX(K, uint, unsigned int, u)\t\t\\\n\tstatic void\t\t\t\t\t\\\n\trun_test_##K(void)\t\t\t\t\\\n\t{\t\t\t\t\t\t\\\n\t\trun_test_##K##_int();\t\t\t\\\n\t\trun_test_##K##_uint();\t\t\t\\\n\t}\n\nGENERATE_TEST(faa)\nGENERATE_TEST(fas)\n\n#undef GENERATE_TEST\n#undef TEST_FAX\n\nint\nmain(void)\n{\n\trun_test_faa();\n\trun_test_fas();\n\n\treturn (0);\n}\n\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_inc.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_INC_T(w, v)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = v;\t\t\t\t\t\\\n\t\tck_pr_inc_##w(&t);\t\t\t\t\t\\\n\t\tif ((t != (uint##w##_t)(v + 1))) {\t\t\t\\\n\t\t\tprintf(\"FAIL [%\" PRIu##w \" -> %\" PRIu##w \"]\\n\",\t\\\n\t\t\t\t\t(uint##w##_t)v, t);\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_INC_B(w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\t\\\n\t\tprintf(\"ck_pr_inc_\" #w \": \");\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\t\\\n\t\t\tuint##w##_t a = common_rand() % ((uint##w##_t)-1);\t\\\n\t\t\tCK_PR_INC_T(w, a);\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\t\\\n\t}\n\n#define CK_PR_INC_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = -1, r = -1 & ~(uint##m##_t)(uint##w##_t)-1;\t\\\n\t\tck_pr_inc_##w((uint##w##_t *)(void *)&t);\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_INC_64\n\tif (m == 64) {\n#if defined(CK_F_PR_INC_32)\n\t\tCK_PR_INC_W(64, 32);\n#endif\n#if defined(CK_PR_INC_16)\n\t\tCK_PR_INC_W(64, 16);\n#endif\n#if defined(CK_PR_INC_8)\n\t\tCK_PR_INC_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_INC_64 */\n\n#ifdef CK_F_PR_INC_32\n\tif (m == 32) {\n#if defined(CK_F_PR_INC_16)\n\t\tCK_PR_INC_W(32, 16);\n#endif\n#if defined(CK_PR_INC_8)\n\t\tCK_PR_INC_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_INC_32 */\n\n#if defined(CK_F_PR_INC_16) && defined(CK_PR_INC_8)\n\tif (m == 16) {\n\t\tCK_PR_INC_W(16, 8);\n\t}\n#endif /* CK_PR_INC_16 && CK_PR_INC_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_INC_64\n\tCK_PR_INC_B(64);\n#endif\n\n#ifdef CK_F_PR_INC_32\n\tCK_PR_INC_B(32);\n#endif\n\n#ifdef CK_F_PR_INC_16\n\tCK_PR_INC_B(16);\n#endif\n\n#ifdef CK_F_PR_INC_8\n\tCK_PR_INC_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_load.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_LOAD_B(w)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = (uint##w##_t)-1, a = 0;\t\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"ck_pr_load_\" #w \": \");\t\t\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\t\t\\\n\t\ta = ck_pr_load_##w(&t);\t\t\t\t\t\t\t\\\n\t\tif (a != t) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##w \" != %#\" PRIx##w \"]\\n\", a, t);\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\tfor (i = 0; i < R_REPEAT; i++) {\t\t\t\t\t\\\n\t\t\tt = (uint##w##_t)common_rand();\t\t\t\t\t\\\n\t\t\ta = ck_pr_load_##w(&t);\t\t\t\t\t\t\\\n\t\t\tif (a != t) {\t\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"FAIL [%#\" PRIx##w \" != %#\" PRIx##w \"]\\n\", a, t);\\\n\t\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\t\t\\\n\t\tprintf(\" SUCCESS\\n\");\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_LOAD_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t f = 0;\t\t\t\t\t\t\\\n\t\tuint##w##_t j = (uint##w##_t)-1;\t\t\t\t\\\n\t\tf = ck_pr_load_##w(&j);\t\t\t\t\t\t\\\n\t\tif (f != j) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##w \"]\\n\", f, j);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_LOAD_64\n\tif (m == 64) {\n#if defined(CK_F_PR_LOAD_32)\n\t\tCK_PR_LOAD_W(64, 32);\n#endif\n#if defined(CK_PR_LOAD_16)\n\t\tCK_PR_LOAD_W(64, 16);\n#endif\n#if defined(CK_PR_LOAD_8)\n\t\tCK_PR_LOAD_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_LOAD_64 */\n\n#ifdef CK_F_PR_LOAD_32\n\tif (m == 32) {\n#if defined(CK_F_PR_LOAD_16)\n\t\tCK_PR_LOAD_W(32, 16);\n#endif\n#if defined(CK_PR_LOAD_8)\n\t\tCK_PR_LOAD_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_LOAD_32 */\n\n#if defined(CK_F_PR_LOAD_16) && defined(CK_PR_LOAD_8)\n\tif (m == 16)\n\t\tCK_PR_LOAD_W(16, 8);\n#endif /* CK_PR_LOAD_16 && CK_PR_LOAD_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_LOAD_64\n\tCK_PR_LOAD_B(64);\n#endif\n\n#ifdef CK_F_PR_LOAD_32\n\tCK_PR_LOAD_B(32);\n#endif\n\n#ifdef CK_F_PR_LOAD_16\n\tCK_PR_LOAD_B(16);\n#endif\n\n#ifdef CK_F_PR_LOAD_8\n\tCK_PR_LOAD_B(8);\n#endif\n\n#if 0\n\tuint64_t a[2] = {0, 0}, b[2] = {0x1111111144444444, 0x2222222266666666};\n\tprintf(\"%\" PRIx64 \":%\" PRIx64 \" -> \", a[0], a[1]);\n\tck_pr_load_64_2(&b, &a);\n\tprintf(\"%\" PRIx64 \":%\" PRIx64 \"\\n\", a[0], a[1]);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_n.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#define REPEAT 2000000\n\n#define TEST_N(K, S, T, P, D)\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\\\n\trun_test_##K##_##S(void)\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tint i, r;\t\t\t\t\t\\\n\t\tT x = 0, y = 0;\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t\tputs(\"***TESTING ck_pr_\"#K\"_\"#S\"***\");\t\t\\\n\t\tcommon_srand((unsigned int)getpid());\t\t\\\n\t\tfor (i = 0; i < REPEAT; ++i) {\t\t\t\\\n\t\t\tr = common_rand();\t\t\t\t\\\n\t\t\tx += r;\t\t\t\t\t\\\n\t\t\tx = P x;\t\t\t\t\\\n\t\t\ty += r;\t\t\t\t\t\\\n\t\t\tck_pr_##K##_##S(&y);\t\t\t\\\n\t\t}\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"Value of operation \"#K\" on 2000000 \"\t\\\n\t\t\t\"random numbers\\n\"\t\t\t\\\n\t\t\t\"\\tusing \"#P\": %\"#D\",\\n\"\t\t\\\n\t\t\t\"\\tusing ck_pr_\"#K\"_\"#S\": %\"#D\",\\n\",\t\\\n\t\t\tx, y);\t\t\t\t\t\\\n\t\t(x == y) ? puts(\"SUCCESS.\")\t\t\t\\\n\t\t\t : puts(\"FAILURE.\");\t\t\t\\\n\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\\\n\t}\n\n#define GENERATE_TEST(K, P)\t\t\t\\\n\tTEST_N(K, int, int, P, d)\t\t\\\n\tTEST_N(K, uint, unsigned int, P, u)\t\\\n\tstatic void\t\t\t\t\\\n\trun_test_##K(void)\t\t\t\\\n\t{\t\t\t\t\t\\\n\t\trun_test_##K##_int();\t\t\\\n\t\trun_test_##K##_uint();\t\t\\\n\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\\\n\t}\n\nGENERATE_TEST(not, ~)\nGENERATE_TEST(neg, -)\n\n#undef GENERATE_TEST\n#undef TEST_N\n\nint\nmain(void)\n{\n\trun_test_not();\n\trun_test_neg();\n\n\treturn (0);\n}\n\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_or.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define BM(m, w) (uint##m##_t)(uint##w##_t)-1\n\n#define CK_PR_OR_T(w, v, d)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t;\t\t\t\t\t\t\t\\\n\t\tck_pr_or_##w(&t, 1ULL << (w - 1));\t\t\t\t\\\n\t\tt = v;\t\t\t\t\t\t\t\t\\\n\t\tck_pr_or_##w(&t, d);\t\t\t\t\t\t\\\n\t\tif (t != (uint##w##_t)(v | d)) {\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w \"]\\n\",\\\n\t\t\t\t\t(uint##w##_t)v, d, t);\t\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_OR_B(w)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\\\n\t\tprintf(\"ck_pr_or_\" #w \": \");\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\\\n\t\t\tuint##w##_t a = (uint##w##_t)common_rand();\t\\\n\t\t\tuint##w##_t b = (uint##w##_t)common_rand();\t\\\n\t\t\tCK_PR_OR_T(w, a, b);\t\t\t\\\n\t\t}\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\\\n\t\tprintf(\"   SUCCESS\\n\");\t\t\t\t\\\n\t}\n\n#define CK_PR_OR_W(m, w)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = 0;\t\t\t\t\t\t\t\t\\\n\t\tck_pr_or_##w((uint##w##_t *)(void *)&t, -1);\t\t\t\t\t\\\n\t\tif (t != BM(m, w)) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"  FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, BM(m, w));\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_OR_64\n\tif (m == 64) {\n#if defined(CK_F_PR_OR_32)\n\t\tCK_PR_OR_W(64, 32);\n#endif\n#if defined(CK_PR_OR_16)\n\t\tCK_PR_OR_W(64, 16);\n#endif\n#if defined(CK_PR_OR_8)\n\t\tCK_PR_OR_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_OR_64 */\n\n#ifdef CK_F_PR_OR_32\n\tif (m == 32) {\n#if defined(CK_F_PR_OR_16)\n\t\tCK_PR_OR_W(32, 16);\n#endif\n#if defined(CK_PR_OR_8)\n\t\tCK_PR_OR_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_OR_32 */\n\n#if defined(CK_F_PR_OR_16) && defined(CK_PR_OR_8)\n\tif (m == 16) {\n\t\tCK_PR_OR_W(16, 8);\n\t}\n#endif /* CK_PR_OR_16 && CK_PR_OR_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_OR_64\n\tCK_PR_OR_B(64);\n#endif\n\n#ifdef CK_F_PR_OR_32\n\tCK_PR_OR_B(32);\n#endif\n\n#ifdef CK_F_PR_OR_16\n\tCK_PR_OR_B(16);\n#endif\n\n#ifdef CK_F_PR_OR_8\n\tCK_PR_OR_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_store.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include \"../../common.h\"\n#include <ck_pr.h>\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_STORE_B(w)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = (uint##w##_t)-1, a = 0, b;\t\t\t\t\\\n\t\tck_pr_store_##w(&b, 1ULL << (w - 1));\t\t\t\t\t\\\n\t\tunsigned int i;\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"ck_pr_store_\" #w \": \");\t\t\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\t\t\\\n\t\tck_pr_store_##w(&a, t);\t\t\t\t\t\t\t\\\n\t\tif (a != t) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##w \" != %#\" PRIx##w \"]\\n\", a, t);\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\tfor (i = 0; i < R_REPEAT; i++) {\t\t\t\t\t\\\n\t\t\tt = (uint##w##_t)common_rand();\t\t\t\t\t\\\n\t\t\tck_pr_store_##w(&a, t);\t\t\t\t\t\t\\\n\t\t\tif (a != t) {\t\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"FAIL [%#\" PRIx##w \" != %#\" PRIx##w \"]\\n\", a, t);\\\n\t\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"SUCCESS\\n\");\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_STORE_W(m, w)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t f = 0;\t\t\t\t\t\t\\\n\t\tuint##w##_t j = (uint##w##_t)-1;\t\t\t\t\\\n\t\tck_pr_store_##w((uint##w##_t *)(void *)&f, j);\t\t\t\\\n\t\tif (f != j) {\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [%#\" PRIx##m \" != %#\" PRIx##w \"]\\n\", f, j);\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_STORE_64\n\tif (m == 64) {\n#if defined(CK_F_PR_STORE_32)\n\t\tCK_PR_STORE_W(64, 32);\n#endif\n#if defined(CK_PR_STORE_16)\n\t\tCK_PR_STORE_W(64, 16);\n#endif\n#if defined(CK_PR_STORE_8)\n\t\tCK_PR_STORE_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_STORE_64 */\n\n#ifdef CK_F_PR_STORE_32\n\tif (m == 32) {\n#if defined(CK_F_PR_STORE_16)\n\t\tCK_PR_STORE_W(32, 16);\n#endif\n#if defined(CK_PR_STORE_8)\n\t\tCK_PR_STORE_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_STORE_32 */\n\n#if defined(CK_F_PR_STORE_16) && defined(CK_PR_STORE_8)\n\tif (m == 16)\n\t\tCK_PR_STORE_W(16, 8);\n#endif /* CK_PR_STORE_16 && CK_PR_STORE_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n#if defined(CK_F_PR_STORE_DOUBLE) && defined(CK_F_PR_LOAD_DOUBLE)\n\tdouble d;\n\n\tck_pr_store_double(&d, 0.0);\n\tif (ck_pr_load_double(&d) != 0.0) {\n\t\tck_error(\"Stored 0 in double, did not find 0.\\n\");\n\t}\n#endif\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_STORE_64\n\tCK_PR_STORE_B(64);\n#endif\n\n#ifdef CK_F_PR_STORE_32\n\tCK_PR_STORE_B(32);\n#endif\n\n#ifdef CK_F_PR_STORE_16\n\tCK_PR_STORE_B(16);\n#endif\n\n#ifdef CK_F_PR_STORE_8\n\tCK_PR_STORE_B(8);\n#endif\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_sub.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define CK_PR_SUB_T(w, v, d)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = v;\t\t\t\t\t\t\t\\\n\t\tck_pr_sub_##w(&t, d);\t\t\t\t\t\t\t\\\n\t\tif (t != (uint##w##_t)(v - d)) {\t\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w \"]\\n\",\t\\\n\t\t\t\t\t(uint##w##_t)v, d, t);\t\t\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_SUB_B(w)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\t\t\t\\\n\t\tprintf(\"ck_pr_sub_\" #w \": \");\t\t\t\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\t\t\t\\\n\t\t\tuint##w##_t a = common_rand() % ((uint##w##_t)-1 / 2);\t\t\\\n\t\t\tuint##w##_t b = common_rand() % ((uint##w##_t)-1 / 2);\t\t\\\n\t\t\tCK_PR_SUB_T(w, a, b);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_SUB_W(m, w)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = 0, r = (uint##m##_t)(uint##w##_t)-1;\t\t\t\\\n\t\tck_pr_sub_##w((uint##w##_t *)(void *)&t, 1);\t\t\t\t\\\n\t\tif (t != r) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"  FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, r);\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t\tt = 0;\t\t\t\t\t\t\t\t\t\\\n\t\tck_pr_sub_##w((uint##w##_t *)(void *)&t, -1);\t\t\t\t\\\n\t\tif (t != 1) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"  FAIL [%#\" PRIx##m \" != 1]\\n\", t);\t\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_SUB_64\n\tif (m == 64) {\n#if defined(CK_F_PR_SUB_32)\n\t\tCK_PR_SUB_W(64, 32);\n#endif\n#if defined(CK_PR_SUB_16)\n\t\tCK_PR_SUB_W(64, 16);\n#endif\n#if defined(CK_PR_SUB_8)\n\t\tCK_PR_SUB_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_SUB_64 */\n\n#ifdef CK_F_PR_SUB_32\n\tif (m == 32) {\n#if defined(CK_F_PR_SUB_16)\n\t\tCK_PR_SUB_W(32, 16);\n#endif\n#if defined(CK_PR_SUB_8)\n\t\tCK_PR_SUB_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_SUB_32 */\n\n#if defined(CK_F_PR_SUB_16) && defined(CK_PR_SUB_8)\n\tif (m == 16) {\n\t\tCK_PR_SUB_W(16, 8);\n\t}\n#endif /* CK_PR_SUB_16 && CK_PR_SUB_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_SUB_64\n\tCK_PR_SUB_B(64);\n#endif\n\n#ifdef CK_F_PR_SUB_32\n\tCK_PR_SUB_B(32);\n#endif\n\n#ifdef CK_F_PR_SUB_16\n\tCK_PR_SUB_B(16);\n#endif\n\n#ifdef CK_F_PR_SUB_8\n\tCK_PR_SUB_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_unary.c",
    "content": "/*\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <stdio.h>\n#include <stdlib.h>\n#include <unistd.h>\n#include <ck_pr.h>\n\n#define REPEAT 2000000\n\n#define TEST_UNARY(K, S, M, T, P, D, H)\t\t\t\t\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\t\t\\\n\ttest_##K##_##S(M *target)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t*target = *target P 1;\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\t\t\\\n\ttest_##K##_##S##_zero(M *target, bool *zero)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t*zero = *target == H;\t\t\t\t\t\t\t\t\t\\\n\t\t*target = *target P 1;\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\\\n\tstatic void\t\t\t\t\t\t\t\t\t\t\t\\\n\trun_test_##K##_##S(bool use_zero)\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tint i;\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tT x = 1, y = 1;\t\t\t\t\t\t\t\t\t\t\\\n\t\tbool zero_x = false, zero_y = false;\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tuse_zero ? puts(\"***TESTING ck_pr_\"#K\"_\"#S\"_zero***\")\t\t\t\t\t\\\n\t\t\t : puts(\"***TESTING ck_pr_\"#K\"_\"#S\"***\");\t\t\t\t\t\\\n\t\tfor (i = 0; i < REPEAT; ++i) {\t\t\t\t\t\t\t\t\\\n\t\t\tif (use_zero) {\t\t\t\t\t\t\t\t\t\\\n\t\t\t\ttest_##K##_##S##_zero(&x, &zero_x);\t\t\t\t\t\\\n\t\t\t\tck_pr_##K##_##S##_zero(&y, &zero_y);\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t\telse {\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\ttest_##K##_##S(&x);\t\t\t\t\t\t\t\\\n\t\t\t\tck_pr_##K##_##S(&y);\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (x != y || zero_x != zero_y) {\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"Serial(%\"#D\") and ck_pr(%\"#D\")\"\t\t\t\t\t\\\n\t\t\t\t\t#K\"_\"#S\" do not match.\\n\"\t\t\t\t\t\\\n\t\t\t\t\t\"FAILURE.\\n\",\t\t\t\t\t\t\t\\\n\t\t\t\t\tx, y);\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\treturn;\t\t\t\t\t\t\t\t\t\\\n\t\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\tif (zero_x)\t\t\t\t\t\t\t\t\t\\\n\t\t\t\tprintf(\"Variables are zero at iteration %d\\n\", i);\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tprintf(\"\\tserial_\"#K\"_\"#S\": %\"#D\"\\n\"\t\t\t\t\t\t\t\\\n\t\t\t\"\\tck_pr_\"#K\"_\"#S\": %\"#D\"\\n\"\t\t\t\t\t\t\t\\\n\t\t\t\"SUCCESS.\\n\",\t\t\t\t\t\t\t\t\t\\\n\t\t\tx, y);\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\treturn;\t\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\n#define GENERATE_TEST(K, P, Y, Z)\t\t\t\t\t\\\n\tTEST_UNARY(K, int, int, int, P, d, Y)\t\t\t\t\\\n\tTEST_UNARY(K, uint, unsigned int, unsigned int, P, u, Z)\t\\\n\tstatic void\t\t\t\t\t\t\t\\\n\trun_test_##K(void)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\\\n\t\trun_test_##K##_int(false);\t\t\t\t\\\n\t\trun_test_##K##_int(true);\t\t\t\t\\\n\t\trun_test_##K##_uint(false);\t\t\t\t\\\n\t\trun_test_##K##_uint(true);\t\t\t\t\\\n\t}\n\nGENERATE_TEST(inc, +, -1, UINT_MAX)\nGENERATE_TEST(dec, -, 1, 1)\n\n#undef GENERATE_TEST\n#undef TEST_UNARY\n\nint\nmain(void)\n{\n\trun_test_inc();\n\trun_test_dec();\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_pr/validate/ck_pr_xor.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <inttypes.h>\n#include <stdbool.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include <ck_pr.h>\n\n#include \"../../common.h\"\n#ifndef R_REPEAT\n#define R_REPEAT 200000\n#endif\n\n#define BM(m, w) ((uint##m##_t)-1 << (w))\n\n#define CK_PR_XOR_T(w, v, d)\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\\\n\t\tuint##w##_t t = v;\t\t\t\t\t\t\\\n\t\tck_pr_xor_##w(&t, d);\t\t\t\t\t\t\\\n\t\tif (t != (uint##w##_t)(v ^ d)) {\t\t\t\t\\\n\t\t\tprintf(\"FAIL [\");\t\t\t\t\t\\\n\t\t\tprintf(\"%\" PRIu##w \" (%\" PRIu##w \") -> %\" PRIu##w \"]\\n\",\\\n\t\t\t\t\t(uint##w##_t)v, d, t);\t\t\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\\\n\t}\n\n#define CK_PR_XOR_B(w)\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\\\n\t\tunsigned int __ck_i = 0;\t\t\t\\\n\t\tprintf(\"ck_pr_xor_\" #w \": \");\t\t\t\\\n\t\tif (w < 10)\t\t\t\t\t\\\n\t\t\tprintf(\" \");\t\t\t\t\\\n\t\tfor (__ck_i = 0; __ck_i < R_REPEAT; __ck_i++) {\t\\\n\t\t\tuint##w##_t a = (uint##w##_t)common_rand();\t\\\n\t\t\tuint##w##_t b = (uint##w##_t)common_rand();\t\\\n\t\t\tCK_PR_XOR_T(w, a, b);\t\t\t\\\n\t\t}\t\t\t\t\t\t\\\n\t\trg_width(w);\t\t\t\t\t\\\n\t\tprintf(\"  SUCCESS\\n\");\t\t\t\t\\\n\t}\n\n#define CK_PR_XOR_W(m, w)\t\t\t\t\t\t\t\t\t\\\n\t{\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tuint##m##_t t = -1;\t\t\t\t\t\t\t\t\\\n\t\tck_pr_xor_##w((uint##w##_t *)(void *)&t, -1);\t\t\t\t\t\\\n\t\tif (t != BM(m, w)) {\t\t\t\t\t\t\t\t\\\n\t\t\tprintf(\"  FAIL [%#\" PRIx##m \" != %#\" PRIx##m \"]\\n\", t, BM(m, w));\t\\\n\t\t\texit(EXIT_FAILURE);\t\t\t\t\t\t\t\\\n\t\t}\t\t\t\t\t\t\t\t\t\t\\\n\t}\n\nstatic void\nrg_width(int m)\n{\n\n\t/* Other architectures are bi-endian. */\n#if !defined(__x86__) && !defined(__x86_64__)\n\treturn;\n#endif\n\n#ifdef CK_F_PR_XOR_64\n\tif (m == 64) {\n#if defined(CK_F_PR_XOR_32)\n\t\tCK_PR_XOR_W(64, 32);\n#endif\n#if defined(CK_PR_XOR_16)\n\t\tCK_PR_XOR_W(64, 16);\n#endif\n#if defined(CK_PR_XOR_8)\n\t\tCK_PR_XOR_W(64, 8);\n#endif\n\t}\n#endif /* CK_PR_XOR_64 */\n\n#ifdef CK_F_PR_XOR_32\n\tif (m == 32) {\n#if defined(CK_F_PR_XOR_16)\n\t\tCK_PR_XOR_W(32, 16);\n#endif\n#if defined(CK_PR_XOR_8)\n\t\tCK_PR_XOR_W(32, 8);\n#endif\n\t}\n#endif /* CK_PR_XOR_32 */\n\n#if defined(CK_F_PR_XOR_16) && defined(CK_PR_XOR_8)\n\tif (m == 16) {\n\t\tCK_PR_XOR_W(16, 8);\n\t}\n#endif /* CK_PR_XOR_16 && CK_PR_XOR_8 */\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\n\tcommon_srand((unsigned int)getpid());\n\n#ifdef CK_F_PR_XOR_64\n\tCK_PR_XOR_B(64);\n#endif\n\n#ifdef CK_F_PR_XOR_32\n\tCK_PR_XOR_B(32);\n#endif\n\n#ifdef CK_F_PR_XOR_16\n\tCK_PR_XOR_B(16);\n#endif\n\n#ifdef CK_F_PR_XOR_8\n\tCK_PR_XOR_B(8);\n#endif\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_queue/validate/ck_list.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <ck_queue.h>\n\n#include \"../../common.h\"\n\nstruct test {\n\tint value;\n\tCK_LIST_ENTRY(test) list_entry;\n};\nstatic CK_LIST_HEAD(test_list, test) head = CK_LIST_HEAD_INITIALIZER(head);\n\nstatic int goal;\n\nstatic void\ntest_foreach(void)\n{\n\tstruct test *n, *next, *safe;\n\tint i, s = 0, j = 0, k = 0;\n\n\tfor (i = goal; i != 0; i = goal) {\n\t\ts = 0;\n\n\t\tCK_LIST_FOREACH(n, &head, list_entry) {\n\t\t\tj++;\n\t\t\tif (s == 0)\n\t\t\t\ts = n->value;\n\t\t\telse\n\t\t\t\ts = s - 1;\n\n\t\t\tif (n->value != s) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, n->value);\n\t\t\t}\n\n\t\t\tnext = CK_LIST_NEXT(n, list_entry);\n\t\t\tif (next != NULL && next->value != s - 1) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, next->value);\n\t\t\t}\n\n\t\t\ti--;\n\t\t}\n\n\t\tif (i == 0)\n\t\t\tbreak;\n\n\t\ts = 0;\n\t\tCK_LIST_FOREACH_SAFE(n, &head, list_entry, safe) {\n\t\t\tk++;\n\n\t\t\tif (s == 0)\n\t\t\t\ts = n->value;\n\t\t\telse\n\t\t\t\ts = s - 1;\n\n\t\t\tif (n->value != s) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, n->value);\n\t\t\t}\n\n\t\t\tnext = CK_LIST_NEXT(n, list_entry);\n\t\t\tif (next != NULL && next->value != s - 1) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, next->value);\n\t\t\t}\n\n\t\t\ti--;\n\t\t}\n\n\t\tif (i == 0 || CK_LIST_EMPTY(&head) == true)\n\t\t\tbreak;\n\t}\n\n\tfprintf(stderr, \"(%d, %d) \", j, k);\n\treturn;\n}\n\nstatic void *\nexecute(void *c)\n{\n\n\t(void)c;\n\ttest_foreach();\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *thread;\n\tstruct test *n, a, b;\n\tstruct test_list target;\n\tint n_threads, i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: %s <number of threads> <number of list entries>\\n\", argv[0]);\n\t}\n\n\tn_threads = atoi(argv[1]);\n\tif (n_threads < 1) {\n\t\tck_error(\"ERROR: Number of threads must be >= 1.\\n\");\n\t}\n\n\tthread = malloc(sizeof(pthread_t) * n_threads);\n\tassert(thread != NULL);\n\n\tgoal = atoi(argv[2]);\n\tif (goal < 4) {\n\t\tck_error(\"ERROR: Number of entries must be >= 4.\\n\");\n\t}\n\n\tfprintf(stderr, \"Beginning serial test...\");\n\tCK_LIST_INIT(&head);\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = i;\n\t\tCK_LIST_INSERT_HEAD(&head, n, list_entry);\n\t}\n\n\ttest_foreach();\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = CK_LIST_FIRST(&head);\n\t\tCK_LIST_REMOVE(n, list_entry);\n\t\tfree(n);\n\t}\n\n\tCK_LIST_INSERT_HEAD(&head, &a, list_entry);\n\tCK_LIST_INSERT_HEAD(&head, &b, list_entry);\n\tCK_LIST_REMOVE(&a, list_entry);\n\tif (CK_LIST_FIRST(&head) != &b)\n\t\tck_error(\"List is in invalid state.\\n\");\n\tCK_LIST_REMOVE(&b, list_entry);\n\n\tif (CK_LIST_EMPTY(&head) == false) {\n\t\tck_error(\"List is not empty after bulk removal.\\n\");\n\t}\n\n\tCK_LIST_INSERT_HEAD(&head, &a, list_entry);\n\tCK_LIST_INSERT_AFTER(&a, &b, list_entry);\n\n\tif (CK_LIST_NEXT(&b, list_entry) != NULL)\n\t\tck_error(\"Inserted item after last, it should not have no next.\\n\");\n\n\tCK_LIST_INIT(&head);\n\n\tCK_LIST_INSERT_HEAD(&head, &a, list_entry);\n\tCK_LIST_INSERT_BEFORE(&a, &b, list_entry);\n\n\tif (CK_LIST_NEXT(&b, list_entry) != &a)\n\t\tck_error(\"Inserted item before last, it should point to last.\\n\");\n\n\tCK_LIST_INIT(&head);\n\tfprintf(stderr, \"done (success)\\n\");\n\n\tfprintf(stderr, \"Beginning parallel traversal...\");\n\n\tn = malloc(sizeof *n);\n\tassert(n != NULL);\n\tn->value = 1;\n\tCK_LIST_INSERT_HEAD(&head, n, list_entry);\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tint r = pthread_create(&thread[i], NULL, execute, NULL);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 2; i <= goal; i++) {\n\t\tvolatile int j;\n\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = i;\n\t\tCK_LIST_INSERT_HEAD(&head, n, list_entry);\n\t\tfor (j = 0; j <= 1000; j++);\n\t}\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tint r = pthread_create(&thread[i], NULL, execute, NULL);\n\t\tassert(r == 0);\n\t}\n\n\tCK_LIST_MOVE(&target, &head, list_entry);\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tvolatile int j;\n\n\t\tif (CK_LIST_EMPTY(&target) == false) {\n\t\t\tstruct test *r = CK_LIST_FIRST(&target);\n\t\t\tCK_LIST_REMOVE(r, list_entry);\n\t\t}\n\n\t\tfor (j = 0; j <= 1000; j++);\n\t}\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \"done (success)\\n\");\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_queue/validate/ck_slist.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <ck_queue.h>\n\n#include \"../../common.h\"\n\nstruct test {\n\tint value;\n\tCK_SLIST_ENTRY(test) list_entry;\n};\nstatic CK_SLIST_HEAD(test_list, test) head = CK_SLIST_HEAD_INITIALIZER(head);\n\nstatic int goal;\n\nstatic void\ntest_foreach(void)\n{\n\tstruct test *n, *next, *safe;\n\tint i, s = 0, j = 0, k = 0;\n\n\tfor (i = goal; i != 0; i = goal) {\n\t\ts = 0;\n\n\t\tCK_SLIST_FOREACH(n, &head, list_entry) {\n\t\t\tj++;\n\t\t\tif (s == 0)\n\t\t\t\ts = n->value;\n\t\t\telse\n\t\t\t\ts = s - 1;\n\n\t\t\tif (n->value != s) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, n->value);\n\t\t\t}\n\n\t\t\tnext = CK_SLIST_NEXT(n, list_entry);\n\t\t\tif (next != NULL && next->value != s - 1) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, next->value);\n\t\t\t}\n\n\t\t\ti--;\n\t\t}\n\n\t\tif (i == 0)\n\t\t\tbreak;\n\n\t\ts = 0;\n\t\tCK_SLIST_FOREACH_SAFE(n, &head, list_entry, safe) {\n\t\t\tk++;\n\n\t\t\tif (s == 0)\n\t\t\t\ts = n->value;\n\t\t\telse\n\t\t\t\ts = s - 1;\n\n\t\t\tif (n->value != s) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, n->value);\n\t\t\t}\n\n\t\t\tnext = CK_SLIST_NEXT(n, list_entry);\n\t\t\tif (next != NULL && next->value != s - 1) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, next->value);\n\t\t\t}\n\n\t\t\ti--;\n\t\t}\n\n\t\tif (i == 0 || CK_SLIST_EMPTY(&head) == true)\n\t\t\tbreak;\n\t}\n\n\tfprintf(stderr, \"(%d, %d) \", j, k);\n\treturn;\n}\n\nstatic void *\nexecute(void *c)\n{\n\n\t(void)c;\n\ttest_foreach();\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *thread;\n\tstruct test *n;\n\tstruct test_list target;\n\tint n_threads, i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: %s <number of threads> <number of list entries>\\n\", argv[0]);\n\t}\n\n\tn_threads = atoi(argv[1]);\n\tif (n_threads < 1) {\n\t\tck_error(\"ERROR: Number of threads must be >= 1.\\n\");\n\t}\n\n\tthread = malloc(sizeof(pthread_t) * n_threads);\n\tassert(thread != NULL);\n\n\tgoal = atoi(argv[2]);\n\tif (goal < 4) {\n\t\tck_error(\"ERROR: Number of entries must be >= 4.\\n\");\n\t}\n\n\tfprintf(stderr, \"Beginning serial test...\");\n\tCK_SLIST_INIT(&head);\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = i;\n\t\tCK_SLIST_INSERT_HEAD(&head, n, list_entry);\n\t}\n\n\ttest_foreach();\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = CK_SLIST_FIRST(&head);\n\t\tCK_SLIST_REMOVE_HEAD(&head, list_entry);\n\t\tfree(n);\n\t}\n\n\tif (CK_SLIST_EMPTY(&head) == false) {\n\t\tck_error(\"List is not empty after bulk removal.\\n\");\n\t}\n\n\tfprintf(stderr, \"done (success)\\n\");\n\n\tfprintf(stderr, \"Beginning parallel traversal...\");\n\n\tn = malloc(sizeof *n);\n\tassert(n != NULL);\n\tn->value = 1;\n\tCK_SLIST_INSERT_HEAD(&head, n, list_entry);\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tint r = pthread_create(&thread[i], NULL, execute, NULL);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 2; i <= goal; i++) {\n\t\tvolatile int j;\n\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = i;\n\t\tCK_SLIST_INSERT_HEAD(&head, n, list_entry);\n\t\tfor (j = 0; j <= 1000; j++);\n\t}\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tint r = pthread_create(&thread[i], NULL, execute, NULL);\n\t\tassert(r == 0);\n\t}\n\n\tCK_SLIST_MOVE(&target, &head, list_entry);\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tvolatile int j;\n\n\t\tif (CK_SLIST_EMPTY(&target) == false)\n\t\t\tCK_SLIST_REMOVE_HEAD(&target, list_entry);\n\n\t\tfor (j = 0; j <= 1000; j++);\n\n\t\tif (CK_SLIST_EMPTY(&target) == false) {\n\t\t\tstruct test *r = CK_SLIST_FIRST(&target);\n\t\t\tCK_SLIST_REMOVE(&target, r, test, list_entry);\n\t\t}\n\t}\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \"done (success)\\n\");\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_queue/validate/ck_stailq.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n#include <ck_queue.h>\n#include \"../../common.h\"\n\nstruct test {\n\tint value;\n\tCK_STAILQ_ENTRY(test) list_entry;\n};\nstatic CK_STAILQ_HEAD(test_list, test) head = CK_STAILQ_HEAD_INITIALIZER(head);\n\nstatic int goal;\n\nstatic void\ntest_foreach(void)\n{\n\tstruct test *n, *next, *safe;\n\tint i, s = 0, j = 0, k = 0;\n\n\tfor (i = goal; i != 0; i = goal) {\n\t\ts = 0;\n\n\t\tCK_STAILQ_FOREACH(n, &head, list_entry) {\n\t\t\tj++;\n\t\t\tif (s == 0)\n\t\t\t\ts = n->value;\n\t\t\telse\n\t\t\t\ts = s - 1;\n\n\t\t\tif (n->value != s) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, n->value);\n\t\t\t}\n\n\t\t\tnext = CK_STAILQ_NEXT(n, list_entry);\n\t\t\tif (next != NULL && next->value != s - 1) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, next->value);\n\t\t\t}\n\n\t\t\ti--;\n\t\t}\n\n\t\tif (i == 0)\n\t\t\tbreak;\n\n\t\ts = 0;\n\t\tCK_STAILQ_FOREACH_SAFE(n, &head, list_entry, safe) {\n\t\t\tk++;\n\n\t\t\tif (s == 0)\n\t\t\t\ts = n->value;\n\t\t\telse\n\t\t\t\ts = s - 1;\n\n\t\t\tif (n->value != s) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, n->value);\n\t\t\t}\n\n\t\t\tnext = CK_STAILQ_NEXT(n, list_entry);\n\t\t\tif (next != NULL && next->value != s - 1) {\n\t\t\t\tck_error(\"\\nExpected %d, but got %d.\\n\",\n\t\t\t\t    s, next->value);\n\t\t\t}\n\n\t\t\ti--;\n\t\t}\n\n\t\tif (i == 0 || CK_STAILQ_EMPTY(&head) == true)\n\t\t\tbreak;\n\t}\n\n\tfprintf(stderr, \"(%d, %d) \", j, k);\n\treturn;\n}\n\nstatic void *\nexecute(void *c)\n{\n\n\t(void)c;\n\ttest_foreach();\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *thread;\n\tstruct test *n, a, b;\n\tstruct test_list target;\n\tint n_threads, i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: %s <number of threads> <number of list entries>\\n\", argv[0]);\n\t}\n\n\tn_threads = atoi(argv[1]);\n\tif (n_threads < 1) {\n\t\tck_error(\"ERROR: Number of threads must be >= 1.\\n\");\n\t}\n\n\tthread = malloc(sizeof(pthread_t) * n_threads);\n\tassert(thread != NULL);\n\n\tgoal = atoi(argv[2]);\n\tif (goal < 4) {\n\t\tck_error(\"ERROR: Number of entries must be >= 4.\\n\");\n\t}\n\n\tfprintf(stderr, \"Beginning serial test...\");\n\tCK_STAILQ_INIT(&head);\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = i;\n\t\tCK_STAILQ_INSERT_HEAD(&head, n, list_entry);\n\t}\n\n\ttest_foreach();\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = CK_STAILQ_FIRST(&head);\n\t\tCK_STAILQ_REMOVE(&head, n, test, list_entry);\n\t\tfree(n);\n\t}\n\n\tif (CK_STAILQ_EMPTY(&head) == false) {\n\t\tck_error(\"List is not empty after bulk removal.\\n\");\n\t}\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = goal - i;\n\t\tCK_STAILQ_INSERT_TAIL(&head, n, list_entry);\n\t}\n\n\ttest_foreach();\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tn = CK_STAILQ_FIRST(&head);\n\t\tCK_STAILQ_REMOVE(&head, n, test, list_entry);\n\t\tfree(n);\n\t}\n\n\tif (CK_STAILQ_EMPTY(&head) == false) {\n\t\tck_error(\"List is not empty after bulk removal.\\n\");\n\t}\n\n\tCK_STAILQ_INSERT_HEAD(&head, &a, list_entry);\n\tCK_STAILQ_INSERT_HEAD(&head, &b, list_entry);\n\tCK_STAILQ_REMOVE(&head, &a, test, list_entry);\n\tif (CK_STAILQ_FIRST(&head) != &b)\n\t\tck_error(\"List is in invalid state.\\n\");\n\tCK_STAILQ_REMOVE(&head, &b, test, list_entry);\n\n\tif (CK_STAILQ_EMPTY(&head) == false) {\n\t\tck_error(\"List is not empty after bulk removal.\\n\");\n\t}\n\n\tCK_STAILQ_INSERT_HEAD(&head, &a, list_entry);\n\tCK_STAILQ_INSERT_AFTER(&head, &a, &b, list_entry);\n\n\tif (CK_STAILQ_NEXT(&b, list_entry) != NULL)\n\t\tck_error(\"Inserted item after last, it should not have no next.\\n\");\n\n\tCK_STAILQ_INIT(&head);\n\n\tCK_STAILQ_INSERT_HEAD(&head, &a, list_entry);\n\tif (CK_STAILQ_NEXT(&a, list_entry) != NULL)\n\t\tck_error(\"Inserted item as last, but it contains next pointer.\\n\");\n\n\tCK_STAILQ_INIT(&head);\n\tfprintf(stderr, \"done (success)\\n\");\n\n\tfprintf(stderr, \"Beginning parallel traversal...\");\n\n\tn = malloc(sizeof *n);\n\tassert(n != NULL);\n\tn->value = 1;\n\tCK_STAILQ_INSERT_HEAD(&head, n, list_entry);\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tint r = pthread_create(&thread[i], NULL, execute, NULL);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 2; i <= goal; i++) {\n\t\tvolatile int j;\n\n\t\tn = malloc(sizeof *n);\n\t\tassert(n != NULL);\n\t\tn->value = i;\n\t\tCK_STAILQ_INSERT_HEAD(&head, n, list_entry);\n\t\tfor (j = 0; j <= 1000; j++);\n\t}\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tint r = pthread_create(&thread[i], NULL, execute, NULL);\n\t\tassert(r == 0);\n\t}\n\n\tCK_STAILQ_MOVE(&target, &head, list_entry);\n\n\tfor (i = 1; i <= goal; i++) {\n\t\tvolatile int j;\n\n\t\tif (CK_STAILQ_EMPTY(&target) == false) {\n\t\t\tstruct test *r = CK_STAILQ_FIRST(&target);\n\t\t\tCK_STAILQ_REMOVE(&target, r, test, list_entry);\n\t\t}\n\n\t\tfor (j = 0; j <= 1000; j++);\n\t}\n\n\tfor (i = 0; i < n_threads; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \"done (success)\\n\");\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rhs/benchmark/parallel_bytestring.c",
    "content": "/*\n * Copyright 2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n#include \"../../common.h\"\n#include <ck_rhs.h>\n#include \"../../../src/ck_ht_hash.h\"\n#include <assert.h>\n#include <ck_epoch.h>\n#include <ck_malloc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <signal.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n#include <unistd.h>\n\nstatic ck_rhs_t hs CK_CC_CACHELINE;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\nstatic ck_epoch_t epoch_hs;\nstatic ck_epoch_record_t epoch_wr;\nstatic int n_threads;\nstatic bool next_stage;\n\nenum state {\n\tHS_STATE_STOP = 0,\n\tHS_STATE_GET,\n\tHS_STATE_STRICT_REPLACEMENT,\n\tHS_STATE_DELETION,\n\tHS_STATE_REPLACEMENT,\n\tHS_STATE_COUNT\n};\n\nstatic ck_spinlock_t mtx = CK_SPINLOCK_INITIALIZER;\nstatic struct affinity affinerator = AFFINITY_INITIALIZER;\nstatic uint64_t accumulator[HS_STATE_COUNT];\nstatic int barrier[HS_STATE_COUNT];\nstatic int state;\n\nstruct hs_epoch {\n\tck_epoch_entry_t epoch_entry;\n};\n\nCOMMON_ALARM_DECLARE_GLOBAL(hs_alarm, alarm_event, next_stage)\n\nstatic void\nalarm_handler(int s)\n{\n\n\t(void)s;\n\tnext_stage = true;\n\treturn;\n}\n\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\th = (unsigned long)MurmurHash64A(c, strlen(c), seed);\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void\nhs_destroy(ck_epoch_entry_t *e)\n{\n\n\tfree(e);\n\treturn;\n}\n\nstatic void *\nhs_malloc(size_t r)\n{\n\tck_epoch_entry_t *b;\n\n\tb = malloc(sizeof(*b) + r);\n\treturn b + 1;\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\tstruct hs_epoch *e = p;\n\n\t(void)b;\n\n\tif (r == true) {\n\t\t/* Destruction requires safe memory reclamation. */\n\t\tck_epoch_call(&epoch_wr, &(--e)->epoch_entry, hs_destroy);\n\t} else {\n\t\tfree(--e);\n\t}\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nstatic void\nset_init(void)\n{\n\tunsigned int mode = CK_RHS_MODE_OBJECT | CK_RHS_MODE_SPMC;\n\n\n\tck_epoch_init(&epoch_hs);\n\tck_epoch_register(&epoch_hs, &epoch_wr, NULL);\n\tcommon_srand48((long int)time(NULL));\n\tif (ck_rhs_init(&hs, mode, hs_hash, hs_compare, &my_allocator, 65536, common_lrand48()) == false) {\n\t\tperror(\"ck_rhs_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\nset_remove(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn (bool)ck_rhs_remove(&hs, h, value);\n}\n\nstatic bool\nset_replace(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_set(&hs, h, value, &previous);\n}\n\nstatic bool\nset_swap(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_fas(&hs, h, value, &previous);\n}\n\nstatic void *\nset_get(const char *value)\n{\n\tunsigned long h;\n\tvoid *v;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\tv = ck_rhs_get(&hs, h, value);\n\treturn v;\n}\n\nstatic bool\nset_insert(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_put(&hs, h, value);\n}\n\nstatic size_t\nset_count(void)\n{\n\n\treturn ck_rhs_count(&hs);\n}\n\nstatic bool\nset_reset(void)\n{\n\n\treturn ck_rhs_reset(&hs);\n}\n\nstatic void *\nreader(void *unused)\n{\n\tsize_t i;\n\tck_epoch_record_t epoch_record;\n\tint state_previous = HS_STATE_STOP;\n\tint n_state = 0;\n\tuint64_t s, j, a;\n\n\t(void)unused;\n\tif (aff_iterate(&affinerator) != 0)\n\t\tperror(\"WARNING: Failed to affine thread\");\n\n\ts = j = a = 0;\n\tck_epoch_register(&epoch_hs, &epoch_record, NULL);\n\tfor (;;) {\n\t\tj++;\n\t\tck_epoch_begin(&epoch_record, NULL);\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tchar *r;\n\n\t\t\tr = set_get(keys[i]);\n\t\t\tif (r == NULL) {\n\t\t\t\tif (n_state == HS_STATE_STRICT_REPLACEMENT) {\n\t\t\t\t\tck_error(\"ERROR: Did not find during replacement: %s\\n\", keys[i]);\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (strcmp(r, keys[i]) == 0)\n\t\t\t\tcontinue;\n\n\t\t\tck_error(\"ERROR: Found invalid value: [%s] but expected [%s]\\n\", (char *)r, keys[i]);\n\t\t}\n\t\ta += rdtsc() - s;\n\t\tck_epoch_end(&epoch_record, NULL);\n\n\t\tn_state = ck_pr_load_int(&state);\n\t\tif (n_state != state_previous) {\n\t\t\tck_spinlock_lock(&mtx);\n\t\t\taccumulator[state_previous] += a / (j * keys_length);\n\t\t\tck_spinlock_unlock(&mtx);\n\n\t\t\tck_pr_inc_int(&barrier[state_previous]);\n\t\t\twhile (ck_pr_load_int(&barrier[state_previous]) != n_threads + 1)\n\t\t\t\tck_pr_stall();\n\n\t\t\tstate_previous = n_state;\n\t\t\ts = j = a = 0;\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nstatic uint64_t\nacc(size_t i)\n{\n\tuint64_t r;\n\n\tck_spinlock_lock(&mtx);\n\tr = accumulator[i];\n\tck_spinlock_unlock(&mtx);\n\n\treturn r;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j, r;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, repeated;\n\tchar **t;\n\tpthread_t *readers;\n\tdouble p_r, p_d;\n\n\tCOMMON_ALARM_DECLARE_LOCAL(hs_alarm, alarm_event)\n\n\tr = 20;\n\ts = 8;\n\tp_d = 0.5;\n\tp_r = 0.5;\n\tn_threads = CORES - 1;\n\n\tif (argc < 2) {\n\t\tck_error(\"Usage: parallel <dictionary> [<interval length> <initial size> <readers>\\n\"\n\t\t    \" <probability of replacement> <probability of deletion> <epoch threshold>]\\n\");\n\t}\n\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tif (argc >= 4)\n\t\ts = (uint64_t)atoi(argv[3]);\n\n\tif (argc >= 5) {\n\t\tn_threads = atoi(argv[4]);\n\t\tif (n_threads < 1) {\n\t\t\tck_error(\"ERROR: Number of readers must be >= 1.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 6) {\n\t\tp_r = atof(argv[5]) / 100.00;\n\t\tif (p_r < 0) {\n\t\t\tck_error(\"ERROR: Probability of replacement must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tif (argc >= 7) {\n\t\tp_d = atof(argv[6]) / 100.00;\n\t\tif (p_d < 0) {\n\t\t\tck_error(\"ERROR: Probability of deletion must be >= 0 and <= 100.\\n\");\n\t\t}\n\t}\n\n\tCOMMON_ALARM_INIT(hs_alarm, alarm_event, r)\n\n\taffinerator.delta = 1;\n\treaders = malloc(sizeof(pthread_t) * n_threads);\n\tassert(readers != NULL);\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(argv[1], \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\tset_init();\n\n\tfor (i = 0; i < (size_t)n_threads; i++) {\n\t\tif (pthread_create(&readers[i], NULL, reader, NULL) != 0) {\n\t\t\tck_error(\"ERROR: Failed to create thread %zu.\\n\", i);\n\t\t}\n\t}\n\n\tfor (i = 0; i < keys_length; i++)\n\t\td += set_insert(keys[i]) == false;\n\n\tfprintf(stderr, \" [S] %d readers, 1 writer.\\n\", n_threads);\n\tfprintf(stderr, \" [S] %zu entries stored and %u duplicates.\\n\\n\",\n\t    set_count(), d);\n\n\tfprintf(stderr, \" ,- BASIC TEST\\n\");\n\tfprintf(stderr, \" | Executing SMR test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += set_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing replacement test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing get test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (set_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\ta = 0;\n\tfprintf(stderr, \" | Executing removal test...\");\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert(keys[i]);\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tfprintf(stderr, \" | Executing negative look-up test...\");\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_get(\"\\x50\\x03\\x04\\x05\\x06\\x10\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tfprintf(stderr, \"done (%\" PRIu64 \" ticks)\\n\", a / (r * keys_length));\n\n\tck_epoch_record_t epoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\n\tfprintf(stderr, \" ,- READER CONCURRENCY\\n\");\n\tfprintf(stderr, \" | Executing reader test...\");\n\n\tck_pr_store_int(&state, HS_STATE_GET);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_STOP]) != n_threads)\n\t\tck_pr_stall();\n\tck_pr_inc_int(&barrier[HS_STATE_STOP]);\n\tcommon_sleep(r);\n\tck_pr_store_int(&state, HS_STATE_STRICT_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_GET]) != n_threads)\n\t\tck_pr_stall();\n\n\tfprintf(stderr, \"done (reader = %\" PRIu64 \" ticks)\\n\",\n\t    acc(HS_STATE_GET) / n_threads);\n\n\tfprintf(stderr, \" | Executing strict replacement test...\");\n\n\ta = repeated = 0;\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tck_pr_inc_int(&barrier[HS_STATE_GET]);\n\tfor (;;) {\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (i & 1) {\n\t\t\t\tset_replace(keys[i]);\n\t\t\t} else {\n\t\t\t\tset_swap(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tck_pr_store_int(&state, HS_STATE_DELETION);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_STRICT_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\tset_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), acc(HS_STATE_STRICT_REPLACEMENT) / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing deletion test (%.2f)...\", p_d * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HS_STATE_STRICT_REPLACEMENT]);\n\tfor (;;) {\n\t\tdouble delete;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\tset_remove(keys[i]);\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HS_STATE_REPLACEMENT);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_DELETION]) != n_threads)\n\t\tck_pr_stall();\n\n\tset_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), acc(HS_STATE_DELETION) / n_threads);\n\n\tcommon_alarm(alarm_handler, &alarm_event, r);\n\n\tfprintf(stderr, \" | Executing replacement test (%.2f)...\", p_r * 100);\n\ta = repeated = 0;\n\tck_pr_inc_int(&barrier[HS_STATE_DELETION]);\n\tfor (;;) {\n\t\tdouble delete, replace;\n\n\t\trepeated++;\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_insert(keys[i]);\n\t\t\tif (p_d != 0.0) {\n\t\t\t\tdelete = common_drand48();\n\t\t\t\tif (delete <= p_d)\n\t\t\t\t\tset_remove(keys[i]);\n\t\t\t} else {\n\t\t\t\tdelete = 0.0;\n\t\t\t}\n\n\t\t\tif (p_r != 0.0) {\n\t\t\t\treplace = common_drand48();\n\t\t\t\tif (replace <= p_r) {\n\t\t\t\t\tif ((i & 1) || (delete <= p_d)) {\n\t\t\t\t\t\tset_replace(keys[i]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tset_swap(keys[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tif (next_stage == true) {\n\t\t\tnext_stage = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tck_pr_store_int(&state, HS_STATE_STOP);\n\twhile (ck_pr_load_int(&barrier[HS_STATE_REPLACEMENT]) != n_threads)\n\t\tck_pr_stall();\n\tset_reset();\n\tck_epoch_synchronize(&epoch_wr);\n\tfprintf(stderr, \"done (writer = %\" PRIu64 \" ticks, reader = %\" PRIu64 \" ticks)\\n\",\n\t    a / (repeated * keys_length), acc(HS_STATE_REPLACEMENT) / n_threads);\n\n\tck_pr_inc_int(&barrier[HS_STATE_REPLACEMENT]);\n\tepoch_temporary = epoch_wr;\n\tck_epoch_synchronize(&epoch_wr);\n\n\tfprintf(stderr, \" '- Summary: %u pending, %u peak, %u reclamations -> \"\n\t    \"%u pending, %u peak, %u reclamations\\n\\n\",\n\t    epoch_temporary.n_pending, epoch_temporary.n_peak, epoch_temporary.n_dispatch,\n\t    epoch_wr.n_pending, epoch_wr.n_peak, epoch_wr.n_dispatch);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rhs/benchmark/serial.c",
    "content": "/*\n * Copyright 2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_rhs.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <time.h>\n\n#include \"../../common.h\"\n#include \"../../../src/ck_ht_hash.h\"\n\nstatic ck_rhs_t hs;\nstatic char **keys;\nstatic size_t keys_length = 0;\nstatic size_t keys_capacity = 128;\nstatic unsigned long global_seed;\n\nstatic void *\nhs_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\n\tfree(p);\n\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\th = (unsigned long)MurmurHash64A(c, strlen(c), seed);\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void\nset_destroy(void)\n{\n\n\tck_rhs_destroy(&hs);\n\treturn;\n}\n\nstatic void\nset_init(unsigned int size, unsigned int mode)\n{\n\n\tif (ck_rhs_init(&hs, CK_RHS_MODE_OBJECT | CK_RHS_MODE_SPMC | mode, hs_hash, hs_compare,\n\t    &my_allocator, size, global_seed) == false) {\n\t\tperror(\"ck_rhs_init\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn;\n}\n\nstatic bool\nset_remove(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_remove(&hs, h, value) != NULL;\n}\n\nstatic bool\nset_swap(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_fas(&hs, h, value, &previous);\n}\n\nstatic bool\nset_replace(const char *value)\n{\n\tunsigned long h;\n\tvoid *previous;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\tck_rhs_set(&hs, h, value, &previous);\n\treturn previous != NULL;\n}\n\nstatic void *\nset_get(const char *value)\n{\n\tunsigned long h;\n\tvoid *v;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\tv = ck_rhs_get(&hs, h, value);\n\treturn v;\n}\n\nstatic bool\nset_insert(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_put(&hs, h, value);\n}\n\nstatic bool\nset_insert_unique(const char *value)\n{\n\tunsigned long h;\n\n\th = CK_RHS_HASH(&hs, hs_hash, value);\n\treturn ck_rhs_put_unique(&hs, h, value);\n}\n\nstatic size_t\nset_count(void)\n{\n\n\treturn ck_rhs_count(&hs);\n}\n\nstatic bool\nset_reset(void)\n{\n\n\treturn ck_rhs_reset(&hs);\n}\n\nstatic void\nset_gc(void)\n{\n\n\tck_rhs_gc(&hs);\n\treturn;\n}\n\nstatic void\nset_rebuild(void)\n{\n\n\tck_rhs_rebuild(&hs);\n\treturn;\n}\n\nstatic void\nkeys_shuffle(char **k)\n{\n\tsize_t i, j;\n\tchar *t;\n\n\tfor (i = keys_length; i > 1; i--) {\n\t\tj = rand() % (i - 1);\n\n\t\tif (j != i - 1) {\n\t\t\tt = k[i - 1];\n\t\t\tk[i - 1] = k[j];\n\t\t\tk[j] = t;\n\t\t}\n\t}\n\n\treturn;\n}\n\nstatic void\nrun_test(const char *file, size_t r, unsigned int size, unsigned int mode)\n{\n\tFILE *fp;\n\tchar buffer[512];\n\tsize_t i, j;\n\tunsigned int d = 0;\n\tuint64_t s, e, a, ri, si, ai, sr, rg, sg, ag, sd, ng, ss, sts, su, sgc, sb;\n\tstruct ck_rhs_stat st;\n\tchar **t;\n\n\tkeys = malloc(sizeof(char *) * keys_capacity);\n\tassert(keys != NULL);\n\n\tfp = fopen(file, \"r\");\n\tassert(fp != NULL);\n\n\twhile (fgets(buffer, sizeof(buffer), fp) != NULL) {\n\t\tbuffer[strlen(buffer) - 1] = '\\0';\n\t\tkeys[keys_length++] = strdup(buffer);\n\t\tassert(keys[keys_length - 1] != NULL);\n\n\t\tif (keys_length == keys_capacity) {\n\t\t\tt = realloc(keys, sizeof(char *) * (keys_capacity *= 2));\n\t\t\tassert(t != NULL);\n\t\t\tkeys = t;\n\t\t}\n\t}\n\n\tt = realloc(keys, sizeof(char *) * keys_length);\n\tassert(t != NULL);\n\tkeys = t;\n\n\tset_init(size, mode);\n\tfor (i = 0; i < keys_length; i++)\n\t\td += set_insert(keys[i]) == false;\n\tck_rhs_stat(&hs, &st);\n\n\tfprintf(stderr, \"# %zu entries stored, %u duplicates, %u probe.\\n\",\n\t    set_count(), d, st.probe_maximum);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = keys_length; i > 0; i--)\n\t\t\td += set_insert(keys[i - 1]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tri = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += set_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsi = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tkeys_shuffle(keys);\n\n\t\tif (set_reset() == false) {\n\t\t\tck_error(\"ERROR: Failed to reset hash table.\\n\");\n\t\t}\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\td += set_insert(keys[i]) == false;\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tai = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_swap(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tss = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_replace(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsr = a / (r * keys_length);\n\n\tset_reset();\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_insert(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = keys_length; i > 0; i--) {\n\t\t\tif (set_get(keys[i - 1]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\trg = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (set_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsg = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\tkeys_shuffle(keys);\n\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tif (set_get(keys[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR: Unexpected NULL value.\\n\");\n\t\t\t}\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tag = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert(keys[i]);\n\t}\n\tsd = a / (r * keys_length);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++) {\n\t\t\tset_get(\"\\x50\\x03\\x04\\x05\\x06\\x10\");\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tng = a / (r * keys_length);\n\n\tset_reset();\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_insert(keys[i]);\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t}\n\tsts = a / (r * keys_length);\n\n\tset_reset();\n\n\t/* Prune duplicates. */\n\tfor (i = 0; i < keys_length; i++) {\n\t\tif (set_insert(keys[i]) == true)\n\t\t\tcontinue;\n\n\t\tfree(keys[i]);\n\t\tkeys[i] = keys[--keys_length];\n\t}\n\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_insert_unique(keys[i]);\n\t\te = rdtsc();\n\t\ta += e - s;\n\n\t\tfor (i = 0; i < keys_length; i++)\n\t\t\tset_remove(keys[i]);\n\t}\n\tsu = a / (r * keys_length);\n\n\tfor (i = 0; i < keys_length; i++)\n\t\tset_insert_unique(keys[i]);\n\n\tfor (i = 0; i < keys_length / 2; i++)\n\t\tset_remove(keys[i]);\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tset_gc();\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsgc = a / r;\n\n\ta = 0;\n\tfor (j = 0; j < r; j++) {\n\t\ts = rdtsc();\n\t\tset_rebuild();\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tsb = a / r;\n\n\tprintf(\"%zu \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \" \"\n\t    \"%\" PRIu64 \"\\n\",\n\t    keys_length, ri, si, ai, ss, sr, rg, sg, ag, sd, ng, sts, su, sgc, sb);\n\n\tfclose(fp);\n\n\tfor (i = 0; i < keys_length; i++) {\n\t\tfree(keys[i]);\n\t}\n\n\tfree(keys);\n\tkeys_length = 0;\n\tset_destroy();\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int r, size;\n\n\tcommon_srand48((long int)time(NULL));\n\tif (argc < 2) {\n\t\tck_error(\"Usage: ck_rhs <dictionary> [<repetitions> <initial size>]\\n\");\n\t}\n\n\tr = 16;\n\tif (argc >= 3)\n\t\tr = atoi(argv[2]);\n\n\tsize = 8;\n\tif (argc >= 4)\n\t\tsize = atoi(argv[3]);\n\n\tglobal_seed = common_lrand48();\n\trun_test(argv[1], r, size, 0);\n\trun_test(argv[1], r, size, CK_RHS_MODE_READ_MOSTLY);\n\tfprintf(stderr, \"#    reverse_insertion serial_insertion random_insertion serial_swap \"\n\t    \"serial_replace reverse_get serial_get random_get serial_remove negative_get tombstone \"\n\t    \"set_unique gc rebuild\\n\\n\");\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rhs/validate/serial.c",
    "content": "/*\n * Copyright 2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyrights\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyrights\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_rhs.h>\n\n#include <assert.h>\n#include <ck_malloc.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#include \"../../common.h\"\n\nstatic void *\nhs_malloc(size_t r)\n{\n\n\treturn malloc(r);\n}\n\nstatic void\nhs_free(void *p, size_t b, bool r)\n{\n\n\t(void)b;\n\t(void)r;\n\tfree(p);\n\treturn;\n}\n\nstatic struct ck_malloc my_allocator = {\n\t.malloc = hs_malloc,\n\t.free = hs_free\n};\n\nconst char *test[] = { \"Samy\", \"Al\", \"Bahra\", \"dances\", \"in\", \"the\", \"wind.\", \"Once\",\n\t\t\t\"upon\", \"a\", \"time\", \"his\", \"gypsy\", \"ate\", \"one\", \"itsy\",\n\t\t\t    \"bitsy\", \"spider.\", \"What\", \"goes\", \"up\", \"must\",\n\t\t\t\t\"come\", \"down.\", \"What\", \"is\", \"down\", \"stays\",\n\t\t\t\t    \"down.\", \"A\", \"B\", \"C\", \"D\", \"E\", \"F\", \"G\", \"H\",\n\t\t\t\t\t\"I\", \"J\", \"K\", \"L\", \"M\", \"N\", \"O\", \"P\", \"Q\" };\n\nconst char *negative = \"negative\";\n\n/* Purposefully crappy hash function. */\nstatic unsigned long\nhs_hash(const void *object, unsigned long seed)\n{\n\tconst char *c = object;\n\tunsigned long h;\n\n\t(void)seed;\n\th = c[0];\n\treturn h;\n}\n\nstatic bool\nhs_compare(const void *previous, const void *compare)\n{\n\n\treturn strcmp(previous, compare) == 0;\n}\n\nstatic void *\ntest_ip(void *key, void *closure)\n{\n\tconst char *a = key;\n\tconst char *b = closure;\n\n\tif (strcmp(a, b) != 0)\n\t\tck_error(\"Mismatch: %s != %s\\n\", a, b);\n\n\treturn closure;\n}\n\nstatic void *\ntest_negative(void *key, void *closure)\n{\n\n\t(void)closure;\n\tif (key != NULL)\n\t\tck_error(\"ERROR: Apply callback expects NULL argument instead of [%s]\\n\", key);\n\n\treturn NULL;\n}\n\nstatic void *\ntest_unique(void *key, void *closure)\n{\n\n\tif (key != NULL)\n\t\tck_error(\"ERROR: Apply callback expects NULL argument instead of [%s]\\n\", key);\n\n\treturn closure;\n}\n\nstatic void *\ntest_remove(void *key, void *closure)\n{\n\n\t(void)key;\n\t(void)closure;\n\n\treturn NULL;\n}\n\nstatic void\nrun_test(unsigned int is, unsigned int ad)\n{\n\tck_rhs_t hs[16];\n\tconst size_t size = sizeof(hs) / sizeof(*hs);\n\tsize_t i, j;\n\tconst char *blob = \"#blobs\";\n\tunsigned long h;\n\n\tif (ck_rhs_init(&hs[0], CK_RHS_MODE_SPMC | CK_RHS_MODE_OBJECT | ad, hs_hash, hs_compare, &my_allocator, is, 6602834) == false)\n\t\tck_error(\"ck_rhs_init\\n\");\n\n\tfor (j = 0; j < size; j++) {\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tif (ck_rhs_get(&hs[j], h, test[i]) != NULL) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (i & 1) {\n\t\t\t\tif (ck_rhs_put_unique(&hs[j], h, test[i]) == false)\n\t\t\t\t\tck_error(\"ERROR [%zu]: Failed to insert unique (%s)\\n\", j, test[i]);\n\t\t\t} else if (ck_rhs_apply(&hs[j], h, test[i], test_unique,\n\t\t\t    (void *)(uintptr_t)test[i]) == false) {\n\t\t\t\tck_error(\"ERROR: Failed to apply for insertion.\\n\");\n\t\t\t}\n\n\t\t\tif (i & 1) {\n\t\t\t\tif (ck_rhs_remove(&hs[j], h, test[i]) == false)\n\t\t\t\t\tck_error(\"ERROR [%zu]: Failed to remove unique (%s)\\n\", j, test[i]);\n\t\t\t} else if (ck_rhs_apply(&hs[j], h, test[i], test_remove, NULL) == false) {\n\t\t\t\tck_error(\"ERROR: Failed to remove apply.\\n\");\n\t\t\t}\n\n\t\t\tif (ck_rhs_apply(&hs[j], h, test[i], test_negative,\n\t\t\t    (void *)(uintptr_t)test[i]) == false)\n\t\t\t\tck_error(\"ERROR: Failed to apply.\\n\");\n\n\t\t\tbreak;\n\t\t}\n\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tck_rhs_put(&hs[j], h, test[i]);\n\t\t\tif (ck_rhs_put(&hs[j], h, test[i]) == true) {\n\t\t\t\tck_error(\"ERROR [%u] [1]: put must fail on collision (%s).\\n\", is, test[i]);\n\t\t\t}\n\t\t\tif (ck_rhs_get(&hs[j], h, test[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: get must not fail after put\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\t/* Test grow semantics. */\n\t\tck_rhs_grow(&hs[j], 128);\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tif (ck_rhs_put(&hs[j], h, test[i]) == true) {\n\t\t\t\tck_error(\"ERROR [%u] [2]: put must fail on collision.\\n\", is);\n\t\t\t}\n\n\t\t\tif (ck_rhs_get(&hs[j], h, test[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: get must not fail\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\th = blob[0];\n\t\tif (ck_rhs_get(&hs[j], h, blob) == NULL) {\n\t\t\tif (j > 0)\n\t\t\t\tck_error(\"ERROR [%u]: Blob must always exist after first.\\n\", is);\n\n\t\t\tif (ck_rhs_put(&hs[j], h, blob) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: A unique blob put failed.\\n\", is);\n\t\t\t}\n\t\t} else {\n\t\t\tif (ck_rhs_put(&hs[j], h, blob) == true) {\n\t\t\t\tck_error(\"ERROR [%u]: Duplicate blob put succeeded.\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\t/* Grow set and check get semantics. */\n\t\tck_rhs_grow(&hs[j], 512);\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\th = test[i][0];\n\t\t\tif (ck_rhs_get(&hs[j], h, test[i]) == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: get must not fail\\n\", is);\n\t\t\t}\n\t\t}\n\n\t\t/* Delete and check negative membership. */\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\tvoid *r;\n\n\t\t\th = test[i][0];\n\t\t\tif (ck_rhs_get(&hs[j], h, test[i]) == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tif (r = ck_rhs_remove(&hs[j], h, test[i]), r == NULL) {\n\t\t\t\tck_error(\"ERROR [%u]: remove must not fail\\n\", is);\n\t\t\t}\n\n\t\t\tif (strcmp(r, test[i]) != 0) {\n\t\t\t\tck_error(\"ERROR [%u]: Removed incorrect node (%s != %s)\\n\", (char *)r, test[i], is);\n\t\t\t}\n\t\t}\n\n\t\t/* Test replacement semantics. */\n\t\tfor (i = 0; i < sizeof(test) / sizeof(*test); i++) {\n\t\t\tvoid *r;\n\t\t\tbool d;\n\n\t\t\th = test[i][0];\n\t\t\td = ck_rhs_get(&hs[j], h, test[i]) != NULL;\n\t\t\tif (ck_rhs_set(&hs[j], h, test[i], &r) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: Failed to set\\n\", is);\n\t\t\t}\n\n\t\t\t/* Expected replacement. */\n\t\t\tif (d == true && (r == NULL || strcmp(r, test[i]) != 0)) {\n\t\t\t\tck_error(\"ERROR [%u]: Incorrect previous value: %s != %s\\n\",\n\t\t\t\t    is, test[i], (char *)r);\n\t\t\t}\n\n\t\t\t/* Replacement should succeed. */\n\t\t\tif (ck_rhs_fas(&hs[j], h, test[i], &r) == false)\n\t\t\t\tck_error(\"ERROR [%u]: ck_rhs_fas must succeed.\\n\", is);\n\n\t\t\tif (strcmp(r, test[i]) != 0) {\n\t\t\t\tck_error(\"ERROR [%u]: Incorrect replaced value: %s != %s\\n\",\n\t\t\t\t    is, test[i], (char *)r);\n\t\t\t}\n\n\t\t\tif (ck_rhs_fas(&hs[j], h, negative, &r) == true)\n\t\t\t\tck_error(\"ERROR [%u]: Replacement of negative should fail.\\n\", is);\n\n\t\t\tif (ck_rhs_set(&hs[j], h, test[i], &r) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: Failed to set [1]\\n\", is);\n\t\t\t}\n\n\t\t\tif (strcmp(r, test[i]) != 0) {\n\t\t\t\tck_error(\"ERROR [%u]: Invalid &hs[j]: %s != %s\\n\", (char *)r, test[i], is);\n\t\t\t}\n\t\t\t/* Attempt in-place mutation. */\n\t\t\tif (ck_rhs_apply(&hs[j], h, test[i], test_ip,\n\t\t\t    (void *)(uintptr_t)test[i]) == false) {\n\t\t\t\tck_error(\"ERROR [%u]: Failed to apply: %s != %s\\n\", is, (char *)r, test[i]);\n\t\t\t}\n\n\t\t\td = ck_rhs_get(&hs[j], h, test[i]) != NULL;\n\t\t\tif (d == false)\n\t\t\t\tck_error(\"ERROR [%u]: Expected [%s] to exist.\\n\", is, test[i]);\n\t\t}\n\n\t\tif (j == size - 1)\n\t\t\tbreak;\n\n\t\tif (ck_rhs_move(&hs[j + 1], &hs[j], hs_hash, hs_compare, &my_allocator) == false)\n\t\t\tck_error(\"Failed to move hash table\");\n\n\t\tck_rhs_gc(&hs[j + 1]);\n\n\t\tif (ck_rhs_rebuild(&hs[j + 1]) == false)\n\t\t\tck_error(\"Failed to rebuild\");\n\t}\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\tunsigned int k;\n\n\tfor (k = 16; k <= 64; k <<= 1) {\n\t\trun_test(k, 0);\n\t\tbreak;\n\t}\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ring/benchmark/latency.c",
    "content": "#include <ck_ring.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS (128000)\n#endif\n\nstruct entry {\n\tint tid;\n\tint value;\n};\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r, size;\n\tuint64_t s, e, e_a, d_a;\n\tstruct entry entry = {0, 0};\n\tck_ring_buffer_t *buf;\n\tck_ring_t ring;\n\n\tif (argc != 2) {\n\t\tck_error(\"Usage: latency <size>\\n\");\n\t}\n\n\tsize = atoi(argv[1]);\n\tif (size <= 4 || (size & (size - 1))) {\n\t\tck_error(\"ERROR: Size must be a power of 2 greater than 4.\\n\");\n\t}\n\n\tbuf = malloc(sizeof(ck_ring_buffer_t) * size);\n\tif (buf == NULL) {\n\t\tck_error(\"ERROR: Failed to allocate buffer\\n\");\n\t}\n\n\tck_ring_init(&ring, size);\n\n\te_a = d_a = s = e = 0;\n\tfor (r = 0; r < ITERATIONS; r++) {\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_enqueue_spsc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_spsc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_spsc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_spsc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\te_a += (e - s) / 4;\n\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_dequeue_spsc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_spsc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_spsc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_spsc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\td_a += (e - s) / 4;\n\t}\n\n\tprintf(\"spsc %10d %16\" PRIu64 \" %16\" PRIu64 \"\\n\", size, e_a / ITERATIONS, d_a / ITERATIONS);\n\n\te_a = d_a = s = e = 0;\n\tfor (r = 0; r < ITERATIONS; r++) {\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_enqueue_spmc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_spmc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_spmc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_spmc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\te_a += (e - s) / 4;\n\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_dequeue_spmc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_spmc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_spmc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_spmc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\td_a += (e - s) / 4;\n\t}\n\n\tprintf(\"spmc %10d %16\" PRIu64 \" %16\" PRIu64 \"\\n\", size, e_a / ITERATIONS, d_a / ITERATIONS);\n\n\tck_ring_init(&ring, size);\n\te_a = d_a = s = e = 0;\n\tfor (r = 0; r < ITERATIONS; r++) {\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_enqueue_mpsc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_mpsc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_mpsc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_mpsc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\te_a += (e - s) / 4;\n\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_dequeue_mpsc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_mpsc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_mpsc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_mpsc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\td_a += (e - s) / 4;\n\t}\n\tprintf(\"mpsc %10d %16\" PRIu64 \" %16\" PRIu64 \"\\n\", size, e_a / ITERATIONS, d_a / ITERATIONS);\n\tck_ring_init(&ring, size);\n\te_a = d_a = s = e = 0;\n\tfor (r = 0; r < ITERATIONS; r++) {\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_enqueue_mpmc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_mpmc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_mpmc(&ring, buf, &entry);\n\t\t\tck_ring_enqueue_mpmc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\te_a += (e - s) / 4;\n\n\t\tfor (i = 0; i < size / 4; i += 4) {\n\t\t\ts = rdtsc();\n\t\t\tck_ring_dequeue_mpmc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_mpmc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_mpmc(&ring, buf, &entry);\n\t\t\tck_ring_dequeue_mpmc(&ring, buf, &entry);\n\t\t\te = rdtsc();\n\t\t}\n\t\td_a += (e - s) / 4;\n\t}\n\tprintf(\"mpmc %10d %16\" PRIu64 \" %16\" PRIu64 \"\\n\", size, e_a / ITERATIONS, d_a / ITERATIONS);\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ring/validate/ck_ring_mpmc.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <pthread.h>\n\n#include <ck_barrier.h>\n#include <ck_ring.h>\n#include <ck_spinlock.h>\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n\tck_ring_buffer_t *buffer;\n};\n\nstruct entry {\n\tunsigned long value_long;\n\tunsigned int magic;\n\tunsigned int ref;\n\tint tid;\n\tint value;\n};\n\nstatic int nthr;\nstatic ck_ring_t *ring;\nstatic ck_ring_t ring_mpmc CK_CC_CACHELINE;\nstatic ck_ring_t ring_mw CK_CC_CACHELINE;\nstatic struct affinity a;\nstatic int size;\nstatic int eb;\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstatic struct context *_context;\n\nstatic unsigned int global_counter;\n\nstatic void *\ntest_mpmc(void *c)\n{\n\tunsigned int observed = 0;\n\tunsigned int enqueue = 0;\n\tunsigned int seed;\n\tint i, k, j, tid;\n\tstruct context *context = c;\n\tck_ring_buffer_t *buffer;\n\tunsigned int *csp;\n\n\tcsp = malloc(sizeof(*csp) * nthr);\n\tassert(csp != NULL);\n\n\tmemset(csp, 0, sizeof(*csp) * nthr);\n\n\tbuffer = context->buffer;\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\ttid = ck_pr_faa_int(&eb, 1);\n\tck_pr_fence_memory();\n\twhile (ck_pr_load_int(&eb) != nthr - 1);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tstruct entry *o = NULL;\n\t\t\tint spin;\n\n\t\t\t/* Keep trying until we encounter at least one node. */\n\t\t\tif (j & 1) {\n\t\t\t\tif (ck_ring_dequeue_mpmc(&ring_mw, buffer, &o) == false)\n\t\t\t\t\to = NULL;\n\t\t\t} else {\n\t\t\t\tif (ck_ring_trydequeue_mpmc(&ring_mw, buffer, &o) == false)\n\t\t\t\t\to = NULL;\n\t\t\t}\n\n\t\t\tif (o == NULL) {\n\t\t\t\to = malloc(sizeof(*o));\n\t\t\t\tif (o == NULL)\n\t\t\t\t\tcontinue;\n\n\t\t\t\to->value_long = (unsigned long)ck_pr_faa_uint(&global_counter, 1) + 1;\n\n\t\t\t\to->magic = 0xdead;\n\t\t\t\to->ref = 0;\n\t\t\t\to->tid = tid;\n\n\t\t\t\tif (ck_ring_enqueue_mpmc(&ring_mw, buffer, o) == false) {\n\t\t\t\t\tfree(o);\n\t\t\t\t} else {\n\t\t\t\t\tenqueue++;\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tobserved++;\n\n\t\t\tif (o->magic != 0xdead) {\n\t\t\t\tck_error(\"[%p] (%x)\\n\",\n\t\t\t\t\t(void *)o, o->magic);\n\t\t\t}\n\n\t\t\to->magic = 0xbeef;\n\n\t\t\tif (csp[o->tid] >= o->value_long)\n\t\t\t\tck_error(\"queue semantics violated: %lu <= %lu\\n\", o->value_long, csp[o->tid]);\n\n\t\t\tcsp[o->tid] = o->value_long;\n\n\t\t\tif (ck_pr_faa_uint(&o->ref, 1) != 0) {\n\t\t\t\tck_error(\"[%p] We dequeued twice.\\n\", (void *)o);\n\t\t\t}\n\n\t\t\tif ((i % 4) == 0) {\n\t\t\t\tspin = common_rand_r(&seed) % 16384;\n\t\t\t\tfor (k = 0; k < spin; k++) {\n\t\t\t\t\tck_pr_stall();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfree(o);\n\t\t}\n\t}\n\n\tfprintf(stderr, \"[%d] dequeue=%u enqueue=%u\\n\", tid, observed, enqueue);\n\treturn NULL;\n}\n\nstatic void *\ntest_spmc(void *c)\n{\n\tunsigned int observed = 0;\n\tunsigned long previous = 0;\n\tunsigned int seed;\n\tint i, k, j, tid;\n\tstruct context *context = c;\n\tck_ring_buffer_t *buffer;\n\n\tbuffer = context->buffer;\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\ttid = ck_pr_faa_int(&eb, 1);\n\tck_pr_fence_memory();\n\twhile (ck_pr_load_int(&eb) != nthr - 1);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tstruct entry *o;\n\t\t\tint spin;\n\n\t\t\t/* Keep trying until we encounter at least one node. */\n\t\t\tif (j & 1) {\n\t\t\t\twhile (ck_ring_dequeue_mpmc(&ring_mpmc, buffer,\n\t\t\t\t    &o) == false);\n\t\t\t} else {\n\t\t\t\twhile (ck_ring_trydequeue_mpmc(&ring_mpmc, buffer,\n\t\t\t\t    &o) == false);\n\t\t\t}\n\n\t\t\tobserved++;\n\t\t\tif (o->value < 0\n\t\t\t    || o->value != o->tid\n\t\t\t    || o->magic != 0xdead\n\t\t\t    || (previous != 0 && previous >= o->value_long)) {\n\t\t\t\tck_error(\"[0x%p] (%x) (%d, %d) >< (0, %d)\\n\",\n\t\t\t\t\t(void *)o, o->magic, o->tid, o->value, size);\n\t\t\t}\n\n\t\t\to->magic = 0xbeef;\n\t\t\to->value = -31337;\n\t\t\to->tid = -31338;\n\t\t\tprevious = o->value_long;\n\n\t\t\tif (ck_pr_faa_uint(&o->ref, 1) != 0) {\n\t\t\t\tck_error(\"[%p] We dequeued twice.\\n\", (void *)o);\n\t\t\t}\n\n\t\t\tif ((i % 4) == 0) {\n\t\t\t\tspin = common_rand_r(&seed) % 16384;\n\t\t\t\tfor (k = 0; k < spin; k++) {\n\t\t\t\t\tck_pr_stall();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfree(o);\n\t\t}\n\t}\n\n\tfprintf(stderr, \"[%d] Observed %u\\n\", tid, observed);\n\treturn NULL;\n}\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tunsigned int s;\n\tint i, j;\n\tbool r;\n\tck_ring_buffer_t *buffer = context->buffer;\n\tck_barrier_centralized_state_t sense =\n\t    CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tif (context->tid == 0) {\n\t\tstruct entry *entries;\n\n\t\tentries = malloc(sizeof(struct entry) * size);\n\t\tassert(entries != NULL);\n\n\t\tif (ck_ring_size(ring) != 0) {\n\t\t\tck_error(\"More entries than expected: %u > 0\\n\",\n\t\t\t\tck_ring_size(ring));\n\t\t}\n\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tentries[i].value = i;\n\t\t\tentries[i].tid = 0;\n\n\t\t\tif (true) {\n\t\t\t\tr = ck_ring_enqueue_mpmc(ring, buffer,\n\t\t\t\t    entries + i);\n\t\t\t} else {\n\t\t\t\tr = ck_ring_enqueue_mpmc_size(ring, buffer,\n\t\t\t\t\tentries + i, &s);\n\n\t\t\t\tif ((int)s != i) {\n\t\t\t\t\tck_error(\"Size is %u, expected %d.\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassert(r != false);\n\t\t}\n\n\t\tif (ck_ring_size(ring) != (unsigned int)size) {\n\t\t\tck_error(\"Less entries than expected: %u < %d\\n\",\n\t\t\t\tck_ring_size(ring), size);\n\t\t}\n\n\t\tif (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) {\n\t\t\tck_error(\"Capacity less than expected: %u < %u\\n\",\n\t\t\t\tck_ring_size(ring), ck_ring_capacity(ring));\n\t\t}\n\t}\n\n\t/*\n\t * Wait for all threads. The idea here is to maximize the contention.\n\t */\n\tck_barrier_centralized(&barrier, &sense, nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tbuffer = _context[context->previous].buffer;\n\t\t\twhile (ck_ring_dequeue_mpmc(ring + context->previous,\n\t\t\t    buffer, &entry) == false);\n\n\t\t\tif (context->previous != (unsigned int)entry->tid) {\n\t\t\t\tck_error(\"[%u:%p] %u != %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tif (entry->value < 0 || entry->value >= size) {\n\t\t\t\tck_error(\"[%u:%p] %u </> %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tentry->tid = context->tid;\n\t\t\tbuffer = context->buffer;\n\n\t\t\tif (true) {\n\t\t\t\tr = ck_ring_enqueue_mpmc(ring + context->tid,\n\t\t\t\t\tbuffer, entry);\n\t\t\t} else {\n\t\t\t\tr = ck_ring_enqueue_mpmc_size(ring + context->tid,\n\t\t\t\t\tbuffer, entry, &s);\n\n\t\t\t\tif ((int)s >= size) {\n\t\t\t\t\tck_error(\"Size %u out of range of %d\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(r == true);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tunsigned long l;\n\tpthread_t *thread;\n\tck_ring_buffer_t *buffer;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size >= 4 && (size & size - 1) == 0);\n\tsize -= 1;\n\n\tring = malloc(sizeof(ck_ring_t) * nthr);\n\tassert(ring);\n\n\t_context = malloc(sizeof(*_context) * nthr);\n\tassert(_context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\tfprintf(stderr, \"SPSC test:\");\n\tfor (i = 0; i < nthr; i++) {\n\t\t_context[i].tid = i;\n\t\tif (i == 0) {\n\t\t\t_context[i].previous = nthr - 1;\n\t\t\t_context[i].next = i + 1;\n\t\t} else if (i == nthr - 1) {\n\t\t\t_context[i].next = 0;\n\t\t\t_context[i].previous = i - 1;\n\t\t} else {\n\t\t\t_context[i].next = i + 1;\n\t\t\t_context[i].previous = i - 1;\n\t\t}\n\n\t\tbuffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));\n\t\tassert(buffer);\n\t\tmemset(buffer, 0, sizeof(ck_ring_buffer_t) * (size + 1));\n\t\t_context[i].buffer = buffer;\n\t\tck_ring_init(ring + i, size + 1);\n\t\tr = pthread_create(thread + i, NULL, test, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \" done\\n\");\n\n\tfprintf(stderr, \"SPMC test:\\n\");\n\tbuffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));\n\tassert(buffer);\n\tmemset(buffer, 0, sizeof(void *) * (size + 1));\n\tck_ring_init(&ring_mpmc, size + 1);\n\tfor (i = 0; i < nthr - 1; i++) {\n\t\t_context[i].buffer = buffer;\n\t\tr = pthread_create(thread + i, NULL, test_spmc, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (l = 0; l < (unsigned long)size * ITERATIONS * (nthr - 1) ; l++) {\n\t\tstruct entry *entry = malloc(sizeof *entry);\n\n\t\tassert(entry != NULL);\n\t\tentry->value_long = l;\n\t\tentry->value = (int)l;\n\t\tentry->tid = (int)l;\n\t\tentry->magic = 0xdead;\n\t\tentry->ref = 0;\n\n\t\t/* Wait until queue is not full. */\n\t\tif (l & 1) {\n\t\t\twhile (ck_ring_enqueue_mpmc(&ring_mpmc,\n\t\t\t    buffer,\n\t\t\t    entry) == false)\n\t\t\t\tck_pr_stall();\n\t\t} else {\n\t\t\tunsigned int s;\n\n\t\t\twhile (ck_ring_enqueue_mpmc_size(&ring_mpmc,\n\t\t\t    buffer, entry, &s) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\n\t\t\tif ((int)s >= (size * ITERATIONS * (nthr - 1))) {\n\t\t\t\tck_error(\"MPMC: Unexpected size of %u\\n\", s);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < nthr - 1; i++)\n\t\tpthread_join(thread[i], NULL);\n\tck_pr_store_int(&eb, 0);\n\tfprintf(stderr, \"MPMC test:\\n\");\n\tbuffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));\n\tassert(buffer);\n\tmemset(buffer, 0, sizeof(void *) * (size + 1));\n\tck_ring_init(&ring_mw, size + 1);\n\tfor (i = 0; i < nthr - 1; i++) {\n\t\t_context[i].buffer = buffer;\n\t\tr = pthread_create(thread + i, NULL, test_mpmc, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr - 1; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ring/validate/ck_ring_mpmc_template.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <pthread.h>\n\n#include <ck_barrier.h>\n#include <ck_ring.h>\n#include <ck_spinlock.h>\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n\tstruct entry **buffer;\n};\n\nstruct entry {\n\tunsigned long value_long;\n\tunsigned int magic;\n\tunsigned int ref;\n\tint tid;\n\tint value;\n};\n\nCK_RING_PROTOTYPE(entry, entry *)\n\nstatic int nthr;\nstatic ck_ring_t *ring;\nstatic ck_ring_t ring_spmc CK_CC_CACHELINE;\nstatic struct affinity a;\nstatic int size;\nstatic int eb;\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstatic struct context *_context;\n\nstatic void *\ntest_spmc(void *c)\n{\n\tunsigned int observed = 0;\n\tunsigned long previous = 0;\n\tunsigned int seed;\n\tint i, k, j, tid;\n\tstruct context *context = c;\n\tstruct entry **buffer;\n\n\tbuffer = context->buffer;\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\ttid = ck_pr_faa_int(&eb, 1);\n\tck_pr_fence_memory();\n\twhile (ck_pr_load_int(&eb) != nthr - 1);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tstruct entry *o;\n\t\t\tint spin;\n\n\t\t\t/* Keep trying until we encounter at least one node. */\n\t\t\tif (j & 1) {\n\t\t\t\twhile (CK_RING_DEQUEUE_MPMC(entry,\n\t\t\t\t    &ring_spmc, buffer, &o) == false);\n\t\t\t} else {\n\t\t\t\twhile (CK_RING_TRYDEQUEUE_MPMC(entry,\n\t\t\t\t    &ring_spmc, buffer, &o) == false);\n\t\t\t}\n\n\t\t\tobserved++;\n\t\t\tif (o->value < 0\n\t\t\t    || o->value != o->tid\n\t\t\t    || o->magic != 0xdead\n\t\t\t    || (previous != 0 && previous >= o->value_long)) {\n\t\t\t\tck_error(\"[0x%p] (%x) (%d, %d) >< (0, %d)\\n\",\n\t\t\t\t\t(void *)o, o->magic, o->tid, o->value, size);\n\t\t\t}\n\n\t\t\to->magic = 0xbeef;\n\t\t\to->value = -31337;\n\t\t\to->tid = -31338;\n\t\t\tprevious = o->value_long;\n\n\t\t\tif (ck_pr_faa_uint(&o->ref, 1) != 0) {\n\t\t\t\tck_error(\"[%p] We dequeued twice.\\n\", (void *)o);\n\t\t\t}\n\n\t\t\tif ((i % 4) == 0) {\n\t\t\t\tspin = common_rand_r(&seed) % 16384;\n\t\t\t\tfor (k = 0; k < spin; k++) {\n\t\t\t\t\tck_pr_stall();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfree(o);\n\t\t}\n\t}\n\n\tfprintf(stderr, \"[%d] Observed %u\\n\", tid, observed);\n\treturn NULL;\n}\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tunsigned int s;\n\tint i, j;\n\tbool r;\n\tstruct entry **buffer = context->buffer;\n\tck_barrier_centralized_state_t sense =\n\t    CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tif (context->tid == 0) {\n\t\tstruct entry **entries;\n\n\t\tentries = malloc(sizeof(struct entry *) * size);\n\t\tassert(entries != NULL);\n\n\t\tif (ck_ring_size(ring) != 0) {\n\t\t\tck_error(\"More entries than expected: %u > 0\\n\",\n\t\t\t\tck_ring_size(ring));\n\t\t}\n\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tentries[i] = malloc(sizeof(struct entry));\n\t\t\tassert(entries[i] != NULL);\n\n\t\t\tentries[i]->value = i;\n\t\t\tentries[i]->tid = 0;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = CK_RING_ENQUEUE_MPMC(entry, ring, buffer,\n\t\t\t\t    &entries[i]);\n\t\t\t} else {\n\t\t\t\tr = CK_RING_ENQUEUE_MPMC_SIZE(entry, ring,\n\t\t\t\t\tbuffer, &entries[i], &s);\n\n\t\t\t\tif ((int)s != i) {\n\t\t\t\t\tck_error(\"Size is %u, expected %d.\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassert(r != false);\n\t\t}\n\n\t\tif (ck_ring_size(ring) != (unsigned int)size) {\n\t\t\tck_error(\"Less entries than expected: %u < %d\\n\",\n\t\t\t\tck_ring_size(ring), size);\n\t\t}\n\n\t\tif (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) {\n\t\t\tck_error(\"Capacity less than expected: %u < %u\\n\",\n\t\t\t\tck_ring_size(ring), ck_ring_capacity(ring));\n\t\t}\n\t}\n\n\t/*\n\t * Wait for all threads. The idea here is to maximize the contention.\n\t */\n\tck_barrier_centralized(&barrier, &sense, nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tbuffer = _context[context->previous].buffer;\n\t\t\twhile (CK_RING_DEQUEUE_MPMC(entry,\n\t\t\t    ring + context->previous,\n\t\t\t    buffer, &entry) == false);\n\n\t\t\tif (context->previous != (unsigned int)entry->tid) {\n\t\t\t\tck_error(\"[%u:%p] %u != %u\\n\",\n\t\t\t\t    context->tid, (void *)entry,\n\t\t\t\t    entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tif (entry->value < 0 || entry->value >= size) {\n\t\t\t\tck_error(\"[%u:%p] %u </> %u\\n\",\n\t\t\t\t    context->tid, (void *)entry,\n\t\t\t\t    entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tentry->tid = context->tid;\n\t\t\tbuffer = context->buffer;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = CK_RING_ENQUEUE_MPMC(entry,\n\t\t\t\t    ring + context->tid,\n\t\t\t\t    buffer, &entry);\n\t\t\t} else {\n\t\t\t\tr = CK_RING_ENQUEUE_MPMC_SIZE(entry,\n\t\t\t\t    ring + context->tid,\n\t\t\t\t    buffer, &entry, &s);\n\n\t\t\t\tif ((int)s >= size) {\n\t\t\t\t\tck_error(\"Size %u out of range of %d\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(r == true);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tunsigned long l;\n\tpthread_t *thread;\n\tstruct entry **buffer;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size >= 4 && (size & size - 1) == 0);\n\tsize -= 1;\n\n\tring = malloc(sizeof(ck_ring_t) * nthr);\n\tassert(ring);\n\n\t_context = malloc(sizeof(*_context) * nthr);\n\tassert(_context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tfprintf(stderr, \"SPSC test:\");\n\tfor (i = 0; i < nthr; i++) {\n\t\t_context[i].tid = i;\n\t\tif (i == 0) {\n\t\t\t_context[i].previous = nthr - 1;\n\t\t\t_context[i].next = i + 1;\n\t\t} else if (i == nthr - 1) {\n\t\t\t_context[i].next = 0;\n\t\t\t_context[i].previous = i - 1;\n\t\t} else {\n\t\t\t_context[i].next = i + 1;\n\t\t\t_context[i].previous = i - 1;\n\t\t}\n\n\t\tbuffer = malloc(sizeof(struct entry *) * (size + 1));\n\t\tassert(buffer);\n\t\tmemset(buffer, 0, sizeof(struct entry *) * (size + 1));\n\t\t_context[i].buffer = buffer;\n\t\tck_ring_init(ring + i, size + 1);\n\t\tr = pthread_create(thread + i, NULL, test, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \" done\\n\");\n\n\tfprintf(stderr, \"MPMC test:\\n\");\n\tbuffer = malloc(sizeof(struct entry *) * (size + 1));\n\tassert(buffer);\n\tmemset(buffer, 0, sizeof(struct entry *) * (size + 1));\n\tck_ring_init(&ring_spmc, size + 1);\n\tfor (i = 0; i < nthr - 1; i++) {\n\t\t_context[i].buffer = buffer;\n\t\tr = pthread_create(thread + i, NULL, test_spmc, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (l = 0; l < (unsigned long)size * ITERATIONS * (nthr - 1) ; l++) {\n\t\tstruct entry *entry = malloc(sizeof *entry);\n\n\t\tassert(entry != NULL);\n\t\tentry->value_long = l;\n\t\tentry->value = (int)l;\n\t\tentry->tid = (int)l;\n\t\tentry->magic = 0xdead;\n\t\tentry->ref = 0;\n\n\t\t/* Wait until queue is not full. */\n\t\tif (l & 1) {\n\t\t\twhile (CK_RING_ENQUEUE_MPMC(entry, &ring_spmc,\n\t\t\t    buffer, &entry) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\t\t} else {\n\t\t\tunsigned int s;\n\n\t\t\twhile (CK_RING_ENQUEUE_MPMC_SIZE(entry, &ring_spmc,\n\t\t\t    buffer, &entry, &s) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\n\t\t\tif ((int)s >= (size * ITERATIONS * (nthr - 1))) {\n\t\t\t\tck_error(\"MPMC: Unexpected size of %u\\n\", s);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < nthr - 1; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ring/validate/ck_ring_spmc.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <pthread.h>\n\n#include <ck_barrier.h>\n#include <ck_ring.h>\n#include <ck_spinlock.h>\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n\tck_ring_buffer_t *buffer;\n};\n\nstruct entry {\n\tunsigned long value_long;\n\tunsigned int magic;\n\tunsigned int ref;\n\tint tid;\n\tint value;\n};\n\nstatic int nthr;\nstatic ck_ring_t *ring;\nstatic ck_ring_t ring_spmc CK_CC_CACHELINE;\nstatic struct affinity a;\nstatic int size;\nstatic int eb;\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstatic struct context *_context;\n\nstatic void *\ntest_spmc(void *c)\n{\n\tunsigned int observed = 0;\n\tunsigned long previous = 0;\n\tunsigned int seed;\n\tint i, k, j, tid;\n\tstruct context *context = c;\n\tck_ring_buffer_t *buffer;\n\n\tbuffer = context->buffer;\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\ttid = ck_pr_faa_int(&eb, 1);\n\tck_pr_fence_memory();\n\twhile (ck_pr_load_int(&eb) != nthr - 1);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tstruct entry *o;\n\t\t\tint spin;\n\n\t\t\t/* Keep trying until we encounter at least one node. */\n\t\t\tif (j & 1) {\n\t\t\t\twhile (ck_ring_dequeue_spmc(&ring_spmc, buffer,\n\t\t\t\t    &o) == false);\n\t\t\t} else {\n\t\t\t\twhile (ck_ring_trydequeue_spmc(&ring_spmc, buffer,\n\t\t\t\t    &o) == false);\n\t\t\t}\n\n\t\t\tobserved++;\n\t\t\tif (o->value < 0\n\t\t\t    || o->value != o->tid\n\t\t\t    || o->magic != 0xdead\n\t\t\t    || (previous != 0 && previous >= o->value_long)) {\n\t\t\t\tck_error(\"[0x%p] (%x) (%d, %d) >< (0, %d)\\n\",\n\t\t\t\t\t(void *)o, o->magic, o->tid, o->value, size);\n\t\t\t}\n\n\t\t\to->magic = 0xbeef;\n\t\t\to->value = -31337;\n\t\t\to->tid = -31338;\n\t\t\tprevious = o->value_long;\n\n\t\t\tif (ck_pr_faa_uint(&o->ref, 1) != 0) {\n\t\t\t\tck_error(\"[%p] We dequeued twice.\\n\", (void *)o);\n\t\t\t}\n\n\t\t\tif ((i % 4) == 0) {\n\t\t\t\tspin = common_rand_r(&seed) % 16384;\n\t\t\t\tfor (k = 0; k < spin; k++) {\n\t\t\t\t\tck_pr_stall();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfree(o);\n\t\t}\n\t}\n\n\tfprintf(stderr, \"[%d] Observed %u\\n\", tid, observed);\n\treturn NULL;\n}\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tunsigned int s;\n\tint i, j;\n\tbool r;\n\tck_ring_buffer_t *buffer = context->buffer;\n\tck_barrier_centralized_state_t sense =\n\t    CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tif (context->tid == 0) {\n\t\tstruct entry *entries;\n\n\t\tentries = malloc(sizeof(struct entry) * size);\n\t\tassert(entries != NULL);\n\n\t\tif (ck_ring_size(ring) != 0) {\n\t\t\tck_error(\"More entries than expected: %u > 0\\n\",\n\t\t\t\tck_ring_size(ring));\n\t\t}\n\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tentries[i].value = i;\n\t\t\tentries[i].tid = 0;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = ck_ring_enqueue_spmc(ring, buffer,\n\t\t\t\t    entries + i);\n\t\t\t} else {\n\t\t\t\tr = ck_ring_enqueue_spmc_size(ring, buffer,\n\t\t\t\t\tentries + i, &s);\n\n\t\t\t\tif ((int)s != i) {\n\t\t\t\t\tck_error(\"Size is %u, expected %d.\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassert(r != false);\n\t\t}\n\n\t\tif (ck_ring_size(ring) != (unsigned int)size) {\n\t\t\tck_error(\"Less entries than expected: %u < %d\\n\",\n\t\t\t\tck_ring_size(ring), size);\n\t\t}\n\n\t\tif (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) {\n\t\t\tck_error(\"Capacity less than expected: %u < %u\\n\",\n\t\t\t\tck_ring_size(ring), ck_ring_capacity(ring));\n\t\t}\n\t}\n\n\t/*\n\t * Wait for all threads. The idea here is to maximize the contention.\n\t */\n\tck_barrier_centralized(&barrier, &sense, nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tbuffer = _context[context->previous].buffer;\n\t\t\twhile (ck_ring_dequeue_spmc(ring + context->previous,\n\t\t\t    buffer, &entry) == false);\n\n\t\t\tif (context->previous != (unsigned int)entry->tid) {\n\t\t\t\tck_error(\"[%u:%p] %u != %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tif (entry->value < 0 || entry->value >= size) {\n\t\t\t\tck_error(\"[%u:%p] %u </> %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tentry->tid = context->tid;\n\t\t\tbuffer = context->buffer;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = ck_ring_enqueue_spmc(ring + context->tid,\n\t\t\t\t\tbuffer, entry);\n\t\t\t} else {\n\t\t\t\tr = ck_ring_enqueue_spmc_size(ring + context->tid,\n\t\t\t\t\tbuffer, entry, &s);\n\n\t\t\t\tif ((int)s >= size) {\n\t\t\t\t\tck_error(\"Size %u out of range of %d\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(r == true);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tunsigned long l;\n\tpthread_t *thread;\n\tck_ring_buffer_t *buffer;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size >= 4 && (size & size - 1) == 0);\n\tsize -= 1;\n\n\tring = malloc(sizeof(ck_ring_t) * nthr);\n\tassert(ring);\n\n\t_context = malloc(sizeof(*_context) * nthr);\n\tassert(_context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tfprintf(stderr, \"SPSC test:\");\n\tfor (i = 0; i < nthr; i++) {\n\t\t_context[i].tid = i;\n\t\tif (i == 0) {\n\t\t\t_context[i].previous = nthr - 1;\n\t\t\t_context[i].next = i + 1;\n\t\t} else if (i == nthr - 1) {\n\t\t\t_context[i].next = 0;\n\t\t\t_context[i].previous = i - 1;\n\t\t} else {\n\t\t\t_context[i].next = i + 1;\n\t\t\t_context[i].previous = i - 1;\n\t\t}\n\n\t\tbuffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));\n\t\tassert(buffer);\n\t\tmemset(buffer, 0, sizeof(ck_ring_buffer_t) * (size + 1));\n\t\t_context[i].buffer = buffer;\n\t\tck_ring_init(ring + i, size + 1);\n\t\tr = pthread_create(thread + i, NULL, test, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \" done\\n\");\n\n\tfprintf(stderr, \"SPMC test:\\n\");\n\tbuffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));\n\tassert(buffer);\n\tmemset(buffer, 0, sizeof(void *) * (size + 1));\n\tck_ring_init(&ring_spmc, size + 1);\n\tfor (i = 0; i < nthr - 1; i++) {\n\t\t_context[i].buffer = buffer;\n\t\tr = pthread_create(thread + i, NULL, test_spmc, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (l = 0; l < (unsigned long)size * ITERATIONS * (nthr - 1) ; l++) {\n\t\tstruct entry *entry = malloc(sizeof *entry);\n\n\t\tassert(entry != NULL);\n\t\tentry->value_long = l;\n\t\tentry->value = (int)l;\n\t\tentry->tid = (int)l;\n\t\tentry->magic = 0xdead;\n\t\tentry->ref = 0;\n\n\t\t/* Wait until queue is not full. */\n\t\tif (l & 1) {\n\t\t\twhile (ck_ring_enqueue_spmc(&ring_spmc,\n\t\t\t    buffer,\n\t\t\t    entry) == false)\n\t\t\t\tck_pr_stall();\n\t\t} else {\n\t\t\tunsigned int s;\n\n\t\t\twhile (ck_ring_enqueue_spmc_size(&ring_spmc,\n\t\t\t    buffer, entry, &s) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\n\t\t\tif ((int)s >= (size * ITERATIONS * (nthr - 1))) {\n\t\t\t\tck_error(\"MPMC: Unexpected size of %u\\n\", s);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < nthr - 1; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ring/validate/ck_ring_spmc_template.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <string.h>\n#include <pthread.h>\n\n#include <ck_barrier.h>\n#include <ck_ring.h>\n#include <ck_spinlock.h>\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n\tstruct entry **buffer;\n};\n\nstruct entry {\n\tunsigned long value_long;\n\tunsigned int magic;\n\tunsigned int ref;\n\tint tid;\n\tint value;\n};\n\nCK_RING_PROTOTYPE(entry, entry *)\n\nstatic int nthr;\nstatic ck_ring_t *ring;\nstatic ck_ring_t ring_spmc CK_CC_CACHELINE;\nstatic struct affinity a;\nstatic int size;\nstatic int eb;\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstatic struct context *_context;\n\nstatic void *\ntest_spmc(void *c)\n{\n\tunsigned int observed = 0;\n\tunsigned long previous = 0;\n\tunsigned int seed;\n\tint i, k, j, tid;\n\tstruct context *context = c;\n\tstruct entry **buffer;\n\n\tbuffer = context->buffer;\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\ttid = ck_pr_faa_int(&eb, 1);\n\tck_pr_fence_memory();\n\twhile (ck_pr_load_int(&eb) != nthr - 1);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tstruct entry *o;\n\t\t\tint spin;\n\n\t\t\t/* Keep trying until we encounter at least one node. */\n\t\t\tif (j & 1) {\n\t\t\t\twhile (CK_RING_DEQUEUE_SPMC(entry,\n\t\t\t\t    &ring_spmc, buffer, &o) == false);\n\t\t\t} else {\n\t\t\t\twhile (CK_RING_TRYDEQUEUE_SPMC(entry,\n\t\t\t\t    &ring_spmc, buffer, &o) == false);\n\t\t\t}\n\n\t\t\tobserved++;\n\t\t\tif (o->value < 0\n\t\t\t    || o->value != o->tid\n\t\t\t    || o->magic != 0xdead\n\t\t\t    || (previous != 0 && previous >= o->value_long)) {\n\t\t\t\tck_error(\"[0x%p] (%x) (%d, %d) >< (0, %d)\\n\",\n\t\t\t\t\t(void *)o, o->magic, o->tid, o->value, size);\n\t\t\t}\n\n\t\t\to->magic = 0xbeef;\n\t\t\to->value = -31337;\n\t\t\to->tid = -31338;\n\t\t\tprevious = o->value_long;\n\n\t\t\tif (ck_pr_faa_uint(&o->ref, 1) != 0) {\n\t\t\t\tck_error(\"[%p] We dequeued twice.\\n\", (void *)o);\n\t\t\t}\n\n\t\t\tif ((i % 4) == 0) {\n\t\t\t\tspin = common_rand_r(&seed) % 16384;\n\t\t\t\tfor (k = 0; k < spin; k++) {\n\t\t\t\t\tck_pr_stall();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfree(o);\n\t\t}\n\t}\n\n\tfprintf(stderr, \"[%d] Observed %u\\n\", tid, observed);\n\treturn NULL;\n}\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tunsigned int s;\n\tint i, j;\n\tbool r;\n\tstruct entry **buffer = context->buffer;\n\tck_barrier_centralized_state_t sense =\n\t    CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tif (context->tid == 0) {\n\t\tstruct entry **entries;\n\n\t\tentries = malloc(sizeof(struct entry *) * size);\n\t\tassert(entries != NULL);\n\n\t\tif (ck_ring_size(ring) != 0) {\n\t\t\tck_error(\"More entries than expected: %u > 0\\n\",\n\t\t\t\tck_ring_size(ring));\n\t\t}\n\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tentries[i] = malloc(sizeof(struct entry));\n\t\t\tassert(entries[i] != NULL);\n\n\t\t\tentries[i]->value = i;\n\t\t\tentries[i]->tid = 0;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = CK_RING_ENQUEUE_SPMC(entry, ring, buffer,\n\t\t\t\t    &entries[i]);\n\t\t\t} else {\n\t\t\t\tr = CK_RING_ENQUEUE_SPMC_SIZE(entry, ring,\n\t\t\t\t\tbuffer, &entries[i], &s);\n\n\t\t\t\tif ((int)s != i) {\n\t\t\t\t\tck_error(\"Size is %u, expected %d.\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassert(r != false);\n\t\t}\n\n\t\tif (ck_ring_size(ring) != (unsigned int)size) {\n\t\t\tck_error(\"Less entries than expected: %u < %d\\n\",\n\t\t\t\tck_ring_size(ring), size);\n\t\t}\n\n\t\tif (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) {\n\t\t\tck_error(\"Capacity less than expected: %u < %u\\n\",\n\t\t\t\tck_ring_size(ring), ck_ring_capacity(ring));\n\t\t}\n\t}\n\n\t/*\n\t * Wait for all threads. The idea here is to maximize the contention.\n\t */\n\tck_barrier_centralized(&barrier, &sense, nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tbuffer = _context[context->previous].buffer;\n\t\t\twhile (CK_RING_DEQUEUE_SPMC(entry,\n\t\t\t    ring + context->previous,\n\t\t\t    buffer, &entry) == false);\n\n\t\t\tif (context->previous != (unsigned int)entry->tid) {\n\t\t\t\tck_error(\"[%u:%p] %u != %u\\n\",\n\t\t\t\t    context->tid, (void *)entry,\n\t\t\t\t    entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tif (entry->value < 0 || entry->value >= size) {\n\t\t\t\tck_error(\"[%u:%p] %u </> %u\\n\",\n\t\t\t\t    context->tid, (void *)entry,\n\t\t\t\t    entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tentry->tid = context->tid;\n\t\t\tbuffer = context->buffer;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = CK_RING_ENQUEUE_SPMC(entry,\n\t\t\t\t    ring + context->tid,\n\t\t\t\t    buffer, &entry);\n\t\t\t} else {\n\t\t\t\tr = CK_RING_ENQUEUE_SPMC_SIZE(entry,\n\t\t\t\t    ring + context->tid,\n\t\t\t\t    buffer, &entry, &s);\n\n\t\t\t\tif ((int)s >= size) {\n\t\t\t\t\tck_error(\"Size %u out of range of %d\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(r == true);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tunsigned long l;\n\tpthread_t *thread;\n\tstruct entry **buffer;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size >= 4 && (size & size - 1) == 0);\n\tsize -= 1;\n\n\tring = malloc(sizeof(ck_ring_t) * nthr);\n\tassert(ring);\n\n\t_context = malloc(sizeof(*_context) * nthr);\n\tassert(_context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tfprintf(stderr, \"SPSC test:\");\n\tfor (i = 0; i < nthr; i++) {\n\t\t_context[i].tid = i;\n\t\tif (i == 0) {\n\t\t\t_context[i].previous = nthr - 1;\n\t\t\t_context[i].next = i + 1;\n\t\t} else if (i == nthr - 1) {\n\t\t\t_context[i].next = 0;\n\t\t\t_context[i].previous = i - 1;\n\t\t} else {\n\t\t\t_context[i].next = i + 1;\n\t\t\t_context[i].previous = i - 1;\n\t\t}\n\n\t\tbuffer = malloc(sizeof(struct entry *) * (size + 1));\n\t\tassert(buffer);\n\t\tmemset(buffer, 0, sizeof(struct entry *) * (size + 1));\n\t\t_context[i].buffer = buffer;\n\t\tck_ring_init(ring + i, size + 1);\n\t\tr = pthread_create(thread + i, NULL, test, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tfprintf(stderr, \" done\\n\");\n\n\tfprintf(stderr, \"SPMC test:\\n\");\n\tbuffer = malloc(sizeof(struct entry *) * (size + 1));\n\tassert(buffer);\n\tmemset(buffer, 0, sizeof(struct entry *) * (size + 1));\n\tck_ring_init(&ring_spmc, size + 1);\n\tfor (i = 0; i < nthr - 1; i++) {\n\t\t_context[i].buffer = buffer;\n\t\tr = pthread_create(thread + i, NULL, test_spmc, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (l = 0; l < (unsigned long)size * ITERATIONS * (nthr - 1) ; l++) {\n\t\tstruct entry *entry = malloc(sizeof *entry);\n\n\t\tassert(entry != NULL);\n\t\tentry->value_long = l;\n\t\tentry->value = (int)l;\n\t\tentry->tid = (int)l;\n\t\tentry->magic = 0xdead;\n\t\tentry->ref = 0;\n\n\t\t/* Wait until queue is not full. */\n\t\tif (l & 1) {\n\t\t\twhile (CK_RING_ENQUEUE_SPMC(entry, &ring_spmc,\n\t\t\t    buffer, &entry) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\t\t} else {\n\t\t\tunsigned int s;\n\n\t\t\twhile (CK_RING_ENQUEUE_SPMC_SIZE(entry, &ring_spmc,\n\t\t\t    buffer, &entry, &s) == false) {\n\t\t\t\tck_pr_stall();\n\t\t\t}\n\n\t\t\tif ((int)s >= (size * ITERATIONS * (nthr - 1))) {\n\t\t\t\tck_error(\"MPMC: Unexpected size of %u\\n\", s);\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (i = 0; i < nthr - 1; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_ring/validate/ck_ring_spsc.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n#include <pthread.h>\n\n#include <ck_barrier.h>\n#include <ck_ring.h>\n#include \"../../common.h\"\n\n#ifndef ITERATIONS\n#define ITERATIONS 128\n#endif\n\nstruct context {\n\tunsigned int tid;\n\tunsigned int previous;\n\tunsigned int next;\n\tvoid *buffer;\n};\n\nstruct entry {\n\tint tid;\n\tint value;\n};\n\nstatic int nthr;\nstatic ck_ring_t *ring;\nstatic struct affinity a;\nstatic int size;\nstatic ck_barrier_centralized_t barrier = CK_BARRIER_CENTRALIZED_INITIALIZER;\nstatic struct context *_context;\n\nstatic void *\ntest(void *c)\n{\n\tstruct context *context = c;\n\tstruct entry *entry;\n\tunsigned int s;\n\tint i, j;\n\tbool r;\n\tck_barrier_centralized_state_t sense =\n\t    CK_BARRIER_CENTRALIZED_STATE_INITIALIZER;\n\tck_ring_buffer_t *buffer;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\tbuffer = context->buffer;\n\tif (context->tid == 0) {\n\t\tstruct entry *entries;\n\n\t\tentries = malloc(sizeof(struct entry) * size);\n\t\tassert(entries != NULL);\n\n\t\tif (ck_ring_size(ring) != 0) {\n\t\t\tck_error(\"More entries than expected: %u > 0\\n\",\n\t\t\t\tck_ring_size(ring));\n\t\t}\n\n\t\tfor (i = 0; i < size; i++) {\n\t\t\tentries[i].value = i;\n\t\t\tentries[i].tid = 0;\n\n\t\t\tif (i & 1) {\n\t\t\t\tr = ck_ring_enqueue_spsc(ring, buffer,\n\t\t\t\t    entries + i);\n\t\t\t} else {\n\t\t\t\tr = ck_ring_enqueue_spsc_size(ring,\n\t\t\t\t\tbuffer, entries + i, &s);\n\n\t\t\t\tif ((int)s != i) {\n\t\t\t\t\tck_error(\"Size is %u, expected %d\\n\",\n\t\t\t\t\t    s, i + 1);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tassert(r != false);\n\t\t}\n\n\t\tif (ck_ring_size(ring) != (unsigned int)size) {\n\t\t\tck_error(\"Less entries than expected: %u < %d\\n\",\n\t\t\t\tck_ring_size(ring), size);\n\t\t}\n\n\t\tif (ck_ring_capacity(ring) != ck_ring_size(ring) + 1) {\n\t\t\tck_error(\"Capacity less than expected: %u < %u\\n\",\n\t\t\t\tck_ring_size(ring), ck_ring_capacity(ring));\n\t\t}\n\t}\n\n\tck_barrier_centralized(&barrier, &sense, nthr);\n\n\tfor (i = 0; i < ITERATIONS; i++) {\n\t\tfor (j = 0; j < size; j++) {\n\t\t\tbuffer = _context[context->previous].buffer;\n\t\t\twhile (ck_ring_dequeue_spsc(ring + context->previous,\n\t\t\t    buffer, &entry) == false);\n\n\t\t\tif (context->previous != (unsigned int)entry->tid) {\n\t\t\t\tck_error(\"[%u:%p] %u != %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tif (entry->value != j) {\n\t\t\t\tck_error(\"[%u:%p] %u != %u\\n\",\n\t\t\t\t\tcontext->tid, (void *)entry, entry->tid, context->previous);\n\t\t\t}\n\n\t\t\tentry->tid = context->tid;\n\t\t\tbuffer = context->buffer;\n\t\t\tif (i & 1) {\n\t\t\t\tr = ck_ring_enqueue_spsc(ring + context->tid,\n\t\t\t\t\tbuffer, entry);\n\t\t\t} else {\n\t\t\t\tr = ck_ring_enqueue_spsc_size(ring +\n\t\t\t\t\tcontext->tid, buffer, entry, &s);\n\n\t\t\t\tif ((int)s >= size) {\n\t\t\t\t\tck_error(\"Size %u is out of range %d\\n\",\n\t\t\t\t\t    s, size);\n\t\t\t\t}\n\t\t\t}\n\t\t\tassert(r == true);\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tint i, r;\n\tck_ring_buffer_t *buffer;\n\tpthread_t *thread;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <threads> <affinity delta> <size>\\n\");\n\t}\n\n\ta.request = 0;\n\ta.delta = atoi(argv[2]);\n\n\tnthr = atoi(argv[1]);\n\tassert(nthr >= 1);\n\n\tsize = atoi(argv[3]);\n\tassert(size >= 4 && (size & size - 1) == 0);\n\tsize -= 1;\n\n\tring = malloc(sizeof(ck_ring_t) * nthr);\n\tassert(ring);\n\n\t_context = malloc(sizeof(*_context) * nthr);\n\tassert(_context);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread);\n\n\tfor (i = 0; i < nthr; i++) {\n\t\t_context[i].tid = i;\n\t\tif (i == 0) {\n\t\t\t_context[i].previous = nthr - 1;\n\t\t\t_context[i].next = i + 1;\n\t\t} else if (i == nthr - 1) {\n\t\t\t_context[i].next = 0;\n\t\t\t_context[i].previous = i - 1;\n\t\t} else {\n\t\t\t_context[i].next = i + 1;\n\t\t\t_context[i].previous = i - 1;\n\t\t}\n\n\t\tbuffer = malloc(sizeof(ck_ring_buffer_t) * (size + 1));\n\t\tassert(buffer);\n\t\t_context[i].buffer = buffer;\n\t\tck_ring_init(ring + i, size + 1);\n\t\tr = pthread_create(thread + i, NULL, test, _context + i);\n\t\tassert(r == 0);\n\t}\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/benchmark/ck_neutral.c",
    "content": "#include \"../ck_neutral.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/benchmark/ck_rp.c",
    "content": "#include \"../ck_rp.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/benchmark/ck_wp.c",
    "content": "#include \"../ck_wp.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/benchmark/latency.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copyright 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_rwcohort.h>\n#include <ck_spinlock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic void\nck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_fas_lock(lock);\n}\n\nstatic void\nck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_fas_unlock(lock);\n}\n\nstatic bool\nck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\treturn ck_spinlock_fas_locked(lock);\n}\n\nCK_COHORT_PROTOTYPE(fas_fas,\n\tck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,\n\tck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)\nLOCK_PROTOTYPE(fas_fas)\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_spinlock_fas_t global_lock = CK_SPINLOCK_FAS_INITIALIZER;\n\tck_spinlock_fas_t local_lock = CK_SPINLOCK_FAS_INITIALIZER;\n\tCK_COHORT_INSTANCE(fas_fas) cohort = CK_COHORT_INITIALIZER;\n\tLOCK_INSTANCE(fas_fas) rw_cohort = LOCK_INITIALIZER;\n\n\tCK_COHORT_INIT(fas_fas, &cohort, &global_lock, &local_lock,\n\t    CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\tLOCK_INIT(fas_fas, &rw_cohort, CK_RWCOHORT_WP_DEFAULT_WAIT_LIMIT);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tWRITE_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t\tWRITE_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tWRITE_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t\tWRITE_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t}\n\te_b = rdtsc();\n\tprintf(\"WRITE: rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tREAD_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tREAD_LOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, &cohort, NULL, NULL);\n\t}\n\te_b = rdtsc();\n\tprintf(\"READ:  rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/benchmark/throughput.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copyright 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_cohort.h>\n#include <ck_rwcohort.h>\n#include <ck_spinlock.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <string.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#define max(x, y) (((x) > (y)) ? (x) : (y))\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic unsigned int barrier;\nstatic unsigned int flag CK_CC_CACHELINE;\nstatic struct affinity affinity;\nstatic unsigned int nthr;\n\nstatic void\nck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\n\t(void)context;\n\tck_spinlock_fas_lock(lock);\n\treturn;\n}\n\nstatic void\nck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\n\t(void)context;\n\tck_spinlock_fas_unlock(lock);\n\treturn;\n}\n\nstatic bool\nck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\n\t(void)context;\n\treturn ck_spinlock_fas_locked(lock);\n}\n\nCK_COHORT_PROTOTYPE(fas_fas,\n    ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,\n    ck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)\nLOCK_PROTOTYPE(fas_fas)\n\nstruct cohort_record {\n\tCK_COHORT_INSTANCE(fas_fas) cohort;\n} CK_CC_CACHELINE;\nstatic struct cohort_record *cohorts;\n\nstatic ck_spinlock_t global_lock = CK_SPINLOCK_INITIALIZER;\nstatic LOCK_INSTANCE(fas_fas) rw_cohort = LOCK_INITIALIZER;\nstatic unsigned int n_cohorts;\n\nstruct block {\n\tunsigned int tid;\n};\n\nstatic void *\nthread_rwlock(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tuint64_t *value = pun;\n\tCK_COHORT_INSTANCE(fas_fas) *cohort;\n\tunsigned int core;\n\n\tif (aff_iterate_core(&affinity, &core) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tcohort = &((cohorts + (core / (int)(affinity.delta)) % n_cohorts)->cohort);\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) != nthr)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) != nthr * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tunsigned int i;\n\tpthread_t *threads;\n\tuint64_t *latency;\n\tstruct block *context;\n\tck_spinlock_fas_t *local_lock;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: throughput <number of cohorts> <threads per cohort> <affinity delta>\\n\");\n\t}\n\n\tn_cohorts = atoi(argv[1]);\n\tif (n_cohorts <= 0) {\n\t\tck_error(\"ERROR: Number of cohorts must be greater than 0\\n\");\n\t}\n\n\tnthr = n_cohorts * atoi(argv[2]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\tcohorts = malloc(sizeof(struct cohort_record) * n_cohorts);\n\tif (cohorts == NULL) {\n\t\tck_error(\"ERROR: Could not allocate cohort structures\\n\");\n\t}\n\n\tcontext = malloc(sizeof(struct block) * nthr);\n\tif (context == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread contexts\\n\");\n\t}\n\n\taffinity.delta = atoi(argv[3]);\n\taffinity.request = 0;\n\n\tlatency = malloc(sizeof(*latency) * nthr);\n\tif (latency == NULL) {\n\t\tck_error(\"ERROR: Could not create latency buffer\\n\");\n\t}\n\tmemset(latency, 0, sizeof(*latency) * nthr);\n\n\tfprintf(stderr, \"Creating cohorts...\");\n\tfor (i = 0 ; i < n_cohorts ; i++) {\n\t\tlocal_lock = malloc(max(CK_MD_CACHELINE, sizeof(ck_spinlock_fas_t)));\n\t\tif (local_lock == NULL) {\n\t\t\tck_error(\"ERROR: Could not allocate local lock\\n\");\n\t\t}\n\t\tCK_COHORT_INIT(fas_fas, &((cohorts + i)->cohort), &global_lock, local_lock,\n\t\t    CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\t\tlocal_lock = NULL;\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Creating threads (rwlock)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread_rwlock, latency + i) != 0) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&flag, 1);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (i = 1; i <= nthr; i++)\n\t\tprintf(\"%10u %20\" PRIu64 \"\\n\", i, latency[i - 1]);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/ck_neutral.h",
    "content": "#define LOCK_PROTOTYPE CK_RWCOHORT_NEUTRAL_PROTOTYPE\n#define LOCK_INSTANCE CK_RWCOHORT_NEUTRAL_INSTANCE\n#define LOCK_INITIALIZER CK_RWCOHORT_NEUTRAL_INITIALIZER\n#define LOCK_INIT(N, C, W) CK_RWCOHORT_NEUTRAL_INIT(N, C)\n#define READ_LOCK CK_RWCOHORT_NEUTRAL_READ_LOCK\n#define WRITE_LOCK CK_RWCOHORT_NEUTRAL_WRITE_LOCK\n#define READ_UNLOCK CK_RWCOHORT_NEUTRAL_READ_UNLOCK\n#define WRITE_UNLOCK CK_RWCOHORT_NEUTRAL_WRITE_UNLOCK\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/ck_rp.h",
    "content": "#define LOCK_PROTOTYPE CK_RWCOHORT_RP_PROTOTYPE\n#define LOCK_INSTANCE CK_RWCOHORT_RP_INSTANCE\n#define LOCK_INITIALIZER CK_RWCOHORT_RP_INITIALIZER\n#define LOCK_INIT CK_RWCOHORT_RP_INIT\n#define READ_LOCK CK_RWCOHORT_RP_READ_LOCK\n#define READ_UNLOCK CK_RWCOHORT_RP_READ_UNLOCK\n#define WRITE_LOCK CK_RWCOHORT_RP_WRITE_LOCK\n#define WRITE_UNLOCK CK_RWCOHORT_RP_WRITE_UNLOCK\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/ck_wp.h",
    "content": "#define LOCK_PROTOTYPE CK_RWCOHORT_WP_PROTOTYPE\n#define LOCK_INSTANCE CK_RWCOHORT_WP_INSTANCE\n#define LOCK_INITIALIZER CK_RWCOHORT_WP_INITIALIZER\n#define LOCK_INIT CK_RWCOHORT_WP_INIT\n#define READ_LOCK CK_RWCOHORT_WP_READ_LOCK\n#define WRITE_LOCK CK_RWCOHORT_WP_WRITE_LOCK\n#define READ_UNLOCK CK_RWCOHORT_WP_READ_UNLOCK\n#define WRITE_UNLOCK CK_RWCOHORT_WP_WRITE_UNLOCK\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/validate/ck_neutral.c",
    "content": "#include \"../ck_neutral.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/validate/ck_rp.c",
    "content": "#include \"../ck_rp.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/validate/ck_wp.c",
    "content": "#include \"../ck_wp.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwcohort/validate/validate.h",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * Copything 2013 Brendon Scheinman.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_rwcohort.h>\n#include <ck_spinlock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\n\nstatic struct affinity a;\nstatic unsigned int locked;\nstatic int nthr;\nstatic ck_spinlock_fas_t global_fas_lock = CK_SPINLOCK_FAS_INITIALIZER;\n\nstatic void\nck_spinlock_fas_lock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_fas_lock(lock);\n}\n\nstatic void\nck_spinlock_fas_unlock_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\tck_spinlock_fas_unlock(lock);\n}\n\nstatic bool\nck_spinlock_fas_locked_with_context(ck_spinlock_fas_t *lock, void *context)\n{\n\t(void)context;\n\treturn ck_spinlock_fas_locked(lock);\n}\n\nCK_COHORT_PROTOTYPE(fas_fas,\n\tck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context,\n\tck_spinlock_fas_lock_with_context, ck_spinlock_fas_unlock_with_context, ck_spinlock_fas_locked_with_context)\nLOCK_PROTOTYPE(fas_fas)\n\nstatic CK_COHORT_INSTANCE(fas_fas) *cohorts;\nstatic LOCK_INSTANCE(fas_fas) rw_cohort = LOCK_INITIALIZER;\nstatic int n_cohorts;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n        int i = ITERATE;\n\tunsigned int l;\n\tunsigned int core;\n\tCK_COHORT_INSTANCE(fas_fas) *cohort;\n\n\tif (aff_iterate_core(&a, &core)) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tcohort = cohorts + (core / (int)(a.delta)) % n_cohorts;\n\n\twhile (i--) {\n                WRITE_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tWRITE_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\n\t\tREAD_LOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tREAD_UNLOCK(fas_fas, &rw_cohort, cohort, NULL, NULL);\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\tint threads_per_cohort;\n\tck_spinlock_fas_t *local_lock;\n\tint i;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: validate <number of cohorts> <threads per cohort> <affinity delta>\\n\");\n\t}\n\n\tn_cohorts = atoi(argv[1]);\n\tif (n_cohorts <= 0) {\n\t\tck_error(\"ERROR: Number of cohorts must be greater than 0\\n\");\n\t}\n\n\tthreads_per_cohort = atoi(argv[2]);\n\tif (threads_per_cohort <= 0) {\n\t\tck_error(\"ERROR: Threads per cohort must be greater than 0\\n\");\n\t}\n\n\tnthr = n_cohorts * threads_per_cohort;\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[3]);\n\n\tfprintf(stderr, \"Creating cohorts...\");\n\tcohorts = malloc(sizeof(CK_COHORT_INSTANCE(fas_fas)) * n_cohorts);\n\tif (cohorts == NULL) {\n\t\tck_error(\"ERROR: Could not allocate base cohort structures\\n\");\n\t}\n\tfor (i = 0 ; i < n_cohorts ; i++) {\n\t\tlocal_lock = malloc(sizeof(ck_spinlock_fas_t));\n\t\tCK_COHORT_INIT(fas_fas, cohorts + i, &global_fas_lock, local_lock,\n\t\t    CK_COHORT_DEFAULT_LOCAL_PASS_LIMIT);\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Creating threads...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwlock/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_rwlock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#define CK_F_PR_RTM\n\n#ifndef STEPS\n#define STEPS 2000000\n#endif\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_rwlock_t rwlock = CK_RWLOCK_INITIALIZER;\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_write_lock(&rwlock);\n\t\tck_rwlock_write_unlock(&rwlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_write_lock(&rwlock);\n\t\tck_rwlock_write_unlock(&rwlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                WRITE: rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n#ifdef CK_F_PR_RTM\n\tstruct ck_elide_config config = CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;\n\tstruct ck_elide_stat st = CK_ELIDE_STAT_INITIALIZER;\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK(ck_rwlock_write, &rwlock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_write, &rwlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK(ck_rwlock_write, &rwlock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_write, &rwlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"          (rtm) WRITE: rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &st, &config, &rwlock);\n\t\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &st, &rwlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &st, &config, &rwlock);\n\t\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &st, &rwlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\" (rtm-adaptive) WRITE: rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n#endif /* CK_F_PR_RTM */\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_read_lock(&rwlock);\n\t\tck_rwlock_read_unlock(&rwlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_rwlock_read_lock(&rwlock);\n\t\tck_rwlock_read_unlock(&rwlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                READ:  rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n#ifdef CK_F_PR_RTM\n\tck_elide_stat_init(&st);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rwlock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rwlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rwlock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rwlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"          (rtm) READ:  rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_read, &st, &config, &rwlock);\n\t\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_read, &st, &rwlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_read, &st, &config, &rwlock);\n\t\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_read, &st, &rwlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\" (rtm-adaptive) READ:  rwlock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n#endif /* CK_F_PR_RTM */\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwlock/benchmark/throughput.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_rwlock.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic int barrier;\nstatic int threads;\nstatic unsigned int flag CK_CC_CACHELINE;\nstatic struct {\n\tck_rwlock_t lock;\n} rw CK_CC_CACHELINE = {\n\t.lock = CK_RWLOCK_INITIALIZER\n};\n\nstatic struct affinity affinity;\n\n#ifdef CK_F_PR_RTM\nstatic void *\nthread_lock_rtm(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tuint64_t *value = pun;\n\n\tif (aff_iterate(&affinity) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &rw.lock);\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &rw.lock);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n#endif /* CK_F_PR_RTM */\n\nstatic void *\nthread_lock(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tuint64_t *value = pun;\n\n\tif (aff_iterate(&affinity) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\tck_rwlock_read_lock(&rw.lock);\n\t\tck_rwlock_read_unlock(&rw.lock);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n\nstatic void\nrwlock_test(pthread_t *p, int d, uint64_t *latency, void *(*f)(void *), const char *label)\n{\n\tint t;\n\n\tck_pr_store_int(&barrier, 0);\n\tck_pr_store_uint(&flag, 0);\n\n\taffinity.delta = d;\n\taffinity.request = 0;\n\n\tfprintf(stderr, \"Creating threads (%s)...\", label);\n\tfor (t = 0; t < threads; t++) {\n\t\tif (pthread_create(&p[t], NULL, f, latency + t) != 0) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", t);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&flag, 1);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (t = 0; t < threads; t++)\n\t\tpthread_join(p[t], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (t = 1; t <= threads; t++)\n\t\tprintf(\"%10u %20\" PRIu64 \"\\n\", t, latency[t - 1]);\n\n\tfprintf(stderr, \"\\n\");\n\treturn;\n}\n\n\nint\nmain(int argc, char *argv[])\n{\n\tint d;\n\tpthread_t *p;\n\tuint64_t *latency;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: throughput <delta> <threads>\\n\");\n\t}\n\n\tthreads = atoi(argv[2]);\n\tif (threads <= 0) {\n\t\tck_error(\"ERROR: Threads must be a value > 0.\\n\");\n\t}\n\n\tp = malloc(sizeof(pthread_t) * threads);\n\tif (p == NULL) {\n\t\tck_error(\"ERROR: Failed to initialize thread.\\n\");\n\t}\n\n\tlatency = malloc(sizeof(uint64_t) * threads);\n\tif (latency == NULL) {\n\t\tck_error(\"ERROR: Failed to create latency buffer.\\n\");\n\t}\n\n\td = atoi(argv[1]);\n\trwlock_test(p, d, latency, thread_lock, \"rwlock\");\n\n#ifdef CK_F_PR_RTM\n\trwlock_test(p, d, latency, thread_lock_rtm, \"rwlock, rtm\");\n#endif /* CK_F_PR_RTM */\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_rwlock/validate/validate.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_rwlock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstatic struct affinity a;\nstatic unsigned int locked;\nstatic unsigned int tid = 2;\nstatic int nthr;\nstatic ck_rwlock_t lock = CK_RWLOCK_INITIALIZER;\nstatic ck_rwlock_recursive_t r_lock = CK_RWLOCK_RECURSIVE_INITIALIZER;\n\nstatic void *\nthread_recursive(void *null CK_CC_UNUSED)\n{\n\tint i = ITERATE;\n\tunsigned int l;\n\tunsigned int t = ck_pr_faa_uint(&tid, 1);\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\twhile (ck_rwlock_recursive_write_trylock(&r_lock, t) == false)\n\t\t\tck_pr_stall();\n\n\t\tck_rwlock_recursive_write_lock(&r_lock, t);\n\t\tck_rwlock_recursive_write_lock(&r_lock, t);\n\t\tck_rwlock_recursive_write_lock(&r_lock, t);\n\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_rwlock_recursive_write_unlock(&r_lock);\n\t\tck_rwlock_recursive_write_unlock(&r_lock);\n\t\tck_rwlock_recursive_write_unlock(&r_lock);\n\t\tck_rwlock_recursive_write_unlock(&r_lock);\n\n\t\tck_rwlock_recursive_read_lock(&r_lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_rwlock_recursive_read_unlock(&r_lock);\n\t}\n\n\treturn (NULL);\n}\n\n#ifdef CK_F_PR_RTM\nstatic void *\nthread_rtm_adaptive(void *null CK_CC_UNUSED)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\tstruct ck_elide_config config = CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;\n\tstruct ck_elide_stat st = CK_ELIDE_STAT_INITIALIZER;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tCK_ELIDE_LOCK_ADAPTIVE(ck_rwlock_write, &st, &config, &lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_rwlock_write, &st, &lock);\n\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &lock);\n\t}\n\n\treturn NULL;\n}\n\nstatic void *\nthread_rtm_mix(void *null CK_CC_UNUSED)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tif (i & 1) {\n\t\t\tCK_ELIDE_LOCK(ck_rwlock_write, &lock);\n\t\t} else {\n\t\t\tck_rwlock_write_lock(&lock);\n\t\t}\n\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\n\t\tif (i & 1) {\n\t\t\tCK_ELIDE_UNLOCK(ck_rwlock_write, &lock);\n\t\t} else {\n\t\t\tck_rwlock_write_unlock(&lock);\n\t\t}\n\n\t\tif (i & 1) {\n\t\t\tCK_ELIDE_LOCK(ck_rwlock_read, &lock);\n\t\t} else {\n\t\t\tck_rwlock_read_lock(&lock);\n\t\t}\n\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\n\t\tif (i & 1) {\n\t\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &lock);\n\t\t} else {\n\t\t\tck_rwlock_read_unlock(&lock);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nstatic void *\nthread_rtm(void *null CK_CC_UNUSED)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tCK_ELIDE_LOCK(ck_rwlock_write, &lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_write, &lock);\n\n\t\tCK_ELIDE_LOCK(ck_rwlock_read, &lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_ELIDE_UNLOCK(ck_rwlock_read, &lock);\n\t}\n\n\treturn (NULL);\n}\n#endif /* CK_F_PR_RTM */\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tck_rwlock_write_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_rwlock_write_unlock(&lock);\n\n\t\tck_rwlock_read_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_rwlock_read_unlock(&lock);\n\t}\n\n\treturn (NULL);\n}\n\nstatic void\nrwlock_test(pthread_t *threads, void *(*f)(void *), const char *test)\n{\n\tint i;\n\n\tfprintf(stderr, \"Creating threads (%s)...\", test);\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, f, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \".\");\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: validate <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\trwlock_test(threads, thread, \"regular\");\n#ifdef CK_F_PR_RTM\n\trwlock_test(threads, thread_rtm, \"rtm\");\n\trwlock_test(threads, thread_rtm_mix, \"rtm-mix\");\n\trwlock_test(threads, thread_rtm_adaptive, \"rtm-adaptive\");\n#endif\n\trwlock_test(threads, thread_recursive, \"recursive\");\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_sequence/benchmark/ck_sequence.c",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_cc.h>\n#include <ck_sequence.h>\n#include <errno.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <inttypes.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS (65536 * 64)\n#endif\n\nstatic ck_sequence_t seqlock CK_CC_CACHELINE = CK_SEQUENCE_INITIALIZER;\n\nint\nmain(void)\n{\n\tunsigned int i = 0;\n\tunsigned int version;\n\tuint64_t a, s;\n\n\t/* Read-side latency. */\n\ta = 0;\n\tfor (i = 0; i < STEPS / 4; i++) {\n\t\ts = rdtsc();\n\t\tck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));\n\t\tck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));\n\t\tck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));\n\t\tck_sequence_read_retry(&seqlock, ck_sequence_read_begin(&seqlock));\n\t\ta += rdtsc() - s;\n\t}\n\tprintf(\"read: %\" PRIu64 \"\\n\", a / STEPS);\n\n\ta = 0;\n\tfor (i = 0; i < STEPS / 4; i++) {\n\t\ts = rdtsc();\n\t\tCK_SEQUENCE_READ(&seqlock, &version);\n\t\tCK_SEQUENCE_READ(&seqlock, &version);\n\t\tCK_SEQUENCE_READ(&seqlock, &version);\n\t\tCK_SEQUENCE_READ(&seqlock, &version);\n\t\ta += rdtsc() - s;\n\t}\n\tprintf(\"READ %\" PRIu64 \"\\n\", a / STEPS);\n\n\t/* Write-side latency. */\n\ta = 0;\n\tfor (i = 0; i < STEPS / 4; i++) {\n\t\ts = rdtsc();\n\t\tck_sequence_write_begin(&seqlock);\n\t\tck_sequence_write_end(&seqlock);\n\t\tck_sequence_write_begin(&seqlock);\n\t\tck_sequence_write_end(&seqlock);\n\t\tck_sequence_write_begin(&seqlock);\n\t\tck_sequence_write_end(&seqlock);\n\t\tck_sequence_write_begin(&seqlock);\n\t\tck_sequence_write_end(&seqlock);\n\t\ta += rdtsc() - s;\n\t}\n\tprintf(\"write: %\" PRIu64 \"\\n\", a / STEPS);\n\n        return 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_sequence/validate/ck_sequence.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_cc.h>\n#include <ck_sequence.h>\n#include <errno.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstruct example {\n        unsigned int a;\n        unsigned int b;\n        unsigned int c;\n};\n\nstatic struct example global CK_CC_CACHELINE;\nstatic ck_sequence_t seqlock CK_CC_CACHELINE = CK_SEQUENCE_INITIALIZER;\nstatic unsigned int barrier;\nstatic struct affinity affinerator;\n\nstatic void\nvalidate(struct example *copy)\n{\n\n\tif (copy->b != copy->a + 1000) {\n\t\tck_error(\"ERROR: Failed regression: copy->b (%u != %u + %u / %u)\\n\",\n\t\t    copy->b, copy->a, 1000, copy->a + 1000);\n\t}\n\n\tif (copy->c != copy->a + copy->b) {\n\t\tck_error(\"ERROR: Failed regression: copy->c (%u != %u + %u / %u)\\n\",\n\t\t    copy->c, copy->a, copy->b, copy->a + copy->b);\n\t}\n\n\treturn;\n}\n\nstatic void *\nconsumer(void *unused CK_CC_UNUSED)\n{\n        struct example copy;\n        uint32_t version;\n        unsigned int retries = 0;\n        unsigned int i;\n\n\tunused = NULL;\n\tif (aff_iterate(&affinerator)) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n        while (ck_pr_load_uint(&barrier) == 0);\n        for (i = 0; i < STEPS; i++) {\n                /*\n                 * Attempt a read of the data structure. If the structure\n                 * has been modified between ck_sequence_read_begin and\n                 * ck_sequence_read_retry then attempt another read since\n                 * the data may be in an inconsistent state.\n                 */\n                do {\n                        version = ck_sequence_read_begin(&seqlock);\n                        copy.a = ck_pr_load_uint(&global.a);\n                        copy.b = ck_pr_load_uint(&global.b);\n\t\t\tcopy.c = ck_pr_load_uint(&global.c);\n\t\t\tretries++;\n                } while (ck_sequence_read_retry(&seqlock, version) == true);\n\t\tvalidate(&copy);\n\n\t\tCK_SEQUENCE_READ(&seqlock, &version) {\n                        copy.a = ck_pr_load_uint(&global.a);\n                        copy.b = ck_pr_load_uint(&global.b);\n\t\t\tcopy.c = ck_pr_load_uint(&global.c);\n\t\t\tretries++;\n\t\t}\n\t\tvalidate(&copy);\n        }\n\n        fprintf(stderr, \"%u retries.\\n\", retries - STEPS);\n\tck_pr_dec_uint(&barrier);\n        return (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n        unsigned int counter = 0;\n\tbool first = true;\n\tint n_threads, i;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: ck_sequence <number of threads> <affinity delta>\\n\");\n\t}\n\n\tn_threads = atoi(argv[1]);\n\tif (n_threads <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * n_threads);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate memory for threads\\n\");\n\t}\n\n\taffinerator.delta = atoi(argv[2]);\n\taffinerator.request = 0;\n\n\tfor (i = 0; i < n_threads; i++) {\n\t\tif (pthread_create(&threads[i], NULL, consumer, NULL)) {\n\t\t\tck_error(\"ERROR: Failed to create thread %d\\n\", i);\n\t\t}\n\t}\n\n        for (;;) {\n                /*\n                 * Update the shared data in a non-blocking fashion.\n\t\t * If the data is modified by multiple writers then\n\t\t * ck_sequence_write_begin must be called after acquiring\n\t\t * the associated lock and ck_sequence_write_end must be\n\t\t * called before relinquishing the lock.\n                 */\n                ck_sequence_write_begin(&seqlock);\n                global.a = counter++;\n\t\tglobal.b = global.a + 1000;\n\t\tglobal.c = global.b + global.a;\n                ck_sequence_write_end(&seqlock);\n\n\t\tif (first == true) {\n\t\t\tck_pr_store_uint(&barrier, n_threads);\n\t\t\tfirst = false;\n\t\t}\n\n                counter++;\n\t\tif (ck_pr_load_uint(&barrier) == 0)\n                        break;\n        }\n\n        printf(\"%u updates made.\\n\", counter);\n        return (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_anderson.c",
    "content": "#include \"../ck_anderson.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_cas.c",
    "content": "#include \"../ck_cas.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_clh.c",
    "content": "#include \"../ck_clh.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_dec.c",
    "content": "#include \"../ck_dec.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_fas.c",
    "content": "#include \"../ck_fas.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_hclh.c",
    "content": "#include \"../ck_hclh.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_mcs.c",
    "content": "#include \"../ck_mcs.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_spinlock.c",
    "content": "#include \"../ck_spinlock.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_ticket.c",
    "content": "#include \"../ck_ticket.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/ck_ticket_pb.c",
    "content": "#include \"../ck_ticket_pb.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/latency.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_bytelock.h>\n#include <ck_spinlock.h>\n#include <inttypes.h>\n#include <stdio.h>\n#include <stdlib.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 30000000\n#endif\n\nLOCK_DEFINE;\n\nint\nmain(void)\n{\n\tCK_CC_UNUSED unsigned int nthr = 1;\n\n\t#ifdef LOCK_INIT\n\tLOCK_INIT;\n\t#endif\n\n\t#ifdef LOCK_STATE\n\tLOCK_STATE;\n\t#endif\n\n\tuint64_t s_b, e_b, i;\n\tCK_CC_UNUSED int core = 0;\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; ++i) {\n\t\t#ifdef LOCK\n\t\tLOCK;\n\t\tUNLOCK;\n\t\tLOCK;\n\t\tUNLOCK;\n\t\tLOCK;\n\t\tUNLOCK;\n\t\tLOCK;\n\t\tUNLOCK;\n\t\t#endif\n\t}\n\te_b = rdtsc();\n\tprintf(\"%15\" PRIu64 \"\\n\", (e_b - s_b) / 4 / STEPS);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/linux_spinlock.c",
    "content": "#include \"../linux_spinlock.h\"\n\n#ifdef THROUGHPUT\n#include \"throughput.h\"\n#elif defined(LATENCY)\n#include \"latency.h\"\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/benchmark/throughput.h",
    "content": "/*\n * Copyright 2008-2012 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n\n#include \"../../common.h\"\n\n/* 8! = 40320, evenly divide 1 .. 8 processor workload. */\n#define WORKLOAD (40320 * 2056)\n\n#ifndef ITERATE\n#define ITERATE 65536\n#endif\n\nstruct block {\n\tunsigned int tid;\n};\n\nstatic struct affinity a;\nstatic unsigned int ready;\n\nstruct counters {\n\tuint64_t value;\n} CK_CC_CACHELINE;\n\nstatic struct counters *count;\nstatic uint64_t nthr;\nstatic unsigned int barrier;\n\nint critical __attribute__((aligned(64)));\n\nLOCK_DEFINE;\n\nCK_CC_USED static void\ngen_lock(void)\n{\n\tCK_CC_UNUSED int core = 0;\n#ifdef LOCK_STATE\n\tLOCK_STATE;\n#endif\n\n#ifdef LOCK\n\tLOCK;\n#endif\n}\n\nCK_CC_USED static void\ngen_unlock(void)\n{\n#ifdef LOCK_STATE\n\tLOCK_STATE;\n#endif\n\n#ifdef UNLOCK\n\tUNLOCK;\n#endif\n}\n\nstatic void *\nfairness(void *null)\n{\n#ifdef LOCK_STATE\n\tLOCK_STATE;\n#endif\n\tstruct block *context = null;\n\tunsigned int i = context->tid;\n\tvolatile int j;\n\tlong int base;\n\tunsigned int core;\n\n        if (aff_iterate_core(&a, &core)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (ck_pr_load_uint(&ready) == 0);\n\n\tck_pr_inc_uint(&barrier);\n\twhile (ck_pr_load_uint(&barrier) != nthr);\n\n\twhile (ready) {\n\t\tLOCK;\n\n\t\tcount[i].value++;\n\t\tif (critical) {\n\t\t\tbase = common_lrand48() % critical;\n\t\t\tfor (j = 0; j < base; j++);\n\t\t}\n\n\t\tUNLOCK;\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tuint64_t v, d;\n\tunsigned int i;\n\tpthread_t *threads;\n\tstruct block *context;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: \" LOCK_NAME \" <number of threads> <affinity delta> <critical section>\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n#ifdef LOCK_INIT\n\tLOCK_INIT;\n#endif\n\n\tcritical = atoi(argv[3]);\n\tif (critical < 0) {\n\t\tck_error(\"ERROR: critical section cannot be negative\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tcontext = malloc(sizeof(struct block) * nthr);\n\tif (context == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread contexts\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\ta.delta = atoi(argv[2]);\n\ta.request = 0;\n\n\tcount = malloc(sizeof(*count) * nthr);\n\tif (count == NULL) {\n\t\tck_error(\"ERROR: Could not create acquisition buffer\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\tmemset(count, 0, sizeof(*count) * nthr);\n\n\tfprintf(stderr, \"Creating threads (fairness)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tcontext[i].tid = i;\n\t\tif (pthread_create(&threads[i], NULL, fairness, context + i)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tck_pr_store_uint(&ready, 1);\n\tcommon_sleep(10);\n\tck_pr_store_uint(&ready, 0);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (i = 0, v = 0; i < nthr; i++) {\n\t\tprintf(\"%d %15\" PRIu64 \"\\n\", i, count[i].value);\n\t\tv += count[i].value;\n\t}\n\n\tprintf(\"\\n# total       : %15\" PRIu64 \"\\n\", v);\n\tprintf(\"# throughput  : %15\" PRIu64 \" a/s\\n\", (v /= nthr) / 10);\n\n\tfor (i = 0, d = 0; i < nthr; i++)\n\t\td += (count[i].value - v) * (count[i].value - v);\n\n\tprintf(\"# average     : %15\" PRIu64 \"\\n\", v);\n\tprintf(\"# deviation   : %.2f (%.2f%%)\\n\\n\", sqrt(d / nthr), (sqrt(d / nthr) / v) * 100.00);\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_anderson.h",
    "content": "#define MAX(a,b) ((a) > (b) ? (a) : (b))\n#define LOCK_NAME \"ck_anderson\"\n#define LOCK_DEFINE static ck_spinlock_anderson_t lock CK_CC_CACHELINE\n#define LOCK_STATE ck_spinlock_anderson_thread_t *nad = NULL\n#define LOCK ck_spinlock_anderson_lock(&lock, &nad)\n#define UNLOCK ck_spinlock_anderson_unlock(&lock, nad)\n#define LOCK_INIT ck_spinlock_anderson_init(&lock, malloc(MAX(64,sizeof(ck_spinlock_anderson_thread_t)) * nthr), nthr)\n#define LOCKED ck_spinlock_anderson_locked(&lock)\n\n#define NO_LOCAL\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_cas.h",
    "content": "#define LOCK_NAME \"ck_cas\"\n#define LOCK_DEFINE static ck_spinlock_cas_t CK_CC_CACHELINE lock = CK_SPINLOCK_CAS_INITIALIZER\n#define LOCK ck_spinlock_cas_lock_eb(&lock)\n#define UNLOCK ck_spinlock_cas_unlock(&lock)\n#define LOCKED ck_spinlock_cas_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_clh.h",
    "content": "#define MAX(a,b) ((a) > (b) ? (a) : (b))\n#define LOCK_NAME \"ck_clh\"\n#define LOCK_DEFINE static ck_spinlock_clh_t CK_CC_CACHELINE *lock = NULL\n#define LOCK_STATE ck_spinlock_clh_t *na = malloc(MAX(sizeof(ck_spinlock_clh_t), 64))\n#define LOCK ck_spinlock_clh_lock(&lock, na)\n#define UNLOCK ck_spinlock_clh_unlock(&na)\n#define LOCK_INIT ck_spinlock_clh_init(&lock, malloc(MAX(sizeof(ck_spinlock_clh_t), 64)))\n#define LOCKED ck_spinlock_clh_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_dec.h",
    "content": "#define LOCK_NAME \"ck_dec\"\n#define LOCK_DEFINE static ck_spinlock_dec_t CK_CC_CACHELINE lock = CK_SPINLOCK_DEC_INITIALIZER\n#define LOCK ck_spinlock_dec_lock_eb(&lock)\n#define UNLOCK ck_spinlock_dec_unlock(&lock)\n#define LOCKED ck_spinlock_dec_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_fas.h",
    "content": "#define LOCK_NAME \"ck_fas\"\n#define LOCK_DEFINE static ck_spinlock_fas_t CK_CC_CACHELINE lock = CK_SPINLOCK_FAS_INITIALIZER\n#define LOCK ck_spinlock_fas_lock_eb(&lock)\n#define UNLOCK ck_spinlock_fas_unlock(&lock)\n#define LOCKED ck_spinlock_fas_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_hclh.h",
    "content": "#define MAX(a,b) ((a) > (b) ? (a) : (b))\n#define LOCK_NAME \"ck_clh\"\n#define LOCK_DEFINE static ck_spinlock_hclh_t CK_CC_CACHELINE *glob_lock; \\\n\t\t    static ck_spinlock_hclh_t CK_CC_CACHELINE *local_lock[CORES / 2]\n#define LOCK_STATE ck_spinlock_hclh_t *na = malloc(MAX(sizeof(ck_spinlock_hclh_t), 64))\n#define LOCK ck_spinlock_hclh_lock(&glob_lock, &local_lock[(core % CORES) / 2], na)\n#define UNLOCK ck_spinlock_hclh_unlock(&na)\n#define LOCK_INIT do {\t\t\t\t\t\t\t\\\n\tint _i;\t\t\t\t\t\t\t\t\\\n\tck_spinlock_hclh_init(&glob_lock, malloc(MAX(sizeof(ck_spinlock_hclh_t), 64)), -1); \\\n\tfor (_i = 0; _i < CORES / 2; _i++) {\t\t\t\t\\\n\t\tck_spinlock_hclh_init(&local_lock[_i], malloc(MAX(sizeof(ck_spinlock_hclh_t), 64)), _i);\t} \\\n} while (0)\n\n#define LOCKED ck_spinlock_hclh_locked(&glob_lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_mcs.h",
    "content": "#define LOCK_NAME \"ck_mcs\"\n#define LOCK_DEFINE static ck_spinlock_mcs_t CK_CC_CACHELINE lock = NULL\n#define LOCK_STATE ck_spinlock_mcs_context_t node CK_CC_CACHELINE;\n#define LOCK ck_spinlock_mcs_lock(&lock, &node)\n#define UNLOCK ck_spinlock_mcs_unlock(&lock, &node)\n#define LOCKED ck_spinlock_mcs_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_spinlock.h",
    "content": "#define LOCK_NAME \"ck_spinlock\"\n#define LOCK_DEFINE static ck_spinlock_t CK_CC_CACHELINE lock = CK_SPINLOCK_INITIALIZER\n#define LOCK ck_spinlock_lock_eb(&lock)\n#define UNLOCK ck_spinlock_unlock(&lock)\n#define LOCKED ck_spinlock_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_ticket.h",
    "content": "#include <ck_spinlock.h>\n\n#define LOCK_NAME \"ck_ticket\"\n#define LOCK_DEFINE static ck_spinlock_ticket_t CK_CC_CACHELINE lock = CK_SPINLOCK_TICKET_INITIALIZER\n#define LOCK ck_spinlock_ticket_lock(&lock)\n#define UNLOCK ck_spinlock_ticket_unlock(&lock)\n#ifdef CK_F_SPINLOCK_TICKET_TRYLOCK\n#define TRYLOCK ck_spinlock_ticket_trylock(&lock)\n#endif\n#define LOCKED ck_spinlock_ticket_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/ck_ticket_pb.h",
    "content": "#define LOCK_NAME \"ck_ticket_pb\"\n#define LOCK_DEFINE static ck_spinlock_ticket_t CK_CC_CACHELINE lock = CK_SPINLOCK_TICKET_INITIALIZER\n#define LOCK ck_spinlock_ticket_lock_pb(&lock, 0)\n#define UNLOCK ck_spinlock_ticket_unlock(&lock)\n#define LOCKED ck_spinlock_ticket_locked(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/linux_spinlock.h",
    "content": "#include <ck_cc.h>\n\nCK_CC_INLINE static void\nspin_lock(volatile unsigned int *lock)\n{\n#ifdef __x86_64__\n            __asm__ __volatile__(\n                    \"\\n1:\\t\"\n                    \"lock ; decl %0\\n\\t\"\n                    \"jns 2f\\n\"\n                    \"3:\\n\"\n                    \"rep;nop\\n\\t\"\n                    \"cmpl $0,%0\\n\\t\"\n                    \"jle 3b\\n\\t\"\n                    \"jmp 1b\\n\"\n                    \"2:\\t\" : \"=m\" (*lock) : : \"memory\");\n#else\n\t*lock = 1;\n#endif\n\n          return;\n}\n\nCK_CC_INLINE static void\nspin_unlock(volatile unsigned int *lock)\n{\n#ifdef __x86_64__\n        __asm__ __volatile__(\"movl $1,%0\" :\"=m\" (*lock) :: \"memory\");\n#else\n\t*lock = 0;\n        return;\n#endif\n}\n\n#define LOCK_NAME \"linux_spinlock\"\n#define LOCK_DEFINE volatile unsigned int lock = 1\n#define LOCK spin_lock(&lock)\n#define UNLOCK spin_unlock(&lock)\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_anderson.c",
    "content": "#include \"../ck_anderson.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_cas.c",
    "content": "#include \"../ck_cas.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_clh.c",
    "content": "#include \"../ck_clh.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_dec.c",
    "content": "#include \"../ck_dec.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_fas.c",
    "content": "#include \"../ck_fas.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_hclh.c",
    "content": "#include \"../ck_hclh.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_mcs.c",
    "content": "#include \"../ck_mcs.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_spinlock.c",
    "content": "#include \"../ck_spinlock.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_ticket.c",
    "content": "#include \"../ck_ticket.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/ck_ticket_pb.c",
    "content": "#include \"../ck_ticket_pb.h\"\n#include \"validate.h\"\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/linux_spinlock.c",
    "content": "#ifdef __x86_64__\n#include \"../linux_spinlock.h\"\n#include \"validate.h\"\n#else\n#include <stdio.h>\n\nint\nmain(void)\n{\n\n\tfprintf(stderr, \"Unsupported.\\n\");\n\treturn 0;\n}\n#endif\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_spinlock/validate/validate.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstruct block {\n\tunsigned int tid;\n};\n\nstatic struct affinity a;\nstatic unsigned int locked = 0;\nstatic uint64_t nthr;\n\nLOCK_DEFINE;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n#ifdef LOCK_STATE\n\tLOCK_STATE;\n#endif\n\tunsigned int i = ITERATE;\n\tunsigned int j;\n\tunsigned int core;\n\n        if (aff_iterate_core(&a, &core)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n#ifdef TRYLOCK\n\t\tif (i & 1) {\n\t\t\tLOCK;\n\t\t} else {\n\t\t\twhile (TRYLOCK == false)\n\t\t\t\tck_pr_stall();\n\t\t}\n#else\n\t\tLOCK;\n#endif\n\n#ifdef LOCKED\n\t\tif (LOCKED == false)\n\t\t\tck_error(\"is_locked operation failed.\");\n#endif\n\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\t\tck_pr_store_uint(&locked, locked + 1);\n\n\t\tj = ck_pr_load_uint(&locked);\n\n\t\tif (j != 10) {\n\t\t\tck_error(\"ERROR (WR): Race condition (%u)\\n\", j);\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\t\tck_pr_store_uint(&locked, locked - 1);\n\n\t\tUNLOCK;\n\t\tLOCK;\n\n\t\tj = ck_pr_load_uint(&locked);\n\t\tif (j != 0) {\n\t\t\tck_error(\"ERROR (RD): Race condition (%u)\\n\", j);\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\n\t\tUNLOCK;\n\t}\n\n\treturn (NULL);\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tuint64_t i;\n\tpthread_t *threads;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: \" LOCK_NAME \" <number of threads> <affinity delta>\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n#ifdef LOCK_INIT\n\tLOCK_INIT;\n#endif\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\ta.delta = atoi(argv[2]);\n\ta.request = 0;\n\n\tfprintf(stderr, \"Creating threads (mutual exclusion)...\");\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, thread, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %\" PRIu64 \"\\n\", i);\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tfprintf(stderr, \"Waiting for threads to finish correctness regression...\");\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\n\treturn (0);\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_stack/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_stack.h>\n#include <ck_spinlock.h>\n#include <inttypes.h>\n#include <stdint.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#ifndef ENTRIES\n#define ENTRIES 4096\n#endif\n\n#ifndef STEPS\n#define STEPS 40000\n#endif\n\n/*\n * Note the redundant post-increment of r. This is to silence\n * some irrelevant GCC warnings.\n */\n\nstatic ck_stack_t stack CK_CC_CACHELINE;\n\nint\nmain(void)\n{\n\tck_stack_entry_t entry[ENTRIES];\n\tck_spinlock_fas_t mutex = CK_SPINLOCK_FAS_INITIALIZER;\n\tvolatile ck_stack_entry_t * volatile r;\n\tuint64_t s, e, a;\n\tunsigned int i;\n\tunsigned int j;\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++) {\n\t\t\tck_spinlock_fas_lock(&mutex);\n\t\t\tck_stack_push_spnc(&stack, entry + j);\n\t\t\tck_spinlock_fas_unlock(&mutex);\n\t\t}\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"     spinlock_push: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_stack_push_spnc(&stack, entry + j);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++) {\n\t\t\tck_spinlock_fas_lock(&mutex);\n\t\t\tr = ck_stack_pop_npsc(&stack);\n\t\t\tck_spinlock_fas_unlock(&mutex);\n\t\t}\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\"      spinlock_pop: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n\tr++;\n\n#ifdef CK_F_STACK_PUSH_UPMC\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_stack_push_upmc(&stack, entry + j);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_stack_push_upmc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n#endif /* CK_F_STACK_PUSH_UPMC */\n\n#ifdef CK_F_STACK_PUSH_MPMC\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_stack_push_mpmc(&stack, entry + j);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_stack_push_mpmc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n#endif /* CK_F_STACK_PUSH_MPMC */\n\n#ifdef CK_F_STACK_PUSH_MPNC\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_stack_push_mpnc(&stack, entry + j);\n\t\te = rdtsc();\n\n\t\ta += e - s;\n\t}\n\tprintf(\"ck_stack_push_mpnc: %16\" PRIu64 \"\\n\", a / STEPS / ENTRIES);\n#endif /* CK_F_STACK_PUSH_MPNC */\n\n#if defined(CK_F_STACK_PUSH_UPMC) && defined(CK_F_STACK_POP_UPMC)\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_stack_push_upmc(&stack, entry + j);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tr = ck_stack_pop_upmc(&stack);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\" ck_stack_pop_upmc: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(entry) / sizeof(*entry)));\n#endif /* CK_F_STACK_PUSH_UPMC && CK_F_STACK_POP_UPMC */\n\n#if defined(CK_F_STACK_POP_MPMC) && defined(CK_F_STACK_PUSH_MPMC)\n\ta = 0;\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_stack_init(&stack);\n\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tck_stack_push_mpmc(&stack, entry + j);\n\n\t\ts = rdtsc();\n\t\tfor (j = 0; j < ENTRIES; j++)\n\t\t\tr = ck_stack_pop_mpmc(&stack);\n\t\te = rdtsc();\n\t\ta += e - s;\n\t}\n\tprintf(\" ck_stack_pop_mpmc: %16\" PRIu64 \"\\n\", a / STEPS / (sizeof(entry) / sizeof(*entry)));\n\tr++;\n#endif\n\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_stack/validate/pair.c",
    "content": "/*\n * Copyright 2009 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#ifdef SPINLOCK\n#include <ck_spinlock.h>\n#endif\n#include <ck_stack.h>\n#include <errno.h>\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <pthread.h>\n#include <sys/time.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef ITEMS\n#define ITEMS (5765760)\n#endif\n\n#define TVTOD(tv) ((tv).tv_sec+((tv).tv_usec / (double)1000000))\n\nstruct entry {\n\tint value;\n#if defined(SPINLOCK) || defined(PTHREADS)\n\tstruct entry *next;\n#else\n\tck_stack_entry_t next;\n#endif\n} CK_CC_CACHELINE;\n\n#ifdef SPINLOCK\nstatic struct entry *stack CK_CC_CACHELINE;\nck_spinlock_fas_t stack_spinlock = CK_SPINLOCK_FAS_INITIALIZER;\n#define UNLOCK ck_spinlock_fas_unlock\n#if defined(EB)\n#define LOCK ck_spinlock_fas_lock_eb\n#else\n#define LOCK ck_spinlock_fas_lock\n#endif\n#elif defined(PTHREADS)\nstatic struct entry *stack CK_CC_CACHELINE;\npthread_mutex_t stack_spinlock = PTHREAD_MUTEX_INITIALIZER;\n#define LOCK pthread_mutex_lock\n#define UNLOCK pthread_mutex_unlock\n#else\nstatic ck_stack_t stack CK_CC_CACHELINE;\nCK_STACK_CONTAINER(struct entry, next, getvalue)\n#endif\n\nstatic struct affinity affinerator;\nstatic unsigned long long nthr;\nstatic volatile unsigned int barrier = 0;\nstatic unsigned int critical;\n\nstatic void *\nstack_thread(void *buffer)\n{\n#if (defined(MPMC) && defined(CK_F_STACK_POP_MPMC)) || (defined(UPMC) && defined(CK_F_STACK_POP_UPMC)) || (defined(TRYUPMC) && defined(CK_F_STACK_TRYPOP_UPMC)) || (defined(TRYMPMC) && defined(CK_F_STACK_TRYPOP_MPMC))\n\tck_stack_entry_t *ref;\n#endif\n\tstruct entry *entry = buffer;\n\tunsigned long long i, n = ITEMS;\n\tunsigned int seed;\n\tint j;\n\n\tif (aff_iterate(&affinerator)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\twhile (barrier == 0);\n\n\tfor (i = 0; i < n; i++) {\n#if defined(MPMC)\n                ck_stack_push_mpmc(&stack, &entry->next);\n#elif defined(TRYMPMC)\n\t\twhile (ck_stack_trypush_mpmc(&stack, &entry->next) == false)\n\t\t\tck_pr_stall();\n#elif defined(UPMC)\n                ck_stack_push_upmc(&stack, &entry->next);\n#elif defined(TRYUPMC)\n\t\twhile (ck_stack_trypush_upmc(&stack, &entry->next) == false)\n\t\t\tck_pr_stall();\n#elif defined(SPINLOCK) || defined(PTHREADS)\n\t\tLOCK(&stack_spinlock);\n\t\tck_pr_store_ptr(&entry->next, stack);\n\t\tck_pr_store_ptr(&stack, entry);\n\t\tUNLOCK(&stack_spinlock);\n#else\n#               error Undefined operation.\n#endif\n\n\t\tif (critical) {\n\t\t\tj = common_rand_r(&seed) % critical;\n\t\t\twhile (j--)\n\t\t\t\t__asm__ __volatile__(\"\" ::: \"memory\");\n\t\t}\n\n#if defined(MPMC)\n#ifdef CK_F_STACK_POP_MPMC\n\t\tref = ck_stack_pop_mpmc(&stack);\n\t\tentry = getvalue(ref);\n#endif\n#elif defined(TRYMPMC)\n#ifdef CK_F_STACK_TRYPOP_MPMC\n\t\twhile (ck_stack_trypop_mpmc(&stack, &ref) == false)\n\t\t\tck_pr_stall();\n\t\tentry = getvalue(ref);\n#endif /* CK_F_STACK_TRYPOP_MPMC */\n#elif defined(UPMC)\n\t\tref = ck_stack_pop_upmc(&stack);\n\t\tentry = getvalue(ref);\n#elif defined(SPINLOCK) || defined(PTHREADS)\n\t\tLOCK(&stack_spinlock);\n\t\tentry = stack;\n\t\tstack = stack->next;\n\t\tUNLOCK(&stack_spinlock);\n#else\n#\t\terror Undefined operation.\n#endif\n\t}\n\n\treturn (NULL);\n}\n\nstatic void\nstack_assert(void)\n{\n\n#if defined(SPINLOCK) || defined(PTHREADS)\n\tassert(stack == NULL);\n#else\n\tassert(CK_STACK_ISEMPTY(&stack));\n#endif\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tstruct entry *bucket;\n\tunsigned long long i, d;\n\tpthread_t *thread;\n\tstruct timeval stv, etv;\n\n#if (defined(TRYMPMC) || defined(MPMC)) && (!defined(CK_F_STACK_PUSH_MPMC) || !defined(CK_F_STACK_POP_MPMC))\n        fprintf(stderr, \"Unsupported.\\n\");\n        return 0;\n#endif\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <threads> <delta> <critical>\\n\");\n\t}\n\n\t{\n\t\tchar *e;\n\n\t\tnthr = strtol(argv[1], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: too many threads\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\n\t\td = strtol(argv[2], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: delta is too large\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\n\t\tcritical = strtoul(argv[3], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: critical section is too large\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\t}\n\n\tsrand(getpid());\n\n\taffinerator.request = 0;\n\taffinerator.delta = d;\n\n\tbucket = malloc(sizeof(struct entry) * nthr);\n\tassert(bucket != NULL);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread != NULL);\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_create(&thread[i], NULL, stack_thread, bucket + i);\n\n\tbarrier = 1;\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tbarrier = 0;\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_create(&thread[i], NULL, stack_thread, bucket + i);\n\n\tcommon_gettimeofday(&stv, NULL);\n\tbarrier = 1;\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\tcommon_gettimeofday(&etv, NULL);\n\n\tstack_assert();\n#ifdef _WIN32\n\tprintf(\"%3llu %.6f\\n\", nthr, TVTOD(etv) - TVTOD(stv));\n#else\n\tprintf(\"%3llu %.6lf\\n\", nthr, TVTOD(etv) - TVTOD(stv));\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_stack/validate/pop.c",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#ifdef SPINLOCK\n#include <ck_spinlock.h>\n#endif\n#include <ck_stack.h>\n#include <errno.h>\n#include <limits.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <pthread.h>\n#include <sys/time.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef ITEMS\n#define ITEMS (5765760 * 2)\n#endif\n\n#define TVTOD(tv) ((tv).tv_sec+((tv).tv_usec / (double)1000000))\n\nstruct entry {\n\tint value;\n#ifdef SPINLOCK\n\tstruct entry *next;\n#else\n\tck_stack_entry_t next;\n#endif\n};\n\n#ifdef SPINLOCK\nstatic struct entry *stack CK_CC_CACHELINE;\nck_spinlock_fas_t stack_spinlock = CK_SPINLOCK_FAS_INITIALIZER;\n#define UNLOCK ck_spinlock_fas_unlock\n#if defined(EB)\n#define LOCK ck_spinlock_fas_lock_eb\n#else\n#define LOCK ck_spinlock_fas_lock\n#endif\n#else\nstatic ck_stack_t stack CK_CC_CACHELINE;\nCK_STACK_CONTAINER(struct entry, next, getvalue)\n#endif\n\nstatic struct affinity affinerator = AFFINITY_INITIALIZER;\nstatic unsigned long long nthr;\nstatic volatile unsigned int barrier = 0;\nstatic unsigned int critical;\n\nstatic void *\nstack_thread(void *unused CK_CC_UNUSED)\n{\n#if (defined(MPMC) && defined(CK_F_STACK_POP_MPMC)) || (defined(UPMC) && defined(CK_F_STACK_POP_UPMC)) || (defined(TRYMPMC) && defined(CK_F_STACK_TRYPOP_MPMC)) || (defined(TRYUPMC) && defined(CK_F_STACK_TRYPOP_UPMC))\n\tck_stack_entry_t *ref;\n#endif\n\tstruct entry *entry = NULL;\n\tunsigned long long i, n = ITEMS / nthr;\n\tunsigned int seed;\n\tint j, previous = INT_MAX;\n\n\tif (aff_iterate(&affinerator)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\twhile (barrier == 0);\n\n\tfor (i = 0; i < n; i++) {\n#ifdef MPMC\n#ifdef CK_F_STACK_POP_MPMC\n\t\tref = ck_stack_pop_mpmc(&stack);\n\t\tassert(ref);\n\t\tentry = getvalue(ref);\n#endif /* CK_F_STACK_POP_MPMC */\n#elif defined(TRYMPMC)\n#ifdef CK_F_STACK_TRYPOP_MPMC\n\t\twhile (ck_stack_trypop_mpmc(&stack, &ref) == false)\n\t\t\tck_pr_stall();\n\t\tassert(ref);\n\t\tentry = getvalue(ref);\n#endif /* CK_F_STACK_TRYPOP_MPMC */\n#elif defined(UPMC)\n\t\tref = ck_stack_pop_upmc(&stack);\n\t\tassert(ref);\n\t\tentry = getvalue(ref);\n#elif defined(TRYUPMC)\n\t\twhile (ck_stack_trypop_upmc(&stack, &ref) == false)\n\t\t\tck_pr_stall();\n\t\tassert(ref);\n\t\tentry = getvalue(ref);\n#elif defined(SPINLOCK)\n\t\tLOCK(&stack_spinlock);\n\t\tentry = stack;\n\t\tstack = stack->next;\n\t\tUNLOCK(&stack_spinlock);\n#else\n#\t\terror Undefined operation.\n#endif\n\n\t\tif (critical) {\n\t\t\tj = common_rand_r(&seed) % critical;\n\t\t\twhile (j--)\n\t\t\t\t__asm__ __volatile__(\"\" ::: \"memory\");\n\t\t}\n\n\t\tassert (previous >= entry->value);\n\t\tprevious = entry->value;\n\t}\n\n\treturn (NULL);\n}\n\nstatic void\nstack_assert(void)\n{\n\n#ifdef SPINLOCK\n\tassert(stack == NULL);\n#else\n\tassert(CK_STACK_ISEMPTY(&stack));\n#endif\n\treturn;\n}\n\nstatic void\npush_stack(struct entry *bucket)\n{\n\tunsigned long long i;\n\n#ifdef SPINLOCK\n\tstack = NULL;\n#else\n\tck_stack_init(&stack);\n#endif\n\n\tfor (i = 0; i < ITEMS; i++) {\n\t\tbucket[i].value = i % INT_MAX;\n#ifdef SPINLOCK\n\t\tbucket[i].next = stack;\n\t\tstack = bucket + i;\n#else\n\t\tck_stack_push_spnc(&stack, &bucket[i].next);\n#endif\n\t}\n\n#ifndef SPINLOCK\n\tck_stack_entry_t *entry;\n\ti = 0;\n\tCK_STACK_FOREACH(&stack, entry) {\n\t\ti++;\n\t}\n\tassert(i == ITEMS);\n#endif\n\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tstruct entry *bucket;\n\tunsigned long long i, d;\n\tpthread_t *thread;\n\tstruct timeval stv, etv;\n\n#if (defined(TRYMPMC) || defined(MPMC)) && (!defined(CK_F_STACK_PUSH_MPMC) || !defined(CK_F_STACK_POP_MPMC))\n\tfprintf(stderr, \"Unsupported.\\n\");\n\treturn 0;\n#endif\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <threads> <delta> <critical>\\n\");\n\t}\n\n\t{\n\t\tchar *e;\n\n\t\tnthr = strtol(argv[1], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: too many threads\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\n\t\td = strtol(argv[2], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: delta is too large\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\n\t\tcritical = strtoul(argv[3], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: critical section is too large\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\t}\n\n\tsrand(getpid());\n\n\taffinerator.delta = d;\n\tbucket = malloc(sizeof(struct entry) * ITEMS);\n\tassert(bucket != NULL);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread != NULL);\n\n\tpush_stack(bucket);\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_create(&thread[i], NULL, stack_thread, NULL);\n\n\tbarrier = 1;\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tbarrier = 0;\n\n\tpush_stack(bucket);\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_create(&thread[i], NULL, stack_thread, NULL);\n\n\tcommon_gettimeofday(&stv, NULL);\n\tbarrier = 1;\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\tcommon_gettimeofday(&etv, NULL);\n\n\tstack_assert();\n#ifdef _WIN32\n\tprintf(\"%3llu %.6f\\n\", nthr, TVTOD(etv) - TVTOD(stv));\n#else\n\tprintf(\"%3llu %.6lf\\n\", nthr, TVTOD(etv) - TVTOD(stv));\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_stack/validate/push.c",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <ck_pr.h>\n#ifdef SPINLOCK\n#include <ck_spinlock.h>\n#endif\n#include <ck_stack.h>\n#include <errno.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <stdint.h>\n#include <pthread.h>\n#include <sys/time.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef ITEMS\n#define ITEMS (5765760 * 2)\n#endif\n\n#define TVTOD(tv) ((tv).tv_sec+((tv).tv_usec / (double)1000000))\n\nstruct entry {\n\tint value;\n#ifdef SPINLOCK\n\tstruct entry *next;\n#else\n\tck_stack_entry_t next;\n#endif\n};\n\n#ifdef SPINLOCK\nstatic struct entry *stack CK_CC_CACHELINE;\n#else\nstatic ck_stack_t stack CK_CC_CACHELINE;\n#endif\n\nCK_STACK_CONTAINER(struct entry, next, getvalue)\n\nstatic struct affinity affinerator = AFFINITY_INITIALIZER;\nstatic unsigned long long nthr;\nstatic volatile unsigned int barrier = 0;\nstatic unsigned int critical;\n\n#if defined(SPINLOCK)\nck_spinlock_fas_t stack_spinlock = CK_SPINLOCK_FAS_INITIALIZER;\n#define UNLOCK ck_spinlock_fas_unlock\n#if defined(EB)\n#define LOCK ck_spinlock_fas_lock_eb\n#else\n#define LOCK ck_spinlock_fas_lock\n#endif\n#elif defined(PTHREAD)\npthread_mutex_t stack_spinlock = PTHREAD_MUTEX_INITIALIZER;\n#define LOCK pthread_mutex_lock\n#define UNLOCK pthread_mutex_unlock\n#endif\n\nstatic void *\nstack_thread(void *buffer)\n{\n\tstruct entry *bucket = buffer;\n\tunsigned long long i, n = ITEMS / nthr;\n\tunsigned int seed;\n\tint j;\n\n\tif (aff_iterate(&affinerator)) {\n\t\tperror(\"ERROR: failed to affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\twhile (barrier == 0);\n\n\tfor (i = 0; i < n; i++) {\n\t\tbucket[i].value = (i + 1) * 2;\n\n#if   defined(MPNC)\n\t\tck_stack_push_mpnc(&stack, &bucket[i].next);\n#elif defined(MPMC)\n\t\tck_stack_push_mpmc(&stack, &bucket[i].next);\n#elif defined(TRYMPMC)\n\t\twhile (ck_stack_trypush_mpmc(&stack, &bucket[i].next) == false)\n\t\t\tck_pr_stall();\n#elif defined(TRYUPMC)\n\t\twhile (ck_stack_trypush_upmc(&stack, &bucket[i].next) == false)\n\t\t\tck_pr_stall();\n#elif defined(UPMC)\n\t\tck_stack_push_upmc(&stack, &bucket[i].next);\n#elif defined(SPINLOCK) || defined(PTHREADS)\n\t\tLOCK(&stack_spinlock);\n\t\tbucket[i].next = stack;\n\t\tstack = bucket + i;\n\t\tUNLOCK(&stack_spinlock);\n#else\n#\t\terror Undefined operation.\n#endif\n\n\t\tif (critical) {\n\t\t\tj = common_rand_r(&seed) % critical;\n\t\t\twhile (j--)\n\t\t\t\t__asm__ __volatile__(\"\" ::: \"memory\");\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nstatic void\nstack_assert(void)\n{\n#ifndef SPINLOCK\n\tck_stack_entry_t *n;\n#endif\n\tstruct entry *p;\n\tunsigned long long c = 0;\n\n#ifdef SPINLOCK\n\tfor (p = stack; p; p = p->next)\n\t\tc++;\n#else\n\tCK_STACK_FOREACH(&stack, n) {\n\t\tp = getvalue(n);\n\t\t(void)((volatile struct entry *)p)->value;\n\t\tc++;\n\t}\n#endif\n\n\tassert(c == ITEMS);\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tstruct entry *bucket;\n\tunsigned long long i, d, n;\n\tpthread_t *thread;\n\tstruct timeval stv, etv;\n\n\tif (argc != 4) {\n\t\tck_error(\"Usage: stack <threads> <delta> <critical>\\n\");\n\t}\n\n\t{\n\t\tchar *e;\n\n\t\tnthr = strtol(argv[1], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: too many threads\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\n\t\td = strtol(argv[2], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: delta is too large\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\n\t\tcritical = strtoul(argv[3], &e, 10);\n\t\tif (errno == ERANGE) {\n\t\t\tperror(\"ERROR: critical section is too large\");\n\t\t\texit(EXIT_FAILURE);\n\t\t} else if (*e != '\\0') {\n\t\t\tck_error(\"ERROR: input format is incorrect\\n\");\n\t\t}\n\t}\n\n\tsrand(getpid());\n\n\taffinerator.request = 0;\n\taffinerator.delta = d;\n\tn = ITEMS / nthr;\n\n#ifndef SPINLOCK\n\tck_stack_init(&stack);\n#else\n\tstack = NULL;\n#endif\n\n\tbucket = malloc(sizeof(struct entry) * ITEMS);\n\tassert(bucket != NULL);\n\n\tthread = malloc(sizeof(pthread_t) * nthr);\n\tassert(thread != NULL);\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_create(&thread[i], NULL, stack_thread, bucket + i * n);\n\n\tbarrier = 1;\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\n\tbarrier = 0;\n\n#ifndef SPINLOCK\n\tck_stack_init(&stack);\n#else\n\tstack = NULL;\n#endif\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_create(&thread[i], NULL, stack_thread, bucket + i * n);\n\n\tcommon_gettimeofday(&stv, NULL);\n\tbarrier = 1;\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(thread[i], NULL);\n\tcommon_gettimeofday(&etv, NULL);\n\n\tstack_assert();\n#ifdef _WIN32\n\tprintf(\"%3llu %.6f\\n\", nthr, TVTOD(etv) - TVTOD(stv));\n#else\n\tprintf(\"%3llu %.6lf\\n\", nthr, TVTOD(etv) - TVTOD(stv));\n#endif\n\treturn 0;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_stack/validate/serial.c",
    "content": "/*\n * Copyright 2009-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <assert.h>\n#include <stdlib.h>\n#include <stdio.h>\n\n#include <ck_stack.h>\n\n#ifndef SIZE\n#define SIZE 1024000\n#endif\n\nstruct entry {\n\tint value;\n\tck_stack_entry_t next;\n};\n\nCK_STACK_CONTAINER(struct entry, next, get_entry)\n\n#define LOOP(PUSH, POP)\t\t\t\t\t\t\t\t\\\n\tfor (i = 0; i < SIZE; i++) {\t\t\t\t\t\t\\\n\t\tentries[i].value = i;\t\t\t\t\t\t\\\n\t\tPUSH(stack, &entries[i].next);\t\t\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\\\n\tfor (i = SIZE - 1; i >= 0; i--) {\t\t\t\t\t\\\n\t\tentry = POP(stack);\t\t\t\t\t\t\\\n\t\tassert(entry);\t\t\t\t\t\t\t\\\n\t\tassert(get_entry(entry)->value == i);\t\t\t\t\\\n\t}\n\nstatic void\nserial(ck_stack_t *stack)\n{\n\tstruct entry *entries;\n\tck_stack_entry_t *entry;\n\tint i;\n\n\tck_stack_init(stack);\n\n\tentries = malloc(sizeof(struct entry) * SIZE);\n\tassert(entries != NULL);\n\n\tLOOP(ck_stack_push_upmc, ck_stack_pop_upmc);\n#ifdef CK_F_STACK_POP_MPMC\n\tLOOP(ck_stack_push_mpmc, ck_stack_pop_mpmc);\n#endif\n\tLOOP(ck_stack_push_mpnc, ck_stack_pop_upmc);\n\tLOOP(ck_stack_push_spnc, ck_stack_pop_npsc);\n\n\treturn;\n}\n\nint\nmain(void)\n{\n\tck_stack_t stack CK_CC_CACHELINE;\n\n\tserial(&stack);\n\treturn (0);\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_swlock/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_swlock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#define CK_F_PR_RTM\n\n#ifndef STEPS\n#define STEPS 2000000\n#endif\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_swlock_t swlock = CK_SWLOCK_INITIALIZER;\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_swlock_write_lock(&swlock);\n\t\tck_swlock_write_unlock(&swlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_swlock_write_lock(&swlock);\n\t\tck_swlock_write_unlock(&swlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                WRITE: swlock            %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_swlock_read_lock(&swlock);\n\t\tck_swlock_read_unlock(&swlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_swlock_read_lock(&swlock);\n\t\tck_swlock_read_unlock(&swlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                READ:  swlock             %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_swlock_write_latch(&swlock);\n\t\tck_swlock_write_unlatch(&swlock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_swlock_write_latch(&swlock);\n\t\tck_swlock_write_unlatch(&swlock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                LATCH: swlock             %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_swlock/benchmark/throughput.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_swlock.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic int barrier;\nstatic int threads;\nstatic unsigned int flag CK_CC_CACHELINE;\nstatic struct {\n\tck_swlock_t lock;\n} rw CK_CC_CACHELINE = {\n\t.lock = CK_SWLOCK_INITIALIZER\n};\n\nstatic struct affinity affinity;\n\nstatic void *\nthread_lock(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tuint64_t *value = pun;\n\n\tif (aff_iterate(&affinity) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\tck_swlock_read_lock(&rw.lock);\n\t\tck_swlock_read_unlock(&rw.lock);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n\nstatic void\nswlock_test(pthread_t *p, int d, uint64_t *latency, void *(*f)(void *), const char *label)\n{\n\tint t;\n\n\tck_pr_store_int(&barrier, 0);\n\tck_pr_store_uint(&flag, 0);\n\n\taffinity.delta = d;\n\taffinity.request = 0;\n\n\tfprintf(stderr, \"Creating threads (%s)...\", label);\n\tfor (t = 0; t < threads; t++) {\n\t\tif (pthread_create(&p[t], NULL, f, latency + t) != 0) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", t);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&flag, 1);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (t = 0; t < threads; t++)\n\t\tpthread_join(p[t], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (t = 1; t <= threads; t++)\n\t\tprintf(\"%10u %20\" PRIu64 \"\\n\", t, latency[t - 1]);\n\n\tfprintf(stderr, \"\\n\");\n\treturn;\n}\n\n\nint\nmain(int argc, char *argv[])\n{\n\tint d;\n\tpthread_t *p;\n\tuint64_t *latency;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: throughput <delta> <threads>\\n\");\n\t}\n\n\tthreads = atoi(argv[2]);\n\tif (threads <= 0) {\n\t\tck_error(\"ERROR: Threads must be a value > 0.\\n\");\n\t}\n\n\tp = malloc(sizeof(pthread_t) * threads);\n\tif (p == NULL) {\n\t\tck_error(\"ERROR: Failed to initialize thread.\\n\");\n\t}\n\n\tlatency = malloc(sizeof(uint64_t) * threads);\n\tif (latency == NULL) {\n\t\tck_error(\"ERROR: Failed to create latency buffer.\\n\");\n\t}\n\n\td = atoi(argv[1]);\n\tswlock_test(p, d, latency, thread_lock, \"swlock\");\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_swlock/validate/validate.c",
    "content": "/*\n * Copyright 2014 Jaidev Sridhar.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_swlock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstatic struct affinity a;\nstatic unsigned int locked;\nstatic int nthr;\nstatic ck_swlock_t lock = CK_SWLOCK_INITIALIZER;\nstatic ck_swlock_t copy;\n#ifdef CK_F_PR_RTM\nstatic void *\nthread_rtm_adaptive(void *arg)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\tint tid = ck_pr_load_int(arg);\n\n\tstruct ck_elide_config config = CK_ELIDE_CONFIG_DEFAULT_INITIALIZER;\n\tstruct ck_elide_stat st = CK_ELIDE_STAT_INITIALIZER;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tif (tid == 0) {\n\t\t\tCK_ELIDE_LOCK_ADAPTIVE(ck_swlock_write, &st, &config, &lock);\n\t\t\t{\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 8) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCK_ELIDE_UNLOCK_ADAPTIVE(ck_swlock_write, &st, &lock);\n\t\t}\n\n\t\tCK_ELIDE_LOCK(ck_swlock_read, &lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_ELIDE_UNLOCK(ck_swlock_read, &lock);\n\t}\n\n\treturn NULL;\n}\n\nstatic void *\nthread_rtm_mix(void *arg)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\tint tid = ck_pr_load_int(arg);\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tif (tid == 0) {\n\t\t\tif (i & 1) {\n\t\t\t\tCK_ELIDE_LOCK(ck_swlock_write, &lock);\n\t\t\t} else {\n\t\t\t\tck_swlock_write_lock(&lock);\n\t\t\t}\n\n\t\t\t{\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 8) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (i & 1) {\n\t\t\t\tCK_ELIDE_UNLOCK(ck_swlock_write, &lock);\n\t\t\t} else {\n\t\t\t\tck_swlock_write_unlock(&lock);\n\t\t\t}\n\t\t}\n\t\tif (i & 1) {\n\t\t\tCK_ELIDE_LOCK(ck_swlock_read, &lock);\n\t\t} else {\n\t\t\tck_swlock_read_lock(&lock);\n\t\t}\n\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\n\t\tif (i & 1) {\n\t\t\tCK_ELIDE_UNLOCK(ck_swlock_read, &lock);\n\t\t} else {\n\t\t\tck_swlock_read_unlock(&lock);\n\t\t}\n\t}\n\n\treturn (NULL);\n}\n\nstatic void *\nthread_rtm(void *arg)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\tint tid = ck_pr_load_int(arg);\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tif (tid == 0) {\n\t\t\tCK_ELIDE_LOCK(ck_swlock_write, &lock);\n\t\t\t{\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 8) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\t\t\t}\n\t\t\tCK_ELIDE_UNLOCK(ck_swlock_write, &lock);\n\t\t}\n\n\t\tCK_ELIDE_LOCK(ck_swlock_read, &lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tCK_ELIDE_UNLOCK(ck_swlock_read, &lock);\n\t}\n\n\treturn (NULL);\n}\n#endif /* CK_F_PR_RTM */\n\nstatic void *\nthread_latch(void *arg)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\tint tid = ck_pr_load_int(arg);\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tif (tid == 0) {\n\t\t\t/* Writer */\n\t\t\tck_swlock_write_latch(&lock);\n\t\t\t{\n\t\t\t\tmemcpy(&copy, &lock, sizeof(ck_swlock_t));\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 8) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\t\t\t\tmemcpy(&lock, &copy, sizeof(ck_swlock_t));\n\t\t\t}\n\t\t\tck_swlock_write_unlatch(&lock);\n\t\t}\n\n\t\tck_swlock_read_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_swlock_read_unlock(&lock);\n\t}\n\n\treturn (NULL);\n}\n\nstatic void *\nthread(void *arg)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\tint tid = ck_pr_load_int(arg);\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tif (tid == 0) {\n\t\t\t/* Writer */\n\t\t\tck_swlock_write_lock(&lock);\n\t\t\t{\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\t\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 8) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t\t}\n\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\t\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\t\tif (l != 0) {\n\t\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t\t}\n\t\t\t}\n\t\t\tck_swlock_write_unlock(&lock);\n\t\t}\n\n\t\tck_swlock_read_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_swlock_read_unlock(&lock);\n\t}\n\n\treturn (NULL);\n}\n\nstatic void\nswlock_test(pthread_t *threads, void *(*f)(void *), const char *test)\n{\n\tint i, tid[nthr];\n\n\tfprintf(stderr, \"Creating threads (%s)...\", test);\n\tfor (i = 0; i < nthr; i++) {\n\t\tck_pr_store_int(&tid[i], i);\n\t\tif (pthread_create(&threads[i], NULL, f, &tid[i])) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \".\");\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: validate <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\tswlock_test(threads, thread, \"regular\");\n\tswlock_test(threads, thread_latch, \"latch\");\n#ifdef CK_F_PR_RTM\n\tswlock_test(threads, thread_rtm, \"rtm\");\n\tswlock_test(threads, thread_rtm_mix, \"rtm-mix\");\n\tswlock_test(threads, thread_rtm_adaptive, \"rtm-adaptive\");\n#endif\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_tflock/benchmark/latency.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_tflock.h>\n#include <inttypes.h>\n#include <stdio.h>\n\n#include \"../../common.h\"\n\n#define CK_F_PR_RTM\n\n#ifndef STEPS\n#define STEPS 2000000\n#endif\n\nint\nmain(void)\n{\n\tuint64_t s_b, e_b, i;\n\tck_tflock_ticket_t tflock = CK_TFLOCK_TICKET_INITIALIZER;\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_tflock_ticket_write_lock(&tflock);\n\t\tck_tflock_ticket_write_unlock(&tflock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_tflock_ticket_write_lock(&tflock);\n\t\tck_tflock_ticket_write_unlock(&tflock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                WRITE: tflock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_tflock_ticket_read_lock(&tflock);\n\t\tck_tflock_ticket_read_unlock(&tflock);\n\t}\n\n\ts_b = rdtsc();\n\tfor (i = 0; i < STEPS; i++) {\n\t\tck_tflock_ticket_read_lock(&tflock);\n\t\tck_tflock_ticket_read_unlock(&tflock);\n\t}\n\te_b = rdtsc();\n\tprintf(\"                READ:  tflock   %15\" PRIu64 \"\\n\", (e_b - s_b) / STEPS);\n\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_tflock/benchmark/throughput.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_tflock.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <stdio.h>\n#include <stdint.h>\n#include <stdlib.h>\n#include <unistd.h>\n\n#include \"../../common.h\"\n\n#ifndef STEPS\n#define STEPS 1000000\n#endif\n\nstatic int barrier;\nstatic int threads;\nstatic unsigned int flag CK_CC_CACHELINE;\nstatic struct {\n\tck_tflock_ticket_t lock;\n} rw CK_CC_CACHELINE = {\n\t.lock = CK_TFLOCK_TICKET_INITIALIZER\n};\n\nstatic struct affinity affinity;\n\nstatic void *\nthread_lock(void *pun)\n{\n\tuint64_t s_b, e_b, a, i;\n\tuint64_t *value = pun;\n\n\tif (aff_iterate(&affinity) != 0) {\n\t\tperror(\"ERROR: Could not affine thread\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads)\n\t\tck_pr_stall();\n\n\tfor (i = 1, a = 0;; i++) {\n\t\ts_b = rdtsc();\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\tck_tflock_ticket_read_lock(&rw.lock);\n\t\tck_tflock_ticket_read_unlock(&rw.lock);\n\t\te_b = rdtsc();\n\n\t\ta += (e_b - s_b) >> 4;\n\n\t\tif (ck_pr_load_uint(&flag) == 1)\n\t\t\tbreak;\n\t}\n\n\tck_pr_inc_int(&barrier);\n\twhile (ck_pr_load_int(&barrier) != threads * 2)\n\t\tck_pr_stall();\n\n\t*value = (a / i);\n\treturn NULL;\n}\n\nstatic void\ntflock_test(pthread_t *p, int d, uint64_t *latency, void *(*f)(void *), const char *label)\n{\n\tint t;\n\n\tck_pr_store_int(&barrier, 0);\n\tck_pr_store_uint(&flag, 0);\n\n\taffinity.delta = d;\n\taffinity.request = 0;\n\n\tfprintf(stderr, \"Creating threads (%s)...\", label);\n\tfor (t = 0; t < threads; t++) {\n\t\tif (pthread_create(&p[t], NULL, f, latency + t) != 0) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", t);\n\t\t}\n\t}\n\tfprintf(stderr, \"done\\n\");\n\n\tcommon_sleep(10);\n\tck_pr_store_uint(&flag, 1);\n\n\tfprintf(stderr, \"Waiting for threads to finish acquisition regression...\");\n\tfor (t = 0; t < threads; t++)\n\t\tpthread_join(p[t], NULL);\n\tfprintf(stderr, \"done\\n\\n\");\n\n\tfor (t = 1; t <= threads; t++)\n\t\tprintf(\"%10u %20\" PRIu64 \"\\n\", t, latency[t - 1]);\n\n\tfprintf(stderr, \"\\n\");\n\treturn;\n}\n\n\nint\nmain(int argc, char *argv[])\n{\n\tint d;\n\tpthread_t *p;\n\tuint64_t *latency;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: throughput <delta> <threads>\\n\");\n\t}\n\n\tthreads = atoi(argv[2]);\n\tif (threads <= 0) {\n\t\tck_error(\"ERROR: Threads must be a value > 0.\\n\");\n\t}\n\n\tp = malloc(sizeof(pthread_t) * threads);\n\tif (p == NULL) {\n\t\tck_error(\"ERROR: Failed to initialize thread.\\n\");\n\t}\n\n\tlatency = malloc(sizeof(uint64_t) * threads);\n\tif (latency == NULL) {\n\t\tck_error(\"ERROR: Failed to create latency buffer.\\n\");\n\t}\n\n\td = atoi(argv[1]);\n\ttflock_test(p, d, latency, thread_lock, \"tflock\");\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/ck_tflock/validate/validate.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <errno.h>\n#include <inttypes.h>\n#include <pthread.h>\n#include <math.h>\n#include <stdint.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <strings.h>\n#include <unistd.h>\n#include <sys/time.h>\n\n#include <ck_pr.h>\n#include <ck_tflock.h>\n\n#include \"../../common.h\"\n\n#ifndef ITERATE\n#define ITERATE 1000000\n#endif\n\nstatic struct affinity a;\nstatic unsigned int locked;\nstatic int nthr;\nstatic ck_tflock_ticket_t lock = CK_TFLOCK_TICKET_INITIALIZER;\n\nstatic void *\nthread(void *null CK_CC_UNUSED)\n{\n\tunsigned int i = ITERATE;\n\tunsigned int l;\n\n        if (aff_iterate(&a)) {\n                perror(\"ERROR: Could not affine thread\");\n                exit(EXIT_FAILURE);\n        }\n\n\twhile (i--) {\n\t\tck_tflock_ticket_write_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\t\t\tck_pr_inc_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 8) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 2\\n\", __LINE__, l);\n\t\t\t}\n\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\t\t\tck_pr_dec_uint(&locked);\n\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [WR:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_tflock_ticket_write_unlock(&lock);\n\n\t\tck_tflock_ticket_read_lock(&lock);\n\t\t{\n\t\t\tl = ck_pr_load_uint(&locked);\n\t\t\tif (l != 0) {\n\t\t\t\tck_error(\"ERROR [RD:%d]: %u != 0\\n\", __LINE__, l);\n\t\t\t}\n\t\t}\n\t\tck_tflock_ticket_read_unlock(&lock);\n\t}\n\n\treturn (NULL);\n}\n\nstatic void\ntflock_ticket_test(pthread_t *threads, void *(*f)(void *), const char *test)\n{\n\tint i;\n\n\tfprintf(stderr, \"Creating threads (%s)...\", test);\n\tfor (i = 0; i < nthr; i++) {\n\t\tif (pthread_create(&threads[i], NULL, f, NULL)) {\n\t\t\tck_error(\"ERROR: Could not create thread %d\\n\", i);\n\t\t}\n\t}\n\tfprintf(stderr, \".\");\n\n\tfor (i = 0; i < nthr; i++)\n\t\tpthread_join(threads[i], NULL);\n\tfprintf(stderr, \"done (passed)\\n\");\n\treturn;\n}\n\nint\nmain(int argc, char *argv[])\n{\n\tpthread_t *threads;\n\n\tif (argc != 3) {\n\t\tck_error(\"Usage: validate <number of threads> <affinity delta>\\n\");\n\t}\n\n\tnthr = atoi(argv[1]);\n\tif (nthr <= 0) {\n\t\tck_error(\"ERROR: Number of threads must be greater than 0\\n\");\n\t}\n\n\tthreads = malloc(sizeof(pthread_t) * nthr);\n\tif (threads == NULL) {\n\t\tck_error(\"ERROR: Could not allocate thread structures\\n\");\n\t}\n\n\ta.delta = atoi(argv[2]);\n\n\ttflock_ticket_test(threads, thread, \"regular\");\n\tck_tflock_ticket_init(&lock);\n\treturn 0;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/regressions/common.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_COMMON_H\n#define CK_COMMON_H\n\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <stdarg.h>\n#include <stdio.h>\n#include <stdlib.h>\n#include <sys/time.h>\n\n#ifdef __linux__\n#include <sched.h>\n#include <sys/types.h>\n#include <sys/syscall.h>\n#elif defined(__MACH__)\n#include <mach/mach.h>\n#include <mach/thread_policy.h>\n#elif defined(__FreeBSD__)\n#include <sys/param.h>\n#include <sys/cpuset.h>\n#endif\n\n#if defined(_WIN32)\n#include <assert.h>\n#define NOMINMAX\n#include <windows.h>\n#define DELTA_EPOCH  11644473600000000ULL\n#else\n#include <signal.h>\n#include <unistd.h>\n#endif\n\n#ifndef CORES\n#define CORES 8\n#endif\n\nCK_CC_INLINE static void\ncommon_srand(unsigned int i)\n{\n#ifdef _WIN32\n\tsrand(i);\n#else\n\tsrandom(i);\n#endif\n}\n\nCK_CC_INLINE static int\ncommon_rand(void)\n{\n#ifdef _WIN32\n\treturn rand();\n#else\n\treturn random();\n#endif\n}\n\nCK_CC_INLINE static int\ncommon_rand_r(unsigned int *i)\n{\n#ifdef _WIN32\n\t(void)i;\n\n\t/*\n\t * When linked with -mthreads, rand() is thread-safe.\n\t * rand_s is also an option.\n\t */\n\treturn rand();\n#else\n\treturn rand_r(i);\n#endif\n}\n\nCK_CC_INLINE static void\ncommon_srand48(long int i)\n{\n#ifdef _WIN32\n\tsrand(i);\n#else\n\tsrand48(i);\n#endif\n}\n\nCK_CC_INLINE static long int\ncommon_lrand48(void)\n{\n#ifdef _WIN32\n\treturn rand();\n#else\n\treturn lrand48();\n#endif\n}\n\nCK_CC_INLINE static double\ncommon_drand48(void)\n{\n#ifdef _WIN32\n\treturn (double)rand()/RAND_MAX;\n#else\n\treturn drand48();\n#endif\n}\n\nCK_CC_INLINE static void\ncommon_sleep(unsigned int n)\n{\n#ifdef _WIN32\n\tSleep(n * 1000);\n#else\n\tsleep(n);\n#endif\n}\n\nCK_CC_INLINE static int\ncommon_gettimeofday(struct timeval *tv, void *tz)\n{\n#ifdef _WIN32\n\tFILETIME ft;\n\tuint64_t tmp_time = 0;\n\tstatic bool tzflag = false;\n\tstruct timezone *tzp = tz;\n\n\tif (tv != NULL) {\n\t\tGetSystemTimeAsFileTime(&ft);\n\t\ttmp_time |= ft.dwHighDateTime;\n\t\ttmp_time <<= 32;\n\t\ttmp_time |= ft.dwLowDateTime;\n\n\t\t/* GetSystemTimeAsFileTime returns 100 nanosecond intervals. */\n\t\ttmp_time /= 10;\n\n\t\t/* Windows' epoch starts on 01/01/1601, while Unix' starts on 01/01/1970. */\n\t\ttmp_time -= DELTA_EPOCH;\n\n\t\ttv->tv_sec = (long)(tmp_time / 1000000UL);\n\t\ttv->tv_usec = (long)(tmp_time % 1000000UL);\n\t}\n\n\n\tif (tz != NULL) {\n\t\tif (tzflag == false) {\n\t\t\t_tzset();\n\t\t\ttzflag = true;\n\t\t}\n\n\t\ttzp->tz_minuteswest = _timezone / 60;\n\t\ttzp->tz_dsttime = _daylight;\n\t}\n\n\treturn 0;\n#else\n\treturn gettimeofday(tv, tz);\n#endif\n}\n\nCK_CC_UNUSED static unsigned int\ncommon_alarm(void (*sig_handler)(int), void *alarm_event, unsigned int duration)\n{\n#ifdef _WIN32\n\t(void)sig_handler;\n\t(void)duration;\n\tbool success;\n\tHANDLE *alarm_handle = alarm_event;\n\tsuccess = SetEvent(*alarm_handle);\n\tassert(success != false);\n\treturn 0;\n#else\n\t(void)alarm_event;\n\tsignal(SIGALRM, sig_handler);\n\treturn alarm(duration);\n#endif\n}\n\n#ifdef _WIN32\n#ifndef SECOND_TIMER\n#define\tSECOND_TIMER 10000000\n#endif\n#define\tCOMMON_ALARM_DECLARE_GLOBAL(prefix, alarm_event_name, flag_name)\t\t\t\t\\\nstatic HANDLE prefix##_common_win_alarm_timer;\t\t\t\t\t\t\t\t\\\nstatic HANDLE alarm_event_name;\t\t\t\t\t\t\t\t\t\t\\\nstatic LARGE_INTEGER prefix##_common_alarm_timer_length;\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void CALLBACK\t\t\t\t\t\t\t\t\t\t\t\\\nprefix##_common_win_alarm_handler(LPVOID arg, DWORD timer_low_value, DWORD timer_high_value)\t\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t(void)arg;\t\t\t\t\t\t\t\t\t\t\t\\\n\t(void)timer_low_value;\t\t\t\t\t\t\t\t\t\t\\\n\t(void)timer_high_value;\t\t\t\t\t\t\t\t\t\t\\\n\tflag_name = true;\t\t\t\t\t\t\t\t\t\t\\\n\treturn;\t\t\t\t\t\t\t\t\t\t\t\t\\\n}\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\nstatic void *\t\t\t\t\t\t\t\t\t\t\t\t\\\nprefix##_common_win_alarm(void *unused)\t\t\t\t\t\t\t\t\t\\\n{\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t(void)unused;\t\t\t\t\t\t\t\t\t\t\t\\\n\tbool timer_success = false;\t\t\t\t\t\t\t\t\t\\\n\tfor (;;) {\t\t\t\t\t\t\t\t\t\t\t\\\n\t\tWaitForSingleObjectEx(alarm_event_name, INFINITE, true);\t\t\t\t\\\n\t\ttimer_success = SetWaitableTimer(prefix##_common_win_alarm_timer,\t\t\t\\\n\t\t\t\t\t\t &prefix##_common_alarm_timer_length,\t\t\t\\\n\t\t\t\t\t\t 0,\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t prefix##_common_win_alarm_handler, NULL, false);\t\\\n\t\tassert(timer_success != false);\t\t\t\t\t\t\t\t\\\n\t\tWaitForSingleObjectEx(prefix##_common_win_alarm_timer, INFINITE, true);\t\t\t\\\n\t}\t\t\t\t\t\t\t\t\t\t\t\t\\\n\t\t\t\t\t\t\t\t\t\t\t\t\t\\\n\treturn NULL;\t\t\t\t\t\t\t\t\t\t\t\\\n}\n\n#define\tCOMMON_ALARM_DECLARE_LOCAL(prefix, alarm_event_name)\t\\\n\tint64_t prefix##_common_alarm_tl;\t\t\t\\\n\tpthread_t prefix##_common_win_alarm_thread;\n\n#define\tCOMMON_ALARM_INIT(prefix, alarm_event_name, duration) \t\t\t\t\\\n\tprefix##_common_alarm_tl = -1 * (duration) * SECOND_TIMER;\t\t\t\\\n\tprefix##_common_alarm_timer_length.LowPart =\t\t\t\t\t\\\n\t\t(DWORD) (prefix##_common_alarm_tl & 0xFFFFFFFF);\t\t\t\\\n\tprefix##_common_alarm_timer_length.HighPart = \t\t\t\t\t\\\n\t\t(LONG) (prefix##_common_alarm_tl >> 32);\t\t\t\t\\\n\talarm_event_name = CreateEvent(NULL, false, false, NULL);\t\t\t\\\n\tassert(alarm_event_name != NULL);\t\t\t\t\t\t\\\n\tprefix##_common_win_alarm_timer = CreateWaitableTimer(NULL, true, NULL);\t\\\n\tassert(prefix##_common_win_alarm_timer != NULL);\t\t\t\t\\\n\tif (pthread_create(&prefix##_common_win_alarm_thread,\t\t\t\t\\\n\t\t\t   NULL,\t\t\t\t\t\t\t\\\n\t\t\t   prefix##_common_win_alarm,\t\t\t\t\t\\\n\t\t\t   NULL) != 0)\t\t\t\t\t\t\t\\\n\t\tck_error(\"ERROR: Failed to create common_win_alarm thread.\\n\");\n#else\n#define\tCOMMON_ALARM_DECLARE_GLOBAL(prefix, alarm_event_name, flag_name)\n#define\tCOMMON_ALARM_DECLARE_LOCAL(prefix, alarm_event_name)\t\\\n\tint alarm_event_name = 0;\n#define\tCOMMON_ALARM_INIT(prefix, alarm_event_name, duration)\n#endif\n\nstruct affinity {\n\tunsigned int delta;\n\tunsigned int request;\n};\n\n#define AFFINITY_INITIALIZER {0, 0}\n\n#ifdef __linux__\n#ifndef gettid\nstatic pid_t\ngettid(void)\n{\n\treturn syscall(__NR_gettid);\n}\n#endif /* gettid */\n\nCK_CC_UNUSED static int\naff_iterate(struct affinity *acb)\n{\n\tcpu_set_t s;\n\tunsigned int c;\n\n\tc = ck_pr_faa_uint(&acb->request, acb->delta);\n\tCPU_ZERO(&s);\n\tCPU_SET(c % CORES, &s);\n\n\treturn sched_setaffinity(gettid(), sizeof(s), &s);\n}\n\nCK_CC_UNUSED static int\naff_iterate_core(struct affinity *acb, unsigned int *core)\n{\n\tcpu_set_t s;\n\n\t*core = ck_pr_faa_uint(&acb->request, acb->delta);\n\tCPU_ZERO(&s);\n\tCPU_SET((*core) % CORES, &s);\n\n\treturn sched_setaffinity(gettid(), sizeof(s), &s);\n}\n#elif defined(__MACH__)\nCK_CC_UNUSED static int\naff_iterate(struct affinity *acb)\n{\n\tthread_affinity_policy_data_t policy;\n\tunsigned int c;\n\n\tc = ck_pr_faa_uint(&acb->request, acb->delta) % CORES;\n\tpolicy.affinity_tag = c;\n\treturn thread_policy_set(mach_thread_self(),\n\t\t\t\t THREAD_AFFINITY_POLICY,\n\t\t\t\t (thread_policy_t)&policy,\n\t\t\t\t THREAD_AFFINITY_POLICY_COUNT);\n}\n\nCK_CC_UNUSED static int\naff_iterate_core(struct affinity *acb, unsigned int *core)\n{\n\tthread_affinity_policy_data_t policy;\n\n\t*core = ck_pr_faa_uint(&acb->request, acb->delta) % CORES;\n\tpolicy.affinity_tag = *core;\n\treturn thread_policy_set(mach_thread_self(),\n\t\t\t\t THREAD_AFFINITY_POLICY,\n\t\t\t\t (thread_policy_t)&policy,\n\t\t\t\t THREAD_AFFINITY_POLICY_COUNT);\n}\n#elif defined(__FreeBSD__)\nCK_CC_UNUSED static int\naff_iterate(struct affinity *acb CK_CC_UNUSED)\n{\n\tunsigned int c;\n\tcpuset_t mask;\n\n\tc = ck_pr_faa_uint(&acb->request, acb->delta) % CORES;\n\tCPU_ZERO(&mask);\n\tCPU_SET(c, &mask);\n\treturn (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,\n\t    sizeof(mask), &mask));\n}\n\nCK_CC_UNUSED static int\naff_iterate_core(struct affinity *acb CK_CC_UNUSED, unsigned int *core)\n{\n\tcpuset_t mask;\n\n\t*core = ck_pr_faa_uint(&acb->request, acb->delta) % CORES;\n\tCPU_ZERO(&mask);\n\tCPU_SET(*core, &mask);\n\treturn (cpuset_setaffinity(CPU_LEVEL_WHICH, CPU_WHICH_TID, -1,\n\t    sizeof(mask), &mask));\n}\n#else\nCK_CC_UNUSED static int\naff_iterate(struct affinity *acb CK_CC_UNUSED)\n{\n\n\treturn (0);\n}\n\nCK_CC_UNUSED static int\naff_iterate_core(struct affinity *acb CK_CC_UNUSED, unsigned int *core)\n{\n\t*core = 0;\n\treturn (0);\n}\n#endif\n\nCK_CC_INLINE static uint64_t\nrdtsc(void)\n{\n#if defined(__x86_64__)\n\tuint32_t eax = 0, edx;\n#if defined(CK_MD_RDTSCP)\n\t__asm__ __volatile__(\"rdtscp\"\n\t\t\t\t: \"+a\" (eax), \"=d\" (edx)\n\t\t\t\t:\n\t\t\t\t: \"%ecx\", \"memory\");\n\n\treturn (((uint64_t)edx << 32) | eax);\n#else\n        __asm__ __volatile__(\"cpuid;\"\n                             \"rdtsc;\"\n                                : \"+a\" (eax), \"=d\" (edx)\n                                :\n                                : \"%ebx\", \"%ecx\", \"memory\");\n\n        __asm__ __volatile__(\"xorl %%eax, %%eax;\"\n                             \"cpuid;\"\n                                :\n                                :\n                                : \"%eax\", \"%ebx\", \"%ecx\", \"%edx\", \"memory\");\n\n        return (((uint64_t)edx << 32) | eax);\n#endif /* !CK_MD_RDTSCP */\n#elif defined(__x86__)\n\tuint32_t eax = 0, edx;\n#if defined(CK_MD_RDTSCP)\n\t__asm__ __volatile__(\"rdtscp\"\n\t\t\t\t: \"+a\" (eax), \"=d\" (edx)\n\t\t\t\t:\n\t\t\t\t: \"%ecx\", \"memory\");\n\n\treturn (((uint64_t)edx << 32) | eax);\n#else\n        __asm__ __volatile__(\"pushl %%ebx;\"\n\t\t\t     \"cpuid;\"\n                             \"rdtsc;\"\n                                : \"+a\" (eax), \"=d\" (edx)\n                                :\n                                : \"%ecx\", \"memory\");\n\n        __asm__ __volatile__(\"xorl %%eax, %%eax;\"\n                             \"cpuid;\"\n\t\t\t     \"popl %%ebx;\"\n                                :\n                                :\n                                : \"%eax\", \"%ecx\", \"%edx\", \"memory\");\n\n        return (((uint64_t)edx << 32) | eax);\n#endif /* !CK_MD_RDTSCP */\n#elif defined(__sparcv9__)\n\tuint64_t r;\n\n        __asm__ __volatile__(\"rd %%tick, %0\"\n\t\t\t\t: \"=r\" (r)\n\t\t\t\t:\n\t\t\t\t: \"memory\");\n        return r;\n#elif defined(__ppc64__)\n\tuint32_t high, low, snapshot;\n\n\tdo {\n\t  __asm__ __volatile__(\"isync;\"\n\t\t\t       \"mftbu %0;\"\n\t\t\t       \"mftb  %1;\"\n\t\t\t       \"mftbu %2;\"\n\t\t\t\t: \"=r\" (high), \"=r\" (low), \"=r\" (snapshot)\n\t\t\t\t:\n\t\t\t\t: \"memory\");\n\t} while (snapshot != high);\n\n\treturn (((uint64_t)high << 32) | low);\n#elif defined(__aarch64__)\n\tuint64_t r;\n\n\t__asm __volatile__ (\"mrs %0, cntvct_el0\" : \"=r\" (r) : : \"memory\");\n\treturn r;\n#else\n\treturn 0;\n#endif\n}\n\nCK_CC_USED static void\nck_error(const char *message, ...)\n{\n\tva_list ap;\n\n\tva_start(ap, message);\n\tvfprintf(stderr, message, ap);\n\tva_end(ap);\n\texit(EXIT_FAILURE);\n}\n\n#define ck_test(A, B, ...) do {\t\t\t\\\n\tif (A)\t\t\t\t\t\\\n\t\tck_error(B, ##__VA_ARGS__);\t\\\n} while (0)\n\n#endif /* CK_COMMON_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_array.c",
    "content": "/*\n * Copyright 2013-2015 Samy Al Bahra\n * Copyright 2013-2014 AppNexus, Inc.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_array.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n#include <ck_string.h>\n\nstatic struct _ck_array *\nck_array_create(struct ck_malloc *allocator, unsigned int length)\n{\n\tstruct _ck_array *active;\n\n\tactive = allocator->malloc(sizeof(struct _ck_array) + sizeof(void *) * length);\n\tif (active == NULL)\n\t\treturn NULL;\n\n\tactive->n_committed = 0;\n\tactive->length = length;\n\n\treturn active;\n}\n\nbool\nck_array_init(struct ck_array *array, unsigned int mode, struct ck_malloc *allocator, unsigned int length)\n{\n\tstruct _ck_array *active;\n\n\t(void)mode;\n\n\tif (allocator->realloc == NULL ||\n\t    allocator->malloc == NULL ||\n\t    allocator->free == NULL ||\n\t    length == 0)\n\t\treturn false;\n\n\tactive = ck_array_create(allocator, length);\n\tif (active == NULL)\n\t\treturn false;\n\n\tarray->n_entries = 0;\n\tarray->allocator = allocator;\n\tarray->active = active;\n\tarray->transaction = NULL;\n\treturn true;\n}\n\nbool\nck_array_put(struct ck_array *array, void *value)\n{\n\tstruct _ck_array *target;\n\tunsigned int size;\n\n\t/*\n\t * If no transaction copy has been necessary, attempt to do in-place\n\t * modification of the array.\n\t */\n\tif (array->transaction == NULL) {\n\t\ttarget = array->active;\n\n\t\tif (array->n_entries == target->length) {\n\t\t\tsize = target->length << 1;\n\n\t\t\ttarget = array->allocator->realloc(target,\n\t\t\t    sizeof(struct _ck_array) + sizeof(void *) * array->n_entries,\n\t\t\t    sizeof(struct _ck_array) + sizeof(void *) * size,\n\t\t\t    true);\n\n\t\t\tif (target == NULL)\n\t\t\t\treturn false;\n\n\t\t\tck_pr_store_uint(&target->length, size);\n\n\t\t\t/* Serialize with respect to contents. */\n\t\t\tck_pr_fence_store();\n\t\t\tck_pr_store_ptr(&array->active, target);\n\t\t}\n\n\t\ttarget->values[array->n_entries++] = value;\n\t\treturn true;\n\t}\n\n\ttarget = array->transaction;\n\tif (array->n_entries == target->length) {\n\t\tsize = target->length << 1;\n\n\t\ttarget = array->allocator->realloc(target,\n\t\t    sizeof(struct _ck_array) + sizeof(void *) * array->n_entries,\n\t\t    sizeof(struct _ck_array) + sizeof(void *) * size,\n\t\t    true);\n\n\t\tif (target == NULL)\n\t\t\treturn false;\n\n\t\ttarget->length = size;\n\t\tarray->transaction = target;\n\t}\n\n\ttarget->values[array->n_entries++] = value;\n\treturn false;\n}\n\nint\nck_array_put_unique(struct ck_array *array, void *value)\n{\n\tunsigned int i, limit;\n\tvoid **v;\n\n\tlimit = array->n_entries;\n\tif (array->transaction != NULL) {\n\t\tv = array->transaction->values;\n\t} else {\n\t\tv = array->active->values;\n\t}\n\n\tfor (i = 0; i < limit; i++) {\n\t\tif (v[i] == value)\n\t\t\treturn 1;\n\t}\n\n\treturn -!ck_array_put(array, value);\n}\n\nbool\nck_array_remove(struct ck_array *array, void *value)\n{\n\tstruct _ck_array *target;\n\tunsigned int i;\n\n\tif (array->transaction != NULL) {\n\t\ttarget = array->transaction;\n\n\t\tfor (i = 0; i < array->n_entries; i++) {\n\t\t\tif (target->values[i] == value) {\n\t\t\t\ttarget->values[i] = target->values[--array->n_entries];\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\ttarget = array->active;\n\n\tfor (i = 0; i < array->n_entries; i++) {\n\t\tif (target->values[i] == value)\n\t\t\tbreak;\n\t}\n\n\tif (i == array->n_entries)\n\t\treturn false;\n\n\t/* If there are pending additions, immediately eliminate the operation. */\n\tif (target->n_committed != array->n_entries) {\n\t\tck_pr_store_ptr(&target->values[i], target->values[--array->n_entries]);\n\t\treturn true;\n\t}\n\n\t/*\n\t * The assumption is that these allocations are small to begin with.\n\t * If there is no immediate opportunity for transaction, allocate a\n\t * transactional array which will be applied upon commit time.\n\t */\n\ttarget = ck_array_create(array->allocator, array->n_entries);\n\tif (target == NULL)\n\t\treturn false;\n\n\tmemcpy(target->values, array->active->values, sizeof(void *) * array->n_entries);\n\ttarget->length = array->n_entries;\n\ttarget->n_committed = array->n_entries;\n\ttarget->values[i] = target->values[--array->n_entries];\n\n\tarray->transaction = target;\n\treturn true;\n}\n\nbool\nck_array_commit(ck_array_t *array)\n{\n\tstruct _ck_array *m = array->transaction;\n\n\tif (m != NULL) {\n\t\tstruct _ck_array *p;\n\n\t\tm->n_committed = array->n_entries;\n\t\tck_pr_fence_store();\n\t\tp = array->active;\n\t\tck_pr_store_ptr(&array->active, m);\n\t\tarray->allocator->free(p, sizeof(struct _ck_array) +\n\t\t    p->length * sizeof(void *), true);\n\t\tarray->transaction = NULL;\n\n\t\treturn true;\n\t}\n\n\tck_pr_fence_store();\n\tck_pr_store_uint(&array->active->n_committed, array->n_entries);\n\treturn true;\n}\n\nvoid\nck_array_deinit(struct ck_array *array, bool defer)\n{\n\n\tarray->allocator->free(array->active,\n\t    sizeof(struct _ck_array) + sizeof(void *) * array->active->length, defer);\n\n\tif (array->transaction != NULL) {\n\t\tarray->allocator->free(array->transaction,\n\t\t    sizeof(struct _ck_array) + sizeof(void *) * array->transaction->length, defer);\n\t}\n\n\tarray->transaction = array->active = NULL;\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_barrier_centralized.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_barrier.h>\n#include <ck_pr.h>\n\nvoid\nck_barrier_centralized(struct ck_barrier_centralized *barrier,\n    struct ck_barrier_centralized_state *state,\n    unsigned int n_threads)\n{\n\tunsigned int sense, value;\n\n\t/*\n\t * Every execution context has a sense associated with it.\n\t * This sense is reversed when the barrier is entered. Every\n\t * thread will spin on the global sense until the last thread\n\t * reverses it.\n\t */\n\tsense = state->sense = ~state->sense;\n\tvalue = ck_pr_faa_uint(&barrier->value, 1);\n\tif (value == n_threads - 1) {\n\t\tck_pr_store_uint(&barrier->value, 0);\n\t\tck_pr_fence_memory();\n\t\tck_pr_store_uint(&barrier->sense, sense);\n\t\treturn;\n\t}\n\n\tck_pr_fence_atomic_load();\n\twhile (sense != ck_pr_load_uint(&barrier->sense))\n\t\tck_pr_stall();\n\n\tck_pr_fence_acquire();\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_barrier_combining.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_barrier.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n\nstruct ck_barrier_combining_queue {\n\tstruct ck_barrier_combining_group *head;\n\tstruct ck_barrier_combining_group *tail;\n};\n\nCK_CC_INLINE static struct ck_barrier_combining_group *\nck_barrier_combining_queue_dequeue(struct ck_barrier_combining_queue *queue)\n{\n\tstruct ck_barrier_combining_group *front = NULL;\n\n\tif (queue->head != NULL) {\n\t\tfront = queue->head;\n\t\tqueue->head = queue->head->next;\n\t}\n\n\treturn front;\n}\n\nCK_CC_INLINE static void\nck_barrier_combining_insert(struct ck_barrier_combining_group *parent,\n    struct ck_barrier_combining_group *tnode,\n    struct ck_barrier_combining_group **child)\n{\n\n\t*child = tnode;\n\ttnode->parent = parent;\n\n\t/*\n\t * After inserting, we must increment the parent group's count for\n\t * number of threads expected to reach it; otherwise, the\n\t * barrier may end prematurely.\n\t */\n\tparent->k++;\n\treturn;\n}\n\n/*\n * This implementation of software combining tree barriers\n * uses level order traversal to insert new thread groups\n * into the barrier's tree. We use a queue to implement this\n * traversal.\n */\nCK_CC_INLINE static void\nck_barrier_combining_queue_enqueue(struct ck_barrier_combining_queue *queue,\n    struct ck_barrier_combining_group *node_value)\n{\n\n\tnode_value->next = NULL;\n\tif (queue->head == NULL) {\n\t\tqueue->head = queue->tail = node_value;\n\t\treturn;\n\t}\n\n\tqueue->tail->next = node_value;\n\tqueue->tail = node_value;\n\n\treturn;\n}\n\n\nvoid\nck_barrier_combining_group_init(struct ck_barrier_combining *root,\n    struct ck_barrier_combining_group *tnode,\n    unsigned int nthr)\n{\n\tstruct ck_barrier_combining_group *node;\n\tstruct ck_barrier_combining_queue queue;\n\n\tqueue.head = queue.tail = NULL;\n\n\ttnode->k = nthr;\n\ttnode->count = 0;\n\ttnode->sense = 0;\n\ttnode->left = tnode->right = NULL;\n\n\t/*\n\t * Finds the first available node for linkage into the combining\n\t * tree. The use of a spinlock is excusable as this is a one-time\n\t * initialization cost.\n\t */\n\tck_spinlock_fas_lock(&root->mutex);\n\tck_barrier_combining_queue_enqueue(&queue, root->root);\n\twhile (queue.head != NULL) {\n\t\tnode = ck_barrier_combining_queue_dequeue(&queue);\n\n\t\t/* If the left child is free, link the group there. */\n\t\tif (node->left == NULL) {\n\t\t\tck_barrier_combining_insert(node, tnode, &node->left);\n\t\t\tgoto leave;\n\t\t}\n\n\t\t/* If the right child is free, link the group there. */\n\t\tif (node->right == NULL) {\n\t\t\tck_barrier_combining_insert(node, tnode, &node->right);\n\t\t\tgoto leave;\n\t\t}\n\n\t\t/*\n\t\t * If unsuccessful, try inserting as a child of the children of the\n\t\t * current node.\n\t\t */\n\t\tck_barrier_combining_queue_enqueue(&queue, node->left);\n\t\tck_barrier_combining_queue_enqueue(&queue, node->right);\n\t}\n\nleave:\n\tck_spinlock_fas_unlock(&root->mutex);\n\treturn;\n}\n\nvoid\nck_barrier_combining_init(struct ck_barrier_combining *root,\n    struct ck_barrier_combining_group *init_root)\n{\n\n\tinit_root->k = 0;\n\tinit_root->count = 0;\n\tinit_root->sense = 0;\n\tinit_root->parent = init_root->left = init_root->right = NULL;\n\tck_spinlock_fas_init(&root->mutex);\n\troot->root = init_root;\n\treturn;\n}\n\nstatic void\nck_barrier_combining_aux(struct ck_barrier_combining *barrier,\n    struct ck_barrier_combining_group *tnode,\n    unsigned int sense)\n{\n\n\t/*\n\t * If this is the last thread in the group, it moves on to the parent group.\n\t * Otherwise, it spins on this group's sense.\n\t */\n\tif (ck_pr_faa_uint(&tnode->count, 1) == tnode->k - 1) {\n\t\t/*\n\t\t * If we are and will be the last thread entering the barrier for the\n\t\t * current group then signal the parent group if one exists.\n\t\t */\n\t\tif (tnode->parent != NULL)\n\t\t\tck_barrier_combining_aux(barrier, tnode->parent, sense);\n\n\t\t/*\n\t\t * Once the thread returns from its parent(s), it reinitializes the group's\n\t\t * arrival count and signals other threads to continue by flipping the group\n\t\t * sense. Order of these operations is not important since we assume a static\n\t\t * number of threads are members of a barrier for the lifetime of the barrier.\n\t\t * Since count is explicitly reinitialized, it is guaranteed that at any point\n\t\t * tnode->count is equivalent to tnode->k if and only if that many threads\n\t\t * are at the barrier.\n\t\t */\n\t\tck_pr_store_uint(&tnode->count, 0);\n\t\tck_pr_fence_store();\n\t\tck_pr_store_uint(&tnode->sense, ~tnode->sense);\n\t} else {\n\t\tck_pr_fence_memory();\n\t\twhile (sense != ck_pr_load_uint(&tnode->sense))\n\t\t\tck_pr_stall();\n\t}\n\n\treturn;\n}\n\nvoid\nck_barrier_combining(struct ck_barrier_combining *barrier,\n    struct ck_barrier_combining_group *tnode,\n    struct ck_barrier_combining_state *state)\n{\n\n\tck_barrier_combining_aux(barrier, tnode, state->sense);\n\n\t/* Reverse the execution context's sense for the next barrier. */\n\tstate->sense = ~state->sense;\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_barrier_dissemination.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_barrier.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_spinlock.h>\n\n#include \"ck_internal.h\"\n\nvoid\nck_barrier_dissemination_init(struct ck_barrier_dissemination *barrier,\n    struct ck_barrier_dissemination_flag **barrier_internal,\n    unsigned int nthr)\n{\n\tunsigned int i, j, k, size, offset;\n\tbool p = nthr & (nthr - 1);\n\n\tbarrier->nthr = nthr;\n\tbarrier->size = size = ck_internal_log(ck_internal_power_2(nthr));\n\tck_pr_store_uint(&barrier->tid, 0);\n\n\tfor (i = 0; i < nthr; ++i) {\n\t\tbarrier[i].flags[0] = barrier_internal[i];\n\t\tbarrier[i].flags[1] = barrier_internal[i] + size;\n\t}\n\n\tfor (i = 0; i < nthr; ++i) {\n\t\tfor (k = 0, offset = 1; k < size; ++k, offset <<= 1) {\n\t\t\t/*\n\t\t\t * Determine the thread's partner, j, for the current round, k.\n\t\t\t * Partners are chosen such that by the completion of the barrier,\n\t\t\t * every thread has been directly (having one of its flag set) or\n\t\t\t * indirectly (having one of its partners's flags set) signaled\n\t\t\t * by every other thread in the barrier.\n\t\t\t */\n\t\t\tif (p == false)\n\t\t\t\tj = (i + offset) & (nthr - 1);\n\t\t\telse\n\t\t\t\tj = (i + offset) % nthr;\n\n\t\t\t/* Set the thread's partner for round k. */\n\t\t\tbarrier[i].flags[0][k].pflag = &barrier[j].flags[0][k].tflag;\n\t\t\tbarrier[i].flags[1][k].pflag = &barrier[j].flags[1][k].tflag;\n\n\t\t\t/* Set the thread's flags to false. */\n\t\t\tbarrier[i].flags[0][k].tflag = barrier[i].flags[1][k].tflag = 0;\n\t\t}\n\t}\n\n\treturn;\n}\n\nvoid\nck_barrier_dissemination_subscribe(struct ck_barrier_dissemination *barrier,\n    struct ck_barrier_dissemination_state *state)\n{\n\n\tstate->parity = 0;\n\tstate->sense = ~0;\n\tstate->tid = ck_pr_faa_uint(&barrier->tid, 1);\n\treturn;\n}\n\nunsigned int\nck_barrier_dissemination_size(unsigned int nthr)\n{\n\n\treturn (ck_internal_log(ck_internal_power_2(nthr)) << 1);\n}\n\nvoid\nck_barrier_dissemination(struct ck_barrier_dissemination *barrier,\n    struct ck_barrier_dissemination_state *state)\n{\n\tunsigned int i;\n\tunsigned int size = barrier->size;\n\n\tfor (i = 0; i < size; ++i) {\n\t\tunsigned int *pflag, *tflag;\n\n\t\tpflag = barrier[state->tid].flags[state->parity][i].pflag;\n\t\ttflag = &barrier[state->tid].flags[state->parity][i].tflag;\n\n\t\t/* Unblock current partner. */\n\t\tck_pr_store_uint(pflag, state->sense);\n\n\t\t/* Wait until some other thread unblocks this one. */\n\t\twhile (ck_pr_load_uint(tflag) != state->sense)\n\t\t\tck_pr_stall();\n\t}\n\n\t/*\n\t * Dissemination barriers use two sets of flags to prevent race conditions\n\t * between successive calls to the barrier. Parity indicates which set will\n\t * be used for the next barrier. They also use a sense reversal technique\n\t * to avoid re-initialization of the flags for every two calls to the barrier.\n\t */\n\tif (state->parity == 1)\n\t\tstate->sense = ~state->sense;\n\n\tstate->parity = 1 - state->parity;\n\n\tck_pr_fence_acquire();\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_barrier_mcs.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_barrier.h>\n#include <ck_cc.h>\n#include <ck_pr.h>\n#include <ck_stdbool.h>\n\nvoid\nck_barrier_mcs_init(struct ck_barrier_mcs *barrier, unsigned int nthr)\n{\n\tunsigned int i, j;\n\n\tck_pr_store_uint(&barrier->tid, 0);\n\n\tfor (i = 0; i < nthr; ++i) {\n\t\tfor (j = 0; j < 4; ++j) {\n\t\t\t/*\n\t\t\t * If there are still threads that don't have parents,\n\t\t\t * add it as a child.\n\t\t\t */\n\t\t\tbarrier[i].havechild[j] = ((i << 2) + j < nthr - 1) ? ~0 : 0;\n\n\t\t\t/*\n\t\t\t * childnotready is initialized to havechild to ensure\n\t\t\t * a thread does not wait for a child that does not exist.\n\t\t\t */\n\t\t\tbarrier[i].childnotready[j] = barrier[i].havechild[j];\n\t\t}\n\n\t\t/* The root thread does not have a parent. */\n\t\tbarrier[i].parent = (i == 0) ?\n\t\t    &barrier[i].dummy :\n\t\t    &barrier[(i - 1) >> 2].childnotready[(i - 1) & 3];\n\n\t\t/* Leaf threads do not have any children. */\n\t\tbarrier[i].children[0] = ((i << 1) + 1 >= nthr)\t?\n\t\t    &barrier[i].dummy :\n\t\t    &barrier[(i << 1) + 1].parentsense;\n\n\t\tbarrier[i].children[1] = ((i << 1) + 2 >= nthr)\t?\n\t\t    &barrier[i].dummy :\n\t\t    &barrier[(i << 1) + 2].parentsense;\n\n\t\tbarrier[i].parentsense = 0;\n\t}\n\n\treturn;\n}\n\nvoid\nck_barrier_mcs_subscribe(struct ck_barrier_mcs *barrier, struct ck_barrier_mcs_state *state)\n{\n\n\tstate->sense = ~0;\n\tstate->vpid = ck_pr_faa_uint(&barrier->tid, 1);\n\treturn;\n}\n\nCK_CC_INLINE static bool\nck_barrier_mcs_check_children(unsigned int *childnotready)\n{\n\n\tif (ck_pr_load_uint(&childnotready[0]) != 0)\n\t\treturn false;\n\tif (ck_pr_load_uint(&childnotready[1]) != 0)\n\t\treturn false;\n\tif (ck_pr_load_uint(&childnotready[2]) != 0)\n\t\treturn false;\n\tif (ck_pr_load_uint(&childnotready[3]) != 0)\n\t\treturn false;\n\n\treturn true;\n}\n\nCK_CC_INLINE static void\nck_barrier_mcs_reinitialize_children(struct ck_barrier_mcs *node)\n{\n\n\tck_pr_store_uint(&node->childnotready[0], node->havechild[0]);\n\tck_pr_store_uint(&node->childnotready[1], node->havechild[1]);\n\tck_pr_store_uint(&node->childnotready[2], node->havechild[2]);\n\tck_pr_store_uint(&node->childnotready[3], node->havechild[3]);\n\treturn;\n}\n\nvoid\nck_barrier_mcs(struct ck_barrier_mcs *barrier,\n    struct ck_barrier_mcs_state *state)\n{\n\n\t/*\n\t * Wait until all children have reached the barrier and are done waiting\n\t * for their children.\n\t */\n\twhile (ck_barrier_mcs_check_children(barrier[state->vpid].childnotready) == false)\n\t\tck_pr_stall();\n\n\t/* Reinitialize for next barrier. */\n\tck_barrier_mcs_reinitialize_children(&barrier[state->vpid]);\n\n\t/* Inform parent thread and its children have arrived at the barrier. */\n\tck_pr_store_uint(barrier[state->vpid].parent, 0);\n\n\t/* Wait until parent indicates all threads have arrived at the barrier. */\n\tif (state->vpid != 0) {\n\t\twhile (ck_pr_load_uint(&barrier[state->vpid].parentsense) != state->sense)\n\t\t\tck_pr_stall();\n\t}\n\n\t/* Inform children of successful barrier. */\n\tck_pr_store_uint(barrier[state->vpid].children[0], state->sense);\n\tck_pr_store_uint(barrier[state->vpid].children[1], state->sense);\n\tstate->sense = ~state->sense;\n\tck_pr_fence_memory();\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_barrier_tournament.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_barrier.h>\n#include <ck_pr.h>\n\n#include \"ck_internal.h\"\n\n/*\n * This is a tournament barrier implementation. Threads are statically\n * assigned roles to perform for each round of the barrier. Winners\n * move on to the next round, while losers spin in their current rounds\n * on their own flags. During the last round, the champion of the tournament\n * sets the last flag that begins the wakeup process.\n */\n\nenum {\n\tCK_BARRIER_TOURNAMENT_BYE,\n\tCK_BARRIER_TOURNAMENT_CHAMPION,\n\tCK_BARRIER_TOURNAMENT_DROPOUT,\n\tCK_BARRIER_TOURNAMENT_LOSER,\n\tCK_BARRIER_TOURNAMENT_WINNER\n};\n\nvoid\nck_barrier_tournament_subscribe(struct ck_barrier_tournament *barrier,\n    struct ck_barrier_tournament_state *state)\n{\n\n\tstate->sense = ~0;\n\tstate->vpid = ck_pr_faa_uint(&barrier->tid, 1);\n\treturn;\n}\n\nvoid\nck_barrier_tournament_init(struct ck_barrier_tournament *barrier,\n    struct ck_barrier_tournament_round **rounds,\n    unsigned int nthr)\n{\n\tunsigned int i, k, size, twok, twokm1, imod2k;\n\n\tck_pr_store_uint(&barrier->tid, 0);\n\tbarrier->size = size = ck_barrier_tournament_size(nthr);\n\n\tfor (i = 0; i < nthr; ++i) {\n\t\t/* The first role is always CK_BARRIER_TOURNAMENT_DROPOUT. */\n\t\trounds[i][0].flag = 0;\n\t\trounds[i][0].role = CK_BARRIER_TOURNAMENT_DROPOUT;\n\t\tfor (k = 1, twok = 2, twokm1 = 1; k < size; ++k, twokm1 = twok, twok <<= 1) {\n\t\t\trounds[i][k].flag = 0;\n\n\t\t\timod2k = i & (twok - 1);\n\t\t\tif (imod2k == 0) {\n\t\t\t\tif ((i + twokm1 < nthr) && (twok < nthr))\n\t\t\t\t\trounds[i][k].role = CK_BARRIER_TOURNAMENT_WINNER;\n\t\t\t\telse if (i + twokm1 >= nthr)\n\t\t\t\t\trounds[i][k].role = CK_BARRIER_TOURNAMENT_BYE;\n\t\t\t}\n\n\t\t\tif (imod2k == twokm1)\n\t\t\t\trounds[i][k].role = CK_BARRIER_TOURNAMENT_LOSER;\n\t\t\telse if ((i == 0) && (twok >= nthr))\n\t\t\t\trounds[i][k].role = CK_BARRIER_TOURNAMENT_CHAMPION;\n\n\t\t\tif (rounds[i][k].role == CK_BARRIER_TOURNAMENT_LOSER)\n\t\t\t\trounds[i][k].opponent = &rounds[i - twokm1][k].flag;\n\t\t\telse if (rounds[i][k].role == CK_BARRIER_TOURNAMENT_WINNER ||\n\t\t\t\t rounds[i][k].role == CK_BARRIER_TOURNAMENT_CHAMPION)\n\t\t\t\trounds[i][k].opponent = &rounds[i + twokm1][k].flag;\n\t\t}\n\t}\n\n\tck_pr_store_ptr(&barrier->rounds, rounds);\n\treturn;\n}\n\nunsigned int\nck_barrier_tournament_size(unsigned int nthr)\n{\n\n\treturn (ck_internal_log(ck_internal_power_2(nthr)) + 1);\n}\n\nvoid\nck_barrier_tournament(struct ck_barrier_tournament *barrier,\n    struct ck_barrier_tournament_state *state)\n{\n\tstruct ck_barrier_tournament_round **rounds = ck_pr_load_ptr(&barrier->rounds);\n\tint round = 1;\n\n\tif (barrier->size == 1)\n\t\treturn;\n\n\tfor (;; ++round) {\n\t\tswitch (rounds[state->vpid][round].role) {\n\t\tcase CK_BARRIER_TOURNAMENT_BYE:\n\t\t\tbreak;\n\t\tcase CK_BARRIER_TOURNAMENT_CHAMPION:\n\t\t\t/*\n\t\t\t * The CK_BARRIER_TOURNAMENT_CHAMPION waits until it wins the tournament; it then\n\t\t\t * sets the final flag before the wakeup phase of the barrier.\n\t\t\t */\n\t\t\twhile (ck_pr_load_uint(&rounds[state->vpid][round].flag) != state->sense)\n\t\t\t\tck_pr_stall();\n\n\t\t\tck_pr_store_uint(rounds[state->vpid][round].opponent, state->sense);\n\t\t\tgoto wakeup;\n\t\tcase CK_BARRIER_TOURNAMENT_DROPOUT:\n\t\t\t/* NOTREACHED */\n\t\t\tbreak;\n\t\tcase CK_BARRIER_TOURNAMENT_LOSER:\n\t\t\t/*\n\t\t\t * CK_BARRIER_TOURNAMENT_LOSERs set the flags of their opponents and wait until\n\t\t\t * their opponents release them after the tournament is over.\n\t\t\t */\n\t\t\tck_pr_store_uint(rounds[state->vpid][round].opponent, state->sense);\n\t\t\twhile (ck_pr_load_uint(&rounds[state->vpid][round].flag) != state->sense)\n\t\t\t\tck_pr_stall();\n\n\t\t\tgoto wakeup;\n\t\tcase CK_BARRIER_TOURNAMENT_WINNER:\n\t\t\t/*\n\t\t\t * CK_BARRIER_TOURNAMENT_WINNERs wait until their current opponent sets their flag; they then\n\t\t\t * continue to the next round of the tournament.\n\t\t\t */\n\t\t\twhile (ck_pr_load_uint(&rounds[state->vpid][round].flag) != state->sense)\n\t\t\t\tck_pr_stall();\n\t\t\tbreak;\n\t\t}\n\t}\n\nwakeup:\n\tfor (round -= 1 ;; --round) {\n\t\tswitch (rounds[state->vpid][round].role) {\n\t\tcase CK_BARRIER_TOURNAMENT_BYE:\n\t\t\tbreak;\n\t\tcase CK_BARRIER_TOURNAMENT_CHAMPION:\n\t\t\t/* NOTREACHED */\n\t\t\tbreak;\n\t\tcase CK_BARRIER_TOURNAMENT_DROPOUT:\n\t\t\tgoto leave;\n\t\t\tbreak;\n\t\tcase CK_BARRIER_TOURNAMENT_LOSER:\n\t\t\t/* NOTREACHED */\n\t\t\tbreak;\n\t\tcase CK_BARRIER_TOURNAMENT_WINNER:\n\t\t\t/*\n\t\t\t * Winners inform their old opponents the tournament is over\n\t\t\t * by setting their flags.\n\t\t\t */\n\t\t\tck_pr_store_uint(rounds[state->vpid][round].opponent, state->sense);\n\t\t\tbreak;\n\t\t}\n\t}\n\nleave:\n\tck_pr_fence_memory();\n\tstate->sense = ~state->sense;\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_epoch.c",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * The implementation here is inspired from the work described in:\n *   Fraser, K. 2004. Practical Lock-Freedom. PhD Thesis, University\n *   of Cambridge Computing Laboratory.\n */\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_epoch.h>\n#include <ck_pr.h>\n#include <ck_stack.h>\n#include <ck_stdbool.h>\n#include <ck_string.h>\n\n/*\n * Only three distinct values are used for reclamation, but reclamation occurs\n * at e+2 rather than e+1. Any thread in a \"critical section\" would have\n * acquired some snapshot (e) of the global epoch value (e_g) and set an active\n * flag. Any hazardous references will only occur after a full memory barrier.\n * For example, assume an initial e_g value of 1, e value of 0 and active value\n * of 0.\n *\n * ck_epoch_begin(...)\n *   e = e_g\n *   active = 1\n *   memory_barrier();\n *\n * Any serialized reads may observe e = 0 or e = 1 with active = 0, or e = 0 or\n * e = 1 with active = 1. The e_g value can only go from 1 to 2 if every thread\n * has already observed the value of \"1\" (or the value we are incrementing\n * from). This guarantees us that for any given value e_g, any threads with-in\n * critical sections (referred to as \"active\" threads from here on) would have\n * an e value of e_g-1 or e_g. This also means that hazardous references may be\n * shared in both e_g-1 and e_g even if they are logically deleted in e_g.\n *\n * For example, assume all threads have an e value of e_g. Another thread may\n * increment to e_g to e_g+1. Older threads may have a reference to an object\n * which is only deleted in e_g+1. It could be that reader threads are\n * executing some hash table look-ups, while some other writer thread (which\n * causes epoch counter tick) actually deletes the same items that reader\n * threads are looking up (this writer thread having an e value of e_g+1).\n * This is possible if the writer thread re-observes the epoch after the\n * counter tick.\n *\n * Psuedo-code for writer:\n *   ck_epoch_begin()\n *   ht_delete(x)\n *   ck_epoch_end()\n *   ck_epoch_begin()\n *   ht_delete(x)\n *   ck_epoch_end()\n *\n * Psuedo-code for reader:\n *   for (;;) {\n *      x = ht_lookup(x)\n *      ck_pr_inc(&x->value);\n *   }\n *\n * Of course, it is also possible for references logically deleted at e_g-1 to\n * still be accessed at e_g as threads are \"active\" at the same time\n * (real-world time) mutating shared objects.\n *\n * Now, if the epoch counter is ticked to e_g+1, then no new hazardous\n * references could exist to objects logically deleted at e_g-1. The reason for\n * this is that at e_g+1, all epoch read-side critical sections started at\n * e_g-1 must have been completed. If any epoch read-side critical sections at\n * e_g-1 were still active, then we would never increment to e_g+1 (active != 0\n * ^ e != e_g).  Additionally, e_g may still have hazardous references to\n * objects logically deleted at e_g-1 which means objects logically deleted at\n * e_g-1 cannot be deleted at e_g+1 unless all threads have observed e_g+1\n * (since it is valid for active threads to be at e_g and threads at e_g still\n * require safe memory accesses).\n *\n * However, at e_g+2, all active threads must be either at e_g+1 or e_g+2.\n * Though e_g+2 may share hazardous references with e_g+1, and e_g+1 shares\n * hazardous references to e_g, no active threads are at e_g or e_g-1. This\n * means no hazardous references could exist to objects deleted at e_g-1 (at\n * e_g+2).\n *\n * To summarize these important points,\n *   1) Active threads will always have a value of e_g or e_g-1.\n *   2) Items that are logically deleted e_g or e_g-1 cannot be physically\n *      deleted.\n *   3) Objects logically deleted at e_g-1 can be physically destroyed at e_g+2\n *      or at e_g+1 if no threads are at e_g.\n *\n * Last but not least, if we are at e_g+2, then no active thread is at e_g\n * which means it is safe to apply modulo-3 arithmetic to e_g value in order to\n * re-use e_g to represent the e_g+3 state. This means it is sufficient to\n * represent e_g using only the values 0, 1 or 2. Every time a thread re-visits\n * a e_g (which can be determined with a non-empty deferral list) it can assume\n * objects in the e_g deferral list involved at least three e_g transitions and\n * are thus, safe, for physical deletion.\n *\n * Blocking semantics for epoch reclamation have additional restrictions.\n * Though we only require three deferral lists, reasonable blocking semantics\n * must be able to more gracefully handle bursty write work-loads which could\n * easily cause e_g wrap-around if modulo-3 arithmetic is used. This allows for\n * easy-to-trigger live-lock situations. The work-around to this is to not\n * apply modulo arithmetic to e_g but only to deferral list indexing.\n */\n#define CK_EPOCH_GRACE 3U\n\nenum {\n\tCK_EPOCH_STATE_USED = 0,\n\tCK_EPOCH_STATE_FREE = 1\n};\n\nCK_STACK_CONTAINER(struct ck_epoch_record, record_next,\n    ck_epoch_record_container)\nCK_STACK_CONTAINER(struct ck_epoch_entry, stack_entry,\n    ck_epoch_entry_container)\n\n#define CK_EPOCH_SENSE_MASK\t(CK_EPOCH_SENSE - 1)\n\nbool\n_ck_epoch_delref(struct ck_epoch_record *record,\n    struct ck_epoch_section *section)\n{\n\tstruct ck_epoch_ref *current, *other;\n\tunsigned int i = section->bucket;\n\n\tcurrent = &record->local.bucket[i];\n\tcurrent->count--;\n\n\tif (current->count > 0)\n\t\treturn false;\n\n\t/*\n\t * If the current bucket no longer has any references, then\n\t * determine whether we have already transitioned into a newer\n\t * epoch. If so, then make sure to update our shared snapshot\n\t * to allow for forward progress.\n\t *\n\t * If no other active bucket exists, then the record will go\n\t * inactive in order to allow for forward progress.\n\t */\n\tother = &record->local.bucket[(i + 1) & CK_EPOCH_SENSE_MASK];\n\tif (other->count > 0 &&\n\t    ((int)(current->epoch - other->epoch) < 0)) {\n\t\t/*\n\t\t * The other epoch value is actually the newest,\n\t\t * transition to it.\n\t\t */\n\t\tck_pr_store_uint(&record->epoch, other->epoch);\n\t}\n\n\treturn true;\n}\n\nvoid\n_ck_epoch_addref(struct ck_epoch_record *record,\n    struct ck_epoch_section *section)\n{\n\tstruct ck_epoch *global = record->global;\n\tstruct ck_epoch_ref *ref;\n\tunsigned int epoch, i;\n\n\tepoch = ck_pr_load_uint(&global->epoch);\n\ti = epoch & CK_EPOCH_SENSE_MASK;\n\tref = &record->local.bucket[i];\n\n\tif (ref->count++ == 0) {\n#ifndef CK_MD_TSO\n\t\tstruct ck_epoch_ref *previous;\n\n\t\t/*\n\t\t * The system has already ticked. If another non-zero bucket\n\t\t * exists, make sure to order our observations with respect\n\t\t * to it. Otherwise, it is possible to acquire a reference\n\t\t * from the previous epoch generation.\n\t\t *\n\t\t * On TSO architectures, the monoticity of the global counter\n\t\t * and load-{store, load} ordering are sufficient to guarantee\n\t\t * this ordering.\n\t\t */\n\t\tprevious = &record->local.bucket[(i + 1) &\n\t\t    CK_EPOCH_SENSE_MASK];\n\t\tif (previous->count > 0)\n\t\t\tck_pr_fence_acqrel();\n#endif /* !CK_MD_TSO */\n\n\t\t/*\n\t\t * If this is this is a new reference into the current\n\t\t * bucket then cache the associated epoch value.\n\t\t */\n\t\tref->epoch = epoch;\n\t}\n\n\tsection->bucket = i;\n\treturn;\n}\n\nvoid\nck_epoch_init(struct ck_epoch *global)\n{\n\n\tck_stack_init(&global->records);\n\tglobal->epoch = 1;\n\tglobal->n_free = 0;\n\tck_pr_fence_store();\n\treturn;\n}\n\nstruct ck_epoch_record *\nck_epoch_recycle(struct ck_epoch *global, void *ct)\n{\n\tstruct ck_epoch_record *record;\n\tck_stack_entry_t *cursor;\n\tunsigned int state;\n\n\tif (ck_pr_load_uint(&global->n_free) == 0)\n\t\treturn NULL;\n\n\tCK_STACK_FOREACH(&global->records, cursor) {\n\t\trecord = ck_epoch_record_container(cursor);\n\n\t\tif (ck_pr_load_uint(&record->state) == CK_EPOCH_STATE_FREE) {\n\t\t\t/* Serialize with respect to deferral list clean-up. */\n\t\t\tck_pr_fence_load();\n\t\t\tstate = ck_pr_fas_uint(&record->state,\n\t\t\t    CK_EPOCH_STATE_USED);\n\t\t\tif (state == CK_EPOCH_STATE_FREE) {\n\t\t\t\tck_pr_dec_uint(&global->n_free);\n\t\t\t\tck_pr_store_ptr(&record->ct, ct);\n\n\t\t\t\t/*\n\t\t\t\t * The context pointer is ordered by a\n\t\t\t\t * subsequent protected section.\n\t\t\t\t */\n\t\t\t\treturn record;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nvoid\nck_epoch_register(struct ck_epoch *global, struct ck_epoch_record *record,\n    void *ct)\n{\n\tsize_t i;\n\n\trecord->global = global;\n\trecord->state = CK_EPOCH_STATE_USED;\n\trecord->active = 0;\n\trecord->epoch = 0;\n\trecord->n_dispatch = 0;\n\trecord->n_peak = 0;\n\trecord->n_pending = 0;\n\trecord->ct = ct;\n\tmemset(&record->local, 0, sizeof record->local);\n\n\tfor (i = 0; i < CK_EPOCH_LENGTH; i++)\n\t\tck_stack_init(&record->pending[i]);\n\n\tck_pr_fence_store();\n\tck_stack_push_upmc(&global->records, &record->record_next);\n\treturn;\n}\n\nvoid\nck_epoch_unregister(struct ck_epoch_record *record)\n{\n\tstruct ck_epoch *global = record->global;\n\tsize_t i;\n\n\trecord->active = 0;\n\trecord->epoch = 0;\n\trecord->n_dispatch = 0;\n\trecord->n_peak = 0;\n\trecord->n_pending = 0;\n\tmemset(&record->local, 0, sizeof record->local);\n\n\tfor (i = 0; i < CK_EPOCH_LENGTH; i++)\n\t\tck_stack_init(&record->pending[i]);\n\n\tck_pr_store_ptr(&record->ct, NULL);\n\tck_pr_fence_store();\n\tck_pr_store_uint(&record->state, CK_EPOCH_STATE_FREE);\n\tck_pr_inc_uint(&global->n_free);\n\treturn;\n}\n\nstatic struct ck_epoch_record *\nck_epoch_scan(struct ck_epoch *global,\n    struct ck_epoch_record *cr,\n    unsigned int epoch,\n    bool *af)\n{\n\tck_stack_entry_t *cursor;\n\n\tif (cr == NULL) {\n\t\tcursor = CK_STACK_FIRST(&global->records);\n\t\t*af = false;\n\t} else {\n\t\tcursor = &cr->record_next;\n\t\t*af = true;\n\t}\n\n\twhile (cursor != NULL) {\n\t\tunsigned int state, active;\n\n\t\tcr = ck_epoch_record_container(cursor);\n\n\t\tstate = ck_pr_load_uint(&cr->state);\n\t\tif (state & CK_EPOCH_STATE_FREE) {\n\t\t\tcursor = CK_STACK_NEXT(cursor);\n\t\t\tcontinue;\n\t\t}\n\n\t\tactive = ck_pr_load_uint(&cr->active);\n\t\t*af |= active;\n\n\t\tif (active != 0 && ck_pr_load_uint(&cr->epoch) != epoch)\n\t\t\treturn cr;\n\n\t\tcursor = CK_STACK_NEXT(cursor);\n\t}\n\n\treturn NULL;\n}\n\nstatic void\nck_epoch_dispatch(struct ck_epoch_record *record, unsigned int e)\n{\n\tunsigned int epoch = e & (CK_EPOCH_LENGTH - 1);\n\tck_stack_entry_t *head, *next, *cursor;\n\tunsigned int n_pending, n_peak;\n\tunsigned int i = 0;\n\n\thead = ck_stack_batch_pop_upmc(&record->pending[epoch]);\n\tfor (cursor = head; cursor != NULL; cursor = next) {\n\t\tstruct ck_epoch_entry *entry =\n\t\t    ck_epoch_entry_container(cursor);\n\n\t\tnext = CK_STACK_NEXT(cursor);\n\t\tentry->function(entry);\n\t\ti++;\n\t}\n\n\tn_peak = ck_pr_load_uint(&record->n_peak);\n\tn_pending = ck_pr_load_uint(&record->n_pending);\n\n\t/* We don't require accuracy around peak calculation. */\n\tif (n_pending > n_peak)\n\t\tck_pr_store_uint(&record->n_peak, n_peak);\n\n\tif (i > 0) {\n\t\tck_pr_add_uint(&record->n_dispatch, i);\n\t\tck_pr_sub_uint(&record->n_pending, i);\n\t}\n\n\treturn;\n}\n\n/*\n * Reclaim all objects associated with a record.\n */\nvoid\nck_epoch_reclaim(struct ck_epoch_record *record)\n{\n\tunsigned int epoch;\n\n\tfor (epoch = 0; epoch < CK_EPOCH_LENGTH; epoch++)\n\t\tck_epoch_dispatch(record, epoch);\n\n\treturn;\n}\n\nCK_CC_FORCE_INLINE static void\nepoch_block(struct ck_epoch *global, struct ck_epoch_record *cr,\n    ck_epoch_wait_cb_t *cb, void *ct)\n{\n\n\tif (cb != NULL)\n\t\tcb(global, cr, ct);\n\n\treturn;\n}\n\n/*\n * This function must not be called with-in read section.\n */\nvoid\nck_epoch_synchronize_wait(struct ck_epoch *global,\n    ck_epoch_wait_cb_t *cb, void *ct)\n{\n\tstruct ck_epoch_record *cr;\n\tunsigned int delta, epoch, goal, i;\n\tbool active;\n\n\tck_pr_fence_memory();\n\n\t/*\n\t * The observation of the global epoch must be ordered with respect to\n\t * all prior operations. The re-ordering of loads is permitted given\n\t * monoticity of global epoch counter.\n\t *\n\t * If UINT_MAX concurrent mutations were to occur then it is possible\n\t * to encounter an ABA-issue. If this is a concern, consider tuning\n\t * write-side concurrency.\n\t */\n\tdelta = epoch = ck_pr_load_uint(&global->epoch);\n\tgoal = epoch + CK_EPOCH_GRACE;\n\n\tfor (i = 0, cr = NULL; i < CK_EPOCH_GRACE - 1; cr = NULL, i++) {\n\t\tbool r;\n\n\t\t/*\n\t\t * Determine whether all threads have observed the current\n\t\t * epoch with respect to the updates on invocation.\n\t\t */\n\t\twhile (cr = ck_epoch_scan(global, cr, delta, &active),\n\t\t    cr != NULL) {\n\t\t\tunsigned int e_d;\n\n\t\t\tck_pr_stall();\n\n\t\t\t/*\n\t\t\t * Another writer may have already observed a grace\n\t\t\t * period.\n\t\t\t */\n\t\t\te_d = ck_pr_load_uint(&global->epoch);\n\t\t\tif (e_d == delta) {\n\t\t\t\tepoch_block(global, cr, cb, ct);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t * If the epoch has been updated, we may have already\n\t\t\t * met our goal.\n\t\t\t */\n\t\t\tdelta = e_d;\n\t\t\tif ((goal > epoch) & (delta >= goal))\n\t\t\t\tgoto leave;\n\n\t\t\tepoch_block(global, cr, cb, ct);\n\n\t\t\t/*\n\t\t\t * If the epoch has been updated, then a grace period\n\t\t\t * requires that all threads are observed idle at the\n\t\t\t * same epoch.\n\t\t\t */\n\t\t\tcr = NULL;\n\t\t}\n\n\t\t/*\n\t\t * If we have observed all threads as inactive, then we assume\n\t\t * we are at a grace period.\n\t\t */\n\t\tif (active == false)\n\t\t\tbreak;\n\n\t\t/*\n\t\t * Increment current epoch. CAS semantics are used to eliminate\n\t\t * increment operations for synchronization that occurs for the\n\t\t * same global epoch value snapshot.\n\t\t *\n\t\t * If we can guarantee there will only be one active barrier or\n\t\t * epoch tick at a given time, then it is sufficient to use an\n\t\t * increment operation. In a multi-barrier workload, however,\n\t\t * it is possible to overflow the epoch value if we apply\n\t\t * modulo-3 arithmetic.\n\t\t */\n\t\tr = ck_pr_cas_uint_value(&global->epoch, delta, delta + 1,\n\t\t    &delta);\n\n\t\t/* Order subsequent thread active checks. */\n\t\tck_pr_fence_atomic_load();\n\n\t\t/*\n\t\t * If CAS has succeeded, then set delta to latest snapshot.\n\t\t * Otherwise, we have just acquired latest snapshot.\n\t\t */\n\t\tdelta = delta + r;\n\t}\n\n\t/*\n\t * A majority of use-cases will not require full barrier semantics.\n\t * However, if non-temporal instructions are used, full barrier\n\t * semantics are necessary.\n\t */\nleave:\n\tck_pr_fence_memory();\n\treturn;\n}\n\nvoid\nck_epoch_synchronize(struct ck_epoch_record *record)\n{\n\n\tck_epoch_synchronize_wait(record->global, NULL, NULL);\n\treturn;\n}\n\nvoid\nck_epoch_barrier(struct ck_epoch_record *record)\n{\n\n\tck_epoch_synchronize(record);\n\tck_epoch_reclaim(record);\n\treturn;\n}\n\nvoid\nck_epoch_barrier_wait(struct ck_epoch_record *record, ck_epoch_wait_cb_t *cb,\n    void *ct)\n{\n\n\tck_epoch_synchronize_wait(record->global, cb, ct);\n\tck_epoch_reclaim(record);\n\treturn;\n}\n\n/*\n * It may be worth it to actually apply these deferral semantics to an epoch\n * that was observed at ck_epoch_call time. The problem is that the latter\n * would require a full fence.\n *\n * ck_epoch_call will dispatch to the latest epoch snapshot that was observed.\n * There are cases where it will fail to reclaim as early as it could. If this\n * becomes a problem, we could actually use a heap for epoch buckets but that\n * is far from ideal too.\n */\nbool\nck_epoch_poll(struct ck_epoch_record *record)\n{\n\tbool active;\n\tunsigned int epoch;\n\tstruct ck_epoch_record *cr = NULL;\n\tstruct ck_epoch *global = record->global;\n\n\tepoch = ck_pr_load_uint(&global->epoch);\n\n\t/* Serialize epoch snapshots with respect to global epoch. */\n\tck_pr_fence_memory();\n\tcr = ck_epoch_scan(global, cr, epoch, &active);\n\tif (cr != NULL) {\n\t\trecord->epoch = epoch;\n\t\treturn false;\n\t}\n\n\t/* We are at a grace period if all threads are inactive. */\n\tif (active == false) {\n\t\trecord->epoch = epoch;\n\t\tfor (epoch = 0; epoch < CK_EPOCH_LENGTH; epoch++)\n\t\t\tck_epoch_dispatch(record, epoch);\n\n\t\treturn true;\n\t}\n\n\t/* If an active thread exists, rely on epoch observation. */\n\t(void)ck_pr_cas_uint(&global->epoch, epoch, epoch + 1);\n\n\tck_epoch_dispatch(record, epoch + 1);\n\treturn true;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_hp.c",
    "content": "/*\n * Copyright 2010-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * (c) Copyright 2008, IBM Corporation.\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/*\n * This is an implementation of hazard pointers as detailed in:\n *   http://www.research.ibm.com/people/m/michael/ieeetpds-2004.pdf\n *\n * This API provides a publishing mechanism that defers destruction of\n * hazard pointers until it is safe to do so. Preventing arbitrary re-use\n * protects against the ABA problem and provides safe memory reclamation.\n * The implementation was derived from the Hazard Pointers implementation\n * from the Amino CBBS project. It has been heavily modified for Concurrency\n * Kit.\n */\n\n#include <ck_backoff.h>\n#include <ck_cc.h>\n#include <ck_hp.h>\n#include <ck_pr.h>\n#include <ck_stack.h>\n#include <ck_stdbool.h>\n#include <ck_stddef.h>\n#include <ck_stdlib.h>\n#include <ck_string.h>\n\nCK_STACK_CONTAINER(struct ck_hp_record, global_entry, ck_hp_record_container)\nCK_STACK_CONTAINER(struct ck_hp_hazard, pending_entry, ck_hp_hazard_container)\n\nvoid\nck_hp_init(struct ck_hp *state,\n\t   unsigned int degree,\n\t   unsigned int threshold,\n\t   ck_hp_destructor_t destroy)\n{\n\n\tstate->threshold = threshold;\n\tstate->degree = degree;\n\tstate->destroy = destroy;\n\tstate->n_subscribers = 0;\n\tstate->n_free = 0;\n\tck_stack_init(&state->subscribers);\n\tck_pr_fence_store();\n\n\treturn;\n}\n\nvoid\nck_hp_set_threshold(struct ck_hp *state, unsigned int threshold)\n{\n\n\tck_pr_store_uint(&state->threshold, threshold);\n\treturn;\n}\n\nstruct ck_hp_record *\nck_hp_recycle(struct ck_hp *global)\n{\n\tstruct ck_hp_record *record;\n\tck_stack_entry_t *entry;\n\tint state;\n\n\tif (ck_pr_load_uint(&global->n_free) == 0)\n\t\treturn NULL;\n\n\tCK_STACK_FOREACH(&global->subscribers, entry) {\n\t\trecord = ck_hp_record_container(entry);\n\n\t\tif (ck_pr_load_int(&record->state) == CK_HP_FREE) {\n\t\t\tck_pr_fence_load();\n\t\t\tstate = ck_pr_fas_int(&record->state, CK_HP_USED);\n\t\t\tif (state == CK_HP_FREE) {\n\t\t\t\tck_pr_dec_uint(&global->n_free);\n\t\t\t\treturn record;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn NULL;\n}\n\nvoid\nck_hp_unregister(struct ck_hp_record *entry)\n{\n\n\tentry->n_pending = 0;\n\tentry->n_peak = 0;\n\tentry->n_reclamations = 0;\n\tck_stack_init(&entry->pending);\n\tck_pr_fence_store();\n\tck_pr_store_int(&entry->state, CK_HP_FREE);\n\tck_pr_inc_uint(&entry->global->n_free);\n\treturn;\n}\n\nvoid\nck_hp_register(struct ck_hp *state,\n    struct ck_hp_record *entry,\n    void **pointers)\n{\n\n\tentry->state = CK_HP_USED;\n\tentry->global = state;\n\tentry->pointers = pointers;\n\tentry->n_pending = 0;\n\tentry->n_peak = 0;\n\tentry->n_reclamations = 0;\n\tmemset(pointers, 0, state->degree * sizeof(void *));\n\tck_stack_init(&entry->pending);\n\tck_pr_fence_store();\n\tck_stack_push_upmc(&state->subscribers, &entry->global_entry);\n\tck_pr_inc_uint(&state->n_subscribers);\n\treturn;\n}\n\nstatic int\nhazard_compare(const void *a, const void *b)\n{\n\tvoid * const *x;\n\tvoid * const *y;\n\n\tx = a;\n\ty = b;\n\treturn ((*x > *y) - (*x < *y));\n}\n\nCK_CC_INLINE static bool\nck_hp_member_scan(ck_stack_entry_t *entry, unsigned int degree, void *pointer)\n{\n\tstruct ck_hp_record *record;\n\tunsigned int i;\n\tvoid *hazard;\n\n\tdo {\n\t\trecord = ck_hp_record_container(entry);\n\t\tif (ck_pr_load_int(&record->state) == CK_HP_FREE)\n\t\t\tcontinue;\n\n\t\tif (ck_pr_load_ptr(&record->pointers) == NULL)\n\t\t\tcontinue;\n\n\t\tfor (i = 0; i < degree; i++) {\n\t\t\thazard = ck_pr_load_ptr(&record->pointers[i]);\n\t\t\tif (hazard == pointer)\n\t\t\t\treturn (true);\n\t\t}\n\t} while ((entry = CK_STACK_NEXT(entry)) != NULL);\n\n\treturn (false);\n}\n\nCK_CC_INLINE static void *\nck_hp_member_cache(struct ck_hp *global, void **cache, unsigned int *n_hazards)\n{\n\tstruct ck_hp_record *record;\n\tck_stack_entry_t *entry;\n\tunsigned int hazards = 0;\n\tunsigned int i;\n\tvoid *pointer;\n\n\tCK_STACK_FOREACH(&global->subscribers, entry) {\n\t\trecord = ck_hp_record_container(entry);\n\t\tif (ck_pr_load_int(&record->state) == CK_HP_FREE)\n\t\t\tcontinue;\n\n\t\tif (ck_pr_load_ptr(&record->pointers) == NULL)\n\t\t\tcontinue;\n\n\t\tfor (i = 0; i < global->degree; i++) {\n\t\t\tif (hazards > CK_HP_CACHE)\n\t\t\t\tbreak;\n\n\t\t\tpointer = ck_pr_load_ptr(&record->pointers[i]);\n\t\t\tif (pointer != NULL)\n\t\t\t\tcache[hazards++] = pointer;\n\t\t}\n\t}\n\n\t*n_hazards = hazards;\n\treturn (entry);\n}\n\nvoid\nck_hp_reclaim(struct ck_hp_record *thread)\n{\n\tstruct ck_hp_hazard *hazard;\n\tstruct ck_hp *global = thread->global;\n\tunsigned int n_hazards;\n\tvoid **cache, *marker, *match;\n\tck_stack_entry_t *previous, *entry, *next;\n\n\t/* Store as many entries as possible in local array. */\n\tcache = thread->cache;\n\tmarker = ck_hp_member_cache(global, cache, &n_hazards);\n\n\t/*\n\t * In theory, there is an n such that (n * (log n) ** 2) < np.\n\t */\n\tqsort(cache, n_hazards, sizeof(void *), hazard_compare);\n\n\tprevious = NULL;\n\tCK_STACK_FOREACH_SAFE(&thread->pending, entry, next) {\n\t\thazard = ck_hp_hazard_container(entry);\n\t\tmatch = bsearch(&hazard->pointer, cache, n_hazards,\n\t\t\t\t  sizeof(void *), hazard_compare);\n\t\tif (match != NULL) {\n\t\t\tprevious = entry;\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (marker != NULL &&\n\t\t    ck_hp_member_scan(marker, global->degree, hazard->pointer)) {\n\t\t\tprevious = entry;\n\t\t\tcontinue;\n\t\t}\n\n\t\tthread->n_pending -= 1;\n\n\t\t/* Remove from the pending stack. */\n\t\tif (previous)\n\t\t\tCK_STACK_NEXT(previous) = CK_STACK_NEXT(entry);\n\t\telse\n\t\t\tCK_STACK_FIRST(&thread->pending) = CK_STACK_NEXT(entry);\n\n\t\t/* The entry is now safe to destroy. */\n\t\tglobal->destroy(hazard->data);\n\t\tthread->n_reclamations++;\n\t}\n\n\treturn;\n}\n\nvoid\nck_hp_retire(struct ck_hp_record *thread,\n    struct ck_hp_hazard *hazard,\n    void *data,\n    void *pointer)\n{\n\n\tck_pr_store_ptr(&hazard->pointer, pointer);\n\tck_pr_store_ptr(&hazard->data, data);\n\tck_stack_push_spnc(&thread->pending, &hazard->pending_entry);\n\n\tthread->n_pending += 1;\n\tif (thread->n_pending > thread->n_peak)\n\t\tthread->n_peak = thread->n_pending;\n\n\treturn;\n}\n\nvoid\nck_hp_free(struct ck_hp_record *thread,\n    struct ck_hp_hazard *hazard,\n    void *data,\n    void *pointer)\n{\n\tstruct ck_hp *global;\n\n\tglobal = ck_pr_load_ptr(&thread->global);\n\tck_pr_store_ptr(&hazard->data, data);\n\tck_pr_store_ptr(&hazard->pointer, pointer);\n\tck_stack_push_spnc(&thread->pending, &hazard->pending_entry);\n\n\tthread->n_pending += 1;\n\tif (thread->n_pending > thread->n_peak)\n\t\tthread->n_peak = thread->n_pending;\n\n\tif (thread->n_pending >= global->threshold)\n\t\tck_hp_reclaim(thread);\n\n\treturn;\n}\n\nvoid\nck_hp_purge(struct ck_hp_record *thread)\n{\n\tck_backoff_t backoff = CK_BACKOFF_INITIALIZER;\n\n\twhile (thread->n_pending > 0) {\n\t\tck_hp_reclaim(thread);\n\t\tif (thread->n_pending > 0)\n\t\t\tck_backoff_eb(&backoff);\n\t}\n\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_hs.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_cc.h>\n#include <ck_hs.h>\n#include <ck_limits.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_string.h>\n\n#include \"ck_internal.h\"\n\n#ifndef CK_HS_PROBE_L1_SHIFT\n#define CK_HS_PROBE_L1_SHIFT 3ULL\n#endif /* CK_HS_PROBE_L1_SHIFT */\n\n#define CK_HS_PROBE_L1 (1 << CK_HS_PROBE_L1_SHIFT)\n#define CK_HS_PROBE_L1_MASK (CK_HS_PROBE_L1 - 1)\n\n#ifndef CK_HS_PROBE_L1_DEFAULT\n#define CK_HS_PROBE_L1_DEFAULT CK_MD_CACHELINE\n#endif\n\n#define CK_HS_VMA_MASK ((uintptr_t)((1ULL << CK_MD_VMA_BITS) - 1))\n#define CK_HS_VMA(x)\t\\\n\t((void *)((uintptr_t)(x) & CK_HS_VMA_MASK))\n\n#define CK_HS_EMPTY     NULL\n#define CK_HS_TOMBSTONE ((void *)~(uintptr_t)0)\n#define CK_HS_G\t\t(2)\n#define CK_HS_G_MASK\t(CK_HS_G - 1)\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_STORE_8)\n#define CK_HS_WORD          uint8_t\n#define CK_HS_WORD_MAX\t    UINT8_MAX\n#define CK_HS_STORE(x, y)   ck_pr_store_8(x, y)\n#define CK_HS_LOAD(x)       ck_pr_load_8(x)\n#elif defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_STORE_16)\n#define CK_HS_WORD          uint16_t\n#define CK_HS_WORD_MAX\t    UINT16_MAX\n#define CK_HS_STORE(x, y)   ck_pr_store_16(x, y)\n#define CK_HS_LOAD(x)       ck_pr_load_16(x)\n#elif defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_STORE_32)\n#define CK_HS_WORD          uint32_t\n#define CK_HS_WORD_MAX\t    UINT32_MAX\n#define CK_HS_STORE(x, y)   ck_pr_store_32(x, y)\n#define CK_HS_LOAD(x)       ck_pr_load_32(x)\n#else\n#error \"ck_hs is not supported on your platform.\"\n#endif\n\nenum ck_hs_probe_behavior {\n\tCK_HS_PROBE = 0,\t/* Default behavior. */\n\tCK_HS_PROBE_TOMBSTONE,\t/* Short-circuit on tombstone. */\n\tCK_HS_PROBE_INSERT\t/* Short-circuit on probe bound if tombstone found. */\n};\n\nstruct ck_hs_map {\n\tunsigned int generation[CK_HS_G];\n\tunsigned int probe_maximum;\n\tunsigned long mask;\n\tunsigned long step;\n\tunsigned int probe_limit;\n\tunsigned int tombstones;\n\tunsigned long n_entries;\n\tunsigned long capacity;\n\tunsigned long size;\n\tCK_HS_WORD *probe_bound;\n\tconst void **entries;\n};\n\nstatic inline void\nck_hs_map_signal(struct ck_hs_map *map, unsigned long h)\n{\n\n\th &= CK_HS_G_MASK;\n\tck_pr_store_uint(&map->generation[h],\n\t    map->generation[h] + 1);\n\tck_pr_fence_store();\n\treturn;\n}\n\nstatic bool \n_ck_hs_next(struct ck_hs *hs, struct ck_hs_map *map, struct ck_hs_iterator *i, void **key)\n{\n\tvoid *value;\n\tif (i->offset >= map->capacity)\n\t\treturn false;\n\n\tdo {\n\t\tvalue = CK_CC_DECONST_PTR(map->entries[i->offset]);\n\t\tif (value != CK_HS_EMPTY && value != CK_HS_TOMBSTONE) {\n#ifdef CK_HS_PP\n\t\t\tif (hs->mode & CK_HS_MODE_OBJECT)\n\t\t\t\tvalue = CK_HS_VMA(value);\n#else\n\t\t\t(void)hs; /* Avoid unused parameter warning. */\n#endif\n\t\t\ti->offset++;\n\t\t\t*key = value;\n\t\t\treturn true;\n\t\t}\n\t} while (++i->offset < map->capacity);\n\n\treturn false;\n}\n\nvoid\nck_hs_iterator_init(struct ck_hs_iterator *iterator)\n{\n\n\titerator->cursor = NULL;\n\titerator->offset = 0;\n\titerator->map = NULL;\n\treturn;\n}\n\nbool\nck_hs_next(struct ck_hs *hs, struct ck_hs_iterator *i, void **key)\n{\n\treturn _ck_hs_next(hs, hs->map, i, key);\n}\n\nbool\nck_hs_next_spmc(struct ck_hs *hs, struct ck_hs_iterator *i, void **key)\n{\n\tstruct ck_hs_map *m = i->map;\n\tif (m == NULL) {\n\t\tm = i->map = ck_pr_load_ptr(&hs->map);\n\t}\n\treturn _ck_hs_next(hs, m, i, key);\n}\n\nvoid\nck_hs_stat(struct ck_hs *hs, struct ck_hs_stat *st)\n{\n\tstruct ck_hs_map *map = hs->map;\n\n\tst->n_entries = map->n_entries;\n\tst->tombstones = map->tombstones;\n\tst->probe_maximum = map->probe_maximum;\n\treturn;\n}\n\nunsigned long\nck_hs_count(struct ck_hs *hs)\n{\n\n\treturn hs->map->n_entries;\n}\n\nstatic void\nck_hs_map_destroy(struct ck_malloc *m, struct ck_hs_map *map, bool defer)\n{\n\n\tm->free(map, map->size, defer);\n\treturn;\n}\n\nvoid\nck_hs_destroy(struct ck_hs *hs)\n{\n\n\tck_hs_map_destroy(hs->m, hs->map, false);\n\treturn;\n}\n\nstatic struct ck_hs_map *\nck_hs_map_create(struct ck_hs *hs, unsigned long entries)\n{\n\tstruct ck_hs_map *map;\n\tunsigned long size, n_entries, prefix, limit;\n\n\tn_entries = ck_internal_power_2(entries);\n\tif (n_entries < CK_HS_PROBE_L1)\n\t\tn_entries = CK_HS_PROBE_L1;\n\n\tsize = sizeof(struct ck_hs_map) + (sizeof(void *) * n_entries + CK_MD_CACHELINE - 1);\n\n\tif (hs->mode & CK_HS_MODE_DELETE) {\n\t\tprefix = sizeof(CK_HS_WORD) * n_entries;\n\t\tsize += prefix;\n\t} else {\n\t\tprefix = 0;\n\t}\n\n\tmap = hs->m->malloc(size);\n\tif (map == NULL)\n\t\treturn NULL;\n\n\tmap->size = size;\n\n\t/* We should probably use a more intelligent heuristic for default probe length. */\n\tlimit = ck_internal_max(n_entries >> (CK_HS_PROBE_L1_SHIFT + 2), CK_HS_PROBE_L1_DEFAULT);\n\tif (limit > UINT_MAX)\n\t\tlimit = UINT_MAX;\n\n\tmap->probe_limit = (unsigned int)limit;\n\tmap->probe_maximum = 0;\n\tmap->capacity = n_entries;\n\tmap->step = ck_internal_bsf(n_entries);\n\tmap->mask = n_entries - 1;\n\tmap->n_entries = 0;\n\n\t/* Align map allocation to cache line. */\n\tmap->entries = (void *)(((uintptr_t)&map[1] + prefix +\n\t    CK_MD_CACHELINE - 1) & ~(CK_MD_CACHELINE - 1));\n\n\tmemset(map->entries, 0, sizeof(void *) * n_entries);\n\tmemset(map->generation, 0, sizeof map->generation);\n\n\tif (hs->mode & CK_HS_MODE_DELETE) {\n\t\tmap->probe_bound = (CK_HS_WORD *)&map[1];\n\t\tmemset(map->probe_bound, 0, prefix);\n\t} else {\n\t\tmap->probe_bound = NULL;\n\t}\n\n\t/* Commit entries purge with respect to map publication. */\n\tck_pr_fence_store();\n\treturn map;\n}\n\nbool\nck_hs_reset_size(struct ck_hs *hs, unsigned long capacity)\n{\n\tstruct ck_hs_map *map, *previous;\n\n\tprevious = hs->map;\n\tmap = ck_hs_map_create(hs, capacity);\n\tif (map == NULL)\n\t\treturn false;\n\n\tck_pr_store_ptr(&hs->map, map);\n\tck_hs_map_destroy(hs->m, previous, true);\n\treturn true;\n}\n\nbool\nck_hs_reset(struct ck_hs *hs)\n{\n\tstruct ck_hs_map *previous;\n\n\tprevious = hs->map;\n\treturn ck_hs_reset_size(hs, previous->capacity);\n}\n\nstatic inline unsigned long\nck_hs_map_probe_next(struct ck_hs_map *map,\n    unsigned long offset,\n    unsigned long h,\n    unsigned long level,\n    unsigned long probes)\n{\n\tunsigned long r, stride;\n\n\tr = (h >> map->step) >> level;\n\tstride = (r & ~CK_HS_PROBE_L1_MASK) << 1 | (r & CK_HS_PROBE_L1_MASK);\n\n\treturn (offset + (probes >> CK_HS_PROBE_L1_SHIFT) +\n\t    (stride | CK_HS_PROBE_L1)) & map->mask;\n}\n\nstatic inline void\nck_hs_map_bound_set(struct ck_hs_map *m,\n    unsigned long h,\n    unsigned long n_probes)\n{\n\tunsigned long offset = h & m->mask;\n\n\tif (n_probes > m->probe_maximum)\n\t\tck_pr_store_uint(&m->probe_maximum, n_probes);\n\n\tif (m->probe_bound != NULL && m->probe_bound[offset] < n_probes) {\n\t\tif (n_probes > CK_HS_WORD_MAX)\n\t\t\tn_probes = CK_HS_WORD_MAX;\n\n\t\tCK_HS_STORE(&m->probe_bound[offset], n_probes);\n\t\tck_pr_fence_store();\n\t}\n\n\treturn;\n}\n\nstatic inline unsigned int\nck_hs_map_bound_get(struct ck_hs_map *m, unsigned long h)\n{\n\tunsigned long offset = h & m->mask;\n\tunsigned int r = CK_HS_WORD_MAX;\n\n\tif (m->probe_bound != NULL) {\n\t\tr = CK_HS_LOAD(&m->probe_bound[offset]);\n\t\tif (r == CK_HS_WORD_MAX)\n\t\t\tr = ck_pr_load_uint(&m->probe_maximum);\n\t} else {\n\t\tr = ck_pr_load_uint(&m->probe_maximum);\n\t}\n\n\treturn r;\n}\n\nbool\nck_hs_grow(struct ck_hs *hs,\n    unsigned long capacity)\n{\n\tstruct ck_hs_map *map, *update;\n\tunsigned long k, i, j, offset, probes;\n\tconst void *previous, **bucket;\n\nrestart:\n\tmap = hs->map;\n\tif (map->capacity > capacity)\n\t\treturn false;\n\n\tupdate = ck_hs_map_create(hs, capacity);\n\tif (update == NULL)\n\t\treturn false;\n\n\tfor (k = 0; k < map->capacity; k++) {\n\t\tunsigned long h;\n\n\t\tprevious = map->entries[k];\n\t\tif (previous == CK_HS_EMPTY || previous == CK_HS_TOMBSTONE)\n\t\t\tcontinue;\n\n#ifdef CK_HS_PP\n\t\tif (hs->mode & CK_HS_MODE_OBJECT)\n\t\t\tprevious = CK_HS_VMA(previous);\n#endif\n\n\t\th = hs->hf(previous, hs->seed);\n\t\toffset = h & update->mask;\n\t\ti = probes = 0;\n\n\t\tfor (;;) {\n\t\t\tbucket = (const void **)((uintptr_t)&update->entries[offset] & ~(CK_MD_CACHELINE - 1));\n\n\t\t\tfor (j = 0; j < CK_HS_PROBE_L1; j++) {\n\t\t\t\tconst void **cursor = bucket + ((j + offset) & (CK_HS_PROBE_L1 - 1));\n\n\t\t\t\tif (probes++ == update->probe_limit)\n\t\t\t\t\tbreak;\n\n\t\t\t\tif (CK_CC_LIKELY(*cursor == CK_HS_EMPTY)) {\n\t\t\t\t\t*cursor = map->entries[k];\n\t\t\t\t\tupdate->n_entries++;\n\n\t\t\t\t\tck_hs_map_bound_set(update, h, probes);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (j < CK_HS_PROBE_L1)\n\t\t\t\tbreak;\n\n\t\t\toffset = ck_hs_map_probe_next(update, offset, h, i++, probes);\n\t\t}\n\n\t\tif (probes > update->probe_limit) {\n\t\t\t/*\n\t\t\t * We have hit the probe limit, map needs to be even larger.\n\t\t\t */\n\t\t\tck_hs_map_destroy(hs->m, update, false);\n\t\t\tcapacity <<= 1;\n\t\t\tgoto restart;\n\t\t}\n\t}\n\n\tck_pr_fence_store();\n\tck_pr_store_ptr(&hs->map, update);\n\tck_hs_map_destroy(hs->m, map, true);\n\treturn true;\n}\n\nstatic void\nck_hs_map_postinsert(struct ck_hs *hs, struct ck_hs_map *map)\n{\n\n\tmap->n_entries++;\n\tif ((map->n_entries << 1) > map->capacity)\n\t\tck_hs_grow(hs, map->capacity << 1);\n\n\treturn;\n}\n\nbool\nck_hs_rebuild(struct ck_hs *hs)\n{\n\n\treturn ck_hs_grow(hs, hs->map->capacity);\n}\n\nstatic const void **\nck_hs_map_probe(struct ck_hs *hs,\n    struct ck_hs_map *map,\n    unsigned long *n_probes,\n    const void ***priority,\n    unsigned long h,\n    const void *key,\n    const void **object,\n    unsigned long probe_limit,\n    enum ck_hs_probe_behavior behavior)\n{\n\tconst void **bucket, **cursor, *k, *compare;\n\tconst void **pr = NULL;\n\tunsigned long offset, j, i, probes, opl;\n\n#ifdef CK_HS_PP\n\t/* If we are storing object pointers, then we may leverage pointer packing. */\n\tunsigned long hv = 0;\n\n\tif (hs->mode & CK_HS_MODE_OBJECT) {\n\t\thv = (h >> 25) & CK_HS_KEY_MASK;\n\t\tcompare = CK_HS_VMA(key);\n\t} else {\n\t\tcompare = key;\n\t}\n#else\n\tcompare = key;\n#endif\n\n\toffset = h & map->mask;\n\t*object = NULL;\n\ti = probes = 0;\n\n\topl = probe_limit;\n\tif (behavior == CK_HS_PROBE_INSERT)\n\t\tprobe_limit = ck_hs_map_bound_get(map, h);\n\n\tfor (;;) {\n\t\tbucket = (const void **)((uintptr_t)&map->entries[offset] & ~(CK_MD_CACHELINE - 1));\n\n\t\tfor (j = 0; j < CK_HS_PROBE_L1; j++) {\n\t\t\tcursor = bucket + ((j + offset) & (CK_HS_PROBE_L1 - 1));\n\n\t\t\tif (probes++ == probe_limit) {\n\t\t\t\tif (probe_limit == opl || pr != NULL) {\n\t\t\t\t\tk = CK_HS_EMPTY;\n\t\t\t\t\tgoto leave;\n\t\t\t\t}\n\n\t\t\t\t/*\n\t\t\t\t * If no eligible slot has been found yet, continue probe\n\t\t\t\t * sequence with original probe limit.\n\t\t\t\t */\n\t\t\t\tprobe_limit = opl;\n\t\t\t}\n\n\t\t\tk = ck_pr_load_ptr(cursor);\n\t\t\tif (k == CK_HS_EMPTY)\n\t\t\t\tgoto leave;\n\n\t\t\tif (k == CK_HS_TOMBSTONE) {\n\t\t\t\tif (pr == NULL) {\n\t\t\t\t\tpr = cursor;\n\t\t\t\t\t*n_probes = probes;\n\n\t\t\t\t\tif (behavior == CK_HS_PROBE_TOMBSTONE) {\n\t\t\t\t\t\tk = CK_HS_EMPTY;\n\t\t\t\t\t\tgoto leave;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n#ifdef CK_HS_PP\n\t\t\tif (hs->mode & CK_HS_MODE_OBJECT) {\n\t\t\t\tif (((uintptr_t)k >> CK_MD_VMA_BITS) != hv)\n\t\t\t\t\tcontinue;\n\n\t\t\t\tk = CK_HS_VMA(k);\n\t\t\t}\n#endif\n\n\t\t\tif (k == compare)\n\t\t\t\tgoto leave;\n\n\t\t\tif (hs->compare == NULL)\n\t\t\t\tcontinue;\n\n\t\t\tif (hs->compare(k, key) == true)\n\t\t\t\tgoto leave;\n\t\t}\n\n\t\toffset = ck_hs_map_probe_next(map, offset, h, i++, probes);\n\t}\n\nleave:\n\tif (probes > probe_limit) {\n\t\tcursor = NULL;\n\t} else {\n\t\t*object = k;\n\t}\n\n\tif (pr == NULL)\n\t\t*n_probes = probes;\n\n\t*priority = pr;\n\treturn cursor;\n}\n\nstatic inline const void *\nck_hs_marshal(unsigned int mode, const void *key, unsigned long h)\n{\n#ifdef CK_HS_PP\n\tconst void *insert;\n\n\tif (mode & CK_HS_MODE_OBJECT) {\n\t\tinsert = (void *)((uintptr_t)CK_HS_VMA(key) |\n\t\t    ((h >> 25) << CK_MD_VMA_BITS));\n\t} else {\n\t\tinsert = key;\n\t}\n\n\treturn insert;\n#else\n\t(void)mode;\n\t(void)h;\n\n\treturn key;\n#endif\n}\n\nbool\nck_hs_gc(struct ck_hs *hs, unsigned long cycles, unsigned long seed)\n{\n\tunsigned long size = 0;\n\tunsigned long i;\n\tstruct ck_hs_map *map = hs->map;\n\tunsigned int maximum;\n\tCK_HS_WORD *bounds = NULL;\n\n\tif (map->n_entries == 0) {\n\t\tck_pr_store_uint(&map->probe_maximum, 0);\n\t\tif (map->probe_bound != NULL)\n\t\t\tmemset(map->probe_bound, 0, sizeof(CK_HS_WORD) * map->capacity);\n\n\t\treturn true;\n\t}\n\n\tif (cycles == 0) {\n\t\tmaximum = 0;\n\n\t\tif (map->probe_bound != NULL) {\n\t\t\tsize = sizeof(CK_HS_WORD) * map->capacity;\n\t\t\tbounds = hs->m->malloc(size);\n\t\t\tif (bounds == NULL)\n\t\t\t\treturn false;\n\n\t\t\tmemset(bounds, 0, size);\n\t\t}\n\t} else {\n\t\tmaximum = map->probe_maximum;\n\t}\n\n\tfor (i = 0; i < map->capacity; i++) {\n\t\tconst void **first, *object, **slot, *entry;\n\t\tunsigned long n_probes, offset, h;\n\n\t\tentry = map->entries[(i + seed) & map->mask];\n\t\tif (entry == CK_HS_EMPTY || entry == CK_HS_TOMBSTONE)\n\t\t\tcontinue;\n\n#ifdef CK_HS_PP\n\t\tif (hs->mode & CK_HS_MODE_OBJECT)\n\t\t\tentry = CK_HS_VMA(entry);\n#endif\n\n\t\th = hs->hf(entry, hs->seed);\n\t\toffset = h & map->mask;\n\n\t\tslot = ck_hs_map_probe(hs, map, &n_probes, &first, h, entry, &object,\n\t\t    ck_hs_map_bound_get(map, h), CK_HS_PROBE);\n\n\t\tif (first != NULL) {\n\t\t\tconst void *insert = ck_hs_marshal(hs->mode, entry, h);\n\n\t\t\tck_pr_store_ptr(first, insert);\n\t\t\tck_hs_map_signal(map, h);\n\t\t\tck_pr_store_ptr(slot, CK_HS_TOMBSTONE);\n\t\t}\n\n\t\tif (cycles == 0) {\n\t\t\tif (n_probes > maximum)\n\t\t\t\tmaximum = n_probes;\n\n\t\t\tif (n_probes > CK_HS_WORD_MAX)\n\t\t\t\tn_probes = CK_HS_WORD_MAX;\n\n\t\t\tif (bounds != NULL && n_probes > bounds[offset])\n\t\t\t\tbounds[offset] = n_probes;\n\t\t} else if (--cycles == 0)\n\t\t\tbreak;\n\t}\n\n\t/*\n\t * The following only apply to garbage collection involving\n\t * a full scan of all entries.\n\t */\n\tif (maximum != map->probe_maximum)\n\t\tck_pr_store_uint(&map->probe_maximum, maximum);\n\n\tif (bounds != NULL) {\n\t\tfor (i = 0; i < map->capacity; i++)\n\t\t\tCK_HS_STORE(&map->probe_bound[i], bounds[i]);\n\n\t\ths->m->free(bounds, size, false);\n\t}\n\n\treturn true;\n}\n\nbool\nck_hs_fas(struct ck_hs *hs,\n    unsigned long h,\n    const void *key,\n    void **previous)\n{\n\tconst void **slot, **first, *object, *insert;\n\tstruct ck_hs_map *map = hs->map;\n\tunsigned long n_probes;\n\n\t*previous = NULL;\n\tslot = ck_hs_map_probe(hs, map, &n_probes, &first, h, key, &object,\n\t    ck_hs_map_bound_get(map, h), CK_HS_PROBE);\n\n\t/* Replacement semantics presume existence. */\n\tif (object == NULL)\n\t\treturn false;\n\n\tinsert = ck_hs_marshal(hs->mode, key, h);\n\n\tif (first != NULL) {\n\t\tck_pr_store_ptr(first, insert);\n\t\tck_hs_map_signal(map, h);\n\t\tck_pr_store_ptr(slot, CK_HS_TOMBSTONE);\n\t} else {\n\t\tck_pr_store_ptr(slot, insert);\n\t}\n\n\t*previous = CK_CC_DECONST_PTR(object);\n\treturn true;\n}\n\n/*\n * An apply function takes two arguments. The first argument is a pointer to a\n * pre-existing object. The second argument is a pointer to the fifth argument\n * passed to ck_hs_apply. If a non-NULL pointer is passed to the first argument\n * and the return value of the apply function is NULL, then the pre-existing\n * value is deleted. If the return pointer is the same as the one passed to the\n * apply function then no changes are made to the hash table.  If the first\n * argument is non-NULL and the return pointer is different than that passed to\n * the apply function, then the pre-existing value is replaced. For\n * replacement, it is required that the value itself is identical to the\n * previous value.\n */\nbool\nck_hs_apply(struct ck_hs *hs,\n    unsigned long h,\n    const void *key,\n    ck_hs_apply_fn_t *fn,\n    void *cl)\n{\n\tconst void **slot, **first, *object, *delta, *insert;\n\tunsigned long n_probes;\n\tstruct ck_hs_map *map;\n\nrestart:\n\tmap = hs->map;\n\n\tslot = ck_hs_map_probe(hs, map, &n_probes, &first, h, key, &object, map->probe_limit, CK_HS_PROBE_INSERT);\n\tif (slot == NULL && first == NULL) {\n\t\tif (ck_hs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\n\t\tgoto restart;\n\t}\n\n\tdelta = fn(CK_CC_DECONST_PTR(object), cl);\n\tif (delta == NULL) {\n\t\t/*\n\t\t * The apply function has requested deletion. If the object doesn't exist,\n\t\t * then exit early.\n\t\t */\n\t\tif (CK_CC_UNLIKELY(object == NULL))\n\t\t\treturn true;\n\n\t\t/* Otherwise, mark slot as deleted. */\n\t\tck_pr_store_ptr(slot, CK_HS_TOMBSTONE);\n\t\tmap->n_entries--;\n\t\tmap->tombstones++;\n\t\treturn true;\n\t}\n\n\t/* The apply function has not requested hash set modification so exit early. */\n\tif (delta == object)\n\t\treturn true;\n\n\t/* A modification or insertion has been requested. */\n\tck_hs_map_bound_set(map, h, n_probes);\n\n\tinsert = ck_hs_marshal(hs->mode, delta, h);\n\tif (first != NULL) {\n\t\t/*\n\t\t * This follows the same semantics as ck_hs_set, please refer to that\n\t\t * function for documentation.\n\t\t */\n\t\tck_pr_store_ptr(first, insert);\n\n\t\tif (object != NULL) {\n\t\t\tck_hs_map_signal(map, h);\n\t\t\tck_pr_store_ptr(slot, CK_HS_TOMBSTONE);\n\t\t}\n\t} else {\n\t\t/*\n\t\t * If we are storing into same slot, then atomic store is sufficient\n\t\t * for replacement.\n\t\t */\n\t\tck_pr_store_ptr(slot, insert);\n\t}\n\n\tif (object == NULL)\n\t\tck_hs_map_postinsert(hs, map);\n\n\treturn true;\n}\n\nbool\nck_hs_set(struct ck_hs *hs,\n    unsigned long h,\n    const void *key,\n    void **previous)\n{\n\tconst void **slot, **first, *object, *insert;\n\tunsigned long n_probes;\n\tstruct ck_hs_map *map;\n\n\t*previous = NULL;\n\nrestart:\n\tmap = hs->map;\n\n\tslot = ck_hs_map_probe(hs, map, &n_probes, &first, h, key, &object, map->probe_limit, CK_HS_PROBE_INSERT);\n\tif (slot == NULL && first == NULL) {\n\t\tif (ck_hs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\n\t\tgoto restart;\n\t}\n\n\tck_hs_map_bound_set(map, h, n_probes);\n\tinsert = ck_hs_marshal(hs->mode, key, h);\n\n\tif (first != NULL) {\n\t\t/* If an earlier bucket was found, then store entry there. */\n\t\tck_pr_store_ptr(first, insert);\n\n\t\t/*\n\t\t * If a duplicate key was found, then delete it after\n\t\t * signaling concurrent probes to restart. Optionally,\n\t\t * it is possible to install tombstone after grace\n\t\t * period if we can guarantee earlier position of\n\t\t * duplicate key.\n\t\t */\n\t\tif (object != NULL) {\n\t\t\tck_hs_map_signal(map, h);\n\t\t\tck_pr_store_ptr(slot, CK_HS_TOMBSTONE);\n\t\t}\n\t} else {\n\t\t/*\n\t\t * If we are storing into same slot, then atomic store is sufficient\n\t\t * for replacement.\n\t\t */\n\t\tck_pr_store_ptr(slot, insert);\n\t}\n\n\tif (object == NULL)\n\t\tck_hs_map_postinsert(hs, map);\n\n\t*previous = CK_CC_DECONST_PTR(object);\n\treturn true;\n}\n\nCK_CC_INLINE static bool\nck_hs_put_internal(struct ck_hs *hs,\n    unsigned long h,\n    const void *key,\n    enum ck_hs_probe_behavior behavior)\n{\n\tconst void **slot, **first, *object, *insert;\n\tunsigned long n_probes;\n\tstruct ck_hs_map *map;\n\nrestart:\n\tmap = hs->map;\n\n\tslot = ck_hs_map_probe(hs, map, &n_probes, &first, h, key, &object,\n\t    map->probe_limit, behavior);\n\n\tif (slot == NULL && first == NULL) {\n\t\tif (ck_hs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\n\t\tgoto restart;\n\t}\n\n\t/* Fail operation if a match was found. */\n\tif (object != NULL)\n\t\treturn false;\n\n\tck_hs_map_bound_set(map, h, n_probes);\n\tinsert = ck_hs_marshal(hs->mode, key, h);\n\n\tif (first != NULL) {\n\t\t/* Insert key into first bucket in probe sequence. */\n\t\tck_pr_store_ptr(first, insert);\n\t} else {\n\t\t/* An empty slot was found. */\n\t\tck_pr_store_ptr(slot, insert);\n\t}\n\n\tck_hs_map_postinsert(hs, map);\n\treturn true;\n}\n\nbool\nck_hs_put(struct ck_hs *hs,\n    unsigned long h,\n    const void *key)\n{\n\n\treturn ck_hs_put_internal(hs, h, key, CK_HS_PROBE_INSERT);\n}\n\nbool\nck_hs_put_unique(struct ck_hs *hs,\n    unsigned long h,\n    const void *key)\n{\n\n\treturn ck_hs_put_internal(hs, h, key, CK_HS_PROBE_TOMBSTONE);\n}\n\nvoid *\nck_hs_get(struct ck_hs *hs,\n    unsigned long h,\n    const void *key)\n{\n\tconst void **first, *object;\n\tstruct ck_hs_map *map;\n\tunsigned long n_probes;\n\tunsigned int g, g_p, probe;\n\tunsigned int *generation;\n\n\tdo {\n\t\tmap = ck_pr_load_ptr(&hs->map);\n\t\tgeneration = &map->generation[h & CK_HS_G_MASK];\n\t\tg = ck_pr_load_uint(generation);\n\t\tprobe  = ck_hs_map_bound_get(map, h);\n\t\tck_pr_fence_load();\n\n\t\tck_hs_map_probe(hs, map, &n_probes, &first, h, key, &object, probe, CK_HS_PROBE);\n\n\t\tck_pr_fence_load();\n\t\tg_p = ck_pr_load_uint(generation);\n\t} while (g != g_p);\n\n\treturn CK_CC_DECONST_PTR(object);\n}\n\nvoid *\nck_hs_remove(struct ck_hs *hs,\n    unsigned long h,\n    const void *key)\n{\n\tconst void **slot, **first, *object;\n\tstruct ck_hs_map *map = hs->map;\n\tunsigned long n_probes;\n\n\tslot = ck_hs_map_probe(hs, map, &n_probes, &first, h, key, &object,\n\t    ck_hs_map_bound_get(map, h), CK_HS_PROBE);\n\tif (object == NULL)\n\t\treturn NULL;\n\n\tck_pr_store_ptr(slot, CK_HS_TOMBSTONE);\n\tmap->n_entries--;\n\tmap->tombstones++;\n\treturn CK_CC_DECONST_PTR(object);\n}\n\nbool\nck_hs_move(struct ck_hs *hs,\n    struct ck_hs *source,\n    ck_hs_hash_cb_t *hf,\n    ck_hs_compare_cb_t *compare,\n    struct ck_malloc *m)\n{\n\n\tif (m == NULL || m->malloc == NULL || m->free == NULL || hf == NULL)\n\t\treturn false;\n\n\ths->mode = source->mode;\n\ths->seed = source->seed;\n\ths->map = source->map;\n\ths->m = m;\n\ths->hf = hf;\n\ths->compare = compare;\n\treturn true;\n}\n\nbool\nck_hs_init(struct ck_hs *hs,\n    unsigned int mode,\n    ck_hs_hash_cb_t *hf,\n    ck_hs_compare_cb_t *compare,\n    struct ck_malloc *m,\n    unsigned long n_entries,\n    unsigned long seed)\n{\n\n\tif (m == NULL || m->malloc == NULL || m->free == NULL || hf == NULL)\n\t\treturn false;\n\n\ths->m = m;\n\ths->mode = mode;\n\ths->seed = seed;\n\ths->hf = hf;\n\ths->compare = compare;\n\n\ths->map = ck_hs_map_create(hs, n_entries);\n\treturn hs->map != NULL;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_ht.c",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#define CK_HT_IM\n#include <ck_ht.h>\n\n/*\n * This implementation borrows several techniques from Josh Dybnis's\n * nbds library which can be found at http://code.google.com/p/nbds\n *\n * This release currently only includes support for 64-bit platforms.\n * We can address 32-bit platforms in a future release.\n */\n#include <ck_cc.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_string.h>\n\n#include \"ck_ht_hash.h\"\n#include \"ck_internal.h\"\n\n#ifndef CK_HT_BUCKET_LENGTH\n\n#ifdef CK_HT_PP\n#define CK_HT_BUCKET_SHIFT 2ULL\n#else\n#define CK_HT_BUCKET_SHIFT 1ULL\n#endif\n\n#define CK_HT_BUCKET_LENGTH (1U << CK_HT_BUCKET_SHIFT)\n#define CK_HT_BUCKET_MASK (CK_HT_BUCKET_LENGTH - 1)\n#endif\n\n#ifndef CK_HT_PROBE_DEFAULT\n#define CK_HT_PROBE_DEFAULT 64ULL\n#endif\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_STORE_8)\n#define CK_HT_WORD\t    uint8_t\n#define CK_HT_WORD_MAX\t    UINT8_MAX\n#define CK_HT_STORE(x, y)   ck_pr_store_8(x, y)\n#define CK_HT_LOAD(x)\t    ck_pr_load_8(x)\n#elif defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_STORE_16)\n#define CK_HT_WORD\t    uint16_t\n#define CK_HT_WORD_MAX\t    UINT16_MAX\n#define CK_HT_STORE(x, y)   ck_pr_store_16(x, y)\n#define CK_HT_LOAD(x)\t    ck_pr_load_16(x)\n#elif defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_STORE_32)\n#define CK_HT_WORD\t    uint32_t\n#define CK_HT_WORD_MAX\t    UINT32_MAX\n#define CK_HT_STORE(x, y)   ck_pr_store_32(x, y)\n#define CK_HT_LOAD(x)\t    ck_pr_load_32(x)\n#else\n#error \"ck_ht is not supported on your platform.\"\n#endif\n\nstruct ck_ht_map {\n\tunsigned int mode;\n\tCK_HT_TYPE deletions;\n\tCK_HT_TYPE probe_maximum;\n\tCK_HT_TYPE probe_length;\n\tCK_HT_TYPE probe_limit;\n\tCK_HT_TYPE size;\n\tCK_HT_TYPE n_entries;\n\tCK_HT_TYPE mask;\n\tCK_HT_TYPE capacity;\n\tCK_HT_TYPE step;\n\tCK_HT_WORD *probe_bound;\n\tstruct ck_ht_entry *entries;\n};\n\nvoid\nck_ht_stat(struct ck_ht *table,\n    struct ck_ht_stat *st)\n{\n\tstruct ck_ht_map *map = table->map;\n\n\tst->n_entries = map->n_entries;\n\tst->probe_maximum = map->probe_maximum;\n\treturn;\n}\n\nvoid\nck_ht_hash(struct ck_ht_hash *h,\n    struct ck_ht *table,\n    const void *key,\n    uint16_t key_length)\n{\n\n\ttable->h(h, key, key_length, table->seed);\n\treturn;\n}\n\nvoid\nck_ht_hash_direct(struct ck_ht_hash *h,\n    struct ck_ht *table,\n    uintptr_t key)\n{\n\n\tck_ht_hash(h, table, &key, sizeof(key));\n\treturn;\n}\n\nstatic void\nck_ht_hash_wrapper(struct ck_ht_hash *h,\n    const void *key,\n    size_t length,\n    uint64_t seed)\n{\n\n\th->value = (unsigned long)MurmurHash64A(key, length, seed);\n\treturn;\n}\n\nstatic struct ck_ht_map *\nck_ht_map_create(struct ck_ht *table, CK_HT_TYPE entries)\n{\n\tstruct ck_ht_map *map;\n\tCK_HT_TYPE size;\n\tuintptr_t prefix;\n\tuint32_t n_entries;\n\n\tn_entries = ck_internal_power_2(entries);\n\tif (n_entries < CK_HT_BUCKET_LENGTH)\n\t\tn_entries = CK_HT_BUCKET_LENGTH;\n\n\tsize = sizeof(struct ck_ht_map) +\n\t\t   (sizeof(struct ck_ht_entry) * n_entries + CK_MD_CACHELINE - 1);\n\n\tif (table->mode & CK_HT_WORKLOAD_DELETE) {\n\t\tprefix = sizeof(CK_HT_WORD) * n_entries;\n\t\tsize += prefix;\n\t} else {\n\t\tprefix = 0;\n\t}\n\n\tmap = table->m->malloc(size);\n\tif (map == NULL)\n\t\treturn NULL;\n\n\tmap->mode = table->mode;\n\tmap->size = size;\n\tmap->probe_limit = ck_internal_max_64(n_entries >>\n\t    (CK_HT_BUCKET_SHIFT + 2), CK_HT_PROBE_DEFAULT);\n\n\tmap->deletions = 0;\n\tmap->probe_maximum = 0;\n\tmap->capacity = n_entries;\n\tmap->step = ck_internal_bsf_64(map->capacity);\n\tmap->mask = map->capacity - 1;\n\tmap->n_entries = 0;\n\tmap->entries = (struct ck_ht_entry *)(((uintptr_t)&map[1] + prefix +\n\t    CK_MD_CACHELINE - 1) & ~(CK_MD_CACHELINE - 1));\n\n\tif (table->mode & CK_HT_WORKLOAD_DELETE) {\n\t\tmap->probe_bound = (CK_HT_WORD *)&map[1];\n\t\tmemset(map->probe_bound, 0, prefix);\n\t} else {\n\t\tmap->probe_bound = NULL;\n\t}\n\n\tmemset(map->entries, 0, sizeof(struct ck_ht_entry) * n_entries);\n\tck_pr_fence_store();\n\treturn map;\n}\n\nstatic inline void\nck_ht_map_bound_set(struct ck_ht_map *m,\n    struct ck_ht_hash h,\n    CK_HT_TYPE n_probes)\n{\n\tCK_HT_TYPE offset = h.value & m->mask;\n\n\tif (n_probes > m->probe_maximum)\n\t\tCK_HT_TYPE_STORE(&m->probe_maximum, n_probes);\n\n\tif (m->probe_bound != NULL && m->probe_bound[offset] < n_probes) {\n\t\tif (n_probes >= CK_HT_WORD_MAX)\n\t\t\tn_probes = CK_HT_WORD_MAX;\n\n\t\tCK_HT_STORE(&m->probe_bound[offset], n_probes);\n\t\tck_pr_fence_store();\n\t}\n\n\treturn;\n}\n\nstatic inline CK_HT_TYPE\nck_ht_map_bound_get(struct ck_ht_map *m, struct ck_ht_hash h)\n{\n\tCK_HT_TYPE offset = h.value & m->mask;\n\tCK_HT_TYPE r = CK_HT_WORD_MAX;\n\n\tif (m->probe_bound != NULL) {\n\t\tr = CK_HT_LOAD(&m->probe_bound[offset]);\n\t\tif (r == CK_HT_WORD_MAX)\n\t\t\tr = CK_HT_TYPE_LOAD(&m->probe_maximum);\n\t} else {\n\t\tr = CK_HT_TYPE_LOAD(&m->probe_maximum);\n\t}\n\n\treturn r;\n}\n\nstatic void\nck_ht_map_destroy(struct ck_malloc *m, struct ck_ht_map *map, bool defer)\n{\n\n\tm->free(map, map->size, defer);\n\treturn;\n}\n\nstatic inline size_t\nck_ht_map_probe_next(struct ck_ht_map *map, size_t offset, ck_ht_hash_t h, size_t probes)\n{\n\tck_ht_hash_t r;\n\tsize_t stride;\n\tunsigned long level = (unsigned long)probes >> CK_HT_BUCKET_SHIFT;\n\n\tr.value = (h.value >> map->step) >> level;\n\tstride = (r.value & ~CK_HT_BUCKET_MASK) << 1\n\t\t     | (r.value & CK_HT_BUCKET_MASK);\n\n\treturn (offset + level +\n\t    (stride | CK_HT_BUCKET_LENGTH)) & map->mask;\n}\n\nbool\nck_ht_init(struct ck_ht *table,\n    unsigned int mode,\n    ck_ht_hash_cb_t *h,\n    struct ck_malloc *m,\n    CK_HT_TYPE entries,\n    uint64_t seed)\n{\n\n\tif (m == NULL || m->malloc == NULL || m->free == NULL)\n\t\treturn false;\n\n\ttable->m = m;\n\ttable->mode = mode;\n\ttable->seed = seed;\n\n\tif (h == NULL) {\n\t\ttable->h = ck_ht_hash_wrapper;\n\t} else {\n\t\ttable->h = h;\n\t}\n\n\ttable->map = ck_ht_map_create(table, entries);\n\treturn table->map != NULL;\n}\n\nstatic struct ck_ht_entry *\nck_ht_map_probe_wr(struct ck_ht_map *map,\n    ck_ht_hash_t h,\n    ck_ht_entry_t *snapshot,\n    ck_ht_entry_t **available,\n    const void *key,\n    uint16_t key_length,\n    CK_HT_TYPE *probe_limit,\n    CK_HT_TYPE *probe_wr)\n{\n\tstruct ck_ht_entry *bucket, *cursor;\n\tstruct ck_ht_entry *first = NULL;\n\tsize_t offset, i, j;\n\tCK_HT_TYPE probes = 0;\n\tCK_HT_TYPE limit;\n\n\tif (probe_limit == NULL) {\n\t\tlimit = ck_ht_map_bound_get(map, h);\n\t} else {\n\t\tlimit = CK_HT_TYPE_MAX;\n\t}\n\n\toffset = h.value & map->mask;\n\tfor (i = 0; i < map->probe_limit; i++) {\n\t\t/*\n\t\t * Probe on a complete cache line first. Scan forward and wrap around to\n\t\t * the beginning of the cache line. Only when the complete cache line has\n\t\t * been scanned do we move on to the next row.\n\t\t */\n\t\tbucket = (void *)((uintptr_t)(map->entries + offset) &\n\t\t\t     ~(CK_MD_CACHELINE - 1));\n\n\t\tfor (j = 0; j < CK_HT_BUCKET_LENGTH; j++) {\n\t\t\tuint16_t k;\n\n\t\t\tif (probes++ > limit)\n\t\t\t\tbreak;\n\n\t\t\tcursor = bucket + ((j + offset) & (CK_HT_BUCKET_LENGTH - 1));\n\n\t\t\t/*\n\t\t\t * It is probably worth it to encapsulate probe state\n\t\t\t * in order to prevent a complete reprobe sequence in\n\t\t\t * the case of intermittent writers.\n\t\t\t */\n\t\t\tif (cursor->key == CK_HT_KEY_TOMBSTONE) {\n\t\t\t\tif (first == NULL) {\n\t\t\t\t\tfirst = cursor;\n\t\t\t\t\t*probe_wr = probes;\n\t\t\t\t}\n\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (cursor->key == CK_HT_KEY_EMPTY)\n\t\t\t\tgoto leave;\n\n\t\t\tif (cursor->key == (uintptr_t)key)\n\t\t\t\tgoto leave;\n\n\t\t\tif (map->mode & CK_HT_MODE_BYTESTRING) {\n\t\t\t\tvoid *pointer;\n\n\t\t\t\t/*\n\t\t\t\t * Check memoized portion of hash value before\n\t\t\t\t * expensive full-length comparison.\n\t\t\t\t */\n\t\t\t\tk = ck_ht_entry_key_length(cursor);\n\t\t\t\tif (k != key_length)\n\t\t\t\t\tcontinue;\n\n#ifdef CK_HT_PP\n\t\t\t\tif ((cursor->value >> CK_MD_VMA_BITS) != ((h.value >> 32) & CK_HT_KEY_MASK))\n\t\t\t\t\tcontinue;\n#else\n\t\t\t\tif (cursor->hash != h.value)\n\t\t\t\t\tcontinue;\n#endif\n\n\t\t\t\tpointer = ck_ht_entry_key(cursor);\n\t\t\t\tif (memcmp(pointer, key, key_length) == 0)\n\t\t\t\t\tgoto leave;\n\t\t\t}\n\t\t}\n\n\t\toffset = ck_ht_map_probe_next(map, offset, h, probes);\n\t}\n\n\tcursor = NULL;\n\nleave:\n\tif (probe_limit != NULL) {\n\t\t*probe_limit = probes;\n\t} else if (first == NULL) {\n\t\t*probe_wr = probes;\n\t}\n\n\t*available = first;\n\n\tif (cursor != NULL) {\n\t\t*snapshot = *cursor;\n\t}\n\n\treturn cursor;\n}\n\nbool\nck_ht_gc(struct ck_ht *ht, unsigned long cycles, unsigned long seed)\n{\n\tCK_HT_WORD *bounds = NULL;\n\tstruct ck_ht_map *map = ht->map;\n\tCK_HT_TYPE maximum, i;\n\tCK_HT_TYPE size = 0;\n\n\tif (map->n_entries == 0) {\n\t\tCK_HT_TYPE_STORE(&map->probe_maximum, 0);\n\t\tif (map->probe_bound != NULL)\n\t\t\tmemset(map->probe_bound, 0, sizeof(CK_HT_WORD) * map->capacity);\n\n\t\treturn true;\n\t}\n\n\tif (cycles == 0) {\n\t\tmaximum = 0;\n\n\t\tif (map->probe_bound != NULL) {\n\t\t\tsize = sizeof(CK_HT_WORD) * map->capacity;\n\t\t\tbounds = ht->m->malloc(size);\n\t\t\tif (bounds == NULL)\n\t\t\t\treturn false;\n\n\t\t\tmemset(bounds, 0, size);\n\t\t}\n\t} else {\n\t\tmaximum = map->probe_maximum;\n\t}\n\n\tfor (i = 0; i < map->capacity; i++) {\n\t\tstruct ck_ht_entry *entry, *priority, snapshot;\n\t\tstruct ck_ht_hash h;\n\t\tCK_HT_TYPE probes_wr;\n\t\tCK_HT_TYPE offset;\n\n\t\tentry = &map->entries[(i + seed) & map->mask];\n\t\tif (entry->key == CK_HT_KEY_EMPTY ||\n\t\t    entry->key == CK_HT_KEY_TOMBSTONE) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (ht->mode & CK_HT_MODE_BYTESTRING) {\n#ifndef CK_HT_PP\n\t\t\th.value = entry->hash;\n#else\n\t\t\tht->h(&h, ck_ht_entry_key(entry), ck_ht_entry_key_length(entry),\n\t\t\t    ht->seed);\n#endif\n\t\t\tentry = ck_ht_map_probe_wr(map, h, &snapshot, &priority,\n\t\t\t    ck_ht_entry_key(entry),\n\t\t\t    ck_ht_entry_key_length(entry),\n\t\t\t    NULL, &probes_wr);\n\t\t} else {\n#ifndef CK_HT_PP\n\t\t\th.value = entry->hash;\n#else\n\t\t\tht->h(&h, &entry->key, sizeof(entry->key), ht->seed);\n#endif\n\t\t\tentry = ck_ht_map_probe_wr(map, h, &snapshot, &priority,\n\t\t\t    (void *)entry->key,\n\t\t\t    sizeof(entry->key),\n\t\t\t    NULL, &probes_wr);\n\t\t}\n\n\t\toffset = h.value & map->mask;\n\n\t\tif (priority != NULL) {\n\t\t\tCK_HT_TYPE_STORE(&map->deletions, map->deletions + 1);\n\t\t\tck_pr_fence_store();\n#ifndef CK_HT_PP\n\t\t\tCK_HT_TYPE_STORE(&priority->key_length, entry->key_length);\n\t\t\tCK_HT_TYPE_STORE(&priority->hash, entry->hash);\n#endif\n\t\t\tck_pr_store_ptr_unsafe(&priority->value, (void *)entry->value);\n\t\t\tck_pr_fence_store();\n\t\t\tck_pr_store_ptr_unsafe(&priority->key, (void *)entry->key);\n\t\t\tck_pr_fence_store();\n\t\t\tCK_HT_TYPE_STORE(&map->deletions, map->deletions + 1);\n\t\t\tck_pr_fence_store();\n\t\t\tck_pr_store_ptr_unsafe(&entry->key, (void *)CK_HT_KEY_TOMBSTONE);\n\t\t\tck_pr_fence_store();\n\t\t}\n\n\t\tif (cycles == 0) {\n\t\t\tif (probes_wr > maximum)\n\t\t\t\tmaximum = probes_wr;\n\n\t\t\tif (probes_wr >= CK_HT_WORD_MAX)\n\t\t\t\tprobes_wr = CK_HT_WORD_MAX;\n\n\t\t\tif (bounds != NULL && probes_wr > bounds[offset])\n\t\t\t\tbounds[offset] = probes_wr;\n\t\t} else if (--cycles == 0)\n\t\t\tbreak;\n\t}\n\n\tif (maximum != map->probe_maximum)\n\t\tCK_HT_TYPE_STORE(&map->probe_maximum, maximum);\n\n\tif (bounds != NULL) {\n\t\tfor (i = 0; i < map->capacity; i++)\n\t\t\tCK_HT_STORE(&map->probe_bound[i], bounds[i]);\n\n\t\tht->m->free(bounds, size, false);\n\t}\n\n\treturn true;\n}\n\nstatic struct ck_ht_entry *\nck_ht_map_probe_rd(struct ck_ht_map *map,\n    ck_ht_hash_t h,\n    ck_ht_entry_t *snapshot,\n    const void *key,\n    uint16_t key_length)\n{\n\tstruct ck_ht_entry *bucket, *cursor;\n\tsize_t offset, i, j;\n\tCK_HT_TYPE probes = 0;\n\tCK_HT_TYPE probe_maximum;\n\n#ifndef CK_HT_PP\n\tCK_HT_TYPE d = 0;\n\tCK_HT_TYPE d_prime = 0;\nretry:\n#endif\n\n\tprobe_maximum = ck_ht_map_bound_get(map, h);\n\toffset = h.value & map->mask;\n\n\tfor (i = 0; i < map->probe_limit; i++) {\n\t\t/*\n\t\t * Probe on a complete cache line first. Scan forward and wrap around to\n\t\t * the beginning of the cache line. Only when the complete cache line has\n\t\t * been scanned do we move on to the next row.\n\t\t */\n\t\tbucket = (void *)((uintptr_t)(map->entries + offset) &\n\t\t\t     ~(CK_MD_CACHELINE - 1));\n\n\t\tfor (j = 0; j < CK_HT_BUCKET_LENGTH; j++) {\n\t\t\tuint16_t k;\n\n\t\t\tif (probes++ > probe_maximum)\n\t\t\t\treturn NULL;\n\n\t\t\tcursor = bucket + ((j + offset) & (CK_HT_BUCKET_LENGTH - 1));\n\n#ifdef CK_HT_PP\n\t\t\tsnapshot->key = (uintptr_t)ck_pr_load_ptr(&cursor->key);\n\t\t\tck_pr_fence_load();\n\t\t\tsnapshot->value = (uintptr_t)ck_pr_load_ptr(&cursor->value);\n#else\n\t\t\td = CK_HT_TYPE_LOAD(&map->deletions);\n\t\t\tsnapshot->key = (uintptr_t)ck_pr_load_ptr(&cursor->key);\n\t\t\tck_pr_fence_load();\n\t\t\tsnapshot->key_length = CK_HT_TYPE_LOAD(&cursor->key_length);\n\t\t\tsnapshot->hash = CK_HT_TYPE_LOAD(&cursor->hash);\n\t\t\tsnapshot->value = (uintptr_t)ck_pr_load_ptr(&cursor->value);\n#endif\n\n\t\t\t/*\n\t\t\t * It is probably worth it to encapsulate probe state\n\t\t\t * in order to prevent a complete reprobe sequence in\n\t\t\t * the case of intermittent writers.\n\t\t\t */\n\t\t\tif (snapshot->key == CK_HT_KEY_TOMBSTONE)\n\t\t\t\tcontinue;\n\n\t\t\tif (snapshot->key == CK_HT_KEY_EMPTY)\n\t\t\t\tgoto leave;\n\n\t\t\tif (snapshot->key == (uintptr_t)key)\n\t\t\t\tgoto leave;\n\n\t\t\tif (map->mode & CK_HT_MODE_BYTESTRING) {\n\t\t\t\tvoid *pointer;\n\n\t\t\t\t/*\n\t\t\t\t * Check memoized portion of hash value before\n\t\t\t\t * expensive full-length comparison.\n\t\t\t\t */\n\t\t\t\tk = ck_ht_entry_key_length(snapshot);\n\t\t\t\tif (k != key_length)\n\t\t\t\t\tcontinue;\n#ifdef CK_HT_PP\n\t\t\t\tif ((snapshot->value >> CK_MD_VMA_BITS) != ((h.value >> 32) & CK_HT_KEY_MASK))\n\t\t\t\t\tcontinue;\n#else\n\t\t\t\tif (snapshot->hash != h.value)\n\t\t\t\t\tcontinue;\n\n\t\t\t\td_prime = CK_HT_TYPE_LOAD(&map->deletions);\n\n\t\t\t\t/*\n\t\t\t\t * It is possible that the slot was\n\t\t\t\t * replaced, initiate a re-probe.\n\t\t\t\t */\n\t\t\t\tif (d != d_prime)\n\t\t\t\t\tgoto retry;\n#endif\n\n\t\t\t\tpointer = ck_ht_entry_key(snapshot);\n\t\t\t\tif (memcmp(pointer, key, key_length) == 0)\n\t\t\t\t\tgoto leave;\n\t\t\t}\n\t\t}\n\n\t\toffset = ck_ht_map_probe_next(map, offset, h, probes);\n\t}\n\n\treturn NULL;\n\nleave:\n\treturn cursor;\n}\n\nCK_HT_TYPE\nck_ht_count(struct ck_ht *table)\n{\n\tstruct ck_ht_map *map = ck_pr_load_ptr(&table->map);\n\n\treturn CK_HT_TYPE_LOAD(&map->n_entries);\n}\n\nbool\nck_ht_next(struct ck_ht *table,\n    struct ck_ht_iterator *i,\n    struct ck_ht_entry **entry)\n{\n\tstruct ck_ht_map *map = table->map;\n\tuintptr_t key;\n\n\tif (i->offset >= map->capacity)\n\t\treturn false;\n\n\tdo {\n\t\tkey = map->entries[i->offset].key;\n\t\tif (key != CK_HT_KEY_EMPTY && key != CK_HT_KEY_TOMBSTONE)\n\t\t\tbreak;\n\t} while (++i->offset < map->capacity);\n\n\tif (i->offset >= map->capacity)\n\t\treturn false;\n\n\t*entry = map->entries + i->offset++;\n\treturn true;\n}\n\nbool\nck_ht_reset_size_spmc(struct ck_ht *table, CK_HT_TYPE size)\n{\n\tstruct ck_ht_map *map, *update;\n\n\tmap = table->map;\n\tupdate = ck_ht_map_create(table, size);\n\tif (update == NULL)\n\t\treturn false;\n\n\tck_pr_store_ptr_unsafe(&table->map, update);\n\tck_ht_map_destroy(table->m, map, true);\n\treturn true;\n}\n\nbool\nck_ht_reset_spmc(struct ck_ht *table)\n{\n\tstruct ck_ht_map *map = table->map;\n\n\treturn ck_ht_reset_size_spmc(table, map->capacity);\n}\n\nbool\nck_ht_grow_spmc(struct ck_ht *table, CK_HT_TYPE capacity)\n{\n\tstruct ck_ht_map *map, *update;\n\tstruct ck_ht_entry *bucket, *previous;\n\tstruct ck_ht_hash h;\n\tsize_t k, i, j, offset;\n\tCK_HT_TYPE probes;\n\nrestart:\n\tmap = table->map;\n\n\tif (map->capacity >= capacity)\n\t\treturn false;\n\n\tupdate = ck_ht_map_create(table, capacity);\n\tif (update == NULL)\n\t\treturn false;\n\n\tfor (k = 0; k < map->capacity; k++) {\n\t\tprevious = &map->entries[k];\n\n\t\tif (previous->key == CK_HT_KEY_EMPTY || previous->key == CK_HT_KEY_TOMBSTONE)\n\t\t\tcontinue;\n\n\t\tif (table->mode & CK_HT_MODE_BYTESTRING) {\n#ifdef CK_HT_PP\n\t\t\tvoid *key;\n\t\t\tuint16_t key_length;\n\n\t\t\tkey = ck_ht_entry_key(previous);\n\t\t\tkey_length = ck_ht_entry_key_length(previous);\n#endif\n\n#ifndef CK_HT_PP\n\t\t\th.value = previous->hash;\n#else\n\t\t\ttable->h(&h, key, key_length, table->seed);\n#endif\n\t\t} else {\n#ifndef CK_HT_PP\n\t\t\th.value = previous->hash;\n#else\n\t\t\ttable->h(&h, &previous->key, sizeof(previous->key), table->seed);\n#endif\n\t\t}\n\n\t\toffset = h.value & update->mask;\n\t\tprobes = 0;\n\n\t\tfor (i = 0; i < update->probe_limit; i++) {\n\t\t\tbucket = (void *)((uintptr_t)(update->entries + offset) & ~(CK_MD_CACHELINE - 1));\n\n\t\t\tfor (j = 0; j < CK_HT_BUCKET_LENGTH; j++) {\n\t\t\t\tstruct ck_ht_entry *cursor = bucket + ((j + offset) & (CK_HT_BUCKET_LENGTH - 1));\n\n\t\t\t\tprobes++;\n\t\t\t\tif (CK_CC_LIKELY(cursor->key == CK_HT_KEY_EMPTY)) {\n\t\t\t\t\t*cursor = *previous;\n\t\t\t\t\tupdate->n_entries++;\n\t\t\t\t\tck_ht_map_bound_set(update, h, probes);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (j < CK_HT_BUCKET_LENGTH)\n\t\t\t\tbreak;\n\n\t\t\toffset = ck_ht_map_probe_next(update, offset, h, probes);\n\t\t}\n\n\t\tif (i == update->probe_limit) {\n\t\t\t/*\n\t\t\t * We have hit the probe limit, the map needs to be even\n\t\t\t * larger.\n\t\t\t */\n\t\t\tck_ht_map_destroy(table->m, update, false);\n\t\t\tcapacity <<= 1;\n\t\t\tgoto restart;\n\t\t}\n\t}\n\n\tck_pr_fence_store();\n\tck_pr_store_ptr_unsafe(&table->map, update);\n\tck_ht_map_destroy(table->m, map, true);\n\treturn true;\n}\n\nbool\nck_ht_remove_spmc(struct ck_ht *table,\n    ck_ht_hash_t h,\n    ck_ht_entry_t *entry)\n{\n\tstruct ck_ht_map *map;\n\tstruct ck_ht_entry *candidate, snapshot;\n\n\tmap = table->map;\n\n\tif (table->mode & CK_HT_MODE_BYTESTRING) {\n\t\tcandidate = ck_ht_map_probe_rd(map, h, &snapshot,\n\t\t    ck_ht_entry_key(entry),\n\t\t    ck_ht_entry_key_length(entry));\n\t} else {\n\t\tcandidate = ck_ht_map_probe_rd(map, h, &snapshot,\n\t\t    (void *)entry->key,\n\t\t    sizeof(entry->key));\n\t}\n\n\t/* No matching entry was found. */\n\tif (candidate == NULL || snapshot.key == CK_HT_KEY_EMPTY)\n\t\treturn false;\n\n\t*entry = snapshot;\n\n\tck_pr_store_ptr_unsafe(&candidate->key, (void *)CK_HT_KEY_TOMBSTONE);\n\tck_pr_fence_store();\n\tCK_HT_TYPE_STORE(&map->n_entries, map->n_entries - 1);\n\treturn true;\n}\n\nbool\nck_ht_get_spmc(struct ck_ht *table,\n    ck_ht_hash_t h,\n    ck_ht_entry_t *entry)\n{\n\tstruct ck_ht_entry *candidate, snapshot;\n\tstruct ck_ht_map *map;\n\tCK_HT_TYPE d, d_prime;\n\nrestart:\n\tmap = ck_pr_load_ptr(&table->map);\n\n\t/*\n\t * Platforms that cannot read key and key_length atomically must reprobe\n\t * on the scan of any single entry.\n\t */\n\td = CK_HT_TYPE_LOAD(&map->deletions);\n\n\tif (table->mode & CK_HT_MODE_BYTESTRING) {\n\t\tcandidate = ck_ht_map_probe_rd(map, h, &snapshot,\n\t\t    ck_ht_entry_key(entry), ck_ht_entry_key_length(entry));\n\t} else {\n\t\tcandidate = ck_ht_map_probe_rd(map, h, &snapshot,\n\t\t    (void *)entry->key, sizeof(entry->key));\n\t}\n\n\td_prime = CK_HT_TYPE_LOAD(&map->deletions);\n\tif (d != d_prime) {\n\t\t/*\n\t\t * It is possible we have read (K, V'). Only valid states are\n\t\t * (K, V), (K', V') and (T, V). Restart load operation in face\n\t\t * of concurrent deletions or replacements.\n\t\t */\n\t\tgoto restart;\n\t}\n\n\tif (candidate == NULL || snapshot.key == CK_HT_KEY_EMPTY)\n\t\treturn false;\n\n\t*entry = snapshot;\n\treturn true;\n}\n\nbool\nck_ht_set_spmc(struct ck_ht *table,\n    ck_ht_hash_t h,\n    ck_ht_entry_t *entry)\n{\n\tstruct ck_ht_entry snapshot, *candidate, *priority;\n\tstruct ck_ht_map *map;\n\tCK_HT_TYPE probes, probes_wr;\n\tbool empty = false;\n\n\tfor (;;) {\n\t\tmap = table->map;\n\n\t\tif (table->mode & CK_HT_MODE_BYTESTRING) {\n\t\t\tcandidate = ck_ht_map_probe_wr(map, h, &snapshot, &priority,\n\t\t\t    ck_ht_entry_key(entry),\n\t\t\t    ck_ht_entry_key_length(entry),\n\t\t\t    &probes, &probes_wr);\n\t\t} else {\n\t\t\tcandidate = ck_ht_map_probe_wr(map, h, &snapshot, &priority,\n\t\t\t    (void *)entry->key,\n\t\t\t    sizeof(entry->key),\n\t\t\t    &probes, &probes_wr);\n\t\t}\n\n\t\tif (priority != NULL) {\n\t\t\tprobes = probes_wr;\n\t\t\tbreak;\n\t\t}\n\n\t\tif (candidate != NULL)\n\t\t\tbreak;\n\n\t\tif (ck_ht_grow_spmc(table, map->capacity << 1) == false)\n\t\t\treturn false;\n\t}\n\n\tif (candidate == NULL) {\n\t\tcandidate = priority;\n\t\tempty = true;\n\t}\n\n\tif (candidate->key != CK_HT_KEY_EMPTY &&\n\t    priority != NULL && candidate != priority) {\n\t\t/*\n\t\t * Entry is moved into another position in probe sequence.\n\t\t * We avoid a state of (K, B) (where [K, B] -> [K', B]) by\n\t\t * guaranteeing a forced reprobe before transitioning from K to\n\t\t * T. (K, B) implies (K, B, D') so we will reprobe successfully\n\t\t * from this transient state.\n\t\t */\n\t\tprobes = probes_wr;\n\n#ifndef CK_HT_PP\n\t\tCK_HT_TYPE_STORE(&priority->key_length, entry->key_length);\n\t\tCK_HT_TYPE_STORE(&priority->hash, entry->hash);\n#endif\n\n\t\t/*\n\t\t * Readers must observe version counter change before they\n\t\t * observe re-use. If they observe re-use, it is at most\n\t\t * a tombstone.\n\t\t */\n\t\tif (priority->value == CK_HT_KEY_TOMBSTONE) {\n\t\t\tCK_HT_TYPE_STORE(&map->deletions, map->deletions + 1);\n\t\t\tck_pr_fence_store();\n\t\t}\n\n\t\tck_pr_store_ptr_unsafe(&priority->value, (void *)entry->value);\n\t\tck_pr_fence_store();\n\t\tck_pr_store_ptr_unsafe(&priority->key, (void *)entry->key);\n\t\tck_pr_fence_store();\n\n\t\t/*\n\t\t * Make sure that readers who observe the tombstone would\n\t\t * also observe counter change.\n\t\t */\n\t\tCK_HT_TYPE_STORE(&map->deletions, map->deletions + 1);\n\t\tck_pr_fence_store();\n\n\t\tck_pr_store_ptr_unsafe(&candidate->key, (void *)CK_HT_KEY_TOMBSTONE);\n\t\tck_pr_fence_store();\n\t} else {\n\t\t/*\n\t\t * In this case we are inserting a new entry or replacing\n\t\t * an existing entry. Yes, this can be combined into above branch,\n\t\t * but isn't because you are actually looking at dying code\n\t\t * (ck_ht is effectively deprecated and is being replaced soon).\n\t\t */\n\t\tbool replace = candidate->key != CK_HT_KEY_EMPTY &&\n\t\t    candidate->key != CK_HT_KEY_TOMBSTONE;\n\n\t\tif (priority != NULL) {\n\t\t\tif (priority->key == CK_HT_KEY_TOMBSTONE) {\n\t\t\t\tCK_HT_TYPE_STORE(&map->deletions, map->deletions + 1);\n\t\t\t\tck_pr_fence_store();\n\t\t\t}\n\n\t\t\tcandidate = priority;\n\t\t\tprobes = probes_wr;\n\t\t}\n\n#ifdef CK_HT_PP\n\t\tck_pr_store_ptr_unsafe(&candidate->value, (void *)entry->value);\n\t\tck_pr_fence_store();\n\t\tck_pr_store_ptr_unsafe(&candidate->key, (void *)entry->key);\n#else\n\t\tCK_HT_TYPE_STORE(&candidate->key_length, entry->key_length);\n\t\tCK_HT_TYPE_STORE(&candidate->hash, entry->hash);\n\t\tck_pr_store_ptr_unsafe(&candidate->value, (void *)entry->value);\n\t\tck_pr_fence_store();\n\t\tck_pr_store_ptr_unsafe(&candidate->key, (void *)entry->key);\n#endif\n\n\t\t/*\n\t\t * If we are insert a new entry then increment number\n\t\t * of entries associated with map.\n\t\t */\n\t\tif (replace == false)\n\t\t\tCK_HT_TYPE_STORE(&map->n_entries, map->n_entries + 1);\n\t}\n\n\tck_ht_map_bound_set(map, h, probes);\n\n\t/* Enforce a load factor of 0.5. */\n\tif (map->n_entries * 2 > map->capacity)\n\t\tck_ht_grow_spmc(table, map->capacity << 1);\n\n\tif (empty == true) {\n\t\tentry->key = CK_HT_KEY_EMPTY;\n\t} else {\n\t\t*entry = snapshot;\n\t}\n\n\treturn true;\n}\n\nbool\nck_ht_put_spmc(struct ck_ht *table,\n    ck_ht_hash_t h,\n    ck_ht_entry_t *entry)\n{\n\tstruct ck_ht_entry snapshot, *candidate, *priority;\n\tstruct ck_ht_map *map;\n\tCK_HT_TYPE probes, probes_wr;\n\n\tfor (;;) {\n\t\tmap = table->map;\n\n\t\tif (table->mode & CK_HT_MODE_BYTESTRING) {\n\t\t\tcandidate = ck_ht_map_probe_wr(map, h, &snapshot, &priority,\n\t\t\t    ck_ht_entry_key(entry),\n\t\t\t    ck_ht_entry_key_length(entry),\n\t\t\t    &probes, &probes_wr);\n\t\t} else {\n\t\t\tcandidate = ck_ht_map_probe_wr(map, h, &snapshot, &priority,\n\t\t\t    (void *)entry->key,\n\t\t\t    sizeof(entry->key),\n\t\t\t    &probes, &probes_wr);\n\t\t}\n\n\t\tif (candidate != NULL || priority != NULL)\n\t\t\tbreak;\n\n\t\tif (ck_ht_grow_spmc(table, map->capacity << 1) == false)\n\t\t\treturn false;\n\t}\n\n\tif (priority != NULL) {\n\t\t/* Version counter is updated before re-use. */\n\t\tCK_HT_TYPE_STORE(&map->deletions, map->deletions + 1);\n\t\tck_pr_fence_store();\n\n\t\t/* Re-use tombstone if one was found. */\n\t\tcandidate = priority;\n\t\tprobes = probes_wr;\n\t} else if (candidate->key != CK_HT_KEY_EMPTY &&\n\t    candidate->key != CK_HT_KEY_TOMBSTONE) {\n\t\t/*\n\t\t * If the snapshot key is non-empty and the value field is not\n\t\t * a tombstone then an identical key was found. As store does\n\t\t * not implement replacement, we will fail.\n\t\t */\n\t\treturn false;\n\t}\n\n\tck_ht_map_bound_set(map, h, probes);\n\n#ifdef CK_HT_PP\n\tck_pr_store_ptr_unsafe(&candidate->value, (void *)entry->value);\n\tck_pr_fence_store();\n\tck_pr_store_ptr_unsafe(&candidate->key, (void *)entry->key);\n#else\n\tCK_HT_TYPE_STORE(&candidate->key_length, entry->key_length);\n\tCK_HT_TYPE_STORE(&candidate->hash, entry->hash);\n\tck_pr_store_ptr_unsafe(&candidate->value, (void *)entry->value);\n\tck_pr_fence_store();\n\tck_pr_store_ptr_unsafe(&candidate->key, (void *)entry->key);\n#endif\n\n\tCK_HT_TYPE_STORE(&map->n_entries, map->n_entries + 1);\n\n\t/* Enforce a load factor of 0.5. */\n\tif (map->n_entries * 2 > map->capacity)\n\t\tck_ht_grow_spmc(table, map->capacity << 1);\n\n\treturn true;\n}\n\nvoid\nck_ht_destroy(struct ck_ht *table)\n{\n\n\tck_ht_map_destroy(table->m, table->map, false);\n\treturn;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_ht_hash.h",
    "content": "/*\n * Copyright 2012-2015 Samy Al Bahra\n * Copyright 2011-2014 AppNexus, Inc.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#ifndef CK_HT_HASH_H\n#define CK_HT_HASH_H\n\n/*\n * This is the Murmur hash written by Austin Appleby.\n */\n\n#include <ck_stdint.h>\n#include <ck_string.h>\n\n//-----------------------------------------------------------------------------\n// MurmurHash3 was written by Austin Appleby, and is placed in the public\n// domain. The author hereby disclaims copyright to this source code.\n\n// Note - The x86 and x64 versions do _not_ produce the same results, as the\n// algorithms are optimized for their respective platforms. You can still\n// compile and run any of them on any platform, but your performance with the\n// non-native version will be less than optimal.\n\n//-----------------------------------------------------------------------------\n// Platform-specific functions and macros\n\n// Microsoft Visual Studio\n\n#if defined(_MSC_VER)\n\n#define FORCE_INLINE    __forceinline\n\n#include <stdlib.h>\n\n#define ROTL32(x,y)     _rotl(x,y)\n#define ROTL64(x,y)     _rotl64(x,y)\n\n#define BIG_CONSTANT(x) (x)\n\n// Other compilers\n\n#else   // defined(_MSC_VER)\n\n#define FORCE_INLINE inline __attribute__((always_inline))\n\nstatic inline uint32_t rotl32 ( uint32_t x, int8_t r )\n{\n  return (x << r) | (x >> (32 - r));\n}\n\nstatic inline uint64_t rotl64 ( uint64_t x, int8_t r )\n{\n  return (x << r) | (x >> (64 - r));\n}\n\n#define ROTL32(x,y)     rotl32(x,y)\n#define ROTL64(x,y)     rotl64(x,y)\n\n#define BIG_CONSTANT(x) (x##LLU)\n\n#endif // !defined(_MSC_VER)\n\n//-----------------------------------------------------------------------------\n// Block read - if your platform needs to do endian-swapping or can only\n// handle aligned reads, do the conversion here\n\nFORCE_INLINE static uint32_t getblock ( const uint32_t * p, int i )\n{\n#ifdef __s390x__\n  uint32_t res;\n\n  __asm__ (\"\tlrv\t%0,%1\\n\"\n\t   : \"=r\" (res) : \"Q\" (p[i]) : \"cc\", \"mem\");\n  return res;\n#else\n  return p[i];\n#endif /* !__s390x__ */\n}\n\n//-----------------------------------------------------------------------------\n// Finalization mix - force all bits of a hash block to avalanche\n\nFORCE_INLINE static uint32_t fmix ( uint32_t h )\n{\n  h ^= h >> 16;\n  h *= 0x85ebca6b;\n  h ^= h >> 13;\n  h *= 0xc2b2ae35;\n  h ^= h >> 16;\n\n  return h;\n}\n\n//-----------------------------------------------------------------------------\n\nstatic inline void MurmurHash3_x86_32 ( const void * key, int len,\n                          uint32_t seed, uint32_t * out )\n{\n  const uint8_t * data = (const uint8_t*)key;\n  const int nblocks = len / 4;\n  int i;\n\n  uint32_t h1 = seed;\n\n  uint32_t c1 = 0xcc9e2d51;\n  uint32_t c2 = 0x1b873593;\n\n  //----------\n  // body\n\n  const uint32_t * blocks = (const uint32_t *)(const void *)(data + nblocks*4);\n\n  for(i = -nblocks; i; i++)\n  {\n    uint32_t k1 = getblock(blocks,i);\n\n    k1 *= c1;\n    k1 = ROTL32(k1,15);\n    k1 *= c2;\n\n    h1 ^= k1;\n    h1 = ROTL32(h1,13);\n    h1 = h1*5+0xe6546b64;\n  }\n\n  //----------\n  // tail\n\n  const uint8_t * tail = (const uint8_t*)(data + nblocks*4);\n\n  uint32_t k1 = 0;\n\n  switch(len & 3)\n  {\n  case 3: k1 ^= tail[2] << 16;\n  /* fall through */\n  case 2: k1 ^= tail[1] << 8;\n  /* fall through */\n  case 1: k1 ^= tail[0];\n          k1 *= c1; k1 = ROTL32(k1,15); k1 *= c2; h1 ^= k1;\n  };\n\n  //----------\n  // finalization\n\n  h1 ^= len;\n\n  h1 = fmix(h1);\n\n  *(uint32_t *)out = h1;\n}\n\nstatic inline uint64_t MurmurHash64A ( const void * key, int len, uint64_t seed )\n{\n  const uint64_t m = BIG_CONSTANT(0xc6a4a7935bd1e995);\n  const int r = 47;\n\n  uint64_t h = seed ^ (len * m);\n\n  const uint64_t * data = (const uint64_t *)key;\n  const uint64_t * end = data + (len/8);\n\n  while(data != end)\n  {\n    uint64_t k;\n\n    if (!((uintptr_t)data & 0x7))\n\t    k = *data++;\n    else {\n\t    memcpy(&k, data, sizeof(k));\n\t    data++;\n    }\n\n    k *= m;\n    k ^= k >> r;\n    k *= m;\n\n    h ^= k;\n    h *= m;\n  }\n\n  const unsigned char * data2 = (const unsigned char*)data;\n\n  switch(len & 7)\n  {\n  case 7: h ^= (uint64_t)(data2[6]) << 48;\n  /* fall through */\n  case 6: h ^= (uint64_t)(data2[5]) << 40;\n  /* fall through */\n  case 5: h ^= (uint64_t)(data2[4]) << 32;\n  /* fall through */\n  case 4: h ^= (uint64_t)(data2[3]) << 24;\n  /* fall through */\n  case 3: h ^= (uint64_t)(data2[2]) << 16;\n  /* fall through */\n  case 2: h ^= (uint64_t)(data2[1]) << 8;\n  /* fall through */\n  case 1: h ^= (uint64_t)(data2[0]);\n          h *= m;\n  };\n\n  h ^= h >> r;\n  h *= m;\n  h ^= h >> r;\n\n  return h;\n}\n\n\n// 64-bit hash for 32-bit platforms\n\nstatic inline uint64_t MurmurHash64B ( const void * key, int len, uint64_t seed )\n{\n  const uint32_t m = 0x5bd1e995;\n  const int r = 24;\n\n  uint32_t h1 = (uint32_t)(seed) ^ len;\n  uint32_t h2 = (uint32_t)(seed >> 32);\n\n  const uint32_t * data = (const uint32_t *)key;\n\n  while(len >= 8)\n  {\n    uint32_t k1 = *data++;\n    k1 *= m; k1 ^= k1 >> r; k1 *= m;\n    h1 *= m; h1 ^= k1;\n    len -= 4;\n\n    uint32_t k2 = *data++;\n    k2 *= m; k2 ^= k2 >> r; k2 *= m;\n    h2 *= m; h2 ^= k2;\n    len -= 4;\n  }\n\n  if(len >= 4)\n  {\n    uint32_t k1 = *data++;\n    k1 *= m; k1 ^= k1 >> r; k1 *= m;\n    h1 *= m; h1 ^= k1;\n    len -= 4;\n  }\n\n  switch(len)\n  {\n  case 3: h2 ^= ((const unsigned char*)data)[2] << 16;\n  /* fall through */\n  case 2: h2 ^= ((const unsigned char*)data)[1] << 8;\n  /* fall through */\n  case 1: h2 ^= ((const unsigned char*)data)[0];\n      h2 *= m;\n  };\n\n  h1 ^= h2 >> 18; h1 *= m;\n  h2 ^= h1 >> 22; h2 *= m;\n  h1 ^= h2 >> 17; h1 *= m;\n  h2 ^= h1 >> 19; h2 *= m;\n\n  uint64_t h = h1;\n\n  h = (h << 32) | h2;\n\n  return h;\n}\n\n#endif /* CK_HT_HASH_H */\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_internal.h",
    "content": "/*\n * Copyright 2011-2015 Samy Al Bahra.\n * Copyright 2011 David Joseph.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n/*\n * Several of these are from: http://graphics.stanford.edu/~seander/bithacks.html\n */\n\n#define CK_INTERNAL_LOG_0 (0xAAAAAAAA)\n#define CK_INTERNAL_LOG_1 (0xCCCCCCCC)\n#define CK_INTERNAL_LOG_2 (0xF0F0F0F0)\n#define CK_INTERNAL_LOG_3 (0xFF00FF00)\n#define CK_INTERNAL_LOG_4 (0xFFFF0000)\n\nCK_CC_INLINE static uint32_t\nck_internal_log(uint32_t v)\n{\n        uint32_t r = (v & CK_INTERNAL_LOG_0) != 0;\n\n\tr |= ((v & CK_INTERNAL_LOG_4) != 0) << 4;\n\tr |= ((v & CK_INTERNAL_LOG_3) != 0) << 3;\n\tr |= ((v & CK_INTERNAL_LOG_2) != 0) << 2;\n\tr |= ((v & CK_INTERNAL_LOG_1) != 0) << 1;\n        return (r);\n}\n\nCK_CC_INLINE static uint32_t\nck_internal_power_2(uint32_t v)\n{\n\n        --v;\n        v |= v >> 1;\n        v |= v >> 2;\n        v |= v >> 4;\n        v |= v >> 8;\n        v |= v >> 16;\n        return (++v);\n}\n\nCK_CC_INLINE static unsigned long\nck_internal_max(unsigned long x, unsigned long y)\n{\n\n\treturn x ^ ((x ^ y) & -(x < y));\n}\n\nCK_CC_INLINE static uint64_t\nck_internal_max_64(uint64_t x, uint64_t y)\n{\n\n\treturn x ^ ((x ^ y) & -(x < y));\n}\n\nCK_CC_INLINE static uint32_t\nck_internal_max_32(uint32_t x, uint32_t y)\n{\n\n\treturn x ^ ((x ^ y) & -(x < y));\n}\n\nCK_CC_INLINE static unsigned long\nck_internal_bsf(unsigned long v)\n{\n#if defined(__GNUC__)\n\treturn __builtin_ffs(v);\n#else\n\tunsigned int i;\n\tconst unsigned int s = sizeof(unsigned long) * 8 - 1;\n\n\tfor (i = 0; i < s; i++) {\n\t\tif (v & (1UL << (s - i)))\n\t\t\treturn sizeof(unsigned long) * 8 - i;\n\t}\n\n\treturn 1;\n#endif /* !__GNUC__ */\n}\n\nCK_CC_INLINE static uint64_t\nck_internal_bsf_64(uint64_t v)\n{\n#if defined(__GNUC__)\n\treturn __builtin_ffs(v);\n#else\n\tunsigned int i;\n\tconst unsigned int s = sizeof(unsigned long) * 8 - 1;\n\n\tfor (i = 0; i < s; i++) {\n\t\tif (v & (1ULL << (63U - i)))\n\t\t\treturn i;\n\t}\n#endif /* !__GNUC__ */\n\n\treturn 1;\n}\n\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/src/ck_rhs.c",
    "content": "/*\n * Copyright 2014-2015 Olivier Houchard.\n * Copyright 2012-2015 Samy Al Bahra.\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n * SUCH DAMAGE.\n */\n\n#include <ck_cc.h>\n#include <ck_rhs.h>\n#include <ck_limits.h>\n#include <ck_md.h>\n#include <ck_pr.h>\n#include <ck_stdint.h>\n#include <ck_stdbool.h>\n#include <ck_string.h>\n\n#include \"ck_internal.h\"\n\n#ifndef CK_RHS_PROBE_L1_SHIFT\n#define CK_RHS_PROBE_L1_SHIFT 3ULL\n#endif /* CK_RHS_PROBE_L1_SHIFT */\n\n#define CK_RHS_PROBE_L1 (1 << CK_RHS_PROBE_L1_SHIFT)\n#define CK_RHS_PROBE_L1_MASK (CK_RHS_PROBE_L1 - 1)\n\n#ifndef CK_RHS_PROBE_L1_DEFAULT\n#define CK_RHS_PROBE_L1_DEFAULT CK_MD_CACHELINE\n#endif\n\n#define CK_RHS_VMA_MASK ((uintptr_t)((1ULL << CK_MD_VMA_BITS) - 1))\n#define CK_RHS_VMA(x)\t\\\n\t((void *)((uintptr_t)(x) & CK_RHS_VMA_MASK))\n\n#define CK_RHS_EMPTY     NULL\n#define CK_RHS_G\t\t(1024)\n#define CK_RHS_G_MASK\t(CK_RHS_G - 1)\n\n#if defined(CK_F_PR_LOAD_8) && defined(CK_F_PR_STORE_8)\n#define CK_RHS_WORD          uint8_t\n#define CK_RHS_WORD_MAX\t    UINT8_MAX\n#define CK_RHS_STORE(x, y)   ck_pr_store_8(x, y)\n#define CK_RHS_LOAD(x)       ck_pr_load_8(x)\n#elif defined(CK_F_PR_LOAD_16) && defined(CK_F_PR_STORE_16)\n#define CK_RHS_WORD          uint16_t\n#define CK_RHS_WORD_MAX\t    UINT16_MAX\n#define CK_RHS_STORE(x, y)   ck_pr_store_16(x, y)\n#define CK_RHS_LOAD(x)       ck_pr_load_16(x)\n#elif defined(CK_F_PR_LOAD_32) && defined(CK_F_PR_STORE_32)\n#define CK_RHS_WORD          uint32_t\n#define CK_RHS_WORD_MAX\t    UINT32_MAX\n#define CK_RHS_STORE(x, y)   ck_pr_store_32(x, y)\n#define CK_RHS_LOAD(x)       ck_pr_load_32(x)\n#else\n#error \"ck_rhs is not supported on your platform.\"\n#endif\n\n#define CK_RHS_MAX_WANTED\t0xffff\n\nenum ck_rhs_probe_behavior {\n\tCK_RHS_PROBE = 0,\t/* Default behavior. */\n\tCK_RHS_PROBE_RH,\t/* Short-circuit if RH slot found. */\n\tCK_RHS_PROBE_INSERT,\t/* Short-circuit on probe bound if tombstone found. */\n\n\tCK_RHS_PROBE_ROBIN_HOOD,/* Look for the first slot available for the entry we are about to replace, only used to internally implement Robin Hood */\n\tCK_RHS_PROBE_NO_RH,\t/* Don't do the RH dance */\n};\nstruct ck_rhs_entry_desc {\n\tunsigned int probes;\n\tunsigned short wanted;\n\tCK_RHS_WORD probe_bound;\n\tbool in_rh;\n\tconst void *entry;\n} CK_CC_ALIGN(16);\n\nstruct ck_rhs_no_entry_desc {\n\tunsigned int probes;\n\tunsigned short wanted;\n\tCK_RHS_WORD probe_bound;\n\tbool in_rh;\n} CK_CC_ALIGN(8);\n\ntypedef long ck_rhs_probe_cb_t(struct ck_rhs *hs,\n    struct ck_rhs_map *map,\n    unsigned long *n_probes,\n    long *priority,\n    unsigned long h,\n    const void *key,\n    const void **object,\n    unsigned long probe_limit,\n    enum ck_rhs_probe_behavior behavior);\n\nstruct ck_rhs_map {\n\tunsigned int generation[CK_RHS_G];\n\tunsigned int probe_maximum;\n\tunsigned long mask;\n\tunsigned long step;\n\tunsigned int probe_limit;\n\tunsigned long n_entries;\n\tunsigned long capacity;\n\tunsigned long size;\n\tunsigned long max_entries;\n\tchar offset_mask;\n\tunion {\n\t\tstruct ck_rhs_entry_desc *descs;\n\t\tstruct ck_rhs_no_entry {\n\t\t\tconst void **entries;\n\t\t\tstruct ck_rhs_no_entry_desc *descs;\n\t\t} no_entries;\n\t} entries;\n\tbool read_mostly;\n\tck_rhs_probe_cb_t *probe_func;\n};\n\nstatic CK_CC_INLINE const void *\nck_rhs_entry(struct ck_rhs_map *map, long offset)\n{\n\n\tif (map->read_mostly)\n\t\treturn (map->entries.no_entries.entries[offset]);\n\telse\n\t\treturn (map->entries.descs[offset].entry);\n}\n\nstatic CK_CC_INLINE const void **\nck_rhs_entry_addr(struct ck_rhs_map *map, long offset)\n{\n\n\tif (map->read_mostly)\n\t\treturn (&map->entries.no_entries.entries[offset]);\n\telse\n\t\treturn (&map->entries.descs[offset].entry);\n}\n\nstatic CK_CC_INLINE struct ck_rhs_entry_desc *\nck_rhs_desc(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\treturn ((struct ck_rhs_entry_desc *)(void *)&map->entries.no_entries.descs[offset]);\n\telse\n\t\treturn (&map->entries.descs[offset]);\n}\n\nstatic CK_CC_INLINE void\nck_rhs_wanted_inc(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\tmap->entries.no_entries.descs[offset].wanted++;\n\telse\n\t\tmap->entries.descs[offset].wanted++;\n}\n\nstatic CK_CC_INLINE unsigned int\nck_rhs_probes(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\treturn (map->entries.no_entries.descs[offset].probes);\n\telse\n\t\treturn (map->entries.descs[offset].probes);\n}\n\nstatic CK_CC_INLINE void\nck_rhs_set_probes(struct ck_rhs_map *map, long offset, unsigned int value)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\tmap->entries.no_entries.descs[offset].probes = value;\n\telse\n\t\tmap->entries.descs[offset].probes = value;\n}\n\nstatic CK_CC_INLINE CK_RHS_WORD\nck_rhs_probe_bound(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\treturn (map->entries.no_entries.descs[offset].probe_bound);\n\telse\n\t\treturn (map->entries.descs[offset].probe_bound);\n}\n\nstatic CK_CC_INLINE CK_RHS_WORD *\nck_rhs_probe_bound_addr(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\treturn (&map->entries.no_entries.descs[offset].probe_bound);\n\telse\n\t\treturn (&map->entries.descs[offset].probe_bound);\n}\n\n\nstatic CK_CC_INLINE bool\nck_rhs_in_rh(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\treturn (map->entries.no_entries.descs[offset].in_rh);\n\telse\n\t\treturn (map->entries.descs[offset].in_rh);\n}\n\nstatic CK_CC_INLINE void\nck_rhs_set_rh(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\tmap->entries.no_entries.descs[offset].in_rh = true;\n\telse\n\t\tmap->entries.descs[offset].in_rh = true;\n}\n\nstatic CK_CC_INLINE void\nck_rhs_unset_rh(struct ck_rhs_map *map, long offset)\n{\n\n\tif (CK_CC_UNLIKELY(map->read_mostly))\n\t\tmap->entries.no_entries.descs[offset].in_rh = false;\n\telse\n\t\tmap->entries.descs[offset].in_rh = false;\n}\n\n\n#define CK_RHS_DEFAULT_LOAD_FACTOR\t50\n\nstatic ck_rhs_probe_cb_t ck_rhs_map_probe;\nstatic ck_rhs_probe_cb_t ck_rhs_map_probe_rm;\n\nbool\nck_rhs_set_load_factor(struct ck_rhs *hs, unsigned int load_factor)\n{\n\tstruct ck_rhs_map *map = hs->map;\n\n\tif (load_factor == 0 || load_factor > 100)\n\t\treturn false;\n\n\ths->load_factor = load_factor;\n\tmap->max_entries = (map->capacity * (unsigned long)hs->load_factor) / 100;\n\twhile (map->n_entries > map->max_entries) {\n\t\tif (ck_rhs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\t\tmap = hs->map;\n\t}\n\treturn true;\n}\n\nvoid\nck_rhs_iterator_init(struct ck_rhs_iterator *iterator)\n{\n\n\titerator->cursor = NULL;\n\titerator->offset = 0;\n\treturn;\n}\n\nbool\nck_rhs_next(struct ck_rhs *hs, struct ck_rhs_iterator *i, void **key)\n{\n\tstruct ck_rhs_map *map = hs->map;\n\tvoid *value;\n\n\tif (i->offset >= map->capacity)\n\t\treturn false;\n\n\tdo {\n\t\tvalue = CK_CC_DECONST_PTR(ck_rhs_entry(map, i->offset));\n\t\tif (value != CK_RHS_EMPTY) {\n#ifdef CK_RHS_PP\n\t\t\tif (hs->mode & CK_RHS_MODE_OBJECT)\n\t\t\t\tvalue = CK_RHS_VMA(value);\n#endif\n\t\t\ti->offset++;\n\t\t\t*key = value;\n\t\t\treturn true;\n\t\t}\n\t} while (++i->offset < map->capacity);\n\n\treturn false;\n}\n\nvoid\nck_rhs_stat(struct ck_rhs *hs, struct ck_rhs_stat *st)\n{\n\tstruct ck_rhs_map *map = hs->map;\n\n\tst->n_entries = map->n_entries;\n\tst->probe_maximum = map->probe_maximum;\n\treturn;\n}\n\nunsigned long\nck_rhs_count(struct ck_rhs *hs)\n{\n\n\treturn hs->map->n_entries;\n}\n\nstatic void\nck_rhs_map_destroy(struct ck_malloc *m, struct ck_rhs_map *map, bool defer)\n{\n\n\tm->free(map, map->size, defer);\n\treturn;\n}\n\nvoid\nck_rhs_destroy(struct ck_rhs *hs)\n{\n\n\tck_rhs_map_destroy(hs->m, hs->map, false);\n\treturn;\n}\n\nstatic struct ck_rhs_map *\nck_rhs_map_create(struct ck_rhs *hs, unsigned long entries)\n{\n\tstruct ck_rhs_map *map;\n\tunsigned long size, n_entries, limit;\n\n\tn_entries = ck_internal_power_2(entries);\n\tif (n_entries < CK_RHS_PROBE_L1)\n\t\tn_entries = CK_RHS_PROBE_L1;\n\n\tif (hs->mode & CK_RHS_MODE_READ_MOSTLY)\n\t\tsize = sizeof(struct ck_rhs_map) +\n\t\t    (sizeof(void *) * n_entries +\n\t\t     sizeof(struct ck_rhs_no_entry_desc) * n_entries +\n\t\t     2 * CK_MD_CACHELINE - 1);\n\telse\n\t\tsize = sizeof(struct ck_rhs_map) +\n\t\t    (sizeof(struct ck_rhs_entry_desc) * n_entries +\n\t\t     CK_MD_CACHELINE - 1);\n\tmap = hs->m->malloc(size);\n\tif (map == NULL)\n\t\treturn NULL;\n\tmap->read_mostly = !!(hs->mode & CK_RHS_MODE_READ_MOSTLY);\n\n\tmap->size = size;\n\t/* We should probably use a more intelligent heuristic for default probe length. */\n\tlimit = ck_internal_max(n_entries >> (CK_RHS_PROBE_L1_SHIFT + 2), CK_RHS_PROBE_L1_DEFAULT);\n\tif (limit > UINT_MAX)\n\t\tlimit = UINT_MAX;\n\n\tmap->probe_limit = (unsigned int)limit;\n\tmap->probe_maximum = 0;\n\tmap->capacity = n_entries;\n\tmap->step = ck_internal_bsf(n_entries);\n\tmap->mask = n_entries - 1;\n\tmap->n_entries = 0;\n\n\tmap->max_entries = (map->capacity * (unsigned long)hs->load_factor) / 100;\n\t/* Align map allocation to cache line. */\n\tif (map->read_mostly) {\n\t\tmap->entries.no_entries.entries = (void *)(((uintptr_t)&map[1] +\n\t\t    CK_MD_CACHELINE - 1) & ~(CK_MD_CACHELINE - 1));\n\t\tmap->entries.no_entries.descs = (void *)(((uintptr_t)map->entries.no_entries.entries + (sizeof(void *) * n_entries) + CK_MD_CACHELINE - 1) &~ (CK_MD_CACHELINE - 1));\n\t\tmemset(map->entries.no_entries.entries, 0,\n\t\t    sizeof(void *) * n_entries);\n\t\tmemset(map->entries.no_entries.descs, 0,\n\t\t    sizeof(struct ck_rhs_no_entry_desc) * n_entries);\n\t\tmap->offset_mask = (CK_MD_CACHELINE / sizeof(void *)) - 1;\n\t\tmap->probe_func = ck_rhs_map_probe_rm;\n\n\t} else {\n\t\tmap->entries.descs = (void *)(((uintptr_t)&map[1] +\n\t\t    CK_MD_CACHELINE - 1) & ~(CK_MD_CACHELINE - 1));\n\t\tmemset(map->entries.descs, 0, sizeof(struct ck_rhs_entry_desc) * n_entries);\n\t\tmap->offset_mask = (CK_MD_CACHELINE / sizeof(struct ck_rhs_entry_desc)) - 1;\n\t\tmap->probe_func = ck_rhs_map_probe;\n\t}\n\tmemset(map->generation, 0, sizeof map->generation);\n\n\t/* Commit entries purge with respect to map publication. */\n\tck_pr_fence_store();\n\treturn map;\n}\n\nbool\nck_rhs_reset_size(struct ck_rhs *hs, unsigned long capacity)\n{\n\tstruct ck_rhs_map *map, *previous;\n\n\tprevious = hs->map;\n\tmap = ck_rhs_map_create(hs, capacity);\n\tif (map == NULL)\n\t\treturn false;\n\n\tck_pr_store_ptr(&hs->map, map);\n\tck_rhs_map_destroy(hs->m, previous, true);\n\treturn true;\n}\n\nbool\nck_rhs_reset(struct ck_rhs *hs)\n{\n\tstruct ck_rhs_map *previous;\n\n\tprevious = hs->map;\n\treturn ck_rhs_reset_size(hs, previous->capacity);\n}\n\nstatic inline unsigned long\nck_rhs_map_probe_next(struct ck_rhs_map *map,\n    unsigned long offset,\n    unsigned long probes)\n{\n\n\tif (probes & map->offset_mask) {\n\t\toffset = (offset &~ map->offset_mask) +\n\t\t    ((offset + 1) & map->offset_mask);\n\t\treturn offset;\n\t} else\n\t\treturn (offset + probes) & map->mask;\n}\n\nstatic inline unsigned long\nck_rhs_map_probe_prev(struct ck_rhs_map *map, unsigned long offset,\n    unsigned long probes)\n{\n\n\tif (probes & map->offset_mask) {\n\t\toffset = (offset &~ map->offset_mask) + ((offset - 1) &\n\t\t    map->offset_mask);\n\t\treturn offset;\n\t} else\n\t\treturn ((offset - probes) & map->mask);\n}\n\n\nstatic inline void\nck_rhs_map_bound_set(struct ck_rhs_map *m,\n    unsigned long h,\n    unsigned long n_probes)\n{\n\tunsigned long offset = h & m->mask;\n\tstruct ck_rhs_entry_desc *desc;\n\n\tif (n_probes > m->probe_maximum)\n\t\tck_pr_store_uint(&m->probe_maximum, n_probes);\n\tif (!(m->read_mostly)) {\n\t\tdesc = &m->entries.descs[offset];\n\n\t\tif (desc->probe_bound < n_probes) {\n\t\t\tif (n_probes > CK_RHS_WORD_MAX)\n\t\t\t\tn_probes = CK_RHS_WORD_MAX;\n\n\t\t\tCK_RHS_STORE(&desc->probe_bound, n_probes);\n\t\t\tck_pr_fence_store();\n\t\t}\n\t}\n\n\treturn;\n}\n\nstatic inline unsigned int\nck_rhs_map_bound_get(struct ck_rhs_map *m, unsigned long h)\n{\n\tunsigned long offset = h & m->mask;\n\tunsigned int r = CK_RHS_WORD_MAX;\n\n\tif (m->read_mostly)\n\t\tr = ck_pr_load_uint(&m->probe_maximum);\n\telse {\n\t\tr = CK_RHS_LOAD(&m->entries.descs[offset].probe_bound);\n\t\tif (r == CK_RHS_WORD_MAX)\n\t\t\tr = ck_pr_load_uint(&m->probe_maximum);\n\t}\n\treturn r;\n}\n\nbool\nck_rhs_grow(struct ck_rhs *hs,\n    unsigned long capacity)\n{\n\tstruct ck_rhs_map *map, *update;\n\tconst void *previous, *prev_saved;\n\tunsigned long k, offset, probes;\n\nrestart:\n\tmap = hs->map;\n\tif (map->capacity > capacity)\n\t\treturn false;\n\n\tupdate = ck_rhs_map_create(hs, capacity);\n\tif (update == NULL)\n\t\treturn false;\n\n\tfor (k = 0; k < map->capacity; k++) {\n\t\tunsigned long h;\n\n\t\tprev_saved = previous = ck_rhs_entry(map, k);\n\t\tif (previous == CK_RHS_EMPTY)\n\t\t\tcontinue;\n\n#ifdef CK_RHS_PP\n\t\tif (hs->mode & CK_RHS_MODE_OBJECT)\n\t\t\tprevious = CK_RHS_VMA(previous);\n#endif\n\n\t\th = hs->hf(previous, hs->seed);\n\t\toffset = h & update->mask;\n\t\tprobes = 0;\n\n\t\tfor (;;) {\n\t\t\tconst void **cursor = ck_rhs_entry_addr(update, offset);\n\n\t\t\tif (probes++ == update->probe_limit) {\n\t\t\t\t/*\n\t\t\t\t * We have hit the probe limit, map needs to be even larger.\n\t\t\t\t */\n\t\t\t\tck_rhs_map_destroy(hs->m, update, false);\n\t\t\t\tcapacity <<= 1;\n\t\t\t\tgoto restart;\n\t\t\t}\n\n\t\t\tif (CK_CC_LIKELY(*cursor == CK_RHS_EMPTY)) {\n\t\t\t\t*cursor = prev_saved;\n\t\t\t\tupdate->n_entries++;\n\t\t\t\tck_rhs_set_probes(update, offset, probes);\n\t\t\t\tck_rhs_map_bound_set(update, h, probes);\n\t\t\t\tbreak;\n\t\t\t} else if (ck_rhs_probes(update, offset) < probes) {\n\t\t\t\tconst void *tmp = prev_saved;\n\t\t\t\tunsigned int old_probes;\n\t\t\t\tprev_saved = previous = *cursor;\n#ifdef CK_RHS_PP\n\t\t\t\tif (hs->mode & CK_RHS_MODE_OBJECT)\n\t\t\t\t\tprevious = CK_RHS_VMA(previous);\n#endif\n\t\t\t\t*cursor = tmp;\n\t\t\t\tck_rhs_map_bound_set(update, h, probes);\n\t\t\t\th = hs->hf(previous, hs->seed);\n\t\t\t\told_probes = ck_rhs_probes(update, offset);\n\t\t\t\tck_rhs_set_probes(update, offset, probes);\n\t\t\t\tprobes = old_probes - 1;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tck_rhs_wanted_inc(update, offset);\n\t\t\toffset = ck_rhs_map_probe_next(update, offset,  probes);\n\t\t}\n\n\t}\n\n\tck_pr_fence_store();\n\tck_pr_store_ptr(&hs->map, update);\n\tck_rhs_map_destroy(hs->m, map, true);\n\treturn true;\n}\n\nbool\nck_rhs_rebuild(struct ck_rhs *hs)\n{\n\n\treturn ck_rhs_grow(hs, hs->map->capacity);\n}\n\nstatic long\nck_rhs_map_probe_rm(struct ck_rhs *hs,\n    struct ck_rhs_map *map,\n    unsigned long *n_probes,\n    long *priority,\n    unsigned long h,\n    const void *key,\n    const void **object,\n    unsigned long probe_limit,\n    enum ck_rhs_probe_behavior behavior)\n{\n\tconst void *k;\n\tconst void *compare;\n\tlong pr = -1;\n\tunsigned long offset, probes, opl;\n\n#ifdef CK_RHS_PP\n\t/* If we are storing object pointers, then we may leverage pointer packing. */\n\tunsigned long hv = 0;\n\n\tif (hs->mode & CK_RHS_MODE_OBJECT) {\n\t\thv = (h >> 25) & CK_RHS_KEY_MASK;\n\t\tcompare = CK_RHS_VMA(key);\n\t} else {\n\t\tcompare = key;\n\t}\n#else\n\tcompare = key;\n#endif\n \t*object = NULL;\n\tif (behavior != CK_RHS_PROBE_ROBIN_HOOD) {\n\t\tprobes = 0;\n\t\toffset = h & map->mask;\n\t} else {\n\t\t/* Restart from the bucket we were previously in */\n\t\tprobes = *n_probes;\n\t\toffset = ck_rhs_map_probe_next(map, *priority,\n\t\t    probes);\n\t}\n\topl = probe_limit;\n\n\tfor (;;) {\n\t\tif (probes++ == probe_limit) {\n\t\t\tif (probe_limit == opl || pr != -1) {\n\t\t\t\tk = CK_RHS_EMPTY;\n\t\t\t\tgoto leave;\n\t\t\t}\n\t\t\t/*\n\t\t\t * If no eligible slot has been found yet, continue probe\n\t\t\t * sequence with original probe limit.\n\t\t\t */\n\t\t\tprobe_limit = opl;\n\t\t}\n\t\tk = ck_pr_load_ptr(&map->entries.no_entries.entries[offset]);\n\t\tif (k == CK_RHS_EMPTY)\n\t\t\tgoto leave;\n\n\t\tif (behavior != CK_RHS_PROBE_NO_RH) {\n\t\t\tstruct ck_rhs_entry_desc *desc = (void *)&map->entries.no_entries.descs[offset];\n\n\t\t\tif (pr == -1 &&\n\t\t\t    desc->in_rh == false && desc->probes < probes) {\n\t\t\t\tpr = offset;\n\t\t\t\t*n_probes = probes;\n\n\t\t\t\tif (behavior == CK_RHS_PROBE_RH ||\n\t\t\t\t    behavior == CK_RHS_PROBE_ROBIN_HOOD) {\n\t\t\t\t\tk = CK_RHS_EMPTY;\n\t\t\t\t\tgoto leave;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (behavior != CK_RHS_PROBE_ROBIN_HOOD) {\n#ifdef CK_RHS_PP\n\t\t\tif (hs->mode & CK_RHS_MODE_OBJECT) {\n\t\t\t\tif (((uintptr_t)k >> CK_MD_VMA_BITS) != hv) {\n\t\t\t\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tk = CK_RHS_VMA(k);\n\t\t\t}\n#endif\n\n\t\t\tif (k == compare)\n\t\t\t\tgoto leave;\n\n\t\t\tif (hs->compare == NULL) {\n\t\t\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (hs->compare(k, key) == true)\n\t\t\t\tgoto leave;\n\t\t}\n\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t}\nleave:\n\tif (probes > probe_limit) {\n\t\toffset = -1;\n\t} else {\n\t\t*object = k;\n\t}\n\n\tif (pr == -1)\n\t\t*n_probes = probes;\n\n\t*priority = pr;\n\treturn offset;\n}\n\nstatic long\nck_rhs_map_probe(struct ck_rhs *hs,\n    struct ck_rhs_map *map,\n    unsigned long *n_probes,\n    long *priority,\n    unsigned long h,\n    const void *key,\n    const void **object,\n    unsigned long probe_limit,\n    enum ck_rhs_probe_behavior behavior)\n{\n\tconst void *k;\n\tconst void *compare;\n\tlong pr = -1;\n\tunsigned long offset, probes, opl;\n\n#ifdef CK_RHS_PP\n\t/* If we are storing object pointers, then we may leverage pointer packing. */\n\tunsigned long hv = 0;\n\n\tif (hs->mode & CK_RHS_MODE_OBJECT) {\n\t\thv = (h >> 25) & CK_RHS_KEY_MASK;\n\t\tcompare = CK_RHS_VMA(key);\n\t} else {\n\t\tcompare = key;\n\t}\n#else\n\tcompare = key;\n#endif\n\n \t*object = NULL;\n\tif (behavior != CK_RHS_PROBE_ROBIN_HOOD) {\n\t\tprobes = 0;\n\t\toffset = h & map->mask;\n\t} else {\n\t\t/* Restart from the bucket we were previously in */\n\t\tprobes = *n_probes;\n\t\toffset = ck_rhs_map_probe_next(map, *priority,\n\t\t    probes);\n\t}\n\topl = probe_limit;\n\tif (behavior == CK_RHS_PROBE_INSERT)\n\t\tprobe_limit = ck_rhs_map_bound_get(map, h);\n\n\tfor (;;) {\n\t\tif (probes++ == probe_limit) {\n\t\t\tif (probe_limit == opl || pr != -1) {\n\t\t\t\tk = CK_RHS_EMPTY;\n\t\t\t\tgoto leave;\n\t\t\t}\n\t\t\t/*\n\t\t\t * If no eligible slot has been found yet, continue probe\n\t\t\t * sequence with original probe limit.\n\t\t\t */\n\t\t\tprobe_limit = opl;\n\t\t}\n\t\tk = ck_pr_load_ptr(&map->entries.descs[offset].entry);\n\t\tif (k == CK_RHS_EMPTY)\n\t\t\tgoto leave;\n\t\tif ((behavior != CK_RHS_PROBE_NO_RH)) {\n\t\t\tstruct ck_rhs_entry_desc *desc = &map->entries.descs[offset];\n\n\t\t\tif (pr == -1 &&\n\t\t\t    desc->in_rh == false && desc->probes < probes) {\n\t\t\t\tpr = offset;\n\t\t\t\t*n_probes = probes;\n\n\t\t\t\tif (behavior == CK_RHS_PROBE_RH ||\n\t\t\t\t    behavior == CK_RHS_PROBE_ROBIN_HOOD) {\n\t\t\t\t\tk = CK_RHS_EMPTY;\n\t\t\t\t\tgoto leave;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (behavior != CK_RHS_PROBE_ROBIN_HOOD) {\n#ifdef CK_RHS_PP\n\t\t\tif (hs->mode & CK_RHS_MODE_OBJECT) {\n\t\t\t\tif (((uintptr_t)k >> CK_MD_VMA_BITS) != hv) {\n\t\t\t\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tk = CK_RHS_VMA(k);\n\t\t\t}\n#endif\n\n\t\t\tif (k == compare)\n\t\t\t\tgoto leave;\n\n\t\t\tif (hs->compare == NULL) {\n\t\t\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (hs->compare(k, key) == true)\n\t\t\t\tgoto leave;\n\t\t}\n\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t}\nleave:\n\tif (probes > probe_limit) {\n\t\toffset = -1;\n\t} else {\n\t\t*object = k;\n\t}\n\n\tif (pr == -1)\n\t\t*n_probes = probes;\n\n\t*priority = pr;\n\treturn offset;\n}\n\nstatic inline const void *\nck_rhs_marshal(unsigned int mode, const void *key, unsigned long h)\n{\n#ifdef CK_RHS_PP\n\tconst void *insert;\n\n\tif (mode & CK_RHS_MODE_OBJECT) {\n\t\tinsert = (void *)((uintptr_t)CK_RHS_VMA(key) | ((h >> 25) << CK_MD_VMA_BITS));\n\t} else {\n\t\tinsert = key;\n\t}\n\n\treturn insert;\n#else\n\t(void)mode;\n\t(void)h;\n\n\treturn key;\n#endif\n}\n\nbool\nck_rhs_gc(struct ck_rhs *hs)\n{\n\tunsigned long i;\n\tstruct ck_rhs_map *map = hs->map;\n\n\tunsigned int max_probes = 0;\n\tfor (i = 0; i < map->capacity; i++) {\n\t\tif (ck_rhs_probes(map, i) > max_probes)\n\t\t\tmax_probes = ck_rhs_probes(map, i);\n\t}\n\tmap->probe_maximum = max_probes;\n\treturn true;\n}\n\nstatic void\nck_rhs_add_wanted(struct ck_rhs *hs, long end_offset, long old_slot,\n\tunsigned long h)\n{\n\tstruct ck_rhs_map *map = hs->map;\n\tlong offset;\n\tunsigned int probes = 1;\n\tbool found_slot = false;\n\tstruct ck_rhs_entry_desc *desc;\n\n\toffset = h & map->mask;\n\n\tif (old_slot == -1)\n\t\tfound_slot = true;\n\twhile (offset != end_offset) {\n\t\tif (offset == old_slot)\n\t\t\tfound_slot = true;\n\t\tif (found_slot) {\n\t\t\tdesc = ck_rhs_desc(map, offset);\n\t\t\tif (desc->wanted < CK_RHS_MAX_WANTED)\n\t\t\t\tdesc->wanted++;\n\t\t}\n\t\toffset = ck_rhs_map_probe_next(map, offset, probes);\n\t\tprobes++;\n\t}\n}\n\nstatic unsigned long\nck_rhs_remove_wanted(struct ck_rhs *hs, long offset, long limit)\n{\n\tstruct ck_rhs_map *map = hs->map;\n\tint probes = ck_rhs_probes(map, offset);\n\tbool do_remove = true;\n\tstruct ck_rhs_entry_desc *desc;\n\n\twhile (probes > 1) {\n\t\tprobes--;\n\t\toffset = ck_rhs_map_probe_prev(map, offset, probes);\n\t\tif (offset == limit)\n\t\t\tdo_remove = false;\n\t\tif (do_remove) {\n\t\t\tdesc = ck_rhs_desc(map, offset);\n\t\t\tif (desc->wanted != CK_RHS_MAX_WANTED)\n\t\t\t\tdesc->wanted--;\n\t\t}\n\t}\n\treturn offset;\n}\n\nstatic long\nck_rhs_get_first_offset(struct ck_rhs_map *map, unsigned long offset, unsigned int probes)\n{\n\twhile (probes > (unsigned long)map->offset_mask + 1) {\n\t\toffset -= ((probes - 1) &~ map->offset_mask);\n\t\toffset &= map->mask;\n\t\toffset = (offset &~ map->offset_mask) +\n\t\t    ((offset - map->offset_mask) & map->offset_mask);\n\t\tprobes -= map->offset_mask + 1;\n\t}\n\treturn ((offset &~ map->offset_mask) + ((offset - (probes - 1)) & map->offset_mask));\n}\n\n#define CK_RHS_MAX_RH\t512\n\nstatic int\nck_rhs_put_robin_hood(struct ck_rhs *hs,\n    long orig_slot, struct ck_rhs_entry_desc *desc)\n{\n\tlong slot, first;\n\tconst void *object, *insert;\n\tunsigned long n_probes;\n\tstruct ck_rhs_map *map;\n\tunsigned long h = 0;\n\tlong prev;\n\tvoid *key;\n\tlong prevs[CK_RHS_MAX_RH];\n\tunsigned int prevs_nb = 0;\n\tunsigned int i;\n\n\tmap = hs->map;\n\tfirst = orig_slot;\n\tn_probes = desc->probes;\nrestart:\n\tkey = CK_CC_DECONST_PTR(ck_rhs_entry(map, first));\n\tinsert = key;\n#ifdef CK_RHS_PP\n\tif (hs->mode & CK_RHS_MODE_OBJECT)\n\t    key = CK_RHS_VMA(key);\n#endif\n\torig_slot = first;\n\tck_rhs_set_rh(map, orig_slot);\n\n\tslot = map->probe_func(hs, map, &n_probes, &first, h, key, &object,\n\t    map->probe_limit, prevs_nb == CK_RHS_MAX_RH ?\n\t    CK_RHS_PROBE_NO_RH : CK_RHS_PROBE_ROBIN_HOOD);\n\n\tif (slot == -1 && first == -1) {\n\t\tif (ck_rhs_grow(hs, map->capacity << 1) == false) {\n\t\t\tdesc->in_rh = false;\n\n\t\t\tfor (i = 0; i < prevs_nb; i++)\n\t\t\t\tck_rhs_unset_rh(map, prevs[i]);\n\n\t\t\treturn -1;\n\t\t}\n\n\t\treturn 1;\n\t}\n\n\tif (first != -1) {\n\t\tdesc = ck_rhs_desc(map, first);\n\t\tint old_probes = desc->probes;\n\n\t\tdesc->probes = n_probes;\n\t\th = ck_rhs_get_first_offset(map, first, n_probes);\n\t\tck_rhs_map_bound_set(map, h, n_probes);\n\t\tprev = orig_slot;\n\t\tprevs[prevs_nb++] = prev;\n\t\tn_probes = old_probes;\n\t\tgoto restart;\n\t} else {\n\t\t/* An empty slot was found. */\n\t\th =  ck_rhs_get_first_offset(map, slot, n_probes);\n\t\tck_rhs_map_bound_set(map, h, n_probes);\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);\n\t\tck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);\n\t\tck_pr_fence_atomic_store();\n\t\tck_rhs_set_probes(map, slot, n_probes);\n\t\tdesc->in_rh = 0;\n\t\tck_rhs_add_wanted(hs, slot, orig_slot, h);\n\t}\n\twhile (prevs_nb > 0) {\n\t\tprev = prevs[--prevs_nb];\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, orig_slot),\n\t\t    ck_rhs_entry(map, prev));\n\t\th = ck_rhs_get_first_offset(map, orig_slot,\n\t\t    desc->probes);\n\t\tck_rhs_add_wanted(hs, orig_slot, prev, h);\n\t\tck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);\n\t\tck_pr_fence_atomic_store();\n\t\torig_slot = prev;\n\t\tdesc->in_rh = false;\n\t\tdesc = ck_rhs_desc(map, orig_slot);\n\t}\n\treturn 0;\n}\n\nstatic void\nck_rhs_do_backward_shift_delete(struct ck_rhs *hs, long slot)\n{\n\tstruct ck_rhs_map *map = hs->map;\n\tstruct ck_rhs_entry_desc *desc, *new_desc = NULL;\n\tunsigned long h;\n\n\tdesc = ck_rhs_desc(map, slot);\n\th = ck_rhs_remove_wanted(hs, slot, -1);\n\twhile (desc->wanted > 0) {\n\t\tunsigned long offset = 0, tmp_offset;\n\t\tunsigned long wanted_probes = 1;\n\t\tunsigned int probe = 0;\n\t\tunsigned int max_probes;\n\n\t\t/* Find a successor */\n\t\twhile (wanted_probes < map->probe_maximum) {\n\t\t\tprobe = wanted_probes;\n\t\t\toffset = ck_rhs_map_probe_next(map, slot, probe);\n\t\t\twhile (probe < map->probe_maximum) {\n\t\t\t\tnew_desc = ck_rhs_desc(map, offset);\n\t\t\t\tif (new_desc->probes == probe + 1)\n\t\t\t\t\tbreak;\n\t\t\t\tprobe++;\n\t\t\t\toffset = ck_rhs_map_probe_next(map, offset,\n\t\t\t\t    probe);\n\t\t\t}\n\t\t\tif (probe < map->probe_maximum)\n\t\t\t\tbreak;\n\t\t\twanted_probes++;\n\t\t}\n\t\tif (!(wanted_probes < map->probe_maximum)) {\n\t\t\tdesc->wanted = 0;\n\t\t\tbreak;\n\t\t}\n\t\tdesc->probes = wanted_probes;\n\t\th = ck_rhs_remove_wanted(hs, offset, slot);\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot),\n\t\t    ck_rhs_entry(map, offset));\n\t\tck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);\n\t\tck_pr_fence_atomic_store();\n\t\tif (wanted_probes < CK_RHS_WORD_MAX) {\n\t\t\tstruct ck_rhs_entry_desc *hdesc = ck_rhs_desc(map, h);\n\t\t\tif (hdesc->wanted == 1)\n\t\t\t\tCK_RHS_STORE(&hdesc->probe_bound,\n\t\t\t\t    wanted_probes);\n\t\t\telse if (hdesc->probe_bound == CK_RHS_WORD_MAX ||\n\t\t\t    hdesc->probe_bound == new_desc->probes) {\n\t\t\t\tprobe++;\n\t\t\t\tif (hdesc->probe_bound == CK_RHS_WORD_MAX)\n\t\t\t\t\tmax_probes = map->probe_maximum;\n\t\t\t\telse {\n\t\t\t\t\tmax_probes = hdesc->probe_bound;\n\t\t\t\t\tmax_probes--;\n\t\t\t\t}\n\t\t\t\ttmp_offset = ck_rhs_map_probe_next(map, offset,\n\t\t\t\t    probe);\n\t\t\t\twhile (probe < max_probes) {\n\t\t\t\t\tif (h == (unsigned long)ck_rhs_get_first_offset(map, tmp_offset, probe))\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tprobe++;\n\t\t\t\t\ttmp_offset = ck_rhs_map_probe_next(map, tmp_offset, probe);\n\t\t\t\t}\n\t\t\t\tif (probe == max_probes)\n\t\t\t\t\tCK_RHS_STORE(&hdesc->probe_bound,\n\t\t\t\t\t    wanted_probes);\n\t\t\t}\n\t\t}\n\t\tif (desc->wanted < CK_RHS_MAX_WANTED)\n\t\t\tdesc->wanted--;\n\t\tslot = offset;\n\t\tdesc = new_desc;\n\t}\n\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot), CK_RHS_EMPTY);\n\tif ((desc->probes - 1) < CK_RHS_WORD_MAX)\n\t\tCK_RHS_STORE(ck_rhs_probe_bound_addr(map, h),\n\t\t    desc->probes - 1);\n\tdesc->probes = 0;\n}\n\nbool\nck_rhs_fas(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key,\n    void **previous)\n{\n\tlong slot, first;\n\tconst void *object;\n\tconst void *insert;\n\tunsigned long n_probes;\n\tstruct ck_rhs_map *map = hs->map;\n\tstruct ck_rhs_entry_desc *desc, *desc2;\n\n\t*previous = NULL;\nrestart:\n\tslot = map->probe_func(hs, map, &n_probes, &first, h, key, &object,\n\t    ck_rhs_map_bound_get(map, h), CK_RHS_PROBE);\n\n\t/* Replacement semantics presume existence. */\n\tif (object == NULL)\n\t\treturn false;\n\n\tinsert = ck_rhs_marshal(hs->mode, key, h);\n\n\tif (first != -1) {\n\t\tint ret;\n\n\t\tdesc = ck_rhs_desc(map, slot);\n\t\tdesc2 = ck_rhs_desc(map, first);\n\t\tdesc->in_rh = true;\n\t\tret = ck_rhs_put_robin_hood(hs, first, desc2);\n\t\tdesc->in_rh = false;\n\t\tif (CK_CC_UNLIKELY(ret == 1))\n\t\t\tgoto restart;\n\t\telse if (CK_CC_UNLIKELY(ret != 0))\n\t\t\treturn false;\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);\n\t\tck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);\n\t\tck_pr_fence_atomic_store();\n\t\tdesc2->probes = n_probes;\n\t\tck_rhs_add_wanted(hs, first, -1, h);\n\t\tck_rhs_do_backward_shift_delete(hs, slot);\n\t} else {\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);\n\t\tck_rhs_set_probes(map, slot, n_probes);\n\t}\n\t*previous = CK_CC_DECONST_PTR(object);\n\treturn true;\n}\n\n/*\n * An apply function takes two arguments. The first argument is a pointer to a\n * pre-existing object. The second argument is a pointer to the fifth argument\n * passed to ck_hs_apply. If a non-NULL pointer is passed to the first argument\n * and the return value of the apply function is NULL, then the pre-existing\n * value is deleted. If the return pointer is the same as the one passed to the\n * apply function then no changes are made to the hash table.  If the first\n * argument is non-NULL and the return pointer is different than that passed to\n * the apply function, then the pre-existing value is replaced. For\n * replacement, it is required that the value itself is identical to the\n * previous value.\n */\nbool\nck_rhs_apply(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key,\n    ck_rhs_apply_fn_t *fn,\n    void *cl)\n{\n\tconst void *insert;\n\tconst void  *object, *delta = false;\n\tunsigned long n_probes;\n\tlong slot, first;\n\tstruct ck_rhs_map *map;\n\tbool delta_set = false;\n\nrestart:\n\tmap = hs->map;\n\n\tslot = map->probe_func(hs, map, &n_probes, &first, h, key, &object, map->probe_limit, CK_RHS_PROBE_INSERT);\n\tif (slot == -1 && first == -1) {\n\t\tif (ck_rhs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\n\t\tgoto restart;\n\t}\n\tif (!delta_set) {\n\t\tdelta = fn(CK_CC_DECONST_PTR(object), cl);\n\t\tdelta_set = true;\n\t}\n\n\tif (delta == NULL) {\n\t\t/*\n\t\t * The apply function has requested deletion. If the object doesn't exist,\n\t\t * then exit early.\n\t\t */\n\t\tif (CK_CC_UNLIKELY(object == NULL))\n\t\t\treturn true;\n\n\t\t/* Otherwise, delete it. */\n\t\tck_rhs_do_backward_shift_delete(hs, slot);\n\t\treturn true;\n\t}\n\n\t/* The apply function has not requested hash set modification so exit early. */\n\tif (delta == object)\n\t\treturn true;\n\n\t/* A modification or insertion has been requested. */\n\tck_rhs_map_bound_set(map, h, n_probes);\n\n\tinsert = ck_rhs_marshal(hs->mode, delta, h);\n\tif (first != -1) {\n\t\t/*\n\t\t * This follows the same semantics as ck_hs_set, please refer to that\n\t\t * function for documentation.\n\t\t */\n\t\tstruct ck_rhs_entry_desc *desc = NULL, *desc2;\n\t\tif (slot != -1) {\n\t\t\tdesc = ck_rhs_desc(map, slot);\n\t\t\tdesc->in_rh = true;\n\t\t}\n\t\tdesc2 = ck_rhs_desc(map, first);\n\t\tint ret = ck_rhs_put_robin_hood(hs, first, desc2);\n\t\tif (slot != -1)\n\t\t\tdesc->in_rh = false;\n\n\t\tif (CK_CC_UNLIKELY(ret == 1))\n\t\t\tgoto restart;\n\t\tif (CK_CC_UNLIKELY(ret == -1))\n\t\t\treturn false;\n\t\t/* If an earlier bucket was found, then store entry there. */\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);\n\t\tdesc2->probes = n_probes;\n\t\t/*\n\t\t * If a duplicate key was found, then delete it after\n\t\t * signaling concurrent probes to restart. Optionally,\n\t\t * it is possible to install tombstone after grace\n\t\t * period if we can guarantee earlier position of\n\t\t * duplicate key.\n\t\t */\n\t\tck_rhs_add_wanted(hs, first, -1, h);\n\t\tif (object != NULL) {\n\t\t\tck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);\n\t\t\tck_pr_fence_atomic_store();\n\t\t\tck_rhs_do_backward_shift_delete(hs, slot);\n\t\t}\n\t} else {\n\t\t/*\n\t\t * If we are storing into same slot, then atomic store is sufficient\n\t\t * for replacement.\n\t\t */\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);\n\t\tck_rhs_set_probes(map, slot, n_probes);\n\t\tif (object == NULL)\n\t\t\tck_rhs_add_wanted(hs, slot, -1, h);\n\t}\n\n\tif (object == NULL) {\n\t\tmap->n_entries++;\n\t\tif ((map->n_entries ) > map->max_entries)\n\t\t\tck_rhs_grow(hs, map->capacity << 1);\n\t}\n\treturn true;\n}\n\nbool\nck_rhs_set(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key,\n    void **previous)\n{\n\tlong slot, first;\n\tconst void *object;\n\tconst void *insert;\n\tunsigned long n_probes;\n\tstruct ck_rhs_map *map;\n\n\t*previous = NULL;\n\nrestart:\n\tmap = hs->map;\n\n\tslot = map->probe_func(hs, map, &n_probes, &first, h, key, &object, map->probe_limit, CK_RHS_PROBE_INSERT);\n\tif (slot == -1 && first == -1) {\n\t\tif (ck_rhs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\n\t\tgoto restart;\n\t}\n\tck_rhs_map_bound_set(map, h, n_probes);\n\tinsert = ck_rhs_marshal(hs->mode, key, h);\n\n\tif (first != -1) {\n\t\tstruct ck_rhs_entry_desc *desc = NULL, *desc2;\n\t\tif (slot != -1) {\n\t\t\tdesc = ck_rhs_desc(map, slot);\n\t\t\tdesc->in_rh = true;\n\t\t}\n\t\tdesc2 = ck_rhs_desc(map, first);\n\t\tint ret = ck_rhs_put_robin_hood(hs, first, desc2);\n\t\tif (slot != -1)\n\t\t\tdesc->in_rh = false;\n\n\t\tif (CK_CC_UNLIKELY(ret == 1))\n\t\t\tgoto restart;\n\t\tif (CK_CC_UNLIKELY(ret == -1))\n\t\t\treturn false;\n\t\t/* If an earlier bucket was found, then store entry there. */\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);\n\t\tdesc2->probes = n_probes;\n\t\t/*\n\t\t * If a duplicate key was found, then delete it after\n\t\t * signaling concurrent probes to restart. Optionally,\n\t\t * it is possible to install tombstone after grace\n\t\t * period if we can guarantee earlier position of\n\t\t * duplicate key.\n\t\t */\n\t\tck_rhs_add_wanted(hs, first, -1, h);\n\t\tif (object != NULL) {\n\t\t\tck_pr_inc_uint(&map->generation[h & CK_RHS_G_MASK]);\n\t\t\tck_pr_fence_atomic_store();\n\t\t\tck_rhs_do_backward_shift_delete(hs, slot);\n\t\t}\n\n\t} else {\n\t\t/*\n\t\t * If we are storing into same slot, then atomic store is sufficient\n\t\t * for replacement.\n\t\t */\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);\n\t\tck_rhs_set_probes(map, slot, n_probes);\n\t\tif (object == NULL)\n\t\t\tck_rhs_add_wanted(hs, slot, -1, h);\n\t}\n\n\tif (object == NULL) {\n\t\tmap->n_entries++;\n\t\tif ((map->n_entries ) > map->max_entries)\n\t\t\tck_rhs_grow(hs, map->capacity << 1);\n\t}\n\n\t*previous = CK_CC_DECONST_PTR(object);\n\treturn true;\n}\n\nstatic bool\nck_rhs_put_internal(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key,\n    enum ck_rhs_probe_behavior behavior)\n{\n\tlong slot, first;\n\tconst void *object;\n\tconst void *insert;\n\tunsigned long n_probes;\n\tstruct ck_rhs_map *map;\n\nrestart:\n\tmap = hs->map;\n\n\tslot = map->probe_func(hs, map, &n_probes, &first, h, key, &object,\n\t    map->probe_limit, behavior);\n\n\tif (slot == -1 && first == -1) {\n\t\tif (ck_rhs_grow(hs, map->capacity << 1) == false)\n\t\t\treturn false;\n\n\t\tgoto restart;\n\t}\n\n\t/* Fail operation if a match was found. */\n\tif (object != NULL)\n\t\treturn false;\n\n\tck_rhs_map_bound_set(map, h, n_probes);\n\tinsert = ck_rhs_marshal(hs->mode, key, h);\n\n\tif (first != -1) {\n\t\tstruct ck_rhs_entry_desc *desc = ck_rhs_desc(map, first);\n\t\tint ret = ck_rhs_put_robin_hood(hs, first, desc);\n\t\tif (CK_CC_UNLIKELY(ret == 1))\n\t\t\treturn ck_rhs_put_internal(hs, h, key, behavior);\n\t\telse if (CK_CC_UNLIKELY(ret == -1))\n\t\t\treturn false;\n\t\t/* Insert key into first bucket in probe sequence. */\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, first), insert);\n\t\tdesc->probes = n_probes;\n\t\tck_rhs_add_wanted(hs, first, -1, h);\n\t} else {\n\t\t/* An empty slot was found. */\n\t\tck_pr_store_ptr(ck_rhs_entry_addr(map, slot), insert);\n\t\tck_rhs_set_probes(map, slot, n_probes);\n\t\tck_rhs_add_wanted(hs, slot, -1, h);\n\t}\n\n\tmap->n_entries++;\n\tif ((map->n_entries ) > map->max_entries)\n\t\tck_rhs_grow(hs, map->capacity << 1);\n\treturn true;\n}\n\nbool\nck_rhs_put(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key)\n{\n\n\treturn ck_rhs_put_internal(hs, h, key, CK_RHS_PROBE_INSERT);\n}\n\nbool\nck_rhs_put_unique(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key)\n{\n\n\treturn ck_rhs_put_internal(hs, h, key, CK_RHS_PROBE_RH);\n}\n\nvoid *\nck_rhs_get(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key)\n{\n\tlong first;\n\tconst void *object;\n\tstruct ck_rhs_map *map;\n\tunsigned long n_probes;\n\tunsigned int g, g_p, probe;\n\tunsigned int *generation;\n\n\tdo {\n\t\tmap = ck_pr_load_ptr(&hs->map);\n\t\tgeneration = &map->generation[h & CK_RHS_G_MASK];\n\t\tg = ck_pr_load_uint(generation);\n\t\tprobe  = ck_rhs_map_bound_get(map, h);\n\t\tck_pr_fence_load();\n\n\t\tfirst = -1;\n\t\tmap->probe_func(hs, map, &n_probes, &first, h, key, &object, probe, CK_RHS_PROBE_NO_RH);\n\n\t\tck_pr_fence_load();\n\t\tg_p = ck_pr_load_uint(generation);\n\t} while (g != g_p);\n\n\treturn CK_CC_DECONST_PTR(object);\n}\n\nvoid *\nck_rhs_remove(struct ck_rhs *hs,\n    unsigned long h,\n    const void *key)\n{\n\tlong slot, first;\n\tconst void *object;\n\tstruct ck_rhs_map *map = hs->map;\n\tunsigned long n_probes;\n\n\tslot = map->probe_func(hs, map, &n_probes, &first, h, key, &object,\n\t    ck_rhs_map_bound_get(map, h), CK_RHS_PROBE_NO_RH);\n\tif (object == NULL)\n\t\treturn NULL;\n\n\tmap->n_entries--;\n\tck_rhs_do_backward_shift_delete(hs, slot);\n\treturn CK_CC_DECONST_PTR(object);\n}\n\nbool\nck_rhs_move(struct ck_rhs *hs,\n    struct ck_rhs *source,\n    ck_rhs_hash_cb_t *hf,\n    ck_rhs_compare_cb_t *compare,\n    struct ck_malloc *m)\n{\n\n\tif (m == NULL || m->malloc == NULL || m->free == NULL || hf == NULL)\n\t\treturn false;\n\n\ths->mode = source->mode;\n\ths->seed = source->seed;\n\ths->map = source->map;\n\ths->load_factor = source->load_factor;\n\ths->m = m;\n\ths->hf = hf;\n\ths->compare = compare;\n\treturn true;\n}\n\nbool\nck_rhs_init(struct ck_rhs *hs,\n    unsigned int mode,\n    ck_rhs_hash_cb_t *hf,\n    ck_rhs_compare_cb_t *compare,\n    struct ck_malloc *m,\n    unsigned long n_entries,\n    unsigned long seed)\n{\n\n\tif (m == NULL || m->malloc == NULL || m->free == NULL || hf == NULL)\n\t\treturn false;\n\n\ths->m = m;\n\ths->mode = mode;\n\ths->seed = seed;\n\ths->hf = hf;\n\ths->compare = compare;\n\ths->load_factor = CK_RHS_DEFAULT_LOAD_FACTOR;\n\n\ths->map = ck_rhs_map_create(hs, n_entries);\n\treturn hs->map != NULL;\n}\n"
  },
  {
    "path": "third_party/concurrency_kit/ck/tools/feature.sh",
    "content": "#!/bin/sh\n# This will generate the list of feature flags for implemented symbols.\n\necho '/* DO NOT EDIT. This is auto-generated from feature.sh */'\nnm ../regressions/ck_pr/validate/ck_pr_cas|cut -d ' ' -f 3|sed s/ck_pr/ck_f_pr/|awk '/^ck_f_pr/ {print \"#define \" toupper($1);}'|sort\n"
  },
  {
    "path": "third_party/cram/.coveragerc",
    "content": "[run]\nomit =\n    cram/__main__.py\n    cram/_encoding.py\n    scripts/cram\nsource = cram\n"
  },
  {
    "path": "third_party/cram/.gitignore",
    "content": "*.orig\n*.rej\n*~\n*.mergebackup\n*.o\n*.so\n*.dll\n*.py[cdo]\n*$py.class\n__pycache__\n*.swp\n*.prof\n\\#*\\#\n.\\#*\n.coverage\n*,cover\nhtmlcov\ntests/*.err\nexamples/*.err\nbuild\ndist\nMANIFEST\ncram.egg-info\n.DS_Store\ntags\ncscope.*\n.idea\n"
  },
  {
    "path": "third_party/cram/.hgignore",
    "content": "syntax: glob\n\n*.orig\n*.rej\n*~\n*.mergebackup\n*.o\n*.so\n*.dll\n*.py[cdo]\n*$py.class\n__pycache__\n*.swp\n*.prof\n\\#*\\#\n.\\#*\n.coverage\n*,cover\nhtmlcov\ntests/*.err\nexamples/*.err\nbuild\ndist\nMANIFEST\ncram.egg-info\n.DS_Store\ntags\ncscope.*\n.idea\n\nsyntax: regexp\n^\\.pc/\n^\\.(pydev)?project\n"
  },
  {
    "path": "third_party/cram/.hgtags",
    "content": "931859fdd3e0d5af442a3e9b5fe6ac0dbfed2309 0.1\n3c471f7a16b435095b98525e7b851b17e871a2ce 0.2\n3c471f7a16b435095b98525e7b851b17e871a2ce 0.2\n995a287114b0a2a0bcd79b9c5ce8ff98765e7c8a 0.2\n924d14e0636a7ff5815c2412409115a69dfc63f0 0.3\n3ba61fadf306c63ec4bc3254522f286a27ac974a 0.4\n112e96e43892344954a98b0f05a32819f2b6c20d 0.5\n05669fd0420dc0cd52f48bc2f2379a61732d14e0 0.6\ne230eb00d4668508766fc32da154ba46c358ff5f 0.7\n"
  },
  {
    "path": "third_party/cram/.pylintrc",
    "content": "[MESSAGES CONTROL]\n# C0330: bad continuation\n# The design check gives mostly useless advice.\n# R0201: method could be a function\n# W0123: eval used\n# W0141: used range\n# W0142: * or ** arguments\n# W0201: attribute defined outside of __init__\n# W0640: unreliable closure/loop variable checking\ndisable=C0330,design,R0201,W0123,W0141,W0142,W0201,W0640\n\n[REPORTS]\nreports=no\n\n[TYPECHECK]\nignored-classes=\ngenerated-members=\n\n[BASIC]\nconst-rgx=(([a-zA-Z_][a-zA-Z0-9_]{2,30})|(__[a-z0-9_]{2,30}__))$\nclass-rgx=[a-zA-Z_][a-zA-Z0-9]{2,30}$\nfunction-rgx=[a-z_][a-z0-9_]{2,30}$\nmethod-rgx=[a-z_][a-z0-9_]{2,30}$\nattr-rgx=[a-z_][a-z0-9_]{0,30}$\nargument-rgx=[a-z_][a-z0-9_]{0,30}$\nvariable-rgx=[a-z_][a-z0-9_]{0,30}$\ninlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$\n\n[CLASSES]\nignore-iface-methods=\ndefining-attr-methods=__init__,__new__\n\n[IMPORTS]\ndeprecated-modules=regsub,TERMIOS,Bastion,rexec\n\n[FORMAT]\nmax-line-length=79\nmax-module-lines=5000\n\n[MISCELLANEOUS]\nnotes=FIXME,XXX,TODO\n"
  },
  {
    "path": "third_party/cram/.travis.yml",
    "content": "language: python\n\nmatrix:\n  allow_failures:\n    - python: nightly\n      env: TESTOPTS=--shell=dash\n    - python: pypy\n      env: TESTOPTS=--shell=dash\n    - python: pypy3\n      env: TESTOPTS=--shell=dash\n  include:\n    - python: \"3.5\"\n      env: TESTOPTS=--shell=dash\n    - python: \"3.5\"\n      env: TESTOPTS=--shell=bash\n    - python: \"3.5\"\n      env: TESTOPTS=--shell=zsh\n      addons:\n        apt:\n          packages:\n            - zsh\n    - python: \"3.4\"\n      env: TESTOPTS=--shell=dash\n    - python: \"3.3\"\n      env: TESTOPTS=--shell=dash\n    - python: \"3.2\"\n      env: TESTOPTS=--shell=dash\n    - python: \"2.7\"\n      env: TESTOPTS=--shell=dash\n    - python: \"2.6\"\n      env: TESTOPTS=--shell=dash\n    - env: PYTHON=2.5 TESTOPTS=--shell=dash\n      addons:\n        apt:\n          sources:\n            - deadsnakes\n          packages:\n            - python2.5\n    - env: PYTHON=2.4 TESTOPTS=--shell=dash\n      addons:\n        apt:\n          sources:\n            - deadsnakes\n          packages:\n            - python2.4\n    - python: nightly\n      env: TESTOPTS=--shell=dash\n    - python: pypy\n      env: TESTOPTS=--shell=dash\n    - python: pypy3\n      env: TESTOPTS=--shell=dash\n  fast_finish: true\n\ninstall: |\n  if [ -z \"$PYTHON\" ]\n  then\n    [ \"$TRAVIS_PYTHON_VERSION\" = \"3.2\" ] && pip install coverage==3.7.1\n    pip install -r requirements.txt\n  fi\n\nscript: |\n  if [ -z \"$PYTHON\" ]\n  then\n    make test TESTOPTS=\"$TESTOPTS\"\n  else\n    make quicktest PYTHON=\"python$PYTHON\"\n  fi\n"
  },
  {
    "path": "third_party/cram/COPYING.txt",
    "content": "                    GNU GENERAL PUBLIC LICENSE\n                       Version 2, June 1991\n\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n                            Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicense is intended to guarantee your freedom to share and change free\nsoftware--to make sure the software is free for all its users.  This\nGeneral Public License applies to most of the Free Software\nFoundation's software and to any other program whose authors commit to\nusing it.  (Some other Free Software Foundation software is covered by\nthe GNU Lesser General Public License instead.)  You can apply it to\nyour programs, too.\n\n  When we speak of free software, we are referring to freedom, not\nprice.  Our General Public Licenses are designed to make sure that you\nhave the freedom to distribute copies of free software (and charge for\nthis service if you wish), that you receive source code or can get it\nif you want it, that you can change the software or use pieces of it\nin new free programs; and that you know you can do these things.\n\n  To protect your rights, we need to make restrictions that forbid\nanyone to deny you these rights or to ask you to surrender the rights.\nThese restrictions translate to certain responsibilities for you if you\ndistribute copies of the software, or if you modify it.\n\n  For example, if you distribute copies of such a program, whether\ngratis or for a fee, you must give the recipients all the rights that\nyou have.  You must make sure that they, too, receive or can get the\nsource code.  And you must show them these terms so they know their\nrights.\n\n  We protect your rights with two steps: (1) copyright the software, and\n(2) offer you this license which gives you legal permission to copy,\ndistribute and/or modify the software.\n\n  Also, for each author's protection and ours, we want to make certain\nthat everyone understands that there is no warranty for this free\nsoftware.  If the software is modified by someone else and passed on, we\nwant its recipients to know that what they have is not the original, so\nthat any problems introduced by others will not reflect on the original\nauthors' reputations.\n\n  Finally, any free program is threatened constantly by software\npatents.  We wish to avoid the danger that redistributors of a free\nprogram will individually obtain patent licenses, in effect making the\nprogram proprietary.  To prevent this, we have made it clear that any\npatent must be licensed for everyone's free use or not licensed at all.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.\n\n                    GNU GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License applies to any program or other work which contains\na notice placed by the copyright holder saying it may be distributed\nunder the terms of this General Public License.  The \"Program\", below,\nrefers to any such program or work, and a \"work based on the Program\"\nmeans either the Program or any derivative work under copyright law:\nthat is to say, a work containing the Program or a portion of it,\neither verbatim or with modifications and/or translated into another\nlanguage.  (Hereinafter, translation is included without limitation in\nthe term \"modification\".)  Each licensee is addressed as \"you\".\n\nActivities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning the Program is not restricted, and the output from the Program\nis covered only if its contents constitute a work based on the\nProgram (independent of having been made by running the Program).\nWhether that is true depends on what the Program does.\n\n  1. You may copy and distribute verbatim copies of the Program's\nsource code as you receive it, in any medium, provided that you\nconspicuously and appropriately publish on each copy an appropriate\ncopyright notice and disclaimer of warranty; keep intact all the\nnotices that refer to this License and to the absence of any warranty;\nand give any other recipients of the Program a copy of this License\nalong with the Program.\n\nYou may charge a fee for the physical act of transferring a copy, and\nyou may at your option offer warranty protection in exchange for a fee.\n\n  2. You may modify your copy or copies of the Program or any portion\nof it, thus forming a work based on the Program, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) You must cause the modified files to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    b) You must cause any work that you distribute or publish, that in\n    whole or in part contains or is derived from the Program or any\n    part thereof, to be licensed as a whole at no charge to all third\n    parties under the terms of this License.\n\n    c) If the modified program normally reads commands interactively\n    when run, you must cause it, when started running for such\n    interactive use in the most ordinary way, to print or display an\n    announcement including an appropriate copyright notice and a\n    notice that there is no warranty (or else, saying that you provide\n    a warranty) and that users may redistribute the program under\n    these conditions, and telling the user how to view a copy of this\n    License.  (Exception: if the Program itself is interactive but\n    does not normally print such an announcement, your work based on\n    the Program is not required to print an announcement.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Program,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Program, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote it.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Program.\n\nIn addition, mere aggregation of another work not based on the Program\nwith the Program (or with a work based on the Program) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may copy and distribute the Program (or a work based on it,\nunder Section 2) in object code or executable form under the terms of\nSections 1 and 2 above provided that you also do one of the following:\n\n    a) Accompany it with the complete corresponding machine-readable\n    source code, which must be distributed under the terms of Sections\n    1 and 2 above on a medium customarily used for software interchange; or,\n\n    b) Accompany it with a written offer, valid for at least three\n    years, to give any third party, for a charge no more than your\n    cost of physically performing source distribution, a complete\n    machine-readable copy of the corresponding source code, to be\n    distributed under the terms of Sections 1 and 2 above on a medium\n    customarily used for software interchange; or,\n\n    c) Accompany it with the information you received as to the offer\n    to distribute corresponding source code.  (This alternative is\n    allowed only for noncommercial distribution and only if you\n    received the program in object code or executable form with such\n    an offer, in accord with Subsection b above.)\n\nThe source code for a work means the preferred form of the work for\nmaking modifications to it.  For an executable work, complete source\ncode means all the source code for all modules it contains, plus any\nassociated interface definition files, plus the scripts used to\ncontrol compilation and installation of the executable.  However, as a\nspecial exception, the source code distributed need not include\nanything that is normally distributed (in either source or binary\nform) with the major components (compiler, kernel, and so on) of the\noperating system on which the executable runs, unless that component\nitself accompanies the executable.\n\nIf distribution of executable or object code is made by offering\naccess to copy from a designated place, then offering equivalent\naccess to copy the source code from the same place counts as\ndistribution of the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  4. You may not copy, modify, sublicense, or distribute the Program\nexcept as expressly provided under this License.  Any attempt\notherwise to copy, modify, sublicense or distribute the Program is\nvoid, and will automatically terminate your rights under this License.\nHowever, parties who have received copies, or rights, from you under\nthis License will not have their licenses terminated so long as such\nparties remain in full compliance.\n\n  5. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Program or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Program (or any work based on the\nProgram), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Program or works based on it.\n\n  6. Each time you redistribute the Program (or any work based on the\nProgram), the recipient automatically receives a license from the\noriginal licensor to copy, distribute or modify the Program subject to\nthese terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties to\nthis License.\n\n  7. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Program at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Program by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Program.\n\nIf any portion of this section is held invalid or unenforceable under\nany particular circumstance, the balance of the section is intended to\napply and the section as a whole is intended to apply in other\ncircumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system, which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  8. If the distribution and/or use of the Program is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Program under this License\nmay add an explicit geographical distribution limitation excluding\nthose countries, so that distribution is permitted only in or among\ncountries not thus excluded.  In such case, this License incorporates\nthe limitation as if written in the body of this License.\n\n  9. The Free Software Foundation may publish revised and/or new versions\nof the General Public License from time to time.  Such new versions will\nbe similar in spirit to the present version, but may differ in detail to\naddress new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Program\nspecifies a version number of this License which applies to it and \"any\nlater version\", you have the option of following the terms and conditions\neither of that version or of any later version published by the Free\nSoftware Foundation.  If the Program does not specify a version number of\nthis License, you may choose any version ever published by the Free Software\nFoundation.\n\n  10. If you wish to incorporate parts of the Program into other free\nprograms whose distribution conditions are different, write to the author\nto ask for permission.  For software which is copyrighted by the Free\nSoftware Foundation, write to the Free Software Foundation; we sometimes\nmake exceptions for this.  Our decision will be guided by the two goals\nof preserving the free status of all derivatives of our free software and\nof promoting the sharing and reuse of software generally.\n\n                            NO WARRANTY\n\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\nREPAIR OR CORRECTION.\n\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGES.\n\n                     END OF TERMS AND CONDITIONS\n\n            How to Apply These Terms to Your New Programs\n\n  If you develop a new program, and you want it to be of the greatest\npossible use to the public, the best way to achieve this is to make it\nfree software which everyone can redistribute and change under these terms.\n\n  To do so, attach the following notices to the program.  It is safest\nto attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least\nthe \"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the program's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License along\n    with this program; if not, write to the Free Software Foundation, Inc.,\n    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.\n\nAlso add information on how to contact you by electronic and paper mail.\n\nIf the program is interactive, make it output a short notice like this\nwhen it starts in an interactive mode:\n\n    Gnomovision version 69, Copyright (C) year name of author\n    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.\n    This is free software, and you are welcome to redistribute it\n    under certain conditions; type `show c' for details.\n\nThe hypothetical commands `show w' and `show c' should show the appropriate\nparts of the General Public License.  Of course, the commands you use may\nbe called something other than `show w' and `show c'; they could even be\nmouse-clicks or menu items--whatever suits your program.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the program, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the program\n  `Gnomovision' (which makes passes at compilers) written by James Hacker.\n\n  <signature of Ty Coon>, 1 April 1989\n  Ty Coon, President of Vice\n\nThis General Public License does not permit incorporating your program into\nproprietary programs.  If your program is a subroutine library, you may\nconsider it more useful to permit linking proprietary applications with the\nlibrary.  If this is what you want to do, use the GNU Lesser General\nPublic License instead of this License.\n"
  },
  {
    "path": "third_party/cram/MANIFEST.in",
    "content": "include .coveragerc .pylintrc .travis.yml Makefile MANIFEST.in\ninclude *.md *.rst *.txt contrib/* scripts/*\nexclude contrib/PKGBUILD\nrecursive-include examples *.t\nrecursive-include tests *.py *.sh *.t\n"
  },
  {
    "path": "third_party/cram/NEWS.rst",
    "content": "======\n News\n======\n\nVersion 0.7 (Feb. 24, 2016)\n---------------------------\n\n* Added the ``-d``/``--debug`` flag that disables diffing of\n  expected/actual output and instead passes through script output to\n  ``stdout``/``stderr``.\n\n* Added the ``--shell-opts`` flag for specifying flags to invoke the\n  shell with. By setting ``--shell-opts='-x'`` and ``--debug``\n  together, this can be used to see shell commands as they're run and\n  their output in real time which can be useful for debugging slow or\n  hanging tests.\n\n* Added xUnit XML output support (for better integration of test\n  results with Bamboo and other continuous integration tools).\n\n* Added support for using (esc) on expected out lines that aren't\n  automatically escaped in actual output.\n\n* Added the ``$TESTSHELL`` environment variable. This allows a test to\n  portably check what shell it was invoked with.\n\n* Added an error message for when no tests are found in a directory.\n\n* Changed ``Makefile`` to install into ``/usr/local`` by default.\n\n* Simplified the ``Makefile``'s targets. The targets available now are\n  ``all``, ``build``, ``check``/``test``, ``clean``, ``dist``,\n  ``install``, and ``quicktest`` (for running the test suite without\n  checking test coverage).\n\n* Fixed non-ASCII strings not being escaped with ``(esc)`` on Python 3.\n\n* Fixed a crash on tests that don't have a trailing newline.\n\n* Fixed a crash when using ``set -x`` with zsh.\n\n\nVersion 0.6 (Aug. 1, 2013)\n--------------------------\n\n* Added the long option ``--preserve-env`` for ``-E``.\n\n* Added support for specifying options in ``.cramrc`` (configurable\n  with the ``CRAMRC`` environment variable).\n\n* Added a ``--shell`` option to change the shell tests are run\n  with. Contributed by `Kamil Kisiel`_.\n\n* Added Arch Linux package metadata (in ``contrib/``). Contributed by\n  `Andrey Vlasovskikh`_.\n\n* Fixed shell commands unintentionally inheriting Python's ``SIGPIPE``\n  handler (causing commands that close pipes to print ``broken pipe``\n  messages).\n\n* Fixed ``EPIPE`` under PyPy when applying patches in\n  ``--interactive`` mode.\n\n* Added ``TESTFILE`` test environment variable (set to the name of the\n  current test).\n\n* Fixed GNU patch 2.7 compatibility by using relative paths instead of\n  absolute paths. Contributed by `Douglas Creager`_.\n\n* Fixed name clashes in temporary test directories (e.g., when running\n  two tests with the same name in different folders).\n\n* **Backwards compatibility:** Fixed improper usage of the subprocess\n  library under Python 3. This fixes Python 3.3 support, but breaks\n  support for Python 3.1-3.2.3 due to a bug in Python. If you're using\n  Python 3.0-3.2, you must upgrade to Python 3.2.4 or newer.\n\n.. _Kamil Kisiel: http://kamilkisiel.net/\n.. _Andrey Vlasovskikh: https://twitter.com/vlasovskikh\n.. _Douglas Creager: http://dcreager.net/\n\n\nVersion 0.5 (Jan. 8, 2011)\n--------------------------\n\n* **The test format has changed:** Matching output not ending in a\n  newline now requires the ``(no-eol)`` keyword instead of ending the\n  line in ``%``.\n\n* Matching output containing unprintable characters now requires the\n  ``(esc)`` keyword. Real output containing unprintable characters\n  will automatically receive ``(esc)``.\n\n* If an expected line matches its real output line exactly, special\n  matching like ``(re)`` or ``(glob)`` will be ignored.\n\n* Regular expressions ending in a trailing backslash are now\n  considered invalid.\n\n* Added an ``--indent`` option for changing the default amount of\n  indentation required to specify commands and output.\n\n* Added support for specifying command line options in the ``CRAM``\n  environment variable.\n\n* The ``--quiet`` and ``--verbose`` options can now be used together.\n\n* When running Cram under Python 3, Unicode-specific line break\n  characters will no longer be parsed as newlines.\n\n* Tests are no longer required to end in a trailing newline.\n\n\nVersion 0.4 (Sep. 28, 2010)\n---------------------------\n\n* **The test format has changed:** Output lines containing regular\n  expressions must now end in ``(re)`` or they'll be matched\n  literally. Lines ending with keywords are matched literally first,\n  however.\n\n* Regular expressions are now matched from beginning to end. In other\n  words ``\\d (re)`` is matched as ``^\\d$``.\n\n* In addition to ``(re)``, ``(glob)`` has been added. It supports\n  ``*``, ``?``, and escaping both characters (and backslashes) using\n  ``\\``.\n\n* **Environment settings have changed:** The ``-D`` flag has been\n  removed, ``$TESTDIR`` is now set to the directory containing the\n  ``.t`` file, and ``$CRAMTMP`` is set to the test runner's temporary\n  directory.\n\n* ``-i``/``--interactive`` now requires ``patch(1)``. Instead of\n  ``.err`` files replacing ``.t`` files during merges, diffs are\n  applied using ``patch(1)``. This prevents matching regular\n  expressions and globs from getting clobbered.\n\n* Previous ``.err`` files are now removed when tests pass.\n\n* Cram now exits with return code ``1`` if any tests failed.\n\n* If a test exits with return code ``80``, it's considered a skipped a\n  test. This is useful for intentionally disabling tests when they\n  only work on certain platforms or in certain settings.\n\n* The number of tests, the number of skipped tests, and the number of\n  failed tests are now printed after all tests are finished.\n\n* Added ``-q``/``--quiet`` to suppress diff output.\n\n* Added `contrib/cram.vim`_ syntax file for Vim. Contributed by `Steve\n  Losh`_.\n\n.. _contrib/cram.vim: https://bitbucket.org/brodie/cram/src/default/contrib/cram.vim\n.. _Steve Losh: http://stevelosh.com/\n\n\nVersion 0.3 (Sep. 20, 2010)\n---------------------------\n\n* Implemented resetting of common environment variables. This behavior\n  can be disabled using the ``-E`` flag.\n\n* Changed the test runner to first make its own overall random\n  temporary directory, make ``tmp`` inside of it and set ``TMPDIR``,\n  etc. to its path, and run each test with a random temporary working\n  directory inside of that.\n\n* Added ``--keep-tmpdir``. Temporary directories are named by test\n  filename (along with a random string).\n\n* Added ``-i``/``--interactive`` to merge actual output back to into\n  tests interactively.\n\n* Added ability to match command output not ending in a newline by\n  suffixing output in the test with ``%``.\n\n\nVersion 0.2 (Sep. 19, 2010)\n---------------------------\n\n* Changed the test runner to run tests with a random temporary working\n  directory.\n\n\nVersion 0.1 (Sep. 19, 2010)\n---------------------------\n\n* Initial release.\n"
  },
  {
    "path": "third_party/cram/README.rst",
    "content": "======================\n Cram: It's test time\n======================\n\nCram is a functional testing framework for command line applications.\nCram tests look like snippets of interactive shell sessions. Cram runs\neach command and compares the command output in the test with the\ncommand's actual output.\n\nHere's a snippet from `Cram's own test suite`_::\n\n    The $PYTHON environment variable should be set when running this test\n    from Python.\n\n      $ [ -n \"$PYTHON\" ] || PYTHON=\"`which python`\"\n      $ [ -n \"$PYTHONPATH\" ] || PYTHONPATH=\"$TESTDIR/..\" && export PYTHONPATH\n      $ if [ -n \"$COVERAGE\" ]; then\n      >   coverage erase\n      >   alias cram=\"`which coverage` run --branch -a $TESTDIR/../scripts/cram\"\n      > else\n      >   alias cram=\"$PYTHON $TESTDIR/../scripts/cram\"\n      > fi\n      $ command -v md5 > /dev/null || alias md5=md5sum\n\n    Usage:\n\n      $ cram -h\n      [Uu]sage: cram \\[OPTIONS\\] TESTS\\.\\.\\. (re)\n\n      [Oo]ptions: (re)\n        -h, --help          show this help message and exit\n        -V, --version       show version information and exit\n        -q, --quiet         don't print diffs\n        -v, --verbose       show filenames and test status\n        -i, --interactive   interactively merge changed test output\n        -d, --debug         write script output directly to the terminal\n        -y, --yes           answer yes to all questions\n        -n, --no            answer no to all questions\n        -E, --preserve-env  don't reset common environment variables\n\t-e, --no-err-files  don't write .err files on test failures\n        --keep-tmpdir       keep temporary directories\n        --shell=PATH        shell to use for running tests (default: /bin/sh)\n        --shell-opts=OPTS   arguments to invoke shell with\n        --indent=NUM        number of spaces to use for indentation (default: 2)\n        --xunit-file=PATH   path to write xUnit XML output\n\nThe format in a nutshell:\n\n* Cram tests use the ``.t`` file extension.\n\n* Lines beginning with two spaces, a dollar sign, and a space are run\n  in the shell.\n\n* Lines beginning with two spaces, a greater than sign, and a space\n  allow multi-line commands.\n\n* All other lines beginning with two spaces are considered command\n  output.\n\n* Output lines ending with a space and the keyword ``(re)`` are\n  matched as `Perl-compatible regular expressions`_.\n\n* Lines ending with a space and the keyword ``(glob)`` are matched\n  with a glob-like syntax. The only special characters supported are\n  ``*`` and ``?``. Both characters can be escaped using ``\\``, and the\n  backslash can be escaped itself.\n\n* Output lines ending with either of the above keywords are always\n  first matched literally with actual command output.\n\n* Lines ending with a space and the keyword ``(no-eol)`` will match\n  actual output that doesn't end in a newline.\n\n* Actual output lines containing unprintable characters are escaped\n  and suffixed with a space and the keyword ``(esc)``. Lines matching\n  unprintable output must also contain the keyword.\n\n* Anything else is a comment.\n\n.. _Cram's own test suite: https://bitbucket.org/brodie/cram/src/0.6/tests/cram.t\n.. _Perl-compatible regular expressions: https://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions\n\n\nDownload\n--------\n\n* `cram-0.7.tar.gz`_ (32 KB, requires Python 2.4-2.7 or Python 3.1 or newer)\n\n.. _cram-0.7.tar.gz: https://bitheap.org/cram/cram-0.7.tar.gz\n\n\nInstallation\n------------\n\nInstall Cram using make::\n\n    $ wget https://bitheap.org/cram/cram-0.7.tar.gz\n    $ tar zxvf cram-0.7.tar.gz\n    $ cd cram-0.7\n    $ make install\n\n\nUsage\n-----\n\nCram will print a dot for each passing test. If a test fails, a\n`unified context diff`_ is printed showing the test's expected output\nand the actual output. Skipped tests (empty tests and tests that exit\nwith return code ``80``) are marked with ``s`` instead of a dot.\n\nFor example, if we run Cram on `its own example tests`_::\n\n    .s.!\n    --- examples/fail.t\n    +++ examples/fail.t.err\n    @@ -3,21 +3,22 @@\n       $ echo 1\n       1\n       $ echo 1\n    -  2\n    +  1\n       $ echo 1\n       1\n\n     Invalid regex:\n\n       $ echo 1\n    -  +++ (re)\n    +  1\n\n     Offset regular expression:\n\n       $ printf 'foo\\nbar\\nbaz\\n\\n1\\nA\\n@\\n'\n       foo\n    +  bar\n       baz\n\n       \\d (re)\n       [A-Z] (re)\n    -  #\n    +  @\n    s.\n    # Ran 6 tests, 2 skipped, 1 failed.\n\nUnless run with ``-e`` or ``--no-err-files``, Cram will also write the\ntest with its actual output to ``examples/fail.t.err``, allowing you to\nuse other diff tools. This file is automatically removed the next time\nthe test passes.\n\nWhen you're first writing a test, you might just write the commands\nand run the test to see what happens. If you run Cram with ``-i`` or\n``--interactive``, you'll be prompted to merge the actual output back\ninto the test. This makes it easy to quickly prototype new tests.\n\nYou can specify a default set of options by creating a ``.cramrc``\nfile. For example::\n\n    [cram]\n    verbose = True\n    indent = 4\n\nIs the same as invoking Cram with ``--verbose`` and ``--indent=4``.\n\nTo change what configuration file Cram loads, you can set the\n``CRAMRC`` environment variable. You can also specify command line\noptions in the ``CRAM`` environment variable.\n\nNote that the following environment variables are reset before tests\nare run:\n\n* ``TMPDIR``, ``TEMP``, and ``TMP`` are set to the test runner's\n  ``tmp`` directory.\n\n* ``LANG``, ``LC_ALL``, and ``LANGUAGE`` are set to ``C``.\n\n* ``TZ`` is set to ``GMT``.\n\n* ``COLUMNS`` is set to ``80``. (Note: When using ``--shell=zsh``,\n  this cannot be reset. It will reflect the actual terminal's width.)\n\n* ``CDPATH`` and ``GREP_OPTIONS`` are set to an empty string.\n\nCram also provides the following environment variables to tests:\n\n* ``CRAMTMP``, set to the test runner's temporary directory.\n\n* ``TESTDIR``, set to the directory containing the test file.\n\n* ``TESTFILE``, set to the basename of the current test file.\n\n* ``TESTSHELL``, set to the value specified by ``--shell``.\n\nAlso note that care should be taken with commands that close the test\nshell's ``stdin``. For example, if you're trying to invoke ``ssh`` in\na test, try adding the ``-n`` option to prevent it from closing\n``stdin``. Similarly, if you invoke a daemon process that inherits\n``stdout`` and fails to close it, it may cause Cram to hang while\nwaiting for the test shell's ``stdout`` to be fully closed.\n\n.. _unified context diff: https://en.wikipedia.org/wiki/Diff#Unified_format\n.. _its own example tests: https://bitbucket.org/brodie/cram/src/default/examples/\n\n\nDevelopment\n-----------\n\nDownload the official development repository using Mercurial_::\n\n    hg clone https://bitbucket.org/brodie/cram\n\nOr Git_::\n\n    git clone https://github.com/brodie/cram.git\n\nTest Cram using Cram::\n\n    pip install -r requirements.txt\n    make test\n\nVisit Bitbucket_ or GitHub_ if you'd like to fork the project, watch\nfor new changes, or report issues.\n\n.. _Mercurial: http://mercurial.selenic.com/\n.. _Git: http://git-scm.com/\n.. _coverage.py: http://nedbatchelder.com/code/coverage/\n.. _Bitbucket: https://bitbucket.org/brodie/cram\n.. _GitHub: https://github.com/brodie/cram\n"
  },
  {
    "path": "third_party/cram/TODO.md",
    "content": "* Add more comments explaining how different parts of the code work.\n\n* Add a man page.\n\n* Implement string substitutions (e.g., --substitute=FOOPORT=123).\n\n* Conditionals (e.g., --define=windows=1, #if windows ... #else ...\n  #endif).\n\n* Support #!/usr/bin/env cram\n\n* Support .cramrc in test directories. Though, if I do this, what happens\n  when there are multiple .cramrc files? Does the deepest one completely\n  override the others? Do they merge together?\n\n* Homebrew formula.\n\n* Debian, Ubuntu, CentOS/RHEL repos.\n\n* Implement a test that does stricter style guide testing.\n\n* Write contributor guidelines.\n\n* Get the test suite running on AppVeyor under MSYS2.\n\n  - http://help.appveyor.com/discussions/suggestions/615-support-for-msys2\n  - https://github.com/behdad/harfbuzz/pull/112/files\n  - https://github.com/khaledhosny/ots/pull/67/files\n  - https://github.com/appveyor/ci/issues/352#issuecomment-138149606\n  - https://github.com/appveyor/ci/issues/597\n  - http://www.appveyor.com\n\n* Get the test suite fully passing with Python.org's Windows\n  distribution.\n\n* Global setup/teardown support.\n\n* Local setup/teardown? This is technically already supported via\n  sourcing scripts and using exit traps, but dedicated syntax might be\n  nice (e.g., #setup ... #endsetup? or maybe just #teardown ...\n  #endteardown or #finally ... #endfinally?).\n\n* Implement -j flag for concurrency.\n\n* Flexible indentation support (with an algorithm similar to Python's\n  for detecting indentation on a per-block basis).\n\n* Some sort of plugin system (one that doesn't require writing plugins\n  in Python) that allows basic extension of Cram's functionality (and\n  possibly even syntax, though perhaps limited to just \"macros\" like\n  #foo, #bar, etc. and matchers like (baz), (quux), etc.).\n\n* Be able to run the Mercurial test suite.\n\n* Write cram plugins for other testing frameworks (nose, py.test,\n  etc.).\n\n* Somehow make it possible to specify tests in Python doc\n  strings (and similar things in other languages like Perl, Ruby,\n  etc.).\n\n* Emacs mode.\n"
  },
  {
    "path": "third_party/cram/contrib/PKGBUILD",
    "content": "# Maintainer: Andrey Vlasovskikh <andrey.vlasovskikh@gmail.com>\n\npkgname=cram\npkgver=0.7\npkgrel=1\npkgdesc=\"Functional tests for command line applications\"\narch=(any)\nurl=\"https://bitheap.org/cram/\"\nlicense=('GPL')\ndepends=('python')\nsource=(\"https://pypi.python.org/packages/source/c/cram/cram-$pkgver.tar.gz\")\nmd5sums=('2ea37ada5190526b9bcaac5e4099221c')\n\nbuild() {\n    cd \"$srcdir/$pkgname-$pkgver\"\n    python setup.py install --root=\"$pkgdir/\" --optimize=1\n}\n"
  },
  {
    "path": "third_party/cram/contrib/cram.vim",
    "content": "\" Vim syntax file\n\" Language: Cram Tests\n\" Author: Steve Losh (steve@stevelosh.com)\n\"\n\" Add the following line to your ~/.vimrc to enable:\n\" au BufNewFile,BufRead *.t set filetype=cram\n\"\n\" If you want folding you'll need the following line as well:\n\" let cram_fold=1\n\"\n\" You might also want to set the starting foldlevel for Cram files:\n\" autocmd Syntax cram setlocal foldlevel=1\n\nif exists(\"b:current_syntax\")\n  finish\nendif\n\nsyn include @Shell syntax/sh.vim\n\nsyn match cramComment /^[^ ].*$/ contains=@Spell\nsyn region cramOutput start=/^  [^$>]/ start=/^  $/ end=/\\v.(\\n\\n*[^ ])\\@=/me=s end=/^  [$>]/me=e-3 end=/^$/ fold containedin=cramBlock\nsyn match cramCommandStart /^  \\$ / containedin=cramCommand\nsyn region cramCommand start=/^  \\$ /hs=s+4,rs=s+4 end=/^  [^>]/me=e-3 end=/^  $/me=e-2 containedin=cramBlock contains=@Shell keepend\nsyn region cramBlock start=/^  /ms=e-2 end=/\\v.(\\n\\n*[^ ])\\@=/me=s end=/^$/me=e-1 fold keepend\n\nhi link cramCommandStart Keyword\nhi link cramComment Normal\nhi link cramOutput Comment\n\nif exists(\"cram_fold\")\n  setlocal foldmethod=syntax\nendif\n\nsyn sync match cramSync grouphere NONE \"^$\"\nsyn sync maxlines=200\n\n\" It's okay to set tab settings here, because an indent of two spaces is specified\n\" by the file format.\nsetlocal tabstop=2 softtabstop=2 shiftwidth=2 expandtab\n\nlet b:current_syntax = \"cram\"\n"
  },
  {
    "path": "third_party/cram/cram/__init__.py",
    "content": "\"\"\"Functional testing framework for command line applications\"\"\"\n\nfrom cram._main import main\nfrom cram._test import test, testfile\n\n__all__ = ['main', 'test', 'testfile']\n"
  },
  {
    "path": "third_party/cram/cram/__main__.py",
    "content": "\"\"\"Main module (invoked by \"python -m cram\")\"\"\"\n\nimport sys\n\nimport cram\n\ntry:\n    sys.exit(cram.main(sys.argv[1:]))\nexcept KeyboardInterrupt:\n    pass\n"
  },
  {
    "path": "third_party/cram/cram/_cli.py",
    "content": "\"\"\"The command line interface implementation\"\"\"\n\nimport os\nimport sys\n\nfrom cram._encoding import b, bytestype, stdoutb\nfrom cram._process import execute\n\n__all__ = ['runcli']\n\ndef _prompt(question, answers, auto=None):\n    \"\"\"Write a prompt to stdout and ask for answer in stdin.\n\n    answers should be a string, with each character a single\n    answer. An uppercase letter is considered the default answer.\n\n    If an invalid answer is given, this asks again until it gets a\n    valid one.\n\n    If auto is set, the question is answered automatically with the\n    specified value.\n    \"\"\"\n    default = [c for c in answers if c.isupper()]\n    while True:\n        sys.stdout.write('%s [%s] ' % (question, answers))\n        sys.stdout.flush()\n        if auto is not None:\n            sys.stdout.write(auto + '\\n')\n            sys.stdout.flush()\n            return auto\n\n        answer = sys.stdin.readline().strip().lower()\n        if not answer and default:\n            return default[0]\n        elif answer and answer in answers.lower():\n            return answer\n\ndef _log(msg=None, verbosemsg=None, verbose=False):\n    \"\"\"Write msg to standard out and flush.\n\n    If verbose is True, write verbosemsg instead.\n    \"\"\"\n    if verbose:\n        msg = verbosemsg\n    if msg:\n        if isinstance(msg, bytestype):\n            stdoutb.write(msg)\n        else: # pragma: nocover\n            sys.stdout.write(msg)\n        sys.stdout.flush()\n\ndef _patch(cmd, diff):\n    \"\"\"Run echo [lines from diff] | cmd -p0\"\"\"\n    out, retcode = execute([cmd, '-p0'], stdin=b('').join(diff))\n    return retcode == 0\n\ndef runcli(tests, quiet=False, verbose=False, patchcmd=None, answer=None,\n           noerrfiles=False):\n    \"\"\"Run tests with command line interface input/output.\n\n    tests should be a sequence of 2-tuples containing the following:\n\n        (test path, test function)\n\n    This function yields a new sequence where each test function is wrapped\n    with a function that handles CLI input/output.\n\n    If quiet is True, diffs aren't printed. If verbose is True,\n    filenames and status information are printed.\n\n    If patchcmd is set, a prompt is written to stdout asking if\n    changed output should be merged back into the original test. The\n    answer is read from stdin. If 'y', the test is patched using patch\n    based on the changed output.\n    \"\"\"\n    total, skipped, failed = [0], [0], [0]\n\n    for path, test in tests:\n        def testwrapper():\n            \"\"\"Test function that adds CLI output\"\"\"\n            total[0] += 1\n            _log(None, path + b(': '), verbose)\n\n            refout, postout, diff = test()\n            if refout is None:\n                skipped[0] += 1\n                _log('s', 'empty\\n', verbose)\n                return refout, postout, diff\n\n            abspath = os.path.abspath(path)\n            errpath = abspath + b('.err')\n\n            if postout is None:\n                skipped[0] += 1\n                _log('s', 'skipped\\n', verbose)\n            elif not diff:\n                _log('.', 'passed\\n', verbose)\n                if os.path.exists(errpath):\n                    os.remove(errpath)\n            else:\n                failed[0] += 1\n                _log('!', 'failed\\n', verbose)\n                if not quiet:\n                    _log('\\n', None, verbose)\n\n                if not noerrfiles:\n                    errfile = open(errpath, 'wb')\n                    try:\n                        for line in postout:\n                            errfile.write(line)\n                    finally:\n                        errfile.close()\n\n                if not quiet:\n                    origdiff = diff\n                    diff = []\n                    for line in origdiff:\n                        stdoutb.write(line)\n                        diff.append(line)\n\n                    if (patchcmd and\n                        _prompt('Accept this change?', 'yN', answer) == 'y'):\n                        if _patch(patchcmd, diff):\n                            _log(None, path + b(': merged output\\n'), verbose)\n                            if not noerrfiles:\n                                os.remove(errpath)\n                        else:\n                            _log(path + b(': merge failed\\n'))\n\n            return refout, postout, diff\n\n        yield (path, testwrapper)\n\n    if total[0] > 0:\n        _log('\\n', None, verbose)\n        _log('# Ran %s tests, %s skipped, %s failed.\\n'\n             % (total[0], skipped[0], failed[0]))\n"
  },
  {
    "path": "third_party/cram/cram/_diff.py",
    "content": "\"\"\"Utilities for diffing test files and their output\"\"\"\n\nimport codecs\nimport difflib\nimport re\n\nfrom cram._encoding import b\n\n__all__ = ['esc', 'glob', 'regex', 'unified_diff']\n\ndef _regex(pattern, s):\n    \"\"\"Match a regular expression or return False if invalid.\n\n    >>> from cram._encoding import b\n    >>> [bool(_regex(r, b('foobar'))) for r in (b('foo.*'), b('***'))]\n    [True, False]\n    \"\"\"\n    try:\n        return re.match(pattern + b(r'\\Z'), s)\n    except re.error:\n        return False\n\ndef _glob(el, l):\n    r\"\"\"Match a glob-like pattern.\n\n    The only supported special characters are * and ?. Escaping is\n    supported.\n\n    >>> from cram._encoding import b\n    >>> bool(_glob(b(r'\\* \\\\ \\? fo?b*'), b('* \\\\ ? foobar')))\n    True\n    \"\"\"\n    i, n = 0, len(el)\n    res = b('')\n    while i < n:\n        c = el[i:i + 1]\n        i += 1\n        if c == b('\\\\') and el[i] in b('*?\\\\'):\n            res += el[i - 1:i + 1]\n            i += 1\n        elif c == b('*'):\n            res += b('.*')\n        elif c == b('?'):\n            res += b('.')\n        else:\n            res += re.escape(c)\n    return _regex(res, l)\n\ndef _matchannotation(keyword, matchfunc, el, l):\n    \"\"\"Apply match function based on annotation keyword\"\"\"\n    ann = b(' (%s)\\n' % keyword)\n    return el.endswith(ann) and matchfunc(el[:-len(ann)], l[:-1])\n\ndef regex(el, l):\n    \"\"\"Apply a regular expression match to a line annotated with '(re)'\"\"\"\n    return _matchannotation('re', _regex, el, l)\n\ndef glob(el, l):\n    \"\"\"Apply a glob match to a line annotated with '(glob)'\"\"\"\n    return _matchannotation('glob', _glob, el, l)\n\ndef esc(el, l):\n    \"\"\"Apply an escape match to a line annotated with '(esc)'\"\"\"\n    ann = b(' (esc)\\n')\n\n    if el.endswith(ann):\n        el = codecs.escape_decode(el[:-len(ann)])[0] + b('\\n')\n    if el == l:\n        return True\n\n    if l.endswith(ann):\n        l = codecs.escape_decode(l[:-len(ann)])[0] + b('\\n')\n    return el == l\n\nclass _SequenceMatcher(difflib.SequenceMatcher, object):\n    \"\"\"Like difflib.SequenceMatcher, but supports custom match functions\"\"\"\n    def __init__(self, *args, **kwargs):\n        self._matchers = kwargs.pop('matchers', [])\n        super(_SequenceMatcher, self).__init__(*args, **kwargs)\n\n    def _match(self, el, l):\n        \"\"\"Tests for matching lines using custom matchers\"\"\"\n        for matcher in self._matchers:\n            if matcher(el, l):\n                return True\n        return False\n\n    def find_longest_match(self, alo, ahi, blo, bhi):\n        \"\"\"Find longest matching block in a[alo:ahi] and b[blo:bhi]\"\"\"\n        # SequenceMatcher uses find_longest_match() to slowly whittle down\n        # the differences between a and b until it has each matching block.\n        # Because of this, we can end up doing the same matches many times.\n        matches = []\n        for n, (el, line) in enumerate(zip(self.a[alo:ahi], self.b[blo:bhi])):\n            if el != line and self._match(el, line):\n                # This fools the superclass's method into thinking that the\n                # regex/glob in a is identical to b by replacing a's line (the\n                # expected output) with b's line (the actual output).\n                self.a[alo + n] = line\n                matches.append((n, el))\n        ret = super(_SequenceMatcher, self).find_longest_match(alo, ahi,\n                                                               blo, bhi)\n        # Restore the lines replaced above. Otherwise, the diff output\n        # would seem to imply that the tests never had any regexes/globs.\n        for n, el in matches:\n            self.a[alo + n] = el\n        return ret\n\ndef unified_diff(l1, l2, fromfile=b(''), tofile=b(''), fromfiledate=b(''),\n                 tofiledate=b(''), n=3, lineterm=b('\\n'), matchers=None):\n    r\"\"\"Compare two sequences of lines; generate the delta as a unified diff.\n\n    This is like difflib.unified_diff(), but allows custom matchers.\n\n    >>> from cram._encoding import b\n    >>> l1 = [b('a\\n'), b('? (glob)\\n')]\n    >>> l2 = [b('a\\n'), b('b\\n')]\n    >>> (list(unified_diff(l1, l2, b('f1'), b('f2'), b('1970-01-01'),\n    ...                    b('1970-01-02'))) ==\n    ...  [b('--- f1\\t1970-01-01\\n'), b('+++ f2\\t1970-01-02\\n'),\n    ...   b('@@ -1,2 +1,2 @@\\n'), b(' a\\n'), b('-? (glob)\\n'), b('+b\\n')])\n    True\n\n    >>> from cram._diff import glob\n    >>> list(unified_diff(l1, l2, matchers=[glob]))\n    []\n    \"\"\"\n    if matchers is None:\n        matchers = []\n    started = False\n    matcher = _SequenceMatcher(None, l1, l2, matchers=matchers)\n    for group in matcher.get_grouped_opcodes(n):\n        if not started:\n            if fromfiledate:\n                fromdate = b('\\t') + fromfiledate\n            else:\n                fromdate = b('')\n            if tofiledate:\n                todate = b('\\t') + tofiledate\n            else:\n                todate = b('')\n            yield b('--- ') + fromfile + fromdate + lineterm\n            yield b('+++ ') + tofile + todate + lineterm\n            started = True\n        i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4]\n        yield (b(\"@@ -%d,%d +%d,%d @@\" % (i1 + 1, i2 - i1, j1 + 1, j2 - j1)) +\n               lineterm)\n        for tag, i1, i2, j1, j2 in group:\n            if tag == 'equal':\n                for line in l1[i1:i2]:\n                    yield b(' ') + line\n                continue\n            if tag == 'replace' or tag == 'delete':\n                for line in l1[i1:i2]:\n                    yield b('-') + line\n            if tag == 'replace' or tag == 'insert':\n                for line in l2[j1:j2]:\n                    yield b('+') + line\n"
  },
  {
    "path": "third_party/cram/cram/_encoding.py",
    "content": "\"\"\"Encoding utilities\"\"\"\n\nimport os\nimport sys\n\ntry:\n    import builtins\nexcept ImportError:\n    import __builtin__ as builtins\n\n__all__ = ['b', 'bchr', 'bytestype', 'envencode', 'fsdecode', 'fsencode',\n           'stdoutb', 'stderrb', 'u', 'ul', 'unicodetype']\n\nbytestype = getattr(builtins, 'bytes', str)\nunicodetype = getattr(builtins, 'unicode', str)\n\nif getattr(os, 'fsdecode', None) is not None:\n    fsdecode = os.fsdecode\n    fsencode = os.fsencode\nelif bytestype is not str:\n    if sys.platform == 'win32':\n        def fsdecode(s):\n            \"\"\"Decode a filename from the filesystem encoding\"\"\"\n            if isinstance(s, unicodetype):\n                return s\n            encoding = sys.getfilesystemencoding()\n            if encoding == 'mbcs':\n                return s.decode(encoding)\n            else:\n                return s.decode(encoding, 'surrogateescape')\n\n        def fsencode(s):\n            \"\"\"Encode a filename to the filesystem encoding\"\"\"\n            if isinstance(s, bytestype):\n                return s\n            encoding = sys.getfilesystemencoding()\n            if encoding == 'mbcs':\n                return s.encode(encoding)\n            else:\n                return s.encode(encoding, 'surrogateescape')\n    else:\n        def fsdecode(s):\n            \"\"\"Decode a filename from the filesystem encoding\"\"\"\n            if isinstance(s, unicodetype):\n                return s\n            return s.decode(sys.getfilesystemencoding(), 'surrogateescape')\n\n        def fsencode(s):\n            \"\"\"Encode a filename to the filesystem encoding\"\"\"\n            if isinstance(s, bytestype):\n                return s\n            return s.encode(sys.getfilesystemencoding(), 'surrogateescape')\nelse:\n    def fsdecode(s):\n        \"\"\"Decode a filename from the filesystem encoding\"\"\"\n        return s\n\n    def fsencode(s):\n        \"\"\"Encode a filename to the filesystem encoding\"\"\"\n        return s\n\nif bytestype is str:\n    def envencode(s):\n        \"\"\"Encode a byte string to the os.environ encoding\"\"\"\n        return s\nelse:\n    envencode = fsdecode\n\nif getattr(sys.stdout, 'buffer', None) is not None:\n    stdoutb = sys.stdout.buffer\n    stderrb = sys.stderr.buffer\nelse:\n    stdoutb = sys.stdout\n    stderrb = sys.stderr\n\nif bytestype is str:\n    def b(s):\n        \"\"\"Convert an ASCII string literal into a bytes object\"\"\"\n        return s\n\n    bchr = chr\n\n    def u(s):\n        \"\"\"Convert an ASCII string literal into a unicode object\"\"\"\n        return s.decode('ascii')\nelse:\n    def b(s):\n        \"\"\"Convert an ASCII string literal into a bytes object\"\"\"\n        return s.encode('ascii')\n\n    def bchr(i):\n        \"\"\"Return a bytes character for a given integer value\"\"\"\n        return bytestype([i])\n\n    def u(s):\n        \"\"\"Convert an ASCII string literal into a unicode object\"\"\"\n        return s\n\ntry:\n    eval(r'u\"\"')\nexcept SyntaxError:\n    ul = eval\nelse:\n    def ul(e):\n        \"\"\"Evaluate e as a unicode string literal\"\"\"\n        return eval('u' + e)\n"
  },
  {
    "path": "third_party/cram/cram/_main.py",
    "content": "\"\"\"Main entry point\"\"\"\n\nimport optparse\nimport os\nimport shlex\nimport shutil\nimport sys\nimport tempfile\n\ntry:\n    import configparser\nexcept ImportError: # pragma: nocover\n    import ConfigParser as configparser\n\nfrom cram._cli import runcli\nfrom cram._encoding import b, fsencode, stderrb, stdoutb\nfrom cram._run import runtests\nfrom cram._xunit import runxunit\n\ndef _which(cmd):\n    \"\"\"Return the path to cmd or None if not found\"\"\"\n    cmd = fsencode(cmd)\n    for p in os.environ['PATH'].split(os.pathsep):\n        path = os.path.join(fsencode(p), cmd)\n        if os.path.isfile(path) and os.access(path, os.X_OK):\n            return os.path.abspath(path)\n    return None\n\ndef _expandpath(path):\n    \"\"\"Expands ~ and environment variables in path\"\"\"\n    return os.path.expanduser(os.path.expandvars(path))\n\nclass _OptionParser(optparse.OptionParser):\n    \"\"\"Like optparse.OptionParser, but supports setting values through\n    CRAM= and .cramrc.\"\"\"\n\n    def __init__(self, *args, **kwargs):\n        self._config_opts = {}\n        optparse.OptionParser.__init__(self, *args, **kwargs)\n\n    def add_option(self, *args, **kwargs):\n        option = optparse.OptionParser.add_option(self, *args, **kwargs)\n        if option.dest and option.dest != 'version':\n            key = option.dest.replace('_', '-')\n            self._config_opts[key] = option.action == 'store_true'\n        return option\n\n    def parse_args(self, args=None, values=None):\n        config = configparser.RawConfigParser()\n        config.read(_expandpath(os.environ.get('CRAMRC', '.cramrc')))\n        defaults = {}\n        for key, isbool in self._config_opts.items():\n            try:\n                if isbool:\n                    try:\n                        value = config.getboolean('cram', key)\n                    except ValueError:\n                        value = config.get('cram', key)\n                        self.error('--%s: invalid boolean value: %r'\n                                   % (key, value))\n                else:\n                    value = config.get('cram', key)\n            except (configparser.NoSectionError, configparser.NoOptionError):\n                pass\n            else:\n                defaults[key] = value\n        self.set_defaults(**defaults)\n\n        eargs = os.environ.get('CRAM', '').strip()\n        if eargs:\n            args = args or []\n            args += shlex.split(eargs)\n\n        try:\n            return optparse.OptionParser.parse_args(self, args, values)\n        except optparse.OptionValueError:\n            self.error(str(sys.exc_info()[1]))\n\ndef _parseopts(args):\n    \"\"\"Parse command line arguments\"\"\"\n    p = _OptionParser(usage='cram [OPTIONS] TESTS...', prog='cram')\n    p.add_option('-V', '--version', action='store_true',\n                 help='show version information and exit')\n    p.add_option('-q', '--quiet', action='store_true',\n                 help=\"don't print diffs\")\n    p.add_option('-v', '--verbose', action='store_true',\n                 help='show filenames and test status')\n    p.add_option('-i', '--interactive', action='store_true',\n                 help='interactively merge changed test output')\n    p.add_option('-d', '--debug', action='store_true',\n                 help='write script output directly to the terminal')\n    p.add_option('-y', '--yes', action='store_true',\n                 help='answer yes to all questions')\n    p.add_option('-n', '--no', action='store_true',\n                 help='answer no to all questions')\n    p.add_option('-E', '--preserve-env', action='store_true',\n                 help=\"don't reset common environment variables\")\n    p.add_option('-e', '--no-err-files', action='store_true',\n                 help=\"don't write .err files on test failures\")\n    p.add_option('--keep-tmpdir', action='store_true',\n                 help='keep temporary directories')\n    p.add_option('--shell', action='store', default='/bin/sh', metavar='PATH',\n                 help='shell to use for running tests (default: %default)')\n    p.add_option('--shell-opts', action='store', metavar='OPTS',\n                 help='arguments to invoke shell with')\n    p.add_option('--indent', action='store', default=2, metavar='NUM',\n                 type='int', help=('number of spaces to use for indentation '\n                                   '(default: %default)'))\n    p.add_option('--xunit-file', action='store', metavar='PATH',\n                 help='path to write xUnit XML output')\n    opts, paths = p.parse_args(args)\n    paths = [fsencode(path) for path in paths]\n    return opts, paths, p.get_usage\n\ndef main(args):\n    \"\"\"Main entry point.\n\n    If you're thinking of using Cram in other Python code (e.g., unit tests),\n    consider using the test() or testfile() functions instead.\n\n    :param args: Script arguments (excluding script name)\n    :type args: str\n    :return: Exit code (non-zero on failure)\n    :rtype: int\n    \"\"\"\n    opts, paths, getusage = _parseopts(args)\n    if opts.version:\n        sys.stdout.write(\"\"\"Cram CLI testing framework (version 0.7)\n\nCopyright (C) 2010-2016 Brodie Rao <brodie@bitheap.org> and others\nThis is free software; see the source for copying conditions. There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\"\"\")\n        return\n\n    conflicts = [('--yes', opts.yes, '--no', opts.no),\n                 ('--quiet', opts.quiet, '--interactive', opts.interactive),\n                 ('--debug', opts.debug, '--quiet', opts.quiet),\n                 ('--debug', opts.debug, '--interactive', opts.interactive),\n                 ('--debug', opts.debug, '--verbose', opts.verbose),\n                 ('--debug', opts.debug, '--xunit-file', opts.xunit_file)]\n    for s1, o1, s2, o2 in conflicts:\n        if o1 and o2:\n            sys.stderr.write('options %s and %s are mutually exclusive\\n'\n                             % (s1, s2))\n            return 2\n\n    shellcmd = _which(opts.shell)\n    if not shellcmd:\n        stderrb.write(b('shell not found: ') + fsencode(opts.shell) + b('\\n'))\n        return 2\n    shell = [shellcmd]\n    if opts.shell_opts:\n        shell += shlex.split(opts.shell_opts)\n\n    patchcmd = None\n    if opts.interactive:\n        patchcmd = _which('patch')\n        if not patchcmd:\n            sys.stderr.write('patch(1) required for -i\\n')\n            return 2\n\n    if not paths:\n        sys.stdout.write(getusage())\n        return 2\n\n    badpaths = [path for path in paths if not os.path.exists(path)]\n    if badpaths:\n        stderrb.write(b('no such file: ') + badpaths[0] + b('\\n'))\n        return 2\n\n    if opts.yes:\n        answer = 'y'\n    elif opts.no:\n        answer = 'n'\n    else:\n        answer = None\n\n    tmpdir = os.environ['CRAMTMP'] = tempfile.mkdtemp('', 'cramtests-')\n    tmpdirb = fsencode(tmpdir)\n    proctmp = os.path.join(tmpdir, 'tmp')\n    for s in ('TMPDIR', 'TEMP', 'TMP'):\n        os.environ[s] = proctmp\n\n    os.mkdir(proctmp)\n    try:\n        tests = runtests(paths, tmpdirb, shell, indent=opts.indent,\n                         cleanenv=not opts.preserve_env, debug=opts.debug,\n                         noerrfiles=opts.no_err_files)\n        if not opts.debug:\n            tests = runcli(tests, quiet=opts.quiet, verbose=opts.verbose,\n                           patchcmd=patchcmd, answer=answer,\n                           noerrfiles=opts.no_err_files)\n            if opts.xunit_file is not None:\n                tests = runxunit(tests, opts.xunit_file)\n\n        hastests = False\n        failed = False\n        for path, test in tests:\n            hastests = True\n            refout, postout, diff = test()\n            if diff:\n                failed = True\n\n        if not hastests:\n            sys.stderr.write('no tests found\\n')\n            return 2\n\n        return int(failed)\n    finally:\n        if opts.keep_tmpdir:\n            stdoutb.write(b('# Kept temporary directory: ') + tmpdirb +\n                          b('\\n'))\n        else:\n            shutil.rmtree(tmpdir)\n"
  },
  {
    "path": "third_party/cram/cram/_process.py",
    "content": "\"\"\"Utilities for running subprocesses\"\"\"\n\nimport os\nimport signal\nimport subprocess\nimport sys\n\nfrom cram._encoding import fsdecode\n\n__all__ = ['PIPE', 'STDOUT', 'execute']\n\nPIPE = subprocess.PIPE\nSTDOUT = subprocess.STDOUT\n\ndef _makeresetsigpipe():\n    \"\"\"Make a function to reset SIGPIPE to SIG_DFL (for use in subprocesses).\n\n    Doing subprocess.Popen(..., preexec_fn=makeresetsigpipe()) will prevent\n    Python's SIGPIPE handler (SIG_IGN) from being inherited by the\n    child process.\n    \"\"\"\n    if (sys.platform == 'win32' or\n        getattr(signal, 'SIGPIPE', None) is None): # pragma: nocover\n        return None\n    return lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL)\n\ndef execute(args, stdin=None, stdout=None, stderr=None, cwd=None, env=None):\n    \"\"\"Run a process and return its output and return code.\n\n    stdin may either be None or a string to send to the process.\n\n    stdout may either be None or PIPE. If set to PIPE, the process's output\n    is returned as a string.\n\n    stderr may either be None or STDOUT. If stdout is set to PIPE and stderr\n    is set to STDOUT, the process's stderr output will be interleaved with\n    stdout and returned as a string.\n\n    cwd sets the process's current working directory.\n\n    env can be set to a dictionary to override the process's environment\n    variables.\n\n    This function returns a 2-tuple of (output, returncode).\n    \"\"\"\n    if sys.platform == 'win32': # pragma: nocover\n        args = [fsdecode(arg) for arg in args]\n\n    p = subprocess.Popen(args, stdin=PIPE, stdout=stdout, stderr=stderr,\n                         cwd=cwd, env=env, bufsize=-1,\n                         preexec_fn=_makeresetsigpipe(),\n                         close_fds=os.name == 'posix')\n    out, err = p.communicate(stdin)\n    return out, p.returncode\n"
  },
  {
    "path": "third_party/cram/cram/_run.py",
    "content": "\"\"\"The test runner\"\"\"\n\nimport os\nimport sys\n\nfrom cram._encoding import b, fsdecode, fsencode\nfrom cram._test import testfile\n\n__all__ = ['runtests']\n\nif sys.platform == 'win32': # pragma: nocover\n    def _walk(top):\n        top = fsdecode(top)\n        for root, dirs, files in os.walk(top):\n            yield (fsencode(root),\n                   [fsencode(p) for p in dirs],\n                   [fsencode(p) for p in files])\nelse:\n    _walk = os.walk\n\ndef _findtests(paths):\n    \"\"\"Yield tests in paths in sorted order\"\"\"\n    for p in paths:\n        if os.path.isdir(p):\n            for root, dirs, files in _walk(p):\n                if os.path.basename(root).startswith(b('.')):\n                    continue\n                for f in sorted(files):\n                    if not f.startswith(b('.')) and f.endswith(b('.t')):\n                        yield os.path.normpath(os.path.join(root, f))\n        else:\n            yield os.path.normpath(p)\n\ndef runtests(paths, tmpdir, shell, indent=2, cleanenv=True, debug=False,\n             noerrfiles=False):\n    \"\"\"Run tests and yield results.\n\n    This yields a sequence of 2-tuples containing the following:\n\n        (test path, test function)\n\n    The test function, when called, runs the test in a temporary directory\n    and returns a 3-tuple:\n\n        (list of lines in the test, same list with actual output, diff)\n    \"\"\"\n    cwd = os.getcwd()\n    seen = set()\n    basenames = set()\n    for i, path in enumerate(_findtests(paths)):\n        abspath = os.path.abspath(path)\n        if abspath in seen:\n            continue\n        seen.add(abspath)\n\n        if not os.stat(path).st_size:\n            yield (path, lambda: (None, None, None))\n            continue\n\n        basename = os.path.basename(path)\n        if basename in basenames:\n            basename = basename + b('-%s' % i)\n        else:\n            basenames.add(basename)\n\n        def test():\n            \"\"\"Run test file\"\"\"\n            testdir = os.path.join(tmpdir, basename)\n            os.mkdir(testdir)\n            try:\n                os.chdir(testdir)\n                return testfile(abspath, shell, indent=indent,\n                                cleanenv=cleanenv, debug=debug,\n                                testname=path, noerrfile=noerrfiles)\n            finally:\n                os.chdir(cwd)\n\n        yield (path, test)\n"
  },
  {
    "path": "third_party/cram/cram/_test.py",
    "content": "\"\"\"Utilities for running individual tests\"\"\"\n\nimport itertools\nimport os\nimport re\nimport time\n\nfrom cram._encoding import b, bchr, bytestype, envencode, unicodetype\nfrom cram._diff import esc, glob, regex, unified_diff\nfrom cram._process import PIPE, STDOUT, execute\n\n__all__ = ['test', 'testfile']\n\n_needescape = re.compile(b(r'[\\x00-\\x09\\x0b-\\x1f\\x7f-\\xff]')).search\n_escapesub = re.compile(b(r'[\\x00-\\x09\\x0b-\\x1f\\\\\\x7f-\\xff]')).sub\n_escapemap = dict((bchr(i), b(r'\\x%02x' % i)) for i in range(256))\n_escapemap.update({b('\\\\'): b('\\\\\\\\'), b('\\r'): b(r'\\r'), b('\\t'): b(r'\\t')})\n\ndef _escape(s):\n    \"\"\"Like the string-escape codec, but doesn't escape quotes\"\"\"\n    return (_escapesub(lambda m: _escapemap[m.group(0)], s[:-1]) +\n            b(' (esc)\\n'))\n\ndef test(lines, shell='/bin/sh', indent=2, testname=None, env=None,\n         cleanenv=True, debug=False, noerrfile=False):\n    r\"\"\"Run test lines and return input, output, and diff.\n\n    This returns a 3-tuple containing the following:\n\n        (list of lines in test, same list with actual output, diff)\n\n    diff is a generator that yields the diff between the two lists.\n\n    If a test exits with return code 80, the actual output is set to\n    None and diff is set to [].\n\n    Note that the TESTSHELL environment variable is available in the\n    test (set to the specified shell). However, the TESTDIR and\n    TESTFILE environment variables are not available. To run actual\n    test files, see testfile().\n\n    Example usage:\n\n    >>> from cram._encoding import b\n    >>> refout, postout, diff = test([b('  $ echo hi\\n'),\n    ...                               b('  [a-z]{2} (re)\\n')])\n    >>> refout == [b('  $ echo hi\\n'), b('  [a-z]{2} (re)\\n')]\n    True\n    >>> postout == [b('  $ echo hi\\n'), b('  hi\\n')]\n    True\n    >>> bool(diff)\n    False\n\n    lines may also be a single bytes string:\n\n    >>> refout, postout, diff = test(b('  $ echo hi\\n  bye\\n'))\n    >>> refout == [b('  $ echo hi\\n'), b('  bye\\n')]\n    True\n    >>> postout == [b('  $ echo hi\\n'), b('  hi\\n')]\n    True\n    >>> bool(diff)\n    True\n    >>> (b('').join(diff) ==\n    ...  b('--- \\n+++ \\n@@ -1,2 +1,2 @@\\n   $ echo hi\\n-  bye\\n+  hi\\n'))\n    True\n\n    Note that the b() function is internal to Cram. If you're using Python 2,\n    use normal string literals instead. If you're using Python 3, use bytes\n    literals.\n\n    :param lines: Test input\n    :type lines: bytes or collections.Iterable[bytes]\n    :param shell: Shell to run test in\n    :type shell: bytes or str or list[bytes] or list[str]\n    :param indent: Amount of indentation to use for shell commands\n    :type indent: int\n    :param testname: Optional test file name (used in diff output)\n    :type testname: bytes or None\n    :param env: Optional environment variables for the test shell\n    :type env: dict or None\n    :param cleanenv: Whether or not to sanitize the environment\n    :type cleanenv: bool\n    :param debug: Whether or not to run in debug mode (don't capture stdout)\n    :type debug: bool\n    :return: Input, output, and diff iterables\n    :rtype: (list[bytes], list[bytes], collections.Iterable[bytes])\n    \"\"\"\n    indent = b(' ') * indent\n    cmdline = indent + b('$ ')\n    conline = indent + b('> ')\n    usalt = 'CRAM%s' % time.time()\n    salt = b(usalt)\n\n    if env is None:\n        env = os.environ.copy()\n\n    if cleanenv:\n        for s in ('LANG', 'LC_ALL', 'LANGUAGE'):\n            env[s] = 'C'\n        env['TZ'] = 'GMT'\n        env['CDPATH'] = ''\n        env['COLUMNS'] = '80'\n        env['GREP_OPTIONS'] = ''\n\n    if isinstance(lines, bytestype):\n        lines = lines.splitlines(True)\n\n    if isinstance(shell, (bytestype, unicodetype)):\n        shell = [shell]\n    env['TESTSHELL'] = shell[0]\n\n    if debug:\n        stdin = []\n        for line in lines:\n            if not line.endswith(b('\\n')):\n                line += b('\\n')\n            if line.startswith(cmdline):\n                stdin.append(line[len(cmdline):])\n            elif line.startswith(conline):\n                stdin.append(line[len(conline):])\n\n        execute(shell + ['-'], stdin=b('').join(stdin), env=env)\n        return ([], [], [])\n\n    after = {}\n    refout, postout = [], []\n    i = pos = prepos = -1\n    stdin = []\n    for i, line in enumerate(lines):\n        if not line.endswith(b('\\n')):\n            line += b('\\n')\n        refout.append(line)\n        if line.startswith(cmdline):\n            after.setdefault(pos, []).append(line)\n            prepos = pos\n            pos = i\n            stdin.append(b('echo %s %s $?\\n' % (usalt, i)))\n            stdin.append(line[len(cmdline):])\n        elif line.startswith(conline):\n            after.setdefault(prepos, []).append(line)\n            stdin.append(line[len(conline):])\n        elif not line.startswith(indent):\n            after.setdefault(pos, []).append(line)\n    stdin.append(b('echo %s %s $?\\n' % (usalt, i + 1)))\n\n    output, retcode = execute(shell + ['-'], stdin=b('').join(stdin),\n                              stdout=PIPE, stderr=STDOUT, env=env)\n    if retcode == 80:\n        return (refout, None, [])\n\n    pos = -1\n    ret = 0\n    for i, line in enumerate(output[:-1].splitlines(True)):\n        out, cmd = line, None\n        if salt in line:\n            out, cmd = line.split(salt, 1)\n\n        if out:\n            if not out.endswith(b('\\n')):\n                out += b(' (no-eol)\\n')\n\n            if _needescape(out):\n                out = _escape(out)\n            postout.append(indent + out)\n\n        if cmd:\n            ret = int(cmd.split()[1])\n            if ret != 0:\n                postout.append(indent + b('[%s]\\n' % (ret)))\n            postout += after.pop(pos, [])\n            pos = int(cmd.split()[0])\n\n    postout += after.pop(pos, [])\n\n    if testname:\n        diffpath = testname\n        errpath = diffpath + b('.err')\n    else:\n        diffpath = errpath = b('')\n    diff = unified_diff(refout, postout, diffpath, errpath,\n                        matchers=[esc, glob, regex])\n    for firstline in diff:\n        return refout, postout, itertools.chain([firstline], diff)\n    return refout, postout, []\n\ndef testfile(path, shell='/bin/sh', indent=2, env=None, cleanenv=True,\n             debug=False, testname=None, noerrfile=False):\n    \"\"\"Run test at path and return input, output, and diff.\n\n    This returns a 3-tuple containing the following:\n\n        (list of lines in test, same list with actual output, diff)\n\n    diff is a generator that yields the diff between the two lists.\n\n    If a test exits with return code 80, the actual output is set to\n    None and diff is set to [].\n\n    Note that the TESTDIR, TESTFILE, and TESTSHELL environment\n    variables are available to use in the test.\n\n    :param path: Path to test file\n    :type path: bytes or str\n    :param shell: Shell to run test in\n    :type shell: bytes or str or list[bytes] or list[str]\n    :param indent: Amount of indentation to use for shell commands\n    :type indent: int\n    :param env: Optional environment variables for the test shell\n    :type env: dict or None\n    :param cleanenv: Whether or not to sanitize the environment\n    :type cleanenv: bool\n    :param debug: Whether or not to run in debug mode (don't capture stdout)\n    :type debug: bool\n    :param testname: Optional test file name (used in diff output)\n    :type testname: bytes or None\n    :return: Input, output, and diff iterables\n    :rtype: (list[bytes], list[bytes], collections.Iterable[bytes])\n    \"\"\"\n    f = open(path, 'rb')\n    try:\n        abspath = os.path.abspath(path)\n        env = env or os.environ.copy()\n        env['TESTDIR'] = envencode(os.path.dirname(abspath))\n        env['TESTFILE'] = envencode(os.path.basename(abspath))\n        if testname is None: # pragma: nocover\n            testname = os.path.basename(abspath)\n        return test(f, shell, indent=indent, testname=testname, env=env,\n                    cleanenv=cleanenv, debug=debug, noerrfile=noerrfile)\n    finally:\n        f.close()\n"
  },
  {
    "path": "third_party/cram/cram/_xunit.py",
    "content": "\"\"\"xUnit XML output\"\"\"\n\nimport locale\nimport os\nimport re\nimport socket\nimport sys\nimport time\n\nfrom cram._encoding import u, ul\n\n__all__ = ['runxunit']\n\n_widecdataregex = ul(r\"'(?:[^\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd\"\n                     r\"\\U00010000-\\U0010ffff]|]]>)'\")\n_narrowcdataregex = ul(r\"'(?:[^\\x09\\x0a\\x0d\\x20-\\ud7ff\\ue000-\\ufffd]\"\n                       r\"|]]>)'\")\n_widequoteattrregex = ul(r\"'[^\\x20\\x21\\x23-\\x25\\x27-\\x3b\\x3d\"\n                         r\"\\x3f-\\ud7ff\\ue000-\\ufffd\"\n                         r\"\\U00010000-\\U0010ffff]'\")\n_narrowquoteattrregex = ul(r\"'[^\\x20\\x21\\x23-\\x25\\x27-\\x3b\\x3d\"\n                           r\"\\x3f-\\ud7ff\\ue000-\\ufffd]'\")\n_replacementchar = ul(r\"'\\N{REPLACEMENT CHARACTER}'\")\n\nif sys.maxunicode >= 0x10ffff: # pragma: nocover\n    _cdatasub = re.compile(_widecdataregex).sub\n    _quoteattrsub = re.compile(_widequoteattrregex).sub\nelse: # pragma: nocover\n    _cdatasub = re.compile(_narrowcdataregex).sub\n    _quoteattrsub = re.compile(_narrowquoteattrregex).sub\n\ndef _cdatareplace(m):\n    \"\"\"Replace _cdatasub() regex match\"\"\"\n    if m.group(0) == u(']]>'):\n        return u(']]>]]&gt;<![CDATA[')\n    else:\n        return _replacementchar\n\ndef _cdata(s):\n    r\"\"\"Escape a string as an XML CDATA block.\n\n    >>> from cram._encoding import ul\n    >>> (_cdata('1<\\'2\\'>&\"3\\x00]]>\\t\\r\\n') ==\n    ...  ul(r\"'<![CDATA[1<\\'2\\'>&\\\"3\\ufffd]]>]]&gt;<![CDATA[\\t\\r\\n]]>'\"))\n    True\n    \"\"\"\n    return u('<![CDATA[%s]]>') % _cdatasub(_cdatareplace, s)\n\ndef _quoteattrreplace(m):\n    \"\"\"Replace _quoteattrsub() regex match\"\"\"\n    return {u('\\t'): u('&#9;'),\n            u('\\n'): u('&#10;'),\n            u('\\r'): u('&#13;'),\n            u('\"'): u('&quot;'),\n            u('&'): u('&amp;'),\n            u('<'): u('&lt;'),\n            u('>'): u('&gt;')}.get(m.group(0), _replacementchar)\n\ndef _quoteattr(s):\n    r\"\"\"Escape a string for use as an XML attribute value.\n\n    >>> from cram._encoding import ul\n    >>> (_quoteattr('1<\\'2\\'>&\"3\\x00]]>\\t\\r\\n') ==\n    ...  ul(r\"'\\\"1&lt;\\'2\\'&gt;&amp;&quot;3\\ufffd]]&gt;&#9;&#13;&#10;\\\"'\"))\n    True\n    \"\"\"\n    return u('\"%s\"') % _quoteattrsub(_quoteattrreplace, s)\n\ndef _timestamp():\n    \"\"\"Return the current time in ISO 8601 format\"\"\"\n    tm = time.localtime()\n    if tm.tm_isdst == 1: # pragma: nocover\n        tz = time.altzone\n    else: # pragma: nocover\n        tz = time.timezone\n\n    timestamp = time.strftime('%Y-%m-%dT%H:%M:%S', tm)\n    tzhours = int(-tz / 60 / 60)\n    tzmins = int(abs(tz) / 60 % 60)\n    timestamp += u('%+03d:%02d') % (tzhours, tzmins)\n    return timestamp\n\ndef runxunit(tests, xmlpath):\n    \"\"\"Run tests with xUnit XML output.\n\n    tests should be a sequence of 2-tuples containing the following:\n\n        (test path, test function)\n\n    This function yields a new sequence where each test function is wrapped\n    with a function that writes test results to an xUnit XML file.\n    \"\"\"\n    suitestart = time.time()\n    timestamp = _timestamp()\n    hostname = socket.gethostname()\n    total, skipped, failed = [0], [0], [0]\n    testcases = []\n\n    for path, test in tests:\n        def testwrapper():\n            \"\"\"Run test and collect XML output\"\"\"\n            total[0] += 1\n\n            start = time.time()\n            refout, postout, diff = test()\n            testtime = time.time() - start\n\n            classname = path.decode(locale.getpreferredencoding(), 'replace')\n            name = os.path.basename(classname)\n\n            if postout is None:\n                skipped[0] += 1\n                testcase = (u('  <testcase classname=%(classname)s\\n'\n                              '            name=%(name)s\\n'\n                              '            time=\"%(time).6f\">\\n'\n                              '    <skipped/>\\n'\n                              '  </testcase>\\n') %\n                            {'classname': _quoteattr(classname),\n                             'name': _quoteattr(name),\n                             'time': testtime})\n            elif diff:\n                failed[0] += 1\n                diff = list(diff)\n                diffu = u('').join(l.decode(locale.getpreferredencoding(),\n                                            'replace')\n                                   for l in diff)\n                testcase = (u('  <testcase classname=%(classname)s\\n'\n                              '            name=%(name)s\\n'\n                              '            time=\"%(time).6f\">\\n'\n                              '    <failure>%(diff)s</failure>\\n'\n                              '  </testcase>\\n') %\n                            {'classname': _quoteattr(classname),\n                             'name': _quoteattr(name),\n                             'time': testtime,\n                             'diff': _cdata(diffu)})\n            else:\n                testcase = (u('  <testcase classname=%(classname)s\\n'\n                              '            name=%(name)s\\n'\n                              '            time=\"%(time).6f\"/>\\n') %\n                            {'classname': _quoteattr(classname),\n                             'name': _quoteattr(name),\n                             'time': testtime})\n            testcases.append(testcase)\n\n            return refout, postout, diff\n\n        yield path, testwrapper\n\n    suitetime = time.time() - suitestart\n    header = (u('<?xml version=\"1.0\" encoding=\"utf-8\"?>\\n'\n                '<testsuite name=\"cram\"\\n'\n                '           tests=\"%(total)d\"\\n'\n                '           failures=\"%(failed)d\"\\n'\n                '           skipped=\"%(skipped)d\"\\n'\n                '           timestamp=%(timestamp)s\\n'\n                '           hostname=%(hostname)s\\n'\n                '           time=\"%(time).6f\">\\n') %\n              {'total': total[0],\n               'failed': failed[0],\n               'skipped': skipped[0],\n               'timestamp': _quoteattr(timestamp),\n               'hostname': _quoteattr(hostname),\n               'time': suitetime})\n    footer = u('</testsuite>\\n')\n\n    xmlfile = open(xmlpath, 'wb')\n    try:\n        xmlfile.write(header.encode('utf-8'))\n        for testcase in testcases:\n            xmlfile.write(testcase.encode('utf-8'))\n        xmlfile.write(footer.encode('utf-8'))\n    finally:\n        xmlfile.close()\n"
  },
  {
    "path": "third_party/cram/examples/.hidden/hidden.t",
    "content": "This test is ignored because it's hidden.\n"
  },
  {
    "path": "third_party/cram/examples/.hidden.t",
    "content": "This test is ignored because it's hidden.\n"
  },
  {
    "path": "third_party/cram/examples/bare.t",
    "content": "  $ true\n"
  },
  {
    "path": "third_party/cram/examples/empty.t",
    "content": ""
  },
  {
    "path": "third_party/cram/examples/env.t",
    "content": "Check environment variables:\n\n  $ echo \"$LANG\"\n  C\n  $ echo \"$LC_ALL\"\n  C\n  $ echo \"$LANGUAGE\"\n  C\n  $ echo \"$TZ\"\n  GMT\n  $ echo \"$CDPATH\"\n  \n  $ echo \"$GREP_OPTIONS\"\n  \n  $ echo \"$CRAMTMP\"\n  .+ (re)\n  $ echo \"$TESTDIR\"\n  */examples (glob)\n  $ ls \"$TESTDIR\"\n  bare.t\n  empty.t\n  env.t\n  fail.t\n  missingeol.t\n  skip.t\n  test.t\n  $ echo \"$TESTFILE\"\n  env.t\n  $ pwd\n  */cramtests*/env.t (glob)\n"
  },
  {
    "path": "third_party/cram/examples/fail.t",
    "content": "Output needing escaping:\n\n  $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  foo\n  $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  bar\n\nWrong output and bad regexes:\n\n  $ echo 1\n  2\n  $ printf '1\\nfoo\\n1\\n'\n  +++ (re)\n  foo\\ (re)\n   (re)\n\nFiller to force a second diff hunk:\n\n\nOffset regular expression:\n\n  $ printf 'foo\\n\\n1\\n'\n  \n  \\d (re)\n"
  },
  {
    "path": "third_party/cram/examples/missingeol.t",
    "content": "  $ printf foo\n  foo (no-eol)"
  },
  {
    "path": "third_party/cram/examples/skip.t",
    "content": "This test is considered \"skipped\" because it exits with return code\n80. This is useful for skipping tests that only work on certain\nplatforms or in certain settings.\n\n  $ exit 80\n"
  },
  {
    "path": "third_party/cram/examples/test.t",
    "content": "Simple commands:\n\n  $ echo foo\n  foo\n  $ printf 'bar\\nbaz\\n' | cat\n  bar\n  baz\n\nMulti-line command:\n\n  $ foo() {\n  >     echo bar\n  > }\n  $ foo\n  bar\n\nRegular expression:\n\n  $ echo foobarbaz\n  foobar.* (re)\n\nGlob:\n\n  $ printf '* \\\\foobarbaz {10}\\n'\n  \\* \\\\fo?bar* {10} (glob)\n\nLiteral match ending in (re) and (glob):\n\n  $ echo 'foo\\Z\\Z\\Z bar (re)'\n  foo\\Z\\Z\\Z bar (re)\n  $ echo 'baz??? quux (glob)'\n  baz??? quux (glob)\n\nExit code:\n\n  $ (exit 1)\n  [1]\n\nWrite to stderr:\n\n  $ echo foo >&2\n  foo\n\nNo newline:\n\n  $ printf foo\n  foo (no-eol)\n  $ printf 'foo\\nbar'\n  foo\n  bar (no-eol)\n  $ printf '  '\n     (no-eol)\n  $ printf '  \\n  '\n    \n     (no-eol)\n  $ echo foo\n  foo\n  $ printf foo\n  foo (no-eol)\n\nEscaped output:\n\n  $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n  $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n  $ echo hi\n  \\x68\\x69 (esc)\n  $ echo '(esc) in output (esc)'\n  (esc) in output (esc)\n  $ echo '(esc) in output (esc)'\n  (esc) in output \\x28esc\\x29 (esc)\n\nCommand that closes a pipe:\n\n  $ cat /dev/urandom | head -1 > /dev/null\n\nIf Cram let Python's SIGPIPE handler get inherited by this script, we\nmight see broken pipe messages.\n"
  },
  {
    "path": "third_party/cram/requirements.txt",
    "content": "check-manifest\ncoverage\npep8\npyflakes\n"
  },
  {
    "path": "third_party/cram/scripts/cram",
    "content": "#!/usr/bin/env python\nimport sys\n\nimport cram\n\ntry:\n    sys.exit(cram.main(sys.argv[1:]))\nexcept KeyboardInterrupt:\n    pass\n"
  },
  {
    "path": "third_party/cram/setup.cfg",
    "content": "[bdist_wheel]\nuniversal = true\n\n[pep8]\n# E129: indentation between lines in conditions\n# E261: two spaces before inline comment\n# E301: expected blank line\n# E302: two new lines between functions/etc.\nignore = E129,E261,E301,E302\n"
  },
  {
    "path": "third_party/cram/setup.py",
    "content": "#!/usr/bin/env python\n\"\"\"Installs cram\"\"\"\n\nimport os\nimport sys\nfrom distutils.core import setup\n\nCOMMANDS = {}\nCRAM_DIR = os.path.abspath(os.path.dirname(__file__))\n\ntry:\n    from wheel.bdist_wheel import bdist_wheel\nexcept ImportError:\n    pass\nelse:\n    COMMANDS['bdist_wheel'] = bdist_wheel\n\ndef long_description():\n    \"\"\"Get the long description from the README\"\"\"\n    return open(os.path.join(sys.path[0], 'README.rst')).read()\n\nsetup(\n    author='Brodie Rao',\n    author_email='brodie@bitheap.org',\n    classifiers=[\n        'Development Status :: 5 - Production/Stable',\n        'Environment :: Console',\n        'Intended Audience :: Developers',\n        'License :: OSI Approved :: GNU General Public License (GPL)',\n        ('License :: OSI Approved :: GNU General Public License v2 '\n         'or later (GPLv2+)'),\n        'Natural Language :: English',\n        'Operating System :: OS Independent',\n        'Programming Language :: Python :: 2',\n        'Programming Language :: Python :: 3',\n        'Programming Language :: Unix Shell',\n        'Topic :: Software Development :: Testing',\n    ],\n    cmdclass=COMMANDS,\n    description='Functional tests for command line applications',\n    download_url='https://bitheap.org/cram/cram-0.7.tar.gz',\n    keywords='automatic functional test framework',\n    license='GNU GPLv2 or any later version',\n    long_description=long_description(),\n    name='cram',\n    packages=['cram'],\n    scripts=['scripts/cram'],\n    url='https://bitheap.org/cram/',\n    version='0.7',\n)\n"
  },
  {
    "path": "third_party/cram/tests/config.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nOptions in .cramrc:\n\n  $ cat > .cramrc <<EOF\n  > [cram]\n  > yes = True\n  > no = 1\n  > indent = 4\n  > EOF\n  $ cram\n  options --yes and --no are mutually exclusive\n  [2]\n  $ mv .cramrc config\n  $ CRAMRC=config cram\n  options --yes and --no are mutually exclusive\n  [2]\n  $ rm config\n\nInvalid option in .cramrc:\n\n  $ cat > .cramrc <<EOF\n  > [cram]\n  > indent = hmm\n  > EOF\n  $ cram\n  [Uu]sage: cram \\[OPTIONS\\] TESTS\\.\\.\\. (re)\n  \n  cram: error: option --indent: invalid integer value: 'hmm'\n  [2]\n  $ rm .cramrc\n  $ cat > .cramrc <<EOF\n  > [cram]\n  > verbose = hmm\n  > EOF\n  $ cram\n  [Uu]sage: cram \\[OPTIONS\\] TESTS\\.\\.\\. (re)\n  \n  cram: error: --verbose: invalid boolean value: 'hmm'\n  [2]\n  $ rm .cramrc\n\nOptions in an environment variable:\n\n  $ CRAM='-y -n' cram\n  options --yes and --no are mutually exclusive\n  [2]\n"
  },
  {
    "path": "third_party/cram/tests/debug.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nDebug mode:\n\n  $ printf '  $ echo hi\\n  > echo bye' > debug.t\n  $ cram -d -v debug.t\n  options --debug and --verbose are mutually exclusive\n  [2]\n  $ cram -d -q debug.t\n  options --debug and --quiet are mutually exclusive\n  [2]\n  $ cram -d -i debug.t\n  options --debug and --interactive are mutually exclusive\n  [2]\n  $ cram -d --xunit-file==cram.xml debug.t\n  options --debug and --xunit-file are mutually exclusive\n  [2]\n  $ cram -d debug.t\n  hi\n  bye\n  $ cram -d examples/empty.t\n\nDebug mode with extra shell arguments:\n\n  $ cram --shell-opts='-s' -d debug.t\n  hi\n  bye\n\nTest debug mode with set -x:\n\n  $ cat > set-x.t <<EOF\n  >   $ echo 1\n  >   1\n  >   $ set -x\n  >   $ echo 2\n  > EOF\n  $ cram -d set-x.t\n  1\n  \\+.*echo 2 (re)\n  2\n\nTest set -x without debug mode:\n\n  $ cram set-x.t\n  !\n  --- set-x.t\n  +++ set-x.t.err\n  @@ -1,4 +1,8 @@\n     $ echo 1\n     1\n     $ set -x\n  \\+  \\+.*echo  \\(no-eol\\) (re)\n     $ echo 2\n  \\+  \\+.*echo 2 (re)\n  +  2\n  \\+  \\+.*echo  \\(no-eol\\) (re)\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n\nNote that the \"+ echo  (no-eol)\" lines are artifacts of the echo commands\nthat Cram inserts into the test in order to track output. It'd be nice if\nCram could avoid removing salt/line number/return code information from those\nlines, but it isn't possible to distinguish between set -x output and normal\noutput.\n"
  },
  {
    "path": "third_party/cram/tests/dist.t",
    "content": "Skip this test if check-manifest isn't available:\n\n  $ command -v check-manifest > /dev/null || exit 80\n\nConfirm that \"make dist\" isn't going to miss any files:\n\n  $ check-manifest \"$TESTDIR/..\"\n  lists of files in version control and sdist match\n"
  },
  {
    "path": "third_party/cram/tests/doctest.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nRun doctests:\n\n  $ doctest \"$TESTDIR\"/../cram\n"
  },
  {
    "path": "third_party/cram/tests/encoding.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nTest with Windows newlines:\n\n  $ printf \"  $ echo hi\\r\\n  hi\\r\\n\" > windows-newlines.t\n  $ cram windows-newlines.t\n  .\n  # Ran 1 tests, 0 skipped, 0 failed.\n\nTest with Latin-1 encoding:\n\n  $ cat > good-latin-1.t <<EOF\n  >   $ printf \"hola se\\361or\\n\"\n  >   hola se\\xf1or (esc)\n  > EOF\n\n  $ cat > bad-latin-1.t <<EOF\n  >   $ printf \"hola se\\361or\\n\"\n  >   hey\n  > EOF\n\n  $ cram good-latin-1.t bad-latin-1.t\n  .!\n  --- bad-latin-1.t\n  +++ bad-latin-1.t.err\n  @@ -1,2 +1,2 @@\n     $ printf \"hola se\\361or\\n\"\n  -  hey\n  +  hola se\\xf1or (esc)\n  \n  # Ran 2 tests, 0 skipped, 1 failed.\n  [1]\n\nTest with UTF-8 encoding:\n\n  $ cat > good-utf-8.t <<EOF\n  >   $ printf \"hola se\\303\\261or\\n\"\n  >   hola se\\xc3\\xb1or (esc)\n  > EOF\n\n  $ cat > bad-utf-8.t <<EOF\n  >   $ printf \"hola se\\303\\261or\\n\"\n  >   hey\n  > EOF\n\n  $ cram good-utf-8.t bad-utf-8.t\n  .!\n  --- bad-utf-8.t\n  +++ bad-utf-8.t.err\n  @@ -1,2 +1,2 @@\n     $ printf \"hola se\\303\\261or\\n\"\n  -  hey\n  +  hola se\\xc3\\xb1or (esc)\n  \n  # Ran 2 tests, 0 skipped, 1 failed.\n  [1]\n\nTest file missing trailing newline:\n\n  $ printf '  $ true' > passing-with-no-newline.t\n  $ cram passing-with-no-newline.t\n  .\n  # Ran 1 tests, 0 skipped, 0 failed.\n\n  $ printf '  $ false' > failing-with-no-newline.t\n  $ cram failing-with-no-newline.t\n  !\n  --- failing-with-no-newline.t\n  +++ failing-with-no-newline.t.err\n  @@ -1,1 +1,2 @@\n     $ false\n  +  [1]\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n"
  },
  {
    "path": "third_party/cram/tests/interactive.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nInteractive mode (don't merge):\n\n  $ cram -n -i examples/fail.t\n  !\n  --- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  Accept this change? [yN] n\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n\nInteractive mode (merge):\n\n  $ cp examples/fail.t examples/fail.t.orig\n  $ cram -y -i examples/fail.t\n  !\n  --- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  Accept this change? [yN] y\n  patching file examples/fail.t\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t\n  .*\\b1d9e5b527f01fbf2d9b1c121d005108c\\b.* (re)\n  $ mv examples/fail.t.orig examples/fail.t\n\nVerbose interactive mode (answer manually and don't merge):\n\n  $ printf 'bad\\nn\\n' | cram -v -i examples/fail.t\n  examples/fail.t: failed\n  --- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  Accept this change? [yN] Accept this change? [yN] # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n  $ printf 'bad\\n\\n' | cram -v -i examples/fail.t\n  examples/fail.t: failed\n  --- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  Accept this change? [yN] Accept this change? [yN] # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n\nVerbose interactive mode (answer manually and merge):\n\n  $ cp examples/fail.t examples/fail.t.orig\n  $ printf 'bad\\ny\\n' | cram -v -i examples/fail.t\n  examples/fail.t: failed\n  --- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  Accept this change? [yN] Accept this change? [yN] patching file examples/fail.t\n  examples/fail.t: merged output\n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t\n  .*\\b1d9e5b527f01fbf2d9b1c121d005108c\\b.* (re)\n  $ mv examples/fail.t.orig examples/fail.t\n\nTest missing patch(1) and patch(1) error:\n\n  $ PATH=. cram -i examples/fail.t\n  patch(1) required for -i\n  [2]\n  $ cat > patch <<EOF\n  > #!/bin/sh\n  > echo \"patch failed\" 1>&2\n  > exit 1\n  > EOF\n  $ chmod +x patch\n  $ PATH=. cram -y -i examples/fail.t\n  !\n  --- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  Accept this change? [yN] y\n  patch failed\n  examples/fail.t: merge failed\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n  $ rm patch examples/fail.t.err\n"
  },
  {
    "path": "third_party/cram/tests/pep8.t",
    "content": "Skip this test if pep8 isn't available:\n\n  $ command -v pep8 > /dev/null || exit 80\n\nCheck that the Python source code style is PEP 8 compliant:\n\n  $ pep8 --config=\"$TESTDIR/..\"/setup.cfg --repeat \"$TESTDIR/..\"\n"
  },
  {
    "path": "third_party/cram/tests/pyflakes.t",
    "content": "Skip this test if pyflakes isn't available:\n\n  $ command -v pyflakes > /dev/null || exit 80\n\nCheck that there are no obvious Python source code errors:\n\n  $ pyflakes \"$TESTDIR/..\"\n"
  },
  {
    "path": "third_party/cram/tests/run-doctests.py",
    "content": "#!/usr/bin/env python\n\nimport doctest\nimport os\nimport sys\n\ndef _getmodules(pkgdir):\n    \"\"\"Import and yield modules in pkgdir\"\"\"\n    for root, dirs, files in os.walk(pkgdir):\n        if '__pycache__' in dirs:\n            dirs.remove('__pycache__')\n        for fn in files:\n            if not fn.endswith('.py') or fn == '__main__.py':\n                continue\n\n            modname = fn.replace(os.sep, '.')[:-len('.py')]\n            if modname.endswith('.__init__'):\n                modname = modname[:-len('.__init__')]\n            modname = '.'.join(['cram', modname])\n            if '.' in modname:\n                fromlist = [modname.rsplit('.', 1)[1]]\n            else:\n                fromlist = []\n\n            yield __import__(modname, {}, {}, fromlist)\n\ndef rundoctests(pkgdir):\n    \"\"\"Run doctests in the given package directory\"\"\"\n    totalfailures = totaltests = 0\n    for module in _getmodules(pkgdir):\n        failures, tests = doctest.testmod(module)\n        totalfailures += failures\n        totaltests += tests\n    return totalfailures != 0\n\nif __name__ == '__main__':\n    try:\n        sys.exit(rundoctests(sys.argv[1]))\n    except KeyboardInterrupt:\n        pass\n"
  },
  {
    "path": "third_party/cram/tests/setup.sh",
    "content": "#!/bin/sh\n\n# Bash doesn't expand aliases by default in non-interactive mode, so\n# we enable it manually if the test is run with --shell=/bin/bash.\n[ \"$TESTSHELL\" = \"/bin/bash\" ] && shopt -s expand_aliases\n\n# The $PYTHON environment variable should be set when running this test\n# from Python.\n[ -n \"$PYTHON\" ] || PYTHON=\"`which python`\"\n[ -n \"$PYTHONPATH\" ] || PYTHONPATH=\"$TESTDIR/..\" && export PYTHONPATH\nif [ -n \"$COVERAGE\" ]; then\n  if [ -z \"$COVERAGE_FILE\" ]; then\n    COVERAGE_FILE=\"$TESTDIR/../.coverage\"\n    export COVERAGE_FILE\n  fi\n\n  alias cram=\"`which \"$COVERAGE\"` run -a --rcfile=$TESTDIR/../.coveragerc \\\n$TESTDIR/../scripts/cram --shell=$TESTSHELL\"\n  alias doctest=\"`which \"$COVERAGE\"` run -a --rcfile=$TESTDIR/../.coveragerc \\\n$TESTDIR/run-doctests.py\"\nelse\n  PYTHON=\"`command -v \"$PYTHON\" || echo \"$PYTHON\"`\"\n  alias cram=\"$PYTHON $TESTDIR/../scripts/cram --shell=$TESTSHELL\"\n  alias doctest=\"$PYTHON $TESTDIR/run-doctests.py\"\nfi\ncommand -v md5 > /dev/null || alias md5=md5sum\n\n# Copy in example tests\ncp -R \"$TESTDIR\"/../examples .\nfind . -name '*.err' -exec rm '{}' \\;\n"
  },
  {
    "path": "third_party/cram/tests/test.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nRun cram examples:\n\n  $ cram -q examples examples/fail.t\n  .s.!.s.\n  # Ran 7 tests, 2 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n  $ rm examples/fail.t.err\n\nRun examples with bash:\n\n  $ cram --shell=/bin/bash -q examples examples/fail.t\n  .s.!.s.\n  # Ran 7 tests, 2 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n  $ rm examples/fail.t.err\n\nVerbose mode:\n\n  $ cram -q -v examples examples/fail.t\n  examples/bare.t: passed\n  examples/empty.t: empty\n  examples/env.t: passed\n  examples/fail.t: failed\n  examples/missingeol.t: passed\n  examples/skip.t: skipped\n  examples/test.t: passed\n  # Ran 7 tests, 2 skipped, 1 failed.\n  [1]\n  $ md5 examples/fail.t examples/fail.t.err\n  .*\\b0f598c2b7b8ca5bcb8880e492ff6b452\\b.* (re)\n  .*\\b7a23dfa85773c77648f619ad0f9df554\\b.* (re)\n  $ rm examples/fail.t.err\n\nTest that a fixed .err file is deleted:\n\n  $ echo \"  $ echo 1\" > fixed.t\n  $ cram fixed.t\n  !\n  --- fixed.t\n  +++ fixed.t.err\n  @@ -1,1 +1,2 @@\n     $ echo 1\n  +  1\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ cp fixed.t.err fixed.t\n  $ cram fixed.t\n  .\n  # Ran 1 tests, 0 skipped, 0 failed.\n  $ test \\! -f fixed.t.err\n  $ rm fixed.t\n\nDon't sterilize environment:\n\n  $ TZ=foo; export TZ\n  $ CDPATH=foo; export CDPATH\n  $ GREP_OPTIONS=foo; export GREP_OPTIONS\n  $ cram -E examples/env.t\n  !\n  \\-\\-\\- examples/env\\.t\\s* (re)\n  \\+\\+\\+ examples/env\\.t\\.err\\s* (re)\n  @@ -7,11 +7,11 @@\n     $ echo \"$LANGUAGE\"\n     C\n     $ echo \"$TZ\"\n  -  GMT\n  +  foo\n     $ echo \"$CDPATH\"\n  -  \n  +  foo\n     $ echo \"$GREP_OPTIONS\"\n  -  \n  +  foo\n     $ echo \"$CRAMTMP\"\n     .+ (re)\n     $ echo \"$TESTDIR\"\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n  $ rm examples/env.t.err\n\nNote: We can't set the locale to foo because some shells will issue\nwarnings for invalid locales.\n\nTest --keep-tmpdir:\n\n  $ cram -q --keep-tmpdir examples/test.t | while read line; do\n  >   echo \"$line\" 1>&2\n  >   msg=`echo \"$line\" | cut -d ' ' -f 1-4`\n  >   if [ \"$msg\" = '# Kept temporary directory:' ]; then\n  >     echo \"$line\" | cut -d ' ' -f 5\n  >   fi\n  > done > keeptmp\n  .\n  # Ran 1 tests, 0 skipped, 0 failed.\n  # Kept temporary directory: */cramtests-* (glob)\n  $ ls \"`cat keeptmp`\" | sort\n  test.t\n  tmp\n\nCustom indentation:\n\n  $ cat > indent.t <<EOF\n  > Indented by 4 spaces:\n  > \n  >     $ echo foo\n  >     foo\n  > \n  > Not part of the test:\n  > \n  >   $ echo foo\n  >   bar\n  > EOF\n  $ cram --indent=4 indent.t\n  .\n  # Ran 1 tests, 0 skipped, 0 failed.\n\nTest running tests with the same filename in different directories:\n\n  $ mkdir subdir1 subdir2\n  $ cat > subdir1/test.t <<EOF\n  >   $ echo 1\n  > EOF\n  $ cat > subdir2/test.t <<EOF\n  >   $ echo 2\n  > EOF\n  $ cram subdir1 subdir2\n  !\n  --- subdir1/test.t\n  +++ subdir1/test.t.err\n  @@ -1,1 +1,2 @@\n     $ echo 1\n  +  1\n  !\n  --- subdir2/test.t\n  +++ subdir2/test.t.err\n  @@ -1,1 +1,2 @@\n     $ echo 2\n  +  2\n  \n  # Ran 2 tests, 0 skipped, 2 failed.\n  [1]\n\nTest failing a test in a read-only directory with the --no-err-files option:\n\n  $ mkdir subdir\n  $ cat > subdir/test.t <<EOF\n  >   $ echo 1\n  > EOF\n  $ chmod a-w subdir\n  $ cram subdir >/dev/null 2>&1\n  [1]\n  $ cram --no-err-files subdir\n  !\n  --- subdir/test.t\n  +++ subdir/test.t.err\n  @@ -1,1 +1,2 @@\n     $ echo 1\n  +  1\n  \n  # Ran 1 tests, 0 skipped, 1 failed.\n  [1]\n\n  $ chmod a+w subdir\n"
  },
  {
    "path": "third_party/cram/tests/usage.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nUsage:\n\n  $ cram -h\n  [Uu]sage: cram \\[OPTIONS\\] TESTS\\.\\.\\. (re)\n  \n  [Oo]ptions: (re)\n    -h, --help          show this help message and exit\n    -V, --version       show version information and exit\n    -q, --quiet         don't print diffs\n    -v, --verbose       show filenames and test status\n    -i, --interactive   interactively merge changed test output\n    -d, --debug         write script output directly to the terminal\n    -y, --yes           answer yes to all questions\n    -n, --no            answer no to all questions\n    -E, --preserve-env  don't reset common environment variables\n    -e, --no-err-files  don't write .err files on test failures\n    --keep-tmpdir       keep temporary directories\n    --shell=PATH        shell to use for running tests (default: /bin/sh)\n    --shell-opts=OPTS   arguments to invoke shell with\n    --indent=NUM        number of spaces to use for indentation (default: 2)\n    --xunit-file=PATH   path to write xUnit XML output\n  $ cram -V\n  Cram CLI testing framework (version 0.7)\n  \n  Copyright (C) 2010-2016 Brodie Rao <brodie@bitheap.org> and others\n  This is free software; see the source for copying conditions. There is NO\n  warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n  $ cram\n  [Uu]sage: cram \\[OPTIONS\\] TESTS\\.\\.\\. (re)\n  [2]\n  $ cram -y -n\n  options --yes and --no are mutually exclusive\n  [2]\n  $ cram non-existent also-not-here\n  no such file: non-existent\n  [2]\n  $ mkdir empty\n  $ cram empty\n  no tests found\n  [2]\n  $ cram --shell=./badsh\n  shell not found: ./badsh\n  [2]\n"
  },
  {
    "path": "third_party/cram/tests/xunit.t",
    "content": "Set up cram alias and example tests:\n\n  $ . \"$TESTDIR\"/setup.sh\n\nxUnit XML output:\n\n  $ cram -q -v --xunit-file=cram.xml examples\n  examples/bare.t: passed\n  examples/empty.t: empty\n  examples/env.t: passed\n  examples/fail.t: failed\n  examples/missingeol.t: passed\n  examples/skip.t: skipped\n  examples/test.t: passed\n  # Ran 7 tests, 2 skipped, 1 failed.\n  [1]\n  $ cat cram.xml\n  <?xml version=\"1.0\" encoding=\"utf-8\"?>\n  <testsuite name=\"cram\"\n             tests=\"7\"\n             failures=\"1\"\n             skipped=\"2\"\n             timestamp=\"\\d+-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\+\\d{2}:\\d{2}\" (re)\n             hostname=\"[^\"]+\" (re)\n             time=\"\\d+\\.\\d{6}\"> (re)\n    <testcase classname=\"examples/bare.t\"\n              name=\"bare.t\"\n              time=\"\\d+\\.\\d{6}\"/> (re)\n    <testcase classname=\"examples/empty.t\"\n              name=\"empty.t\"\n              time=\"\\d+\\.\\d{6}\"> (re)\n      <skipped/>\n    </testcase>\n    <testcase classname=\"examples/env.t\"\n              name=\"env.t\"\n              time=\"\\d+\\.\\d{6}\"/> (re)\n    <testcase classname=\"examples/fail.t\"\n              name=\"fail.t\"\n              time=\"\\d+\\.\\d{6}\"> (re)\n      <failure><![CDATA[--- examples/fail.t\n  +++ examples/fail.t.err\n  @@ -1,18 +1,18 @@\n   Output needing escaping:\n   \n     $ printf '\\00\\01\\02\\03\\04\\05\\06\\07\\010\\011\\013\\014\\016\\017\\020\\021\\022\\n'\n  -  foo\n  +  \\x00\\x01\\x02\\x03\\x04\\x05\\x06\\x07\\x08\\t\\x0b\\x0c\\x0e\\x0f\\x10\\x11\\x12 (esc)\n     $ printf '\\023\\024\\025\\026\\027\\030\\031\\032\\033\\034\\035\\036\\037\\040\\047\\n'\n  -  bar\n  +  \\x13\\x14\\x15\\x16\\x17\\x18\\x19\\x1a\\x1b\\x1c\\x1d\\x1e\\x1f ' (esc)\n   \n   Wrong output and bad regexes:\n   \n     $ echo 1\n  -  2\n  +  1\n     $ printf '1\\nfoo\\n1\\n'\n  -  +++ (re)\n  -  foo\\ (re)\n  -   (re)\n  +  1\n  +  foo\n  +  1\n   \n   Filler to force a second diff hunk:\n   \n  @@ -20,5 +20,6 @@\n   Offset regular expression:\n   \n     $ printf 'foo\\n\\n1\\n'\n  +  foo\n     \n     \\d (re)\n  ]]></failure>\n    </testcase>\n    <testcase classname=\"examples/missingeol.t\"\n              name=\"missingeol.t\"\n              time=\"\\d+\\.\\d{6}\"/> (re)\n    <testcase classname=\"examples/skip.t\"\n              name=\"skip.t\"\n              time=\"\\d+\\.\\d{6}\"> (re)\n      <skipped/>\n    </testcase>\n    <testcase classname=\"examples/test.t\"\n              name=\"test.t\"\n              time=\"\\d+\\.\\d{6}\"/> (re)\n  </testsuite>\n  $ rm cram.xml examples/fail.t.err\n"
  },
  {
    "path": "third_party/luajit/Makefile.am",
    "content": "# Copyright (C) 2016 Alexey Kopytov <akopytov@gmail.com>\n#\n# This program is free software; you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation; either version 2 of the License, or\n# (at your option) any later version.\n#\n# This program is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this program; if not, write to the Free Software\n# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n\nEXTRA_DIST = luajit\n\nif IS_MACOS\nexport MACOSX_DEPLOYMENT_TARGET := @MACOSX_DEPLOYMENT_TARGET@\nendif\n\nall-local: $(builddir)/lib/libluajit-5.1.a\n\n# LuaJIT does not support VPATH builds\n$(builddir)/lib/libluajit-5.1.a:\n\t$(MAKE) -C $(srcdir)/luajit clean\n\trm -rf tmp\n\tmkdir tmp\n\ttar -C $(srcdir) -cf - luajit | tar -xf - -C tmp/\n\tchmod -R u+w tmp\n\t$(MAKE) -C tmp/luajit \\\n                PREFIX=$(abs_top_builddir)/third_party/luajit \\\n                INSTALL_INC=$(abs_top_builddir)/third_party/luajit/inc \\\n                install\n\nclean-local:\n\trm -rf tmp bin inc lib share\n"
  },
  {
    "path": "third_party/luajit/luajit/.gitignore",
    "content": "*.[oa]\n*.so\n*.obj\n*.lib\n*.exp\n*.dll\n*.exe\n*.manifest\n*.dmp\n*.swp\n.tags\n"
  },
  {
    "path": "third_party/luajit/luajit/COPYRIGHT",
    "content": "===============================================================================\nLuaJIT -- a Just-In-Time Compiler for Lua. https://luajit.org/\n\nCopyright (C) 2005-2022 Mike Pall. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n[ MIT license: https://www.opensource.org/licenses/mit-license.php ]\n\n===============================================================================\n[ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]\n\nCopyright (C) 1994-2012 Lua.org, PUC-Rio.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n===============================================================================\n[ LuaJIT includes code from dlmalloc, which has this license statement: ]\n\nThis is a version (aka dlmalloc) of malloc/free/realloc written by\nDoug Lea and released to the public domain, as explained at\nhttps://creativecommons.org/licenses/publicdomain\n\n===============================================================================\n"
  },
  {
    "path": "third_party/luajit/luajit/README",
    "content": "README for LuaJIT 2.1.0-beta3\n-----------------------------\n\nLuaJIT is a Just-In-Time (JIT) compiler for the Lua programming language.\n\nProject Homepage: https://luajit.org/\n\nLuaJIT is Copyright (C) 2005-2022 Mike Pall.\nLuaJIT is free software, released under the MIT license.\nSee full Copyright Notice in the COPYRIGHT file or in luajit.h.\n\nDocumentation for LuaJIT is available in HTML format.\nPlease point your favorite browser to:\n\n doc/luajit.html\n\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/bluequad-print.css",
    "content": "/* Copyright (C) 2004-2022 Mike Pall.\n *\n * You are welcome to use the general ideas of this design for your own sites.\n * But please do not steal the stylesheet, the layout or the color scheme.\n */\nbody {\n  font-family: serif;\n  font-size: 11pt;\n  margin: 0 3em;\n  padding: 0;\n  border: none;\n}\na:link, a:visited, a:hover, a:active {\n  text-decoration: none;\n  background: transparent;\n  color: #0000ff;\n}\nh1, h2, h3 {\n  font-family: sans-serif;\n  font-weight: bold;\n  text-align: left;\n  margin: 0.5em 0;\n  padding: 0;\n}\nh1 {\n  font-size: 200%;\n}\nh2 {\n  font-size: 150%;\n}\nh3 {\n  font-size: 125%;\n}\np {\n  margin: 0 0 0.5em 0;\n  padding: 0;\n}\nul, ol {\n  margin: 0.5em 0;\n  padding: 0 0 0 2em;\n}\nul {\n  list-style: outside square;\n}\nol {\n  list-style: outside decimal;\n}\nli {\n  margin: 0;\n  padding: 0;\n}\ndl {\n  margin: 1em 0;\n  padding: 1em;\n  border: 1px solid black;\n}\ndt {\n  font-weight: bold;\n  margin: 0;\n  padding: 0;\n}\ndt sup {\n  float: right;\n  margin-left: 1em;\n}\ndd {\n  margin: 0.5em 0 0 2em;\n  padding: 0;\n}\ntable {\n  table-layout: fixed;\n  width: 100%;\n  margin: 1em 0;\n  padding: 0;\n  border: 1px solid black;\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntr {\n  margin: 0;\n  padding: 0;\n  border: none;\n}\ntd {\n  text-align: left;\n  margin: 0;\n  padding: 0.2em 0.5em;\n  border-top: 1px solid black;\n  border-bottom: 1px solid black;\n}\ntr.separate td {\n  border-top: double;\n}\ntt, pre, code, kbd, samp {\n  font-family: monospace;\n  font-size: 75%;\n}\nkbd {\n  font-weight: bolder;\n}\nblockquote, pre {\n  margin: 1em 2em;\n  padding: 0;\n}\nimg {\n  border: none;\n  vertical-align: baseline;\n  margin: 0;\n  padding: 0;\n}\nimg.left {\n  float: left;\n  margin: 0.5em 1em 0.5em 0;\n}\nimg.right {\n  float: right;\n  margin: 0.5em 0 0.5em 1em;\n}\n.flush {\n  clear: both;\n  visibility: hidden;\n}\n.hide, .noprint, #nav {\n  display: none !important;\n}\n.pagebreak {\n  page-break-before: always;\n}\n#site {\n  text-align: right;\n  font-family: sans-serif;\n  font-weight: bold;\n  margin: 0 1em;\n  border-bottom: 1pt solid black;\n}\n#site a {\n  font-size: 1.2em;\n}\n#site a:link, #site a:visited {\n  text-decoration: none;\n  font-weight: bold;\n  background: transparent;\n  color: #ffffff;\n}\n#logo {\n  color: #ff8000;\n}\n#head {\n  clear: both;\n  margin: 0 1em;\n}\n#main {\n  line-height: 1.3;\n  text-align: justify;\n  margin: 1em;\n}\n#foot {\n  clear: both;\n  font-size: 80%;\n  text-align: center;\n  margin: 0 1.25em;\n  padding: 0.5em 0 0 0;\n  border-top: 1pt solid black;\n  page-break-before: avoid;\n  page-break-after: avoid;\n}\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/bluequad.css",
    "content": "/* Copyright (C) 2004-2022 Mike Pall.\n *\n * You are welcome to use the general ideas of this design for your own sites.\n * But please do not steal the stylesheet, the layout or the color scheme.\n */\n/* colorscheme:\n *\n * site  |  head   #4162bf/white   | #6078bf/#e6ecff\n * ------+------   ----------------+-------------------\n * nav   |  main   #bfcfff         | #e6ecff/black\n *\n * nav:  hiback   loback     #c5d5ff #b9c9f9\n *       hiborder loborder   #e6ecff #97a7d7\n *       link     hover      #2142bf #ff0000\n *\n * link: link visited hover  #2142bf #8122bf #ff0000\n *\n * main: boxback  boxborder  #f0f4ff #bfcfff\n */\nbody {\n  font-family: Verdana, Arial, Helvetica, sans-serif;\n  font-size: 10pt;\n  margin: 0;\n  padding: 0;\n  border: none;\n  background: #e0e0e0;\n  color: #000000;\n}\na:link {\n  text-decoration: none;\n  background: transparent;\n  color: #2142bf;\n}\na:visited {\n  text-decoration: none;\n  background: transparent;\n  color: #8122bf;\n}\na:hover, a:active {\n  text-decoration: underline;\n  background: transparent;\n  color: #ff0000;\n}\nh1, h2, h3 {\n  font-weight: bold;\n  text-align: left;\n  margin: 0.5em 0;\n  padding: 0;\n  background: transparent;\n}\nh1 {\n  font-size: 200%;\n  line-height: 3em; /* really 6em relative to body, match #site span */\n  margin: 0;\n}\nh2 {\n  font-size: 150%;\n  color: #606060;\n}\nh3 {\n  font-size: 125%;\n  color: #404040;\n}\np {\n  max-width: 600px;\n  margin: 0 0 0.5em 0;\n  padding: 0;\n}\nb {\n  color: #404040;\n}\nul, ol {\n  max-width: 600px;\n  margin: 0.5em 0;\n  padding: 0 0 0 2em;\n}\nul {\n  list-style: outside square;\n}\nol {\n  list-style: outside decimal;\n}\nli {\n  margin: 0;\n  padding: 0;\n}\ndl {\n  max-width: 600px;\n  margin: 1em 0;\n  padding: 1em;\n  border: 1px solid #bfcfff;\n  background: #f0f4ff;\n}\ndt {\n  font-weight: bold;\n  margin: 0;\n  padding: 0;\n}\ndt sup {\n  float: right;\n  margin-left: 1em;\n  color: #808080;\n}\ndt a:visited {\n  text-decoration: none;\n  color: #2142bf;\n}\ndt a:hover, dt a:active {\n  text-decoration: none;\n  color: #ff0000;\n}\ndd {\n  margin: 0.5em 0 0 2em;\n  padding: 0;\n}\ndiv.tablewrap { /* for IE *sigh* */\n  max-width: 600px;\n}\ntable {\n  table-layout: fixed;\n  border-spacing: 0;\n  border-collapse: collapse;\n  max-width: 600px;\n  width: 100%;\n  margin: 1em 0;\n  padding: 0;\n  border: 1px solid #bfcfff;\n}\ntr {\n  margin: 0;\n  padding: 0;\n  border: none;\n}\ntr.odd {\n  background: #f0f4ff;\n}\ntr.separate td {\n  border-top: 1px solid #bfcfff;\n}\ntd {\n  text-align: left;\n  margin: 0;\n  padding: 0.2em 0.5em;\n  border: none;\n}\ntt, code, kbd, samp {\n  font-family: Courier New, Courier, monospace;\n  line-height: 1.2;\n  font-size: 110%;\n}\nkbd {\n  font-weight: bolder;\n}\nblockquote, pre {\n  max-width: 600px;\n  margin: 1em 2em;\n  padding: 0;\n}\npre {\n  line-height: 1.1;\n}\npre.code {\n  line-height: 1.4;\n  margin: 0.5em 0 1em 0.5em;\n  padding: 0.5em 1em;\n  border: 1px solid #bfcfff;\n  background: #f0f4ff;\n}\npre.mark {\n  padding-left: 2em;\n}\nspan.codemark {\n  position:absolute;\n  left: 16em;\n  color: #4040c0;\n}\nspan.mark {\n  color: #4040c0;\n  font-family: Courier New, Courier, monospace;\n  line-height: 1.1;\n}\nimg {\n  border: none;\n  vertical-align: baseline;\n  margin: 0;\n  padding: 0;\n}\nimg.left {\n  float: left;\n  margin: 0.5em 1em 0.5em 0;\n}\nimg.right {\n  float: right;\n  margin: 0.5em 0 0.5em 1em;\n}\n.indent {\n  padding-left: 1em;\n}\n.flush {\n  clear: both;\n  visibility: hidden;\n}\n.hide, .noscreen {\n  display: none !important;\n}\n.ext {\n  color: #ff8000;\n}\n.new {\n  font-size: 6pt;\n  vertical-align: middle;\n  background: #ff8000;\n  color: #ffffff;\n}\n#site {\n  clear: both;\n  float: left;\n  width: 13em;\n  text-align: center;\n  font-weight: bold;\n  margin: 0;\n  padding: 0;\n  background: transparent;\n  color: #ffffff;\n}\n#site a {\n  font-size: 200%;\n}\n#site a:link, #site a:visited {\n  text-decoration: none;\n  font-weight: bold;\n  background: transparent;\n  color: #ffffff;\n}\n#site span {\n  line-height: 3em; /* really 6em relative to body, match h1 */\n}\n#logo {\n  color: #ffb380;\n}\n#head {\n  margin: 0;\n  padding: 0 0 0 2em;\n  border-left: solid 13em #4162bf;\n  border-right: solid 3em #6078bf;\n  background: #6078bf;\n  color: #e6ecff;\n}\n#nav {\n  clear: both;\n  float: left;\n  overflow: hidden;\n  text-align: left;\n  line-height: 1.5;\n  width: 13em;\n  padding-top: 1em;\n  background: transparent;\n}\n#nav ul {\n  list-style: none outside;\n  margin: 0;\n  padding: 0;\n}\n#nav li {\n  margin: 0;\n  padding: 0;\n}\n#nav a {\n  display: block;\n  text-decoration: none;\n  font-weight: bold;\n  margin: 0;\n  padding: 2px 1em;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  background: transparent;\n  color: #2142bf;\n}\n#nav a:hover, #nav a:active {\n  text-decoration: none;\n  border-top: 1px solid #97a7d7;\n  border-bottom: 1px solid #e6ecff;\n  background: #b9c9f9;\n  color: #ff0000;\n}\n#nav a.current, #nav a.current:hover, #nav a.current:active {\n  border-top: 1px solid #e6ecff;\n  border-bottom: 1px solid #97a7d7;\n  background: #c5d5ff;\n  color: #2142bf;\n}\n#nav ul ul a {\n  padding: 0 1em 0 1.7em;\n}\n#nav ul ul ul a {\n  padding: 0 0.5em 0 2.4em;\n}\n#main {\n  line-height: 1.5;\n  text-align: left;\n  margin: 0;\n  padding: 1em 2em;\n  border-left: solid 13em #bfcfff;\n  border-right: solid 3em #e6ecff;\n  background: #e6ecff;\n}\n#foot {\n  clear: both;\n  font-size: 80%;\n  text-align: center;\n  margin: 0;\n  padding: 0.5em;\n  background: #6078bf;\n  color: #ffffff;\n}\n#foot a:link, #foot a:visited {\n  text-decoration: underline;\n  background: transparent;\n  color: #ffffff;\n}\n#foot a:hover, #foot a:active {\n  text-decoration: underline;\n  background: transparent;\n  color: #bfcfff;\n}\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/contact.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Contact</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Contact</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nIf you want to report bugs, propose fixes or suggest enhancements,\nplease use the\n<a href=\"https://github.com/LuaJIT/LuaJIT/issues\"><span class=\"ext\">&raquo;</span>&nbsp;GitHub issue tracker</a>.\n</p>\n<p>\nPlease send general questions to the\n<a href=\"https://luajit.org/list.html\"><span class=\"ext\">&raquo;</span>&nbsp;LuaJIT mailing list</a>.\n</p>\n<p>\nYou can also send any questions you have directly to me:\n</p>\n\n<script type=\"text/javascript\">\n<!--\nvar xS=\"@-:\\\" .0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ<abc>defghijklmnopqrstuvwxyz\";function xD(s)\n{var len=s.length;var r=\"\";for(var i=0;i<len;i++)\n{var c=s.charAt(i);var n=xS.indexOf(c);if(n!=-1)c=xS.charAt(69-n);r+=c;}\ndocument.write(\"<\"+\"p>\"+r+\"<\"+\"/p>\\n\");}\n//-->\n</script>\n<script type=\"text/javascript\">\n<!--\nxD(\"fyZKB8xv\\\"FJytmz8.KAB0u52D\")\n//--></script>\n<noscript>\n<p><img src=\"img/contact.png\" alt=\"Contact info in image\" width=\"170\" height=\"13\">\n</p>\n</noscript>\n\n<p><i>\nNote: I cannot reply to GMail, Google Workplace, Outlook or Office365\nmail addresses, since they prefer to mindlessly filter out mails sent\nfrom small domains using independent mail servers, such as mine. If you\ndon't like that, please complain to Google or Microsoft, not me.\n</i></p>\n\n<h2>Copyright</h2>\n<p>\nAll documentation is\nCopyright &copy; 2005-2022 Mike Pall.\n</p>\n\n\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_buffer.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>String Buffer Library</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\n.lib {\n  vertical-align: middle;\n  margin-left: 5px;\n  padding: 0 5px;\n  font-size: 60%;\n  border-radius: 5px;\n  background: #c5d5ff;\n  color: #000;\n}\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>String Buffer Library</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a class=\"current\" href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nThe string buffer library allows <b>high-performance manipulation of\nstring-like data</b>.\n</p>\n<p>\nUnlike Lua strings, which are constants, string buffers are\n<b>mutable</b> sequences of 8-bit (binary-transparent) characters. Data\ncan be stored, formatted and encoded into a string buffer and later\nconverted, extracted or decoded.\n</p>\n<p>\nThe convenient string buffer API simplifies common string manipulation\ntasks, that would otherwise require creating many intermediate strings.\nString buffers improve performance by eliminating redundant memory\ncopies, object creation, string interning and garbage collection\noverhead. In conjunction with the FFI library, they allow zero-copy\noperations.\n</p>\n<p>\nThe string buffer library also includes a high-performance\n<a href=\"serialize\">serializer</a> for Lua objects.\n</p>\n\n<h2 id=\"wip\" style=\"color:#ff0000\">Work in Progress</h2>\n<p>\n<b style=\"color:#ff0000\">This library is a work in progress. More\nfunctionality will be added soon.</b>\n</p>\n\n<h2 id=\"use\">Using the String Buffer Library</h2>\n<p>\nThe string buffer library is built into LuaJIT by default, but it's not\nloaded by default. Add this to the start of every Lua file that needs\none of its functions:\n</p>\n<pre class=\"code\">\nlocal buffer = require(\"string.buffer\")\n</pre>\n<p>\nThe convention for the syntax shown on this page is that <tt>buffer</tt>\nrefers to the buffer library and <tt>buf</tt> refers to an individual\nbuffer object.\n</p>\n<p>\nPlease note the difference between a Lua function call, e.g.\n<tt>buffer.new()</tt> (with a dot) and a Lua method call, e.g.\n<tt>buf:reset()</tt> (with a colon).\n</p>\n\n<h3 id=\"buffer_object\">Buffer Objects</h3>\n<p>\nA buffer object is a garbage-collected Lua object. After creation with\n<tt>buffer.new()</tt>, it can (and should) be reused for many operations.\nWhen the last reference to a buffer object is gone, it will eventually\nbe freed by the garbage collector, along with the allocated buffer\nspace.\n</p>\n<p>\nBuffers operate like a FIFO (first-in first-out) data structure. Data\ncan be appended (written) to the end of the buffer and consumed (read)\nfrom the front of the buffer. These operations may be freely mixed.\n</p>\n<p>\nThe buffer space that holds the characters is managed automatically\n&mdash; it grows as needed and already consumed space is recycled. Use\n<tt>buffer.new(size)</tt> and <tt>buf:free()</tt>, if you need more\ncontrol.\n</p>\n<p>\nThe maximum size of a single buffer is the same as the maximum size of a\nLua string, which is slightly below two gigabytes. For huge data sizes,\nneither strings nor buffers are the right data structure &mdash; use the\nFFI library to directly map memory or files up to the virtual memory\nlimit of your OS.\n</p>\n\n<h3 id=\"buffer_overview\">Buffer Method Overview</h3>\n<ul>\n<li>\nThe <tt>buf:put*()</tt>-like methods append (write) characters to the\nend of the buffer.\n</li>\n<li>\nThe <tt>buf:get*()</tt>-like methods consume (read) characters from the\nfront of the buffer.\n</li>\n<li>\nOther methods, like <tt>buf:tostring()</tt> only read the buffer\ncontents, but don't change the buffer.\n</li>\n<li>\nThe <tt>buf:set()</tt> method allows zero-copy consumption of a string\nor an FFI cdata object as a buffer.\n</li>\n<li>\nThe FFI-specific methods allow zero-copy read/write-style operations or\nmodifying the buffer contents in-place. Please check the\n<a href=\"#ffi_caveats\">FFI caveats</a> below, too.\n</li>\n<li>\nMethods that don't need to return anything specific, return the buffer\nobject itself as a convenience. This allows method chaining, e.g.:\n<tt>buf:reset():encode(obj)</tt> or <tt>buf:skip(len):get()</tt>\n</li>\n</ul>\n\n<h2 id=\"create\">Buffer Creation and Management</h2>\n\n<h3 id=\"buffer_new\"><tt>local buf = buffer.new([size [,options]])<br>\nlocal buf = buffer.new([options])</tt></h3>\n<p>\nCreates a new buffer object.\n</p>\n<p>\nThe optional <tt>size</tt> argument ensures a minimum initial buffer\nsize. This is strictly an optimization when the required buffer size is\nknown beforehand. The buffer space will grow as needed, in any case.\n</p>\n<p>\nThe optional table <tt>options</tt> sets various\n<a href=\"#serialize_options\">serialization options</a>.\n</p>\n\n<h3 id=\"buffer_reset\"><tt>buf = buf:reset()</tt></h3>\n<p>\nReset (empty) the buffer. The allocated buffer space is not freed and\nmay be reused.\n</p>\n\n<h3 id=\"buffer_free\"><tt>buf = buf:free()</tt></h3>\n<p>\nThe buffer space of the buffer object is freed. The object itself\nremains intact, empty and may be reused.\n</p>\n<p>\nNote: you normally don't need to use this method. The garbage collector\nautomatically frees the buffer space, when the buffer object is\ncollected. Use this method, if you need to free the associated memory\nimmediately.\n</p>\n\n<h2 id=\"write\">Buffer Writers</h2>\n\n<h3 id=\"buffer_put\"><tt>buf = buf:put([str|num|obj] [,…])</tt></h3>\n<p>\nAppends a string <tt>str</tt>, a number <tt>num</tt> or any object\n<tt>obj</tt> with a <tt>__tostring</tt> metamethod to the buffer.\nMultiple arguments are appended in the given order.\n</p>\n<p>\nAppending a buffer to a buffer is possible and short-circuited\ninternally. But it still involves a copy. Better combine the buffer\nwrites to use a single buffer.\n</p>\n\n<h3 id=\"buffer_putf\"><tt>buf = buf:putf(format, …)</tt></h3>\n<p>\nAppends the formatted arguments to the buffer. The <tt>format</tt>\nstring supports the same options as <tt>string.format()</tt>.\n</p>\n\n<h3 id=\"buffer_putcdata\"><tt>buf = buf:putcdata(cdata, len)</tt><span class=\"lib\">FFI</span></h3>\n<p>\nAppends the given <tt>len</tt> number of bytes from the memory pointed\nto by the FFI <tt>cdata</tt> object to the buffer. The object needs to\nbe convertible to a (constant) pointer.\n</p>\n\n<h3 id=\"buffer_set\"><tt>buf = buf:set(str)<br>\nbuf = buf:set(cdata, len)</tt><span class=\"lib\">FFI</span></h3>\n<p>\nThis method allows zero-copy consumption of a string or an FFI cdata\nobject as a buffer. It stores a reference to the passed string\n<tt>str</tt> or the FFI <tt>cdata</tt> object in the buffer. Any buffer\nspace originally allocated is freed. This is <i>not</i> an append\noperation, unlike the <tt>buf:put*()</tt> methods.\n</p>\n<p>\nAfter calling this method, the buffer behaves as if\n<tt>buf:free():put(str)</tt> or <tt>buf:free():put(cdata,&nbsp;len)</tt>\nhad been called. However, the data is only referenced and not copied, as\nlong as the buffer is only consumed.\n</p>\n<p>\nIn case the buffer is written to later on, the referenced data is copied\nand the object reference is removed (copy-on-write semantics).\n</p>\n<p>\nThe stored reference is an anchor for the garbage collector and keeps the\noriginally passed string or FFI cdata object alive.\n</p>\n\n<h3 id=\"buffer_reserve\"><tt>ptr, len = buf:reserve(size)</tt><span class=\"lib\">FFI</span><br>\n<tt>buf = buf:commit(used)</tt><span class=\"lib\">FFI</span></h3>\n<p>\nThe <tt>reserve</tt> method reserves at least <tt>size</tt> bytes of\nwrite space in the buffer. It returns an <tt>uint8_t&nbsp;*</tt> FFI\ncdata pointer <tt>ptr</tt> that points to this space.\n</p>\n<p>\nThe available length in bytes is returned in <tt>len</tt>. This is at\nleast <tt>size</tt> bytes, but may be more to facilitate efficient\nbuffer growth. You can either make use of the additional space or ignore\n<tt>len</tt> and only use <tt>size</tt> bytes.\n</p>\n<p>\nThe <tt>commit</tt> method appends the <tt>used</tt> bytes of the\npreviously returned write space to the buffer data.\n</p>\n<p>\nThis pair of methods allows zero-copy use of C read-style APIs:\n</p>\n<pre class=\"code\">\nlocal MIN_SIZE = 65536\nrepeat\n  local ptr, len = buf:reserve(MIN_SIZE)\n  local n = C.read(fd, ptr, len)\n  if n == 0 then break end -- EOF.\n  if n &lt; 0 then error(\"read error\") end\n  buf:commit(n)\nuntil false\n</pre>\n<p>\nThe reserved write space is <i>not</i> initialized. At least the\n<tt>used</tt> bytes <b>must</b> be written to before calling the\n<tt>commit</tt> method. There's no need to call the <tt>commit</tt>\nmethod, if nothing is added to the buffer (e.g. on error).\n</p>\n\n<h2 id=\"read\">Buffer Readers</h2>\n\n<h3 id=\"buffer_length\"><tt>len = #buf</tt></h3>\n<p>\nReturns the current length of the buffer data in bytes.\n</p>\n\n<h3 id=\"buffer_concat\"><tt>res = str|num|buf .. str|num|buf […]</tt></h3>\n<p>\nThe Lua concatenation operator <tt>..</tt> also accepts buffers, just\nlike strings or numbers. It always returns a string and not a buffer.\n</p>\n<p>\nNote that although this is supported for convenience, this thwarts one\nof the main reasons to use buffers, which is to avoid string\nallocations. Rewrite it with <tt>buf:put()</tt> and <tt>buf:get()</tt>.\n</p>\n<p>\nMixing this with unrelated objects that have a <tt>__concat</tt>\nmetamethod may not work, since these probably only expect strings.\n</p>\n\n<h3 id=\"buffer_skip\"><tt>buf = buf:skip(len)</tt></h3>\n<p>\nSkips (consumes) <tt>len</tt> bytes from the buffer up to the current\nlength of the buffer data.\n</p>\n\n<h3 id=\"buffer_get\"><tt>str, … = buf:get([len|nil] [,…])</tt></h3>\n<p>\nConsumes the buffer data and returns one or more strings. If called\nwithout arguments, the whole buffer data is consumed. If called with a\nnumber, up to <tt>len</tt> bytes are consumed. A <tt>nil</tt> argument\nconsumes the remaining buffer space (this only makes sense as the last\nargument). Multiple arguments consume the buffer data in the given\norder.\n</p>\n<p>\nNote: a zero length or no remaining buffer data returns an empty string\nand not <tt>nil</tt>.\n</p>\n\n<h3 id=\"buffer_tostring\"><tt>str = buf:tostring()<br>\nstr = tostring(buf)</tt></h3>\n<p>\nCreates a string from the buffer data, but doesn't consume it. The\nbuffer remains unchanged.\n</p>\n<p>\nBuffer objects also define a <tt>__tostring</tt> metamethod. This means\nbuffers can be passed to the global <tt>tostring()</tt> function and\nmany other functions that accept this in place of strings. The important\ninternal uses in functions like <tt>io.write()</tt> are short-circuited\nto avoid the creation of an intermediate string object.\n</p>\n\n<h3 id=\"buffer_ref\"><tt>ptr, len = buf:ref()</tt><span class=\"lib\">FFI</span></h3>\n<p>\nReturns an <tt>uint8_t&nbsp;*</tt> FFI cdata pointer <tt>ptr</tt> that\npoints to the buffer data. The length of the buffer data in bytes is\nreturned in <tt>len</tt>.\n</p>\n<p>\nThe returned pointer can be directly passed to C functions that expect a\nbuffer and a length. You can also do bytewise reads\n(<tt>local&nbsp;x&nbsp;=&nbsp;ptr[i]</tt>) or writes\n(<tt>ptr[i]&nbsp;=&nbsp;0x40</tt>) of the buffer data.\n</p>\n<p>\nIn conjunction with the <tt>skip</tt> method, this allows zero-copy use\nof C write-style APIs:\n</p>\n<pre class=\"code\">\nrepeat\n  local ptr, len = buf:ref()\n  if len == 0 then break end\n  local n = C.write(fd, ptr, len)\n  if n &lt; 0 then error(\"write error\") end\n  buf:skip(n)\nuntil n >= len\n</pre>\n<p>\nUnlike Lua strings, buffer data is <i>not</i> implicitly\nzero-terminated. It's not safe to pass <tt>ptr</tt> to C functions that\nexpect zero-terminated strings. If you're not using <tt>len</tt>, then\nyou're doing something wrong.\n</p>\n\n<h2 id=\"serialize\">Serialization of Lua Objects</h2>\n<p>\nThe following functions and methods allow <b>high-speed serialization</b>\n(encoding) of a Lua object into a string and decoding it back to a Lua\nobject. This allows convenient storage and transport of <b>structured\ndata</b>.\n</p>\n<p>\nThe encoded data is in an <a href=\"#serialize_format\">internal binary\nformat</a>. The data can be stored in files, binary-transparent\ndatabases or transmitted to other LuaJIT instances across threads,\nprocesses or networks.\n</p>\n<p>\nEncoding speed can reach up to 1 Gigabyte/second on a modern desktop- or\nserver-class system, even when serializing many small objects. Decoding\nspeed is mostly constrained by object creation cost.\n</p>\n<p>\nThe serializer handles most Lua types, common FFI number types and\nnested structures. Functions, thread objects, other FFI cdata and full\nuserdata cannot be serialized (yet).\n</p>\n<p>\nThe encoder serializes nested structures as trees. Multiple references\nto a single object will be stored separately and create distinct objects\nafter decoding. Circular references cause an error.\n</p>\n\n<h3 id=\"serialize_methods\">Serialization Functions and Methods</h3>\n\n<h3 id=\"buffer_encode\"><tt>str = buffer.encode(obj)<br>\nbuf = buf:encode(obj)</tt></h3>\n<p>\nSerializes (encodes) the Lua object <tt>obj</tt>. The stand-alone\nfunction returns a string <tt>str</tt>. The buffer method appends the\nencoding to the buffer.\n</p>\n<p>\n<tt>obj</tt> can be any of the supported Lua types &mdash; it doesn't\nneed to be a Lua table.\n</p>\n<p>\nThis function may throw an error when attempting to serialize\nunsupported object types, circular references or deeply nested tables.\n</p>\n\n<h3 id=\"buffer_decode\"><tt>obj = buffer.decode(str)<br>\nobj = buf:decode()</tt></h3>\n<p>\nThe stand-alone function deserializes (decodes) the string\n<tt>str</tt>, the buffer method deserializes one object from the\nbuffer. Both return a Lua object <tt>obj</tt>.\n</p>\n<p>\nThe returned object may be any of the supported Lua types &mdash;\neven <tt>nil</tt>.\n</p>\n<p>\nThis function may throw an error when fed with malformed or incomplete\nencoded data. The stand-alone function throws when there's left-over\ndata after decoding a single top-level object. The buffer method leaves\nany left-over data in the buffer.\n</p>\n<p>\nAttempting to deserialize an FFI type will throw an error, if the FFI\nlibrary is not built-in or has not been loaded, yet.\n</p>\n\n<h3 id=\"serialize_options\">Serialization Options</h3>\n<p>\nThe <tt>options</tt> table passed to <tt>buffer.new()</tt> may contain\nthe following members (all optional):\n</p>\n<ul>\n<li>\n<tt>dict</tt> is a Lua table holding a <b>dictionary of strings</b> that\ncommonly occur as table keys of objects you are serializing. These keys\nare compactly encoded as indexes during serialization. A well-chosen\ndictionary saves space and improves serialization performance.\n</li>\n<li>\n<tt>metatable</tt> is a Lua table holding a <b>dictionary of metatables</b>\nfor the table objects you are serializing.\n</li>\n</ul>\n<p>\n<tt>dict</tt> needs to be an array of strings and <tt>metatable</tt> needs\nto be an array of tables. Both starting at index 1 and without holes (no\n<tt>nil</tt> in between). The tables are anchored in the buffer object and\ninternally modified into a two-way index (don't do this yourself, just pass\na plain array). The tables must not be modified after they have been passed\nto <tt>buffer.new()</tt>.\n</p>\n<p>\nThe <tt>dict</tt> and <tt>metatable</tt> tables used by the encoder and\ndecoder must be the same. Put the most common entries at the front. Extend\nat the end to ensure backwards-compatibility &mdash; older encodings can\nthen still be read. You may also set some indexes to <tt>false</tt> to\nexplicitly drop backwards-compatibility. Old encodings that use these\nindexes will throw an error when decoded.\n</p>\n<p>\nMetatables that are not found in the <tt>metatable</tt> dictionary are\nignored when encoding. Decoding returns a table with a <tt>nil</tt>\nmetatable.\n</p>\n<p>\nNote: parsing and preparation of the options table is somewhat\nexpensive. Create a buffer object only once and recycle it for multiple\nuses. Avoid mixing encoder and decoder buffers, since the\n<tt>buf:set()</tt> method frees the already allocated buffer space:\n</p>\n<pre class=\"code\">\nlocal options = {\n  dict = { \"commonly\", \"used\", \"string\", \"keys\" },\n}\nlocal buf_enc = buffer.new(options)\nlocal buf_dec = buffer.new(options)\n\nlocal function encode(obj)\n  return buf_enc:reset():encode(obj):get()\nend\n\nlocal function decode(str)\n  return buf_dec:set(str):decode()\nend\n</pre>\n\n<h3 id=\"serialize_stream\">Streaming Serialization</h3>\n<p>\nIn some contexts, it's desirable to do piecewise serialization of large\ndatasets, also known as <i>streaming</i>.\n</p>\n<p>\nThis serialization format can be safely concatenated and supports streaming.\nMultiple encodings can simply be appended to a buffer and later decoded\nindividually:\n</p>\n<pre class=\"code\">\nlocal buf = buffer.new()\nbuf:encode(obj1)\nbuf:encode(obj2)\nlocal copy1 = buf:decode()\nlocal copy2 = buf:decode()\n</pre>\n<p>\nHere's how to iterate over a stream:\n</p>\n<pre class=\"code\">\nwhile #buf ~= 0 do\n  local obj = buf:decode()\n  -- Do something with obj.\nend\n</pre>\n<p>\nSince the serialization format doesn't prepend a length to its encoding,\nnetwork applications may need to transmit the length, too.\n</p>\n\n<h3 id=\"serialize_format\">Serialization Format Specification</h3>\n<p>\nThis serialization format is designed for <b>internal use</b> by LuaJIT\napplications. Serialized data is upwards-compatible and portable across\nall supported LuaJIT platforms.\n</p>\n<p>\nIt's an <b>8-bit binary format</b> and not human-readable. It uses e.g.\nembedded zeroes and stores embedded Lua string objects unmodified, which\nare 8-bit-clean, too. Encoded data can be safely concatenated for\nstreaming and later decoded one top-level object at a time.\n</p>\n<p>\nThe encoding is reasonably compact, but tuned for maximum performance,\nnot for minimum space usage. It compresses well with any of the common\nbyte-oriented data compression algorithms.\n</p>\n<p>\nAlthough documented here for reference, this format is explicitly\n<b>not</b> intended to be a 'public standard' for structured data\ninterchange across computer languages (like JSON or MessagePack). Please\ndo not use it as such.\n</p>\n<p>\nThe specification is given below as a context-free grammar with a\ntop-level <tt>object</tt> as the starting point. Alternatives are\nseparated by the <tt>|</tt> symbol and <tt>*</tt> indicates repeats.\nGrouping is implicit or indicated by <tt>{…}</tt>. Terminals are\neither plain hex numbers, encoded as bytes, or have a <tt>.format</tt>\nsuffix.\n</p>\n<pre>\nobject    → nil | false | true\n          | null | lightud32 | lightud64\n          | int | num | tab | tab_mt\n          | int64 | uint64 | complex\n          | string\n\nnil       → 0x00\nfalse     → 0x01\ntrue      → 0x02\n\nnull      → 0x03                            // NULL lightuserdata\nlightud32 → 0x04 data.I                   // 32 bit lightuserdata\nlightud64 → 0x05 data.L                   // 64 bit lightuserdata\n\nint       → 0x06 int.I                                 // int32_t\nnum       → 0x07 double.L\n\ntab       → 0x08                                   // Empty table\n          | 0x09 h.U h*{object object}          // Key/value hash\n          | 0x0a a.U a*object                    // 0-based array\n          | 0x0b a.U a*object h.U h*{object object}      // Mixed\n          | 0x0c a.U (a-1)*object                // 1-based array\n          | 0x0d a.U (a-1)*object h.U h*{object object}  // Mixed\ntab_mt    → 0x0e (index-1).U tab          // Metatable dict entry\n\nint64     → 0x10 int.L                             // FFI int64_t\nuint64    → 0x11 uint.L                           // FFI uint64_t\ncomplex   → 0x12 re.L im.L                         // FFI complex\n\nstring    → (0x20+len).U len*char.B\n          | 0x0f (index-1).U                 // String dict entry\n\n.B = 8 bit\n.I = 32 bit little-endian\n.L = 64 bit little-endian\n.U = prefix-encoded 32 bit unsigned number n:\n     0x00..0xdf   → n.B\n     0xe0..0x1fdf → (0xe0|(((n-0xe0)>>8)&0x1f)).B ((n-0xe0)&0xff).B\n   0x1fe0..       → 0xff n.I\n</pre>\n\n<h2 id=\"error\">Error handling</h2>\n<p>\nMany of the buffer methods can throw an error. Out-of-memory or usage\nerrors are best caught with an outer wrapper for larger parts of code.\nThere's not much one can do after that, anyway.\n</p>\n<p>\nOTOH, you may want to catch some errors individually. Buffer methods need\nto receive the buffer object as the first argument. The Lua colon-syntax\n<tt>obj:method()</tt> does that implicitly. But to wrap a method with\n<tt>pcall()</tt>, the arguments need to be passed like this:\n</p>\n<pre class=\"code\">\nlocal ok, err = pcall(buf.encode, buf, obj)\nif not ok then\n  -- Handle error in err.\nend\n</pre>\n\n<h2 id=\"ffi_caveats\">FFI caveats</h2>\n<p>\nThe string buffer library has been designed to work well together with\nthe FFI library. But due to the low-level nature of the FFI library,\nsome care needs to be taken:\n</p>\n<p>\nFirst, please remember that FFI pointers are zero-indexed. The space\nreturned by <tt>buf:reserve()</tt> and <tt>buf:ref()</tt> starts at the\nreturned pointer and ends before <tt>len</tt> bytes after that.\n</p>\n<p>\nI.e. the first valid index is <tt>ptr[0]</tt> and the last valid index\nis <tt>ptr[len-1]</tt>. If the returned length is zero, there's no valid\nindex at all. The returned pointer may even be <tt>NULL</tt>.\n</p>\n<p>\nThe space pointed to by the returned pointer is only valid as long as\nthe buffer is not modified in any way (neither append, nor consume, nor\nreset, etc.). The pointer is also not a GC anchor for the buffer object\nitself.\n</p>\n<p>\nBuffer data is only guaranteed to be byte-aligned. Casting the returned\npointer to a data type with higher alignment may cause unaligned\naccesses. It depends on the CPU architecture whether this is allowed or\nnot (it's always OK on x86/x64 and mostly OK on other modern\narchitectures).\n</p>\n<p>\nFFI pointers or references do not count as GC anchors for an underlying\nobject. E.g. an <tt>array</tt> allocated with <tt>ffi.new()</tt> is\nanchored by <tt>buf:set(array,&nbsp;len)</tt>, but not by\n<tt>buf:set(array+offset,&nbsp;len)</tt>. The addition of the offset\ncreates a new pointer, even when the offset is zero. In this case, you\nneed to make sure there's still a reference to the original array as\nlong as its contents are in use by the buffer.\n</p>\n<p>\nEven though each LuaJIT VM instance is single-threaded (but you can\ncreate multiple VMs), FFI data structures can be accessed concurrently.\nBe careful when reading/writing FFI cdata from/to buffers to avoid\nconcurrent accesses or modifications. In particular, the memory\nreferenced by <tt>buf:set(cdata,&nbsp;len)</tt> must not be modified\nwhile buffer readers are working on it. Shared, but read-only memory\nmappings of files are OK, but only if the file does not change.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_c_api.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Lua/C API Extensions</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Lua/C API Extensions</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a class=\"current\" href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nLuaJIT adds some extensions to the standard Lua/C API. The LuaJIT include\ndirectory must be in the compiler search path (<tt>-I<i>path</i></tt>)\nto be able to include the required header for C code:\n</p>\n<pre class=\"code\">\n#include \"luajit.h\"\n</pre>\n<p>\nOr for C++ code:\n</p>\n<pre class=\"code\">\n#include \"lua.hpp\"\n</pre>\n\n<h2 id=\"luaJIT_setmode\"><tt>luaJIT_setmode(L, idx, mode)</tt>\n&mdash; Control VM</h2>\n<p>\nThis is a C API extension to allow control of the VM from C code. The\nfull prototype of <tt>LuaJIT_setmode</tt> is:\n</p>\n<pre class=\"code\">\nLUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);\n</pre>\n<p>\nThe returned status is either success (<tt>1</tt>) or failure (<tt>0</tt>).\nThe second argument is either <tt>0</tt> or a stack index (similar to the\nother Lua/C API functions).\n</p>\n<p>\nThe third argument specifies the mode, which is 'or'ed with a flag.\nThe flag can be <tt>LUAJIT_MODE_OFF</tt> to turn a feature off,\n<tt>LUAJIT_MODE_ON</tt> to turn a feature on, or\n<tt>LUAJIT_MODE_FLUSH</tt> to flush cached code.\n</p>\n<p>\nThe following modes are defined:\n</p>\n\n<h3 id=\"mode_engine\"><tt>luaJIT_setmode(L, 0, LUAJIT_MODE_ENGINE|flag)</tt></h3>\n<p>\nTurn the whole JIT compiler on or off or flush the whole cache of compiled code.\n</p>\n\n<h3 id=\"mode_func\"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_FUNC|flag)</tt><br>\n<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLFUNC|flag)</tt><br>\n<tt>luaJIT_setmode(L, idx, LUAJIT_MODE_ALLSUBFUNC|flag)</tt></h3>\n<p>\nThis sets the mode for the function at the stack index <tt>idx</tt> or\nthe parent of the calling function (<tt>idx = 0</tt>). It either\nenables JIT compilation for a function, disables it and flushes any\nalready compiled code, or only flushes already compiled code. This\napplies recursively to all sub-functions of the function with\n<tt>LUAJIT_MODE_ALLFUNC</tt> or only to the sub-functions with\n<tt>LUAJIT_MODE_ALLSUBFUNC</tt>.\n</p>\n\n<h3 id=\"mode_trace\"><tt>luaJIT_setmode(L, trace,<br>\n&nbsp;&nbsp;LUAJIT_MODE_TRACE|LUAJIT_MODE_FLUSH)</tt></h3>\n<p>\nFlushes the specified root trace and all of its side traces from the cache.\nThe code for the trace will be retained as long as there are any other\ntraces which link to it.\n</p>\n\n<h3 id=\"mode_wrapcfunc\"><tt>luaJIT_setmode(L, idx, LUAJIT_MODE_WRAPCFUNC|flag)</tt></h3>\n<p>\nThis mode defines a wrapper function for calls to C functions. If\ncalled with <tt>LUAJIT_MODE_ON</tt>, the stack index at <tt>idx</tt>\nmust be a <tt>lightuserdata</tt> object holding a pointer to the wrapper\nfunction. From now on, all C functions are called through the wrapper\nfunction. If called with <tt>LUAJIT_MODE_OFF</tt> this mode is turned\noff and all C functions are directly called.\n</p>\n<p>\nThe wrapper function can be used for debugging purposes or to catch\nand convert foreign exceptions. But please read the section on\n<a href=\"extensions.html#exceptions\">C++&nbsp;exception interoperability</a>\nfirst. Recommended usage can be seen in this C++ code excerpt:\n</p>\n<pre class=\"code\">\n#include &lt;exception&gt;\n#include \"lua.hpp\"\n\n// Catch C++ exceptions and convert them to Lua error messages.\n// Customize as needed for your own exception classes.\nstatic int wrap_exceptions(lua_State *L, lua_CFunction f)\n{\n  try {\n    return f(L);  // Call wrapped function and return result.\n  } catch (const char *s) {  // Catch and convert exceptions.\n    lua_pushstring(L, s);\n  } catch (std::exception& e) {\n    lua_pushstring(L, e.what());\n  } catch (...) {\n    lua_pushliteral(L, \"caught (...)\");\n  }\n  return lua_error(L);  // Rethrow as a Lua error.\n}\n\nstatic int myinit(lua_State *L)\n{\n  ...\n  // Define wrapper function and enable it.\n  lua_pushlightuserdata(L, (void *)wrap_exceptions);\n  luaJIT_setmode(L, -1, LUAJIT_MODE_WRAPCFUNC|LUAJIT_MODE_ON);\n  lua_pop(L, 1);\n  ...\n}\n</pre>\n<p>\nNote that you can only define <b>a single global wrapper function</b>,\nso be careful when using this mechanism from multiple C++ modules.\nAlso note that this mechanism is not without overhead.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_ffi.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>FFI Library</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>FFI Library</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a class=\"current\" href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\n\nThe FFI library allows <b>calling external C&nbsp;functions</b> and\n<b>using C&nbsp;data structures</b> from pure Lua code.\n\n</p>\n<p>\n\nThe FFI library largely obviates the need to write tedious manual\nLua/C bindings in C. No need to learn a separate binding language\n&mdash; <b>it parses plain C&nbsp;declarations!</b> These can be\ncut-n-pasted from C&nbsp;header files or reference manuals. It's up to\nthe task of binding large libraries without the need for dealing with\nfragile binding generators.\n\n</p>\n<p>\nThe FFI library is tightly integrated into LuaJIT (it's not available\nas a separate module). The code generated by the JIT-compiler for\naccesses to C&nbsp;data structures from Lua code is on par with the\ncode a C&nbsp;compiler would generate. Calls to C&nbsp;functions can\nbe inlined in JIT-compiled code, unlike calls to functions bound via\nthe classic Lua/C API.\n</p>\n<p>\nThis page gives a short introduction to the usage of the FFI library.\n<em>Please use the FFI sub-topics in the navigation bar to learn more.</em>\n</p>\n\n<h2 id=\"call\">Motivating Example: Calling External C Functions</h2>\n<p>\nIt's really easy to call an external C&nbsp;library function:\n</p>\n<pre class=\"code mark\">\n<span class=\"codemark\">&#9312;\n&#9313;\n\n\n&#9314;</span>local ffi = require(\"ffi\")\nffi.cdef[[\n<span style=\"color:#00a000;\">int printf(const char *fmt, ...);</span>\n]]\nffi.C.printf(\"Hello %s!\", \"world\")\n</pre>\n<p>\nSo, let's pick that apart:\n</p>\n<p>\n<span class=\"mark\">&#9312;</span> Load the FFI library.\n</p>\n<p>\n<span class=\"mark\">&#9313;</span> Add a C&nbsp;declaration\nfor the function. The part inside the double-brackets (in green) is\njust standard C&nbsp;syntax.\n</p>\n<p>\n<span class=\"mark\">&#9314;</span> Call the named\nC&nbsp;function &mdash; Yes, it's that simple!\n</p>\n<p style=\"font-size: 8pt;\">\nActually, what goes on behind the scenes is far from simple: <span\nstyle=\"color:#4040c0;\">&#9314;</span> makes use of the standard\nC&nbsp;library namespace <tt>ffi.C</tt>. Indexing this namespace with\na symbol name (<tt>\"printf\"</tt>) automatically binds it to the\nstandard C&nbsp;library. The result is a special kind of object which,\nwhen called, runs the <tt>printf</tt> function. The arguments passed\nto this function are automatically converted from Lua objects to the\ncorresponding C&nbsp;types.\n</p>\n<p>\nOk, so maybe the use of <tt>printf()</tt> wasn't such a spectacular\nexample. You could have done that with <tt>io.write()</tt> and\n<tt>string.format()</tt>, too. But you get the idea ...\n</p>\n<p>\nSo here's something to pop up a message box on Windows:\n</p>\n<pre class=\"code\">\nlocal ffi = require(\"ffi\")\nffi.cdef[[\n<span style=\"color:#00a000;\">int MessageBoxA(void *w, const char *txt, const char *cap, int type);</span>\n]]\nffi.C.MessageBoxA(nil, \"Hello world!\", \"Test\", 0)\n</pre>\n<p>\nBing! Again, that was far too easy, no?\n</p>\n<p style=\"font-size: 8pt;\">\nCompare this with the effort required to bind that function using the\nclassic Lua/C API: create an extra C&nbsp;file, add a C&nbsp;function\nthat retrieves and checks the argument types passed from Lua and calls\nthe actual C&nbsp;function, add a list of module functions and their\nnames, add a <tt>luaopen_*</tt> function and register all module\nfunctions, compile and link it into a shared library (DLL), move it to\nthe proper path, add Lua code that loads the module aaaand ... finally\ncall the binding function. Phew!\n</p>\n\n<h2 id=\"cdata\">Motivating Example: Using C Data Structures</h2>\n<p>\nThe FFI library allows you to create and access C&nbsp;data\nstructures. Of course, the main use for this is for interfacing with\nC&nbsp;functions. But they can be used stand-alone, too.\n</p>\n<p>\nLua is built upon high-level data types. They are flexible, extensible\nand dynamic. That's why we all love Lua so much. Alas, this can be\ninefficient for certain tasks, where you'd really want a low-level\ndata type. E.g. a large array of a fixed structure needs to be\nimplemented with a big table holding lots of tiny tables. This imposes\nboth a substantial memory overhead as well as a performance overhead.\n</p>\n<p>\nHere's a sketch of a library that operates on color images, plus a\nsimple benchmark. First, the plain Lua version:\n</p>\n<pre class=\"code\">\nlocal floor = math.floor\n\nlocal function image_ramp_green(n)\n  local img = {}\n  local f = 255/(n-1)\n  for i=1,n do\n    img[i] = { red = 0, green = floor((i-1)*f), blue = 0, alpha = 255 }\n  end\n  return img\nend\n\nlocal function image_to_gray(img, n)\n  for i=1,n do\n    local y = floor(0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue)\n    img[i].red = y; img[i].green = y; img[i].blue = y\n  end\nend\n\nlocal N = 400*400\nlocal img = image_ramp_green(N)\nfor i=1,1000 do\n  image_to_gray(img, N)\nend\n</pre>\n<p>\nThis creates a table with 160.000 pixels, each of which is a table\nholding four number values in the range of 0-255. First, an image with\na green ramp is created (1D for simplicity), then the image is\nconverted to grayscale 1000 times. Yes, that's silly, but I was in\nneed of a simple example ...\n</p>\n<p>\nAnd here's the FFI version. The modified parts have been marked in\nbold:\n</p>\n<pre class=\"code mark\">\n<span class=\"codemark\">&#9312;\n\n\n\n\n\n&#9313;\n\n&#9314;\n&#9315;\n\n\n\n\n\n\n&#9314;\n&#9316;</span><b>local ffi = require(\"ffi\")\nffi.cdef[[\n</b><span style=\"color:#00a000;\">typedef struct { uint8_t red, green, blue, alpha; } rgba_pixel;</span><b>\n]]</b>\n\nlocal function image_ramp_green(n)\n  <b>local img = ffi.new(\"rgba_pixel[?]\", n)</b>\n  local f = 255/(n-1)\n  for i=<b>0,n-1</b> do\n    <b>img[i].green = i*f</b>\n    <b>img[i].alpha = 255</b>\n  end\n  return img\nend\n\nlocal function image_to_grey(img, n)\n  for i=<b>0,n-1</b> do\n    local y = <b>0.3*img[i].red + 0.59*img[i].green + 0.11*img[i].blue</b>\n    img[i].red = y; img[i].green = y; img[i].blue = y\n  end\nend\n\nlocal N = 400*400\nlocal img = image_ramp_green(N)\nfor i=1,1000 do\n  image_to_grey(img, N)\nend\n</pre>\n<p>\nOk, so that wasn't too difficult:\n</p>\n<p>\n<span class=\"mark\">&#9312;</span> First, load the FFI\nlibrary and declare the low-level data type. Here we choose a\n<tt>struct</tt> which holds four byte fields, one for each component\nof a 4x8&nbsp;bit RGBA pixel.\n</p>\n<p>\n<span class=\"mark\">&#9313;</span> Creating the data\nstructure with <tt>ffi.new()</tt> is straightforward &mdash; the\n<tt>'?'</tt> is a placeholder for the number of elements of a\nvariable-length array.\n</p>\n<p>\n<span class=\"mark\">&#9314;</span> C&nbsp;arrays are\nzero-based, so the indexes have to run from <tt>0</tt> to\n<tt>n-1</tt>. One might want to allocate one more element instead to\nsimplify converting legacy code.\n</p>\n<p>\n<span class=\"mark\">&#9315;</span> Since <tt>ffi.new()</tt>\nzero-fills the array by default, we only need to set the green and the\nalpha fields.\n</p>\n<p>\n<span class=\"mark\">&#9316;</span> The calls to\n<tt>math.floor()</tt> can be omitted here, because floating-point\nnumbers are already truncated towards zero when converting them to an\ninteger. This happens implicitly when the number is stored in the\nfields of each pixel.\n</p>\n<p>\nNow let's have a look at the impact of the changes: first, memory\nconsumption for the image is down from 22&nbsp;Megabytes to\n640&nbsp;Kilobytes (400*400*4 bytes). That's a factor of 35x less! So,\nyes, tables do have a noticeable overhead. BTW: The original program\nwould consume 40&nbsp;Megabytes in plain Lua (on x64).\n</p>\n<p>\nNext, performance: the pure Lua version runs in 9.57 seconds (52.9\nseconds with the Lua interpreter) and the FFI version runs in 0.48\nseconds on my machine (YMMV). That's a factor of 20x faster (110x\nfaster than the Lua interpreter).\n</p>\n<p style=\"font-size: 8pt;\">\nThe avid reader may notice that converting the pure Lua version over\nto use array indexes for the colors (<tt>[1]</tt> instead of\n<tt>.red</tt>, <tt>[2]</tt> instead of <tt>.green</tt> etc.) ought to\nbe more compact and faster. This is certainly true (by a factor of\n~1.7x). Switching to a struct-of-arrays would help, too.\n</p>\n<p style=\"font-size: 8pt;\">\nHowever, the resulting code would be less idiomatic and rather\nerror-prone. And it still doesn't get even close to the performance of\nthe FFI version of the code. Also, high-level data structures cannot\nbe easily passed to other C&nbsp;functions, especially I/O functions,\nwithout undue conversion penalties.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_ffi_api.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>ffi.* API Functions</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ntable.abitable { width: 30em; line-height: 1.2; }\ntr.abihead td { font-weight: bold; }\ntd.abiparam { font-weight: bold; width: 6em; }\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1><tt>ffi.*</tt> API Functions</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a class=\"current\" href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nThis page describes the API functions provided by the FFI library in\ndetail. It's recommended to read through the\n<a href=\"ext_ffi.html\">introduction</a> and the\n<a href=\"ext_ffi_tutorial.html\">FFI tutorial</a> first.\n</p>\n\n<h2 id=\"glossary\">Glossary</h2>\n<ul>\n<li><b>cdecl</b> &mdash; An abstract C&nbsp;type declaration (a Lua\nstring).</li>\n<li><b>ctype</b> &mdash; A C&nbsp;type object. This is a special kind of\n<b>cdata</b> returned by <tt>ffi.typeof()</tt>. It serves as a\n<b>cdata</b> <a href=\"#ffi_new\">constructor</a> when called.</li>\n<li><b>cdata</b> &mdash; A C&nbsp;data object. It holds a value of the\ncorresponding <b>ctype</b>.</li>\n<li><b>ct</b> &mdash; A C&nbsp;type specification which can be used for\nmost of the API functions. Either a <b>cdecl</b>, a <b>ctype</b> or a\n<b>cdata</b> serving as a template type.</li>\n<li><b>cb</b> &mdash; A callback object. This is a C&nbsp;data object\nholding a special function pointer. Calling this function from\nC&nbsp;code runs an associated Lua function.</li>\n<li><b>VLA</b> &mdash; A variable-length array is declared with a\n<tt>?</tt> instead of the number of elements, e.g. <tt>\"int[?]\"</tt>.\nThe number of elements (<tt>nelem</tt>) must be given when it's\n<a href=\"#ffi_new\">created</a>.</li>\n<li><b>VLS</b> &mdash; A variable-length struct is a <tt>struct</tt> C\ntype where the last element is a <b>VLA</b>. The same rules for\ndeclaration and creation apply.</li>\n</ul>\n\n<h2 id=\"decl\">Declaring and Accessing External Symbols</h2>\n<p>\nExternal symbols must be declared first and can then be accessed by\nindexing a <a href=\"ext_ffi_semantics.html#clib\">C&nbsp;library\nnamespace</a>, which automatically binds the symbol to a specific\nlibrary.\n</p>\n\n<h3 id=\"ffi_cdef\"><tt>ffi.cdef(def)</tt></h3>\n<p>\nAdds multiple C&nbsp;declarations for types or external symbols (named\nvariables or functions). <tt>def</tt> must be a Lua string. It's\nrecommended to use the syntactic sugar for string arguments as\nfollows:\n</p>\n<pre class=\"code\">\nffi.cdef[[\n<span style=\"color:#00a000;\">typedef struct foo { int a, b; } foo_t;  // Declare a struct and typedef.\nint dofoo(foo_t *f, int n);  /* Declare an external C function. */</span>\n]]\n</pre>\n<p>\nThe contents of the string (the part in green above) must be a\nsequence of\n<a href=\"ext_ffi_semantics.html#clang\">C&nbsp;declarations</a>,\nseparated by semicolons. The trailing semicolon for a single\ndeclaration may be omitted.\n</p>\n<p>\nPlease note, that external symbols are only <em>declared</em>, but they\nare <em>not bound</em> to any specific address, yet. Binding is\nachieved with C&nbsp;library namespaces (see below).\n</p>\n<p style=\"color: #c00000;\">\nC&nbsp;declarations are not passed through a C&nbsp;pre-processor,\nyet. No pre-processor tokens are allowed, except for\n<tt>#pragma&nbsp;pack</tt>. Replace <tt>#define</tt> in existing\nC&nbsp;header files with <tt>enum</tt>, <tt>static&nbsp;const</tt>\nor <tt>typedef</tt> and/or pass the files through an external\nC&nbsp;pre-processor (once). Be careful not to include unneeded or\nredundant declarations from unrelated header files.\n</p>\n\n<h3 id=\"ffi_C\"><tt>ffi.C</tt></h3>\n<p>\nThis is the default C&nbsp;library namespace &mdash; note the\nuppercase <tt>'C'</tt>. It binds to the default set of symbols or\nlibraries on the target system. These are more or less the same as a\nC&nbsp;compiler would offer by default, without specifying extra link\nlibraries.\n</p>\n<p>\nOn POSIX systems, this binds to symbols in the default or global\nnamespace. This includes all exported symbols from the executable and\nany libraries loaded into the global namespace. This includes at least\n<tt>libc</tt>, <tt>libm</tt>, <tt>libdl</tt> (on Linux),\n<tt>libgcc</tt> (if compiled with GCC), as well as any exported\nsymbols from the Lua/C&nbsp;API provided by LuaJIT itself.\n</p>\n<p>\nOn Windows systems, this binds to symbols exported from the\n<tt>*.exe</tt>, the <tt>lua51.dll</tt> (i.e. the Lua/C&nbsp;API\nprovided by LuaJIT itself), the C&nbsp;runtime library LuaJIT was linked\nwith (<tt>msvcrt*.dll</tt>), <tt>kernel32.dll</tt>,\n<tt>user32.dll</tt> and <tt>gdi32.dll</tt>.\n</p>\n\n<h3 id=\"ffi_load\"><tt>clib = ffi.load(name [,global])</tt></h3>\n<p>\nThis loads the dynamic library given by <tt>name</tt> and returns\na new C&nbsp;library namespace which binds to its symbols. On POSIX\nsystems, if <tt>global</tt> is <tt>true</tt>, the library symbols are\nloaded into the global namespace, too.\n</p>\n<p>\nIf <tt>name</tt> is a path, the library is loaded from this path.\nOtherwise <tt>name</tt> is canonicalized in a system-dependent way and\nsearched in the default search path for dynamic libraries:\n</p>\n<p>\nOn POSIX systems, if the name contains no dot, the extension\n<tt>.so</tt> is appended. Also, the <tt>lib</tt> prefix is prepended\nif necessary. So <tt>ffi.load(\"z\")</tt> looks for <tt>\"libz.so\"</tt>\nin the default shared library search path.\n</p>\n<p>\nOn Windows systems, if the name contains no dot, the extension\n<tt>.dll</tt> is appended. So <tt>ffi.load(\"ws2_32\")</tt> looks for\n<tt>\"ws2_32.dll\"</tt> in the default DLL search path.\n</p>\n\n<h2 id=\"create\">Creating cdata Objects</h2>\n<p>\nThe following API functions create cdata objects (<tt>type()</tt>\nreturns <tt>\"cdata\"</tt>). All created cdata objects are\n<a href=\"ext_ffi_semantics.html#gc\">garbage collected</a>.\n</p>\n\n<h3 id=\"ffi_new\"><tt>cdata = ffi.new(ct [,nelem] [,init...])<br>\ncdata = <em>ctype</em>([nelem,] [init...])</tt></h3>\n<p>\nCreates a cdata object for the given <tt>ct</tt>. VLA/VLS types\nrequire the <tt>nelem</tt> argument. The second syntax uses a ctype as\na constructor and is otherwise fully equivalent.\n</p>\n<p>\nThe cdata object is initialized according to the\n<a href=\"ext_ffi_semantics.html#init\">rules for initializers</a>,\nusing the optional <tt>init</tt> arguments. Excess initializers cause\nan error.\n</p>\n<p>\nPerformance notice: if you want to create many objects of one kind,\nparse the cdecl only once and get its ctype with\n<tt>ffi.typeof()</tt>. Then use the ctype as a constructor repeatedly.\n</p>\n<p style=\"font-size: 8pt;\">\nPlease note, that an anonymous <tt>struct</tt> declaration implicitly\ncreates a new and distinguished ctype every time you use it for\n<tt>ffi.new()</tt>. This is probably <b>not</b> what you want,\nespecially if you create more than one cdata object. Different anonymous\n<tt>structs</tt> are not considered assignment-compatible by the\nC&nbsp;standard, even though they may have the same fields! Also, they\nare considered different types by the JIT-compiler, which may cause an\nexcessive number of traces. It's strongly suggested to either declare\na named <tt>struct</tt> or <tt>typedef</tt> with <tt>ffi.cdef()</tt>\nor to create a single ctype object for an anonymous <tt>struct</tt>\nwith <tt>ffi.typeof()</tt>.\n</p>\n\n<h3 id=\"ffi_typeof\"><tt>ctype = ffi.typeof(ct)</tt></h3>\n<p>\nCreates a ctype object for the given <tt>ct</tt>.\n</p>\n<p>\nThis function is especially useful to parse a cdecl only once and then\nuse the resulting ctype object as a <a href=\"#ffi_new\">constructor</a>.\n</p>\n\n<h3 id=\"ffi_cast\"><tt>cdata = ffi.cast(ct, init)</tt></h3>\n<p>\nCreates a scalar cdata object for the given <tt>ct</tt>. The cdata\nobject is initialized with <tt>init</tt> using the \"cast\" variant of\nthe <a href=\"ext_ffi_semantics.html#convert\">C&nbsp;type conversion\nrules</a>.\n</p>\n<p>\nThis functions is mainly useful to override the pointer compatibility\nchecks or to convert pointers to addresses or vice versa.\n</p>\n\n<h3 id=\"ffi_metatype\"><tt>ctype = ffi.metatype(ct, metatable)</tt></h3>\n<p>\nCreates a ctype object for the given <tt>ct</tt> and associates it with\na metatable. Only <tt>struct</tt>/<tt>union</tt> types, complex numbers\nand vectors are allowed. Other types may be wrapped in a\n<tt>struct</tt>, if needed.\n</p>\n<p>\nThe association with a metatable is permanent and cannot be changed\nafterwards. Neither the contents of the <tt>metatable</tt> nor the\ncontents of an <tt>__index</tt> table (if any) may be modified\nafterwards. The associated metatable automatically applies to all uses\nof this type, no matter how the objects are created or where they\noriginate from. Note that predefined operations on types have\nprecedence (e.g. declared field names cannot be overridden).\n</p>\n<p>\nAll standard Lua metamethods are implemented. These are called directly,\nwithout shortcuts, and on any mix of types. For binary operations, the\nleft operand is checked first for a valid ctype metamethod. The\n<tt>__gc</tt> metamethod only applies to <tt>struct</tt>/<tt>union</tt>\ntypes and performs an implicit <a href=\"#ffi_gc\"><tt>ffi.gc()</tt></a>\ncall during creation of an instance.\n</p>\n\n<h3 id=\"ffi_gc\"><tt>cdata = ffi.gc(cdata, finalizer)</tt></h3>\n<p>\nAssociates a finalizer with a pointer or aggregate cdata object. The\ncdata object is returned unchanged.\n</p>\n<p>\nThis function allows safe integration of unmanaged resources into the\nautomatic memory management of the LuaJIT garbage collector. Typical\nusage:\n</p>\n<pre class=\"code\">\nlocal p = ffi.gc(ffi.C.malloc(n), ffi.C.free)\n...\np = nil -- Last reference to p is gone.\n-- GC will eventually run finalizer: ffi.C.free(p)\n</pre>\n<p>\nA cdata finalizer works like the <tt>__gc</tt> metamethod for userdata\nobjects: when the last reference to a cdata object is gone, the\nassociated finalizer is called with the cdata object as an argument. The\nfinalizer can be a Lua function or a cdata function or cdata function\npointer. An existing finalizer can be removed by setting a <tt>nil</tt>\nfinalizer, e.g. right before explicitly deleting a resource:\n</p>\n<pre class=\"code\">\nffi.C.free(ffi.gc(p, nil)) -- Manually free the memory.\n</pre>\n\n<h2 id=\"info\">C&nbsp;Type Information</h2>\n<p>\nThe following API functions return information about C&nbsp;types.\nThey are most useful for inspecting cdata objects.\n</p>\n\n<h3 id=\"ffi_sizeof\"><tt>size = ffi.sizeof(ct [,nelem])</tt></h3>\n<p>\nReturns the size of <tt>ct</tt> in bytes. Returns <tt>nil</tt> if\nthe size is not known (e.g. for <tt>\"void\"</tt> or function types).\nRequires <tt>nelem</tt> for VLA/VLS types, except for cdata objects.\n</p>\n\n<h3 id=\"ffi_alignof\"><tt>align = ffi.alignof(ct)</tt></h3>\n<p>\nReturns the minimum required alignment for <tt>ct</tt> in bytes.\n</p>\n\n<h3 id=\"ffi_offsetof\"><tt>ofs [,bpos,bsize] = ffi.offsetof(ct, field)</tt></h3>\n<p>\nReturns the offset (in bytes) of <tt>field</tt> relative to the start\nof <tt>ct</tt>, which must be a <tt>struct</tt>. Additionally returns\nthe position and the field size (in bits) for bit fields.\n</p>\n\n<h3 id=\"ffi_istype\"><tt>status = ffi.istype(ct, obj)</tt></h3>\n<p>\nReturns <tt>true</tt> if <tt>obj</tt> has the C&nbsp;type given by\n<tt>ct</tt>. Returns <tt>false</tt> otherwise.\n</p>\n<p>\nC&nbsp;type qualifiers (<tt>const</tt> etc.) are ignored. Pointers are\nchecked with the standard pointer compatibility rules, but without any\nspecial treatment for <tt>void&nbsp;*</tt>. If <tt>ct</tt> specifies a\n<tt>struct</tt>/<tt>union</tt>, then a pointer to this type is accepted,\ntoo. Otherwise the types must match exactly.\n</p>\n<p>\nNote: this function accepts all kinds of Lua objects for the\n<tt>obj</tt> argument, but always returns <tt>false</tt> for non-cdata\nobjects.\n</p>\n\n<h2 id=\"util\">Utility Functions</h2>\n\n<h3 id=\"ffi_errno\"><tt>err = ffi.errno([newerr])</tt></h3>\n<p>\nReturns the error number set by the last C&nbsp;function call which\nindicated an error condition. If the optional <tt>newerr</tt> argument\nis present, the error number is set to the new value and the previous\nvalue is returned.\n</p>\n<p>\nThis function offers a portable and OS-independent way to get and set the\nerror number. Note that only <em>some</em> C&nbsp;functions set the error\nnumber. And it's only significant if the function actually indicated an\nerror condition (e.g. with a return value of <tt>-1</tt> or\n<tt>NULL</tt>). Otherwise, it may or may not contain any previously set\nvalue.\n</p>\n<p>\nYou're advised to call this function only when needed and as close as\npossible after the return of the related C&nbsp;function. The\n<tt>errno</tt> value is preserved across hooks, memory allocations,\ninvocations of the JIT compiler and other internal VM activity. The same\napplies to the value returned by <tt>GetLastError()</tt> on Windows, but\nyou need to declare and call it yourself.\n</p>\n\n<h3 id=\"ffi_string\"><tt>str = ffi.string(ptr [,len])</tt></h3>\n<p>\nCreates an interned Lua string from the data pointed to by\n<tt>ptr</tt>.\n</p>\n<p>\nIf the optional argument <tt>len</tt> is missing, <tt>ptr</tt> is\nconverted to a <tt>\"char&nbsp;*\"</tt> and the data is assumed to be\nzero-terminated. The length of the string is computed with\n<tt>strlen()</tt>.\n</p>\n<p>\nOtherwise <tt>ptr</tt> is converted to a <tt>\"void&nbsp;*\"</tt> and\n<tt>len</tt> gives the length of the data. The data may contain\nembedded zeros and need not be byte-oriented (though this may cause\nendianess issues).\n</p>\n<p>\nThis function is mainly useful to convert (temporary)\n<tt>\"const&nbsp;char&nbsp;*\"</tt> pointers returned by\nC&nbsp;functions to Lua strings and store them or pass them to other\nfunctions expecting a Lua string. The Lua string is an (interned) copy\nof the data and bears no relation to the original data area anymore.\nLua strings are 8&nbsp;bit clean and may be used to hold arbitrary,\nnon-character data.\n</p>\n<p>\nPerformance notice: it's faster to pass the length of the string, if\nit's known. E.g. when the length is returned by a C&nbsp;call like\n<tt>sprintf()</tt>.\n</p>\n\n<h3 id=\"ffi_copy\"><tt>ffi.copy(dst, src, len)<br>\nffi.copy(dst, str)</tt></h3>\n<p>\nCopies the data pointed to by <tt>src</tt> to <tt>dst</tt>.\n<tt>dst</tt> is converted to a <tt>\"void&nbsp;*\"</tt> and <tt>src</tt>\nis converted to a <tt>\"const void&nbsp;*\"</tt>.\n</p>\n<p>\nIn the first syntax, <tt>len</tt> gives the number of bytes to copy.\nCaveat: if <tt>src</tt> is a Lua string, then <tt>len</tt> must not\nexceed <tt>#src+1</tt>.\n</p>\n<p>\nIn the second syntax, the source of the copy must be a Lua string. All\nbytes of the string <em>plus a zero-terminator</em> are copied to\n<tt>dst</tt> (i.e. <tt>#src+1</tt> bytes).\n</p>\n<p>\nPerformance notice: <tt>ffi.copy()</tt> may be used as a faster\n(inlinable) replacement for the C&nbsp;library functions\n<tt>memcpy()</tt>, <tt>strcpy()</tt> and <tt>strncpy()</tt>.\n</p>\n\n<h3 id=\"ffi_fill\"><tt>ffi.fill(dst, len [,c])</tt></h3>\n<p>\nFills the data pointed to by <tt>dst</tt> with <tt>len</tt> constant\nbytes, given by <tt>c</tt>. If <tt>c</tt> is omitted, the data is\nzero-filled.\n</p>\n<p>\nPerformance notice: <tt>ffi.fill()</tt> may be used as a faster\n(inlinable) replacement for the C&nbsp;library function\n<tt>memset(dst,&nbsp;c,&nbsp;len)</tt>. Please note the different\norder of arguments!\n</p>\n\n<h2 id=\"target\">Target-specific Information</h2>\n\n<h3 id=\"ffi_abi\"><tt>status = ffi.abi(param)</tt></h3>\n<p>\nReturns <tt>true</tt> if <tt>param</tt> (a Lua string) applies for the\ntarget ABI (Application Binary Interface). Returns <tt>false</tt>\notherwise. The following parameters are currently defined:\n</p>\n<table class=\"abitable\">\n<tr class=\"abihead\">\n<td class=\"abiparam\">Parameter</td>\n<td class=\"abidesc\">Description</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"abiparam\">32bit</td><td class=\"abidesc\">32 bit architecture</td></tr>\n<tr class=\"even\">\n<td class=\"abiparam\">64bit</td><td class=\"abidesc\">64 bit architecture</td></tr>\n<tr class=\"odd separate\">\n<td class=\"abiparam\">le</td><td class=\"abidesc\">Little-endian architecture</td></tr>\n<tr class=\"even\">\n<td class=\"abiparam\">be</td><td class=\"abidesc\">Big-endian architecture</td></tr>\n<tr class=\"odd separate\">\n<td class=\"abiparam\">fpu</td><td class=\"abidesc\">Target has a hardware FPU</td></tr>\n<tr class=\"even\">\n<td class=\"abiparam\">softfp</td><td class=\"abidesc\">softfp calling conventions</td></tr>\n<tr class=\"odd\">\n<td class=\"abiparam\">hardfp</td><td class=\"abidesc\">hardfp calling conventions</td></tr>\n<tr class=\"even separate\">\n<td class=\"abiparam\">eabi</td><td class=\"abidesc\">EABI variant of the standard ABI</td></tr>\n<tr class=\"odd\">\n<td class=\"abiparam\">win</td><td class=\"abidesc\">Windows variant of the standard ABI</td></tr>\n<tr class=\"even\">\n<td class=\"abiparam\">uwp</td><td class=\"abidesc\">Universal Windows Platform</td></tr>\n<tr class=\"odd\">\n<td class=\"abiparam\">gc64</td><td class=\"abidesc\">64 bit GC references</td></tr>\n</table>\n\n<h3 id=\"ffi_os\"><tt>ffi.os</tt></h3>\n<p>\nContains the target OS name. Same contents as\n<a href=\"ext_jit.html#jit_os\"><tt>jit.os</tt></a>.\n</p>\n\n<h3 id=\"ffi_arch\"><tt>ffi.arch</tt></h3>\n<p>\nContains the target architecture name. Same contents as\n<a href=\"ext_jit.html#jit_arch\"><tt>jit.arch</tt></a>.\n</p>\n\n<h2 id=\"callback\">Methods for Callbacks</h2>\n<p>\nThe C&nbsp;types for <a href=\"ext_ffi_semantics.html#callback\">callbacks</a>\nhave some extra methods:\n</p>\n\n<h3 id=\"callback_free\"><tt>cb:free()</tt></h3>\n<p>\nFree the resources associated with a callback. The associated Lua\nfunction is unanchored and may be garbage collected. The callback\nfunction pointer is no longer valid and must not be called again\n(it may be reused by a subsequently created callback).\n</p>\n\n<h3 id=\"callback_set\"><tt>cb:set(func)</tt></h3>\n<p>\nAssociate a new Lua function with a callback. The C&nbsp;type of the\ncallback and the callback function pointer are unchanged.\n</p>\n<p>\nThis method is useful to dynamically switch the receiver of callbacks\nwithout creating a new callback each time and registering it again (e.g.\nwith a GUI library).\n</p>\n\n<h2 id=\"extended\">Extended Standard Library Functions</h2>\n<p>\nThe following standard library functions have been extended to work\nwith cdata objects:\n</p>\n\n<h3 id=\"tonumber\"><tt>n = tonumber(cdata)</tt></h3>\n<p>\nConverts a number cdata object to a <tt>double</tt> and returns it as\na Lua number. This is particularly useful for boxed 64&nbsp;bit\ninteger values. Caveat: this conversion may incur a precision loss.\n</p>\n\n<h3 id=\"tostring\"><tt>s = tostring(cdata)</tt></h3>\n<p>\nReturns a string representation of the value of 64&nbsp;bit integers\n(<tt><b>\"</b>nnn<b>LL\"</b></tt> or <tt><b>\"</b>nnn<b>ULL\"</b></tt>) or\ncomplex numbers (<tt><b>\"</b>re&plusmn;im<b>i\"</b></tt>). Otherwise\nreturns a string representation of the C&nbsp;type of a ctype object\n(<tt><b>\"ctype&lt;</b>type<b>&gt;\"</b></tt>) or a cdata object\n(<tt><b>\"cdata&lt;</b>type<b>&gt;:&nbsp;</b>address\"</tt>), unless you\noverride it with a <tt>__tostring</tt> metamethod (see\n<a href=\"#ffi_metatype\"><tt>ffi.metatype()</tt></a>).\n</p>\n\n<h3 id=\"pairs\"><tt>iter, obj, start = pairs(cdata)<br>\niter, obj, start = ipairs(cdata)<br></tt></h3>\n<p>\nCalls the <tt>__pairs</tt> or <tt>__ipairs</tt> metamethod of the\ncorresponding ctype.\n</p>\n\n<h2 id=\"literals\">Extensions to the Lua Parser</h2>\n<p>\nThe parser for Lua source code treats numeric literals with the\nsuffixes <tt>LL</tt> or <tt>ULL</tt> as signed or unsigned 64&nbsp;bit\nintegers. Case doesn't matter, but uppercase is recommended for\nreadability. It handles decimal (<tt>42LL</tt>), hexadecimal\n(<tt>0x2aLL</tt>) and binary (<tt>0b101010LL</tt>) literals.\n</p>\n<p>\nThe imaginary part of complex numbers can be specified by suffixing\nnumber literals with <tt>i</tt> or <tt>I</tt>, e.g. <tt>12.5i</tt>.\nCaveat: you'll need to use <tt>1i</tt> to get an imaginary part with\nthe value one, since <tt>i</tt> itself still refers to a variable\nnamed <tt>i</tt>.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_ffi_semantics.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>FFI Semantics</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ntable.convtable { line-height: 1.2; }\ntr.convhead td { font-weight: bold; }\ntd.convop { font-style: italic; width: 40%; }\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>FFI Semantics</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a class=\"current\" href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nThis page describes the detailed semantics underlying the FFI library\nand its interaction with both Lua and C&nbsp;code.\n</p>\n<p>\nGiven that the FFI library is designed to interface with C&nbsp;code\nand that declarations can be written in plain C&nbsp;syntax, <b>it\nclosely follows the C&nbsp;language semantics</b>, wherever possible.\nSome minor concessions are needed for smoother interoperation with Lua\nlanguage semantics.\n</p>\n<p>\nPlease don't be overwhelmed by the contents of this page &mdash; this\nis a reference and you may need to consult it, if in doubt. It doesn't\nhurt to skim this page, but most of the semantics \"just work\" as you'd\nexpect them to work. It should be straightforward to write\napplications using the LuaJIT FFI for developers with a C or C++\nbackground.\n</p>\n\n<h2 id=\"clang\">C Language Support</h2>\n<p>\nThe FFI library has a built-in C&nbsp;parser with a minimal memory\nfootprint. It's used by the <a href=\"ext_ffi_api.html\">ffi.* library\nfunctions</a> to declare C&nbsp;types or external symbols.\n</p>\n<p>\nIts only purpose is to parse C&nbsp;declarations, as found e.g. in\nC&nbsp;header files. Although it does evaluate constant expressions,\nit's <em>not</em> a C&nbsp;compiler. The body of <tt>inline</tt>\nC&nbsp;function definitions is simply ignored.\n</p>\n<p>\nAlso, this is <em>not</em> a validating C&nbsp;parser. It expects and\naccepts correctly formed C&nbsp;declarations, but it may choose to\nignore bad declarations or show rather generic error messages. If in\ndoubt, please check the input against your favorite C&nbsp;compiler.\n</p>\n<p>\nThe C&nbsp;parser complies to the <b>C99 language standard</b> plus\nthe following extensions:\n</p>\n<ul>\n\n<li>The <tt>'\\e'</tt> escape in character and string literals.</li>\n\n<li>The C99/C++ boolean type, declared with the keywords <tt>bool</tt>\nor <tt>_Bool</tt>.</li>\n\n<li>Complex numbers, declared with the keywords <tt>complex</tt> or\n<tt>_Complex</tt>.</li>\n\n<li>Two complex number types: <tt>complex</tt> (aka\n<tt>complex&nbsp;double</tt>) and <tt>complex&nbsp;float</tt>.</li>\n\n<li>Vector types, declared with the GCC <tt>mode</tt> or\n<tt>vector_size</tt> attribute.</li>\n\n<li>Unnamed ('transparent') <tt>struct</tt>/<tt>union</tt> fields\ninside a <tt>struct</tt>/<tt>union</tt>.</li>\n\n<li>Incomplete <tt>enum</tt> declarations, handled like incomplete\n<tt>struct</tt> declarations.</li>\n\n<li>Unnamed <tt>enum</tt> fields inside a\n<tt>struct</tt>/<tt>union</tt>. This is similar to a scoped C++\n<tt>enum</tt>, except that declared constants are visible in the\nglobal namespace, too.</li>\n\n<li>Scoped <tt>static&nbsp;const</tt> declarations inside a\n<tt>struct</tt>/<tt>union</tt> (from C++).</li>\n\n<li>Zero-length arrays (<tt>[0]</tt>), empty\n<tt>struct</tt>/<tt>union</tt>, variable-length arrays (VLA,\n<tt>[?]</tt>) and variable-length structs (VLS, with a trailing\nVLA).</li>\n\n<li>C++ reference types (<tt>int&nbsp;&amp;x</tt>).</li>\n\n<li>Alternate GCC keywords with '<tt>__</tt>', e.g.\n<tt>__const__</tt>.</li>\n\n<li>GCC <tt>__attribute__</tt> with the following attributes:\n<tt>aligned</tt>, <tt>packed</tt>, <tt>mode</tt>,\n<tt>vector_size</tt>, <tt>cdecl</tt>, <tt>fastcall</tt>,\n<tt>stdcall</tt>, <tt>thiscall</tt>.</li>\n\n<li>The GCC <tt>__extension__</tt> keyword and the GCC\n<tt>__alignof__</tt> operator.</li>\n\n<li>GCC <tt>__asm__(\"symname\")</tt> symbol name redirection for\nfunction declarations.</li>\n\n<li>MSVC keywords for fixed-length types: <tt>__int8</tt>,\n<tt>__int16</tt>, <tt>__int32</tt> and <tt>__int64</tt>.</li>\n\n<li>MSVC <tt>__cdecl</tt>, <tt>__fastcall</tt>, <tt>__stdcall</tt>,\n<tt>__thiscall</tt>, <tt>__ptr32</tt>, <tt>__ptr64</tt>,\n<tt>__declspec(align(n))</tt> and <tt>#pragma&nbsp;pack</tt>.</li>\n\n<li>All other GCC/MSVC-specific attributes are ignored.</li>\n\n</ul>\n<p>\nThe following C&nbsp;types are predefined by the C&nbsp;parser (like\na <tt>typedef</tt>, except re-declarations will be ignored):\n</p>\n<ul>\n\n<li>Vararg handling: <tt>va_list</tt>, <tt>__builtin_va_list</tt>,\n<tt>__gnuc_va_list</tt>.</li>\n\n<li>From <tt>&lt;stddef.h&gt;</tt>: <tt>ptrdiff_t</tt>,\n<tt>size_t</tt>, <tt>wchar_t</tt>.</li>\n\n<li>From <tt>&lt;stdint.h&gt;</tt>: <tt>int8_t</tt>, <tt>int16_t</tt>,\n<tt>int32_t</tt>, <tt>int64_t</tt>, <tt>uint8_t</tt>,\n<tt>uint16_t</tt>, <tt>uint32_t</tt>, <tt>uint64_t</tt>,\n<tt>intptr_t</tt>, <tt>uintptr_t</tt>.</li>\n\n<li>From <tt>&lt;unistd.h&gt;</tt> (POSIX): <tt>ssize_t</tt>.</li>\n\n</ul>\n<p>\nYou're encouraged to use these types in preference to\ncompiler-specific extensions or target-dependent standard types.\nE.g. <tt>char</tt> differs in signedness and <tt>long</tt> differs in\nsize, depending on the target architecture and platform ABI.\n</p>\n<p>\nThe following C&nbsp;features are <b>not</b> supported:\n</p>\n<ul>\n\n<li>A declaration must always have a type specifier; it doesn't\ndefault to an <tt>int</tt> type.</li>\n\n<li>Old-style empty function declarations (K&amp;R) are not allowed.\nAll C&nbsp;functions must have a proper prototype declaration. A\nfunction declared without parameters (<tt>int&nbsp;foo();</tt>) is\ntreated as a function taking zero arguments, like in C++.</li>\n\n<li>The <tt>long double</tt> C&nbsp;type is parsed correctly, but\nthere's no support for the related conversions, accesses or arithmetic\noperations.</li>\n\n<li>Wide character strings and character literals are not\nsupported.</li>\n\n<li><a href=\"#status\">See below</a> for features that are currently\nnot implemented.</li>\n\n</ul>\n\n<h2 id=\"convert\">C Type Conversion Rules</h2>\n\n<h3 id=\"convert_tolua\">Conversions from C&nbsp;types to Lua objects</h3>\n<p>\nThese conversion rules apply for <em>read accesses</em> to\nC&nbsp;types: indexing pointers, arrays or\n<tt>struct</tt>/<tt>union</tt> types; reading external variables or\nconstant values; retrieving return values from C&nbsp;calls:\n</p>\n<table class=\"convtable\">\n<tr class=\"convhead\">\n<td class=\"convin\">Input</td>\n<td class=\"convop\">Conversion</td>\n<td class=\"convout\">Output</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"convin\"><tt>int8_t</tt>, <tt>int16_t</tt></td><td class=\"convop\">&rarr;<sup>sign-ext</sup> <tt>int32_t</tt> &rarr; <tt>double</tt></td><td class=\"convout\">number</td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>uint8_t</tt>, <tt>uint16_t</tt></td><td class=\"convop\">&rarr;<sup>zero-ext</sup> <tt>int32_t</tt> &rarr; <tt>double</tt></td><td class=\"convout\">number</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\"><tt>int32_t</tt>, <tt>uint32_t</tt></td><td class=\"convop\">&rarr; <tt>double</tt></td><td class=\"convout\">number</td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>int64_t</tt>, <tt>uint64_t</tt></td><td class=\"convop\">boxed value</td><td class=\"convout\">64 bit int cdata</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\"><tt>double</tt>, <tt>float</tt></td><td class=\"convop\">&rarr; <tt>double</tt></td><td class=\"convout\">number</td></tr>\n<tr class=\"even separate\">\n<td class=\"convin\"><tt>bool</tt></td><td class=\"convop\">0 &rarr; <tt>false</tt>, otherwise <tt>true</tt></td><td class=\"convout\">boolean</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\"><tt>enum</tt></td><td class=\"convop\">boxed value</td><td class=\"convout\">enum cdata</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Complex number</td><td class=\"convop\">boxed value</td><td class=\"convout\">complex cdata</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Vector</td><td class=\"convop\">boxed value</td><td class=\"convout\">vector cdata</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Pointer</td><td class=\"convop\">boxed value</td><td class=\"convout\">pointer cdata</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">Array</td><td class=\"convop\">boxed reference</td><td class=\"convout\">reference cdata</td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>struct</tt>/<tt>union</tt></td><td class=\"convop\">boxed reference</td><td class=\"convout\">reference cdata</td></tr>\n</table>\n<p>\nBitfields are treated like their underlying type.\n</p>\n<p>\nReference types are dereferenced <em>before</em> a conversion can take\nplace &mdash; the conversion is applied to the C&nbsp;type pointed to\nby the reference.\n</p>\n\n<h3 id=\"convert_fromlua\">Conversions from Lua objects to C&nbsp;types</h3>\n<p>\nThese conversion rules apply for <em>write accesses</em> to\nC&nbsp;types: indexing pointers, arrays or\n<tt>struct</tt>/<tt>union</tt> types; initializing cdata objects;\ncasts to C&nbsp;types; writing to external variables; passing\narguments to C&nbsp;calls:\n</p>\n<table class=\"convtable\">\n<tr class=\"convhead\">\n<td class=\"convin\">Input</td>\n<td class=\"convop\">Conversion</td>\n<td class=\"convout\">Output</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">number</td><td class=\"convop\">&rarr;</td><td class=\"convout\"><tt>double</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">boolean</td><td class=\"convop\"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class=\"convout\"><tt>bool</tt></td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">nil</td><td class=\"convop\"><tt>NULL</tt> &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">lightuserdata</td><td class=\"convop\">lightuserdata address &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">userdata</td><td class=\"convop\">userdata payload &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">io.* file</td><td class=\"convop\">get FILE * handle &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">string</td><td class=\"convop\">match against <tt>enum</tt> constant</td><td class=\"convout\"><tt>enum</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">string</td><td class=\"convop\">copy string data + zero-byte</td><td class=\"convout\"><tt>int8_t[]</tt>, <tt>uint8_t[]</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">string</td><td class=\"convop\">string data &rarr;</td><td class=\"convout\"><tt>const char[]</tt></td></tr>\n<tr class=\"even separate\">\n<td class=\"convin\">function</td><td class=\"convop\"><a href=\"#callback\">create callback</a> &rarr;</td><td class=\"convout\">C function type</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">table</td><td class=\"convop\"><a href=\"#init_table\">table initializer</a></td><td class=\"convout\">Array</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">table</td><td class=\"convop\"><a href=\"#init_table\">table initializer</a></td><td class=\"convout\"><tt>struct</tt>/<tt>union</tt></td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">cdata</td><td class=\"convop\">cdata payload &rarr;</td><td class=\"convout\">C type</td></tr>\n</table>\n<p>\nIf the result type of this conversion doesn't match the\nC&nbsp;type of the destination, the\n<a href=\"#convert_between\">conversion rules between C&nbsp;types</a>\nare applied.\n</p>\n<p>\nReference types are immutable after initialization (\"no re-seating of\nreferences\"). For initialization purposes or when passing values to\nreference parameters, they are treated like pointers. Note that unlike\nin C++, there's no way to implement automatic reference generation of\nvariables under the Lua language semantics. If you want to call a\nfunction with a reference parameter, you need to explicitly pass a\none-element array.\n</p>\n\n<h3 id=\"convert_between\">Conversions between C&nbsp;types</h3>\n<p>\nThese conversion rules are more or less the same as the standard\nC&nbsp;conversion rules. Some rules only apply to casts, or require\npointer or type compatibility:\n</p>\n<table class=\"convtable\">\n<tr class=\"convhead\">\n<td class=\"convin\">Input</td>\n<td class=\"convop\">Conversion</td>\n<td class=\"convout\">Output</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">Signed integer</td><td class=\"convop\">&rarr;<sup>narrow or sign-extend</sup></td><td class=\"convout\">Integer</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Unsigned integer</td><td class=\"convop\">&rarr;<sup>narrow or zero-extend</sup></td><td class=\"convout\">Integer</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Integer</td><td class=\"convop\">&rarr;<sup>round</sup></td><td class=\"convout\"><tt>double</tt>, <tt>float</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>double</tt>, <tt>float</tt></td><td class=\"convop\">&rarr;<sup>trunc</sup> <tt>int32_t</tt> &rarr;<sup>narrow</sup></td><td class=\"convout\"><tt>(u)int8_t</tt>, <tt>(u)int16_t</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"convin\"><tt>double</tt>, <tt>float</tt></td><td class=\"convop\">&rarr;<sup>trunc</sup></td><td class=\"convout\"><tt>(u)int32_t</tt>, <tt>(u)int64_t</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>double</tt>, <tt>float</tt></td><td class=\"convop\">&rarr;<sup>round</sup></td><td class=\"convout\"><tt>float</tt>, <tt>double</tt></td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">Number</td><td class=\"convop\">n == 0 &rarr; 0, otherwise 1</td><td class=\"convout\"><tt>bool</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>bool</tt></td><td class=\"convop\"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class=\"convout\">Number</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">Complex number</td><td class=\"convop\">convert real part</td><td class=\"convout\">Number</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Number</td><td class=\"convop\">convert real part, imag = 0</td><td class=\"convout\">Complex number</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Complex number</td><td class=\"convop\">convert real and imag part</td><td class=\"convout\">Complex number</td></tr>\n<tr class=\"even separate\">\n<td class=\"convin\">Number</td><td class=\"convop\">convert scalar and replicate</td><td class=\"convout\">Vector</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Vector</td><td class=\"convop\">copy (same size)</td><td class=\"convout\">Vector</td></tr>\n<tr class=\"even separate\">\n<td class=\"convin\"><tt>struct</tt>/<tt>union</tt></td><td class=\"convop\">take base address (compat)</td><td class=\"convout\">Pointer</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Array</td><td class=\"convop\">take base address (compat)</td><td class=\"convout\">Pointer</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Function</td><td class=\"convop\">take function address</td><td class=\"convout\">Function pointer</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">Number</td><td class=\"convop\">convert via <tt>uintptr_t</tt> (cast)</td><td class=\"convout\">Pointer</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Pointer</td><td class=\"convop\">convert address (compat/cast)</td><td class=\"convout\">Pointer</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Pointer</td><td class=\"convop\">convert address (cast)</td><td class=\"convout\">Integer</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Array</td><td class=\"convop\">convert base address (cast)</td><td class=\"convout\">Integer</td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">Array</td><td class=\"convop\">copy (compat)</td><td class=\"convout\">Array</td></tr>\n<tr class=\"even\">\n<td class=\"convin\"><tt>struct</tt>/<tt>union</tt></td><td class=\"convop\">copy (identical type)</td><td class=\"convout\"><tt>struct</tt>/<tt>union</tt></td></tr>\n</table>\n<p>\nBitfields or <tt>enum</tt> types are treated like their underlying\ntype.\n</p>\n<p>\nConversions not listed above will raise an error. E.g. it's not\npossible to convert a pointer to a complex number or vice versa.\n</p>\n\n<h3 id=\"convert_vararg\">Conversions for vararg C&nbsp;function arguments</h3>\n<p>\nThe following default conversion rules apply when passing Lua objects\nto the variable argument part of vararg C&nbsp;functions:\n</p>\n<table class=\"convtable\">\n<tr class=\"convhead\">\n<td class=\"convin\">Input</td>\n<td class=\"convop\">Conversion</td>\n<td class=\"convout\">Output</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">number</td><td class=\"convop\">&rarr;</td><td class=\"convout\"><tt>double</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">boolean</td><td class=\"convop\"><tt>false</tt> &rarr; 0, <tt>true</tt> &rarr; 1</td><td class=\"convout\"><tt>bool</tt></td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\">nil</td><td class=\"convop\"><tt>NULL</tt> &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">userdata</td><td class=\"convop\">userdata payload &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">lightuserdata</td><td class=\"convop\">lightuserdata address &rarr;</td><td class=\"convout\"><tt>(void *)</tt></td></tr>\n<tr class=\"even separate\">\n<td class=\"convin\">string</td><td class=\"convop\">string data &rarr;</td><td class=\"convout\"><tt>const char *</tt></td></tr>\n<tr class=\"odd separate\">\n<td class=\"convin\"><tt>float</tt> cdata</td><td class=\"convop\">&rarr;</td><td class=\"convout\"><tt>double</tt></td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Array cdata</td><td class=\"convop\">take base address</td><td class=\"convout\">Element pointer</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\"><tt>struct</tt>/<tt>union</tt> cdata</td><td class=\"convop\">take base address</td><td class=\"convout\"><tt>struct</tt>/<tt>union</tt> pointer</td></tr>\n<tr class=\"even\">\n<td class=\"convin\">Function cdata</td><td class=\"convop\">take function address</td><td class=\"convout\">Function pointer</td></tr>\n<tr class=\"odd\">\n<td class=\"convin\">Any other cdata</td><td class=\"convop\">no conversion</td><td class=\"convout\">C type</td></tr>\n</table>\n<p>\nTo pass a Lua object, other than a cdata object, as a specific type,\nyou need to override the conversion rules: create a temporary cdata\nobject with a constructor or a cast and initialize it with the value\nto pass:\n</p>\n<p>\nAssuming <tt>x</tt> is a Lua number, here's how to pass it as an\ninteger to a vararg function:\n</p>\n<pre class=\"code\">\nffi.cdef[[\nint printf(const char *fmt, ...);\n]]\nffi.C.printf(\"integer value: %d\\n\", ffi.new(\"int\", x))\n</pre>\n<p>\nIf you don't do this, the default Lua number &rarr; <tt>double</tt>\nconversion rule applies. A vararg C&nbsp;function expecting an integer\nwill see a garbled or uninitialized value.\n</p>\n\n<h2 id=\"init\">Initializers</h2>\n<p>\nCreating a cdata object with\n<a href=\"ext_ffi_api.html#ffi_new\"><tt>ffi.new()</tt></a> or the\nequivalent constructor syntax always initializes its contents, too.\nDifferent rules apply, depending on the number of optional\ninitializers and the C&nbsp;types involved:\n</p>\n<ul>\n<li>If no initializers are given, the object is filled with zero bytes.</li>\n\n<li>Scalar types (numbers and pointers) accept a single initializer.\nThe Lua object is <a href=\"#convert_fromlua\">converted to the scalar\nC&nbsp;type</a>.</li>\n\n<li>Valarrays (complex numbers and vectors) are treated like scalars\nwhen a single initializer is given. Otherwise they are treated like\nregular arrays.</li>\n\n<li>Aggregate types (arrays and structs) accept either a single cdata\ninitializer of the same type (copy constructor), a single\n<a href=\"#init_table\">table initializer</a>, or a flat list of\ninitializers.</li>\n\n<li>The elements of an array are initialized, starting at index zero.\nIf a single initializer is given for an array, it's repeated for all\nremaining elements. This doesn't happen if two or more initializers\nare given: all remaining uninitialized elements are filled with zero\nbytes.</li>\n\n<li>Byte arrays may also be initialized with a Lua string. This copies\nthe whole string plus a terminating zero-byte. The copy stops early only\nif the array has a known, fixed size.</li>\n\n<li>The fields of a <tt>struct</tt> are initialized in the order of\ntheir declaration. Uninitialized fields are filled with zero\nbytes.</li>\n\n<li>Only the first field of a <tt>union</tt> can be initialized with a\nflat initializer.</li>\n\n<li>Elements or fields which are aggregates themselves are initialized\nwith a <em>single</em> initializer, but this may be a table\ninitializer or a compatible aggregate.</li>\n\n<li>Excess initializers cause an error.</li>\n\n</ul>\n\n<h2 id=\"init_table\">Table Initializers</h2>\n<p>\nThe following rules apply if a Lua table is used to initialize an\nArray or a <tt>struct</tt>/<tt>union</tt>:\n</p>\n<ul>\n\n<li>If the table index <tt>[0]</tt> is non-<tt>nil</tt>, then the\ntable is assumed to be zero-based. Otherwise it's assumed to be\none-based.</li>\n\n<li>Array elements, starting at index zero, are initialized one-by-one\nwith the consecutive table elements, starting at either index\n<tt>[0]</tt> or <tt>[1]</tt>. This process stops at the first\n<tt>nil</tt> table element.</li>\n\n<li>If exactly one array element was initialized, it's repeated for\nall the remaining elements. Otherwise all remaining uninitialized\nelements are filled with zero bytes.</li>\n\n<li>The above logic only applies to arrays with a known fixed size.\nA VLA is only initialized with the element(s) given in the table.\nDepending on the use case, you may need to explicitly add a\n<tt>NULL</tt> or <tt>0</tt> terminator to a VLA.</li>\n\n<li>A <tt>struct</tt>/<tt>union</tt> can be initialized in the\norder of the declaration of its fields. Each field is initialized with\nconsecutive table elements, starting at either index <tt>[0]</tt>\nor <tt>[1]</tt>. This process stops at the first <tt>nil</tt> table\nelement.</li>\n\n<li>Otherwise, if neither index <tt>[0]</tt> nor <tt>[1]</tt> is present,\na <tt>struct</tt>/<tt>union</tt> is initialized by looking up each field\nname (as a string key) in the table. Each non-<tt>nil</tt> value is\nused to initialize the corresponding field.</li>\n\n<li>Uninitialized fields of a <tt>struct</tt> are filled with zero\nbytes, except for the trailing VLA of a VLS.</li>\n\n<li>Initialization of a <tt>union</tt> stops after one field has been\ninitialized. If no field has been initialized, the <tt>union</tt> is\nfilled with zero bytes.</li>\n\n<li>Elements or fields which are aggregates themselves are initialized\nwith a <em>single</em> initializer, but this may be a nested table\ninitializer (or a compatible aggregate).</li>\n\n<li>Excess initializers for an array cause an error. Excess\ninitializers for a <tt>struct</tt>/<tt>union</tt> are ignored.\nUnrelated table entries are ignored, too.</li>\n\n</ul>\n<p>\nExample:\n</p>\n<pre class=\"code\">\nlocal ffi = require(\"ffi\")\n\nffi.cdef[[\nstruct foo { int a, b; };\nunion bar { int i; double d; };\nstruct nested { int x; struct foo y; };\n]]\n\nffi.new(\"int[3]\", {})            --> 0, 0, 0\nffi.new(\"int[3]\", {1})           --> 1, 1, 1\nffi.new(\"int[3]\", {1,2})         --> 1, 2, 0\nffi.new(\"int[3]\", {1,2,3})       --> 1, 2, 3\nffi.new(\"int[3]\", {[0]=1})       --> 1, 1, 1\nffi.new(\"int[3]\", {[0]=1,2})     --> 1, 2, 0\nffi.new(\"int[3]\", {[0]=1,2,3})   --> 1, 2, 3\nffi.new(\"int[3]\", {[0]=1,2,3,4}) --> error: too many initializers\n\nffi.new(\"struct foo\", {})            --> a = 0, b = 0\nffi.new(\"struct foo\", {1})           --> a = 1, b = 0\nffi.new(\"struct foo\", {1,2})         --> a = 1, b = 2\nffi.new(\"struct foo\", {[0]=1,2})     --> a = 1, b = 2\nffi.new(\"struct foo\", {b=2})         --> a = 0, b = 2\nffi.new(\"struct foo\", {a=1,b=2,c=3}) --> a = 1, b = 2  'c' is ignored\n\nffi.new(\"union bar\", {})        --> i = 0, d = 0.0\nffi.new(\"union bar\", {1})       --> i = 1, d = ?\nffi.new(\"union bar\", {[0]=1,2}) --> i = 1, d = ?    '2' is ignored\nffi.new(\"union bar\", {d=2})     --> i = ?, d = 2.0\n\nffi.new(\"struct nested\", {1,{2,3}})     --> x = 1, y.a = 2, y.b = 3\nffi.new(\"struct nested\", {x=1,y={2,3}}) --> x = 1, y.a = 2, y.b = 3\n</pre>\n\n<h2 id=\"cdata_ops\">Operations on cdata Objects</h2>\n<p>\nAll standard Lua operators can be applied to cdata objects or a\nmix of a cdata object and another Lua object. The following list shows\nthe predefined operations.\n</p>\n<p>\nReference types are dereferenced <em>before</em> performing each of\nthe operations below &mdash; the operation is applied to the\nC&nbsp;type pointed to by the reference.\n</p>\n<p>\nThe predefined operations are always tried first before deferring to a\nmetamethod or index table (if any) for the corresponding ctype (except\nfor <tt>__new</tt>). An error is raised if the metamethod lookup or\nindex table lookup fails.\n</p>\n\n<h3 id=\"cdata_array\">Indexing a cdata object</h3>\n<ul>\n\n<li><b>Indexing a pointer/array</b>: a cdata pointer/array can be\nindexed by a cdata number or a Lua number. The element address is\ncomputed as the base address plus the number value multiplied by the\nelement size in bytes. A read access loads the element value and\n<a href=\"#convert_tolua\">converts it to a Lua object</a>. A write\naccess <a href=\"#convert_fromlua\">converts a Lua object to the element\ntype</a> and stores the converted value to the element. An error is\nraised if the element size is undefined or a write access to a\nconstant element is attempted.</li>\n\n<li><b>Dereferencing a <tt>struct</tt>/<tt>union</tt> field</b>: a\ncdata <tt>struct</tt>/<tt>union</tt> or a pointer to a\n<tt>struct</tt>/<tt>union</tt> can be dereferenced by a string key,\ngiving the field name. The field address is computed as the base\naddress plus the relative offset of the field. A read access loads the\nfield value and <a href=\"#convert_tolua\">converts it to a Lua\nobject</a>. A write access <a href=\"#convert_fromlua\">converts a Lua\nobject to the field type</a> and stores the converted value to the\nfield. An error is raised if a write access to a constant\n<tt>struct</tt>/<tt>union</tt> or a constant field is attempted.\nScoped enum constants or static constants are treated like a constant\nfield.</li>\n\n<li><b>Indexing a complex number</b>: a complex number can be indexed\neither by a cdata number or a Lua number with the values 0 or 1, or by\nthe strings <tt>\"re\"</tt> or <tt>\"im\"</tt>. A read access loads the\nreal part (<tt>[0]</tt>, <tt>.re</tt>) or the imaginary part\n(<tt>[1]</tt>, <tt>.im</tt>) part of a complex number and\n<a href=\"#convert_tolua\">converts it to a Lua number</a>. The\nsub-parts of a complex number are immutable &mdash; assigning to an\nindex of a complex number raises an error. Accessing out-of-bound\nindexes returns unspecified results, but is guaranteed not to trigger\nmemory access violations.</li>\n\n<li><b>Indexing a vector</b>: a vector is treated like an array for\nindexing purposes, except the vector elements are immutable &mdash;\nassigning to an index of a vector raises an error.</li>\n\n</ul>\n<p>\nA ctype object can be indexed with a string key, too. The only\npredefined operation is reading scoped constants of\n<tt>struct</tt>/<tt>union</tt> types. All other accesses defer\nto the corresponding metamethods or index tables (if any).\n</p>\n<p>\nNote: since there's (deliberately) no address-of operator, a cdata\nobject holding a value type is effectively immutable after\ninitialization. The JIT compiler benefits from this fact when applying\ncertain optimizations.\n</p>\n<p>\nAs a consequence, the <em>elements</em> of complex numbers and\nvectors are immutable. But the elements of an aggregate holding these\ntypes <em>may</em> be modified, of course. I.e. you cannot assign to\n<tt>foo.c.im</tt>, but you can assign a (newly created) complex number\nto <tt>foo.c</tt>.\n</p>\n<p>\nThe JIT compiler implements strict aliasing rules: accesses to different\ntypes do <b>not</b> alias, except for differences in signedness (this\napplies even to <tt>char</tt> pointers, unlike C99). Type punning\nthrough unions is explicitly detected and allowed.\n</p>\n\n<h3 id=\"cdata_call\">Calling a cdata object</h3>\n<ul>\n\n<li><b>Constructor</b>: a ctype object can be called and used as a\n<a href=\"ext_ffi_api.html#ffi_new\">constructor</a>. This is equivalent\nto <tt>ffi.new(ct, ...)</tt>, unless a <tt>__new</tt> metamethod is\ndefined. The <tt>__new</tt> metamethod is called with the ctype object\nplus any other arguments passed to the constructor. Note that you have to\nuse <tt>ffi.new</tt> inside the metamethod, since calling <tt>ct(...)</tt>\nwould cause infinite recursion.</li>\n\n<li><b>C&nbsp;function call</b>: a cdata function or cdata function\npointer can be called. The passed arguments are\n<a href=\"#convert_fromlua\">converted to the C&nbsp;types</a> of the\nparameters given by the function declaration. Arguments passed to the\nvariable argument part of vararg C&nbsp;function use\n<a href=\"#convert_vararg\">special conversion rules</a>. This\nC&nbsp;function is called and the return value (if any) is\n<a href=\"#convert_tolua\">converted to a Lua object</a>.<br>\nOn Windows/x86 systems, <tt>__stdcall</tt> functions are automatically\ndetected, and a function declared as <tt>__cdecl</tt> (the default) is\nsilently fixed up after the first call.</li>\n\n</ul>\n\n<h3 id=\"cdata_arith\">Arithmetic on cdata objects</h3>\n<ul>\n\n<li><b>Pointer arithmetic</b>: a cdata pointer/array and a cdata\nnumber or a Lua number can be added or subtracted. The number must be\non the right-hand side for a subtraction. The result is a pointer of\nthe same type with an address plus or minus the number value\nmultiplied by the element size in bytes. An error is raised if the\nelement size is undefined.</li>\n\n<li><b>Pointer difference</b>: two compatible cdata pointers/arrays\ncan be subtracted. The result is the difference between their\naddresses, divided by the element size in bytes. An error is raised if\nthe element size is undefined or zero.</li>\n\n<li><b>64&nbsp;bit integer arithmetic</b>: the standard arithmetic\noperators (<tt>+&nbsp;-&nbsp;*&nbsp;/&nbsp;%&nbsp;^</tt> and unary\nminus) can be applied to two cdata numbers, or a cdata number and a\nLua number. If one of them is an <tt>uint64_t</tt>, the other side is\nconverted to an <tt>uint64_t</tt> and an unsigned arithmetic operation\nis performed. Otherwise, both sides are converted to an\n<tt>int64_t</tt> and a signed arithmetic operation is performed. The\nresult is a boxed 64&nbsp;bit cdata object.<br>\n\nIf one of the operands is an <tt>enum</tt> and the other operand is a\nstring, the string is converted to the value of a matching <tt>enum</tt>\nconstant before the above conversion.<br>\n\nThese rules ensure that 64&nbsp;bit integers are \"sticky\". Any\nexpression involving at least one 64&nbsp;bit integer operand results\nin another one. The undefined cases for the division, modulo and power\noperators return <tt>2LL&nbsp;^&nbsp;63</tt> or\n<tt>2ULL&nbsp;^&nbsp;63</tt>.<br>\n\nYou'll have to explicitly convert a 64&nbsp;bit integer to a Lua\nnumber (e.g. for regular floating-point calculations) with\n<tt>tonumber()</tt>. But note this may incur a precision loss.</li>\n\n<li><b>64&nbsp;bit bitwise operations</b>: the rules for 64&nbsp;bit\narithmetic operators apply analogously.<br>\n\nUnlike the other <tt>bit.*</tt> operations, <tt>bit.tobit()</tt>\nconverts a cdata number via <tt>int64_t</tt> to <tt>int32_t</tt> and\nreturns a Lua number.<br>\n\nFor <tt>bit.band()</tt>, <tt>bit.bor()</tt> and <tt>bit.bxor()</tt>, the\nconversion to <tt>int64_t</tt> or <tt>uint64_t</tt> applies to\n<em>all</em> arguments, if <em>any</em> argument is a cdata number.<br>\n\nFor all other operations, only the first argument is used to determine\nthe output type. This implies that a cdata number as a shift count for\nshifts and rotates is accepted, but that alone does <em>not</em> cause\na cdata number output.\n\n</ul>\n\n<h3 id=\"cdata_comp\">Comparisons of cdata objects</h3>\n<ul>\n\n<li><b>Pointer comparison</b>: two compatible cdata pointers/arrays\ncan be compared. The result is the same as an unsigned comparison of\ntheir addresses. <tt>nil</tt> is treated like a <tt>NULL</tt> pointer,\nwhich is compatible with any other pointer type.</li>\n\n<li><b>64&nbsp;bit integer comparison</b>: two cdata numbers, or a\ncdata number and a Lua number can be compared with each other. If one\nof them is an <tt>uint64_t</tt>, the other side is converted to an\n<tt>uint64_t</tt> and an unsigned comparison is performed. Otherwise,\nboth sides are converted to an <tt>int64_t</tt> and a signed\ncomparison is performed.<br>\n\nIf one of the operands is an <tt>enum</tt> and the other operand is a\nstring, the string is converted to the value of a matching <tt>enum</tt>\nconstant before the above conversion.<br>\n\n<li><b>Comparisons for equality/inequality</b> never raise an error.\nEven incompatible pointers can be compared for equality by address. Any\nother incompatible comparison (also with non-cdata objects) treats the\ntwo sides as unequal.</li>\n\n</ul>\n\n<h3 id=\"cdata_key\">cdata objects as table keys</h3>\n<p>\nLua tables may be indexed by cdata objects, but this doesn't provide\nany useful semantics &mdash; <b>cdata objects are unsuitable as table\nkeys!</b>\n</p>\n<p>\nA cdata object is treated like any other garbage-collected object and\nis hashed and compared by its address for table indexing. Since\nthere's no interning for cdata value types, the same value may be\nboxed in different cdata objects with different addresses. Thus,\n<tt>t[1LL+1LL]</tt> and <tt>t[2LL]</tt> usually <b>do not</b> point to\nthe same hash slot, and they certainly <b>do not</b> point to the same\nhash slot as <tt>t[2]</tt>.\n</p>\n<p>\nIt would seriously drive up implementation complexity and slow down\nthe common case, if one were to add extra handling for by-value\nhashing and comparisons to Lua tables. Given the ubiquity of their use\ninside the VM, this is not acceptable.\n</p>\n<p>\nThere are three viable alternatives, if you really need to use cdata\nobjects as keys:\n</p>\n<ul>\n\n<li>If you can get by with the precision of Lua numbers\n(52&nbsp;bits), then use <tt>tonumber()</tt> on a cdata number or\ncombine multiple fields of a cdata aggregate to a Lua number. Then use\nthe resulting Lua number as a key when indexing tables.<br>\nOne obvious benefit: <tt>t[tonumber(2LL)]</tt> <b>does</b> point to\nthe same slot as <tt>t[2]</tt>.</li>\n\n<li>Otherwise, use either <tt>tostring()</tt> on 64&nbsp;bit integers\nor complex numbers or combine multiple fields of a cdata aggregate to\na Lua string (e.g. with\n<a href=\"ext_ffi_api.html#ffi_string\"><tt>ffi.string()</tt></a>). Then\nuse the resulting Lua string as a key when indexing tables.</li>\n\n<li>Create your own specialized hash table implementation using the\nC&nbsp;types provided by the FFI library, just like you would in\nC&nbsp;code. Ultimately, this may give much better performance than the\nother alternatives or what a generic by-value hash table could\npossibly provide.</li>\n\n</ul>\n\n<h2 id=\"param\">Parameterized Types</h2>\n<p>\nTo facilitate some abstractions, the two functions\n<a href=\"ext_ffi_api.html#ffi_typeof\"><tt>ffi.typeof</tt></a> and\n<a href=\"ext_ffi_api.html#ffi_cdef\"><tt>ffi.cdef</tt></a> support\nparameterized types in C&nbsp;declarations. Note: none of the other API\nfunctions taking a cdecl allow this.\n</p>\n<p>\nAny place you can write a <b><tt>typedef</tt> name</b>, an\n<b>identifier</b> or a <b>number</b> in a declaration, you can write\n<tt>$</tt> (the dollar sign) instead. These placeholders are replaced in\norder of appearance with the arguments following the cdecl string:\n</p>\n<pre class=\"code\">\n-- Declare a struct with a parameterized field type and name:\nffi.cdef([[\ntypedef struct { $ $; } foo_t;\n]], type1, name1)\n\n-- Anonymous struct with dynamic names:\nlocal bar_t = ffi.typeof(\"struct { int $, $; }\", name1, name2)\n-- Derived pointer type:\nlocal bar_ptr_t = ffi.typeof(\"$ *\", bar_t)\n\n-- Parameterized dimensions work even where a VLA won't work:\nlocal matrix_t = ffi.typeof(\"uint8_t[$][$]\", width, height)\n</pre>\n<p>\nCaveat: this is <em>not</em> simple text substitution! A passed ctype or\ncdata object is treated like the underlying type, a passed string is\nconsidered an identifier and a number is considered a number. You must\nnot mix this up: e.g. passing <tt>\"int\"</tt> as a string doesn't work in\nplace of a type, you'd need to use <tt>ffi.typeof(\"int\")</tt> instead.\n</p>\n<p>\nThe main use for parameterized types are libraries implementing abstract\ndata types\n(<a href=\"https://www.freelists.org/post/luajit/ffi-type-of-pointer-to,8\"><span class=\"ext\">&raquo;</span>&nbsp;example</a>),\nsimilar to what can be achieved with C++ template metaprogramming.\nAnother use case are derived types of anonymous structs, which avoids\npollution of the global struct namespace.\n</p>\n<p>\nPlease note that parameterized types are a nice tool and indispensable\nfor certain use cases. But you'll want to use them sparingly in regular\ncode, e.g. when all types are actually fixed.\n</p>\n\n<h2 id=\"gc\">Garbage Collection of cdata Objects</h2>\n<p>\nAll explicitly (<tt>ffi.new()</tt>, <tt>ffi.cast()</tt> etc.) or\nimplicitly (accessors) created cdata objects are garbage collected.\nYou need to ensure to retain valid references to cdata objects\nsomewhere on a Lua stack, an upvalue or in a Lua table while they are\nstill in use. Once the last reference to a cdata object is gone, the\ngarbage collector will automatically free the memory used by it (at\nthe end of the next GC cycle).\n</p>\n<p>\nPlease note, that pointers themselves are cdata objects, however they\nare <b>not</b> followed by the garbage collector. So e.g. if you\nassign a cdata array to a pointer, you must keep the cdata object\nholding the array alive as long as the pointer is still in use:\n</p>\n<pre class=\"code\">\nffi.cdef[[\ntypedef struct { int *a; } foo_t;\n]]\n\nlocal s = ffi.new(\"foo_t\", ffi.new(\"int[10]\")) -- <span style=\"color:#c00000;\">WRONG!</span>\n\nlocal a = ffi.new(\"int[10]\") -- <span style=\"color:#00a000;\">OK</span>\nlocal s = ffi.new(\"foo_t\", a)\n-- Now do something with 's', but keep 'a' alive until you're done.\n</pre>\n<p>\nSimilar rules apply for Lua strings which are implicitly converted to\n<tt>\"const&nbsp;char&nbsp;*\"</tt>: the string object itself must be\nreferenced somewhere or it'll be garbage collected eventually. The\npointer will then point to stale data, which may have already been\noverwritten. Note that <em>string literals</em> are automatically kept\nalive as long as the function containing it (actually its prototype)\nis not garbage collected.\n</p>\n<p>\nObjects which are passed as an argument to an external C&nbsp;function\nare kept alive until the call returns. So it's generally safe to\ncreate temporary cdata objects in argument lists. This is a common\nidiom for <a href=\"#convert_vararg\">passing specific C&nbsp;types to\nvararg functions</a>.\n</p>\n<p>\nMemory areas returned by C functions (e.g. from <tt>malloc()</tt>)\nmust be manually managed, of course (or use\n<a href=\"ext_ffi_api.html#ffi_gc\"><tt>ffi.gc()</tt></a>). Pointers to\ncdata objects are indistinguishable from pointers returned by C\nfunctions (which is one of the reasons why the GC cannot follow them).\n</p>\n\n<h2 id=\"callback\">Callbacks</h2>\n<p>\nThe LuaJIT FFI automatically generates special callback functions\nwhenever a Lua function is converted to a C&nbsp;function pointer. This\nassociates the generated callback function pointer with the C&nbsp;type\nof the function pointer and the Lua function object (closure).\n</p>\n<p>\nThis can happen implicitly due to the usual conversions, e.g. when\npassing a Lua function to a function pointer argument. Or, you can use\n<tt>ffi.cast()</tt> to explicitly cast a Lua function to a\nC&nbsp;function pointer.\n</p>\n<p>\nCurrently, only certain C&nbsp;function types can be used as callback\nfunctions. Neither C&nbsp;vararg functions nor functions with\npass-by-value aggregate argument or result types are supported. There\nare no restrictions on the kind of Lua functions that can be called\nfrom the callback &mdash; no checks for the proper number of arguments\nare made. The return value of the Lua function will be converted to the\nresult type, and an error will be thrown for invalid conversions.\n</p>\n<p>\nIt's allowed to throw errors across a callback invocation, but it's not\nadvisable in general. Do this only if you know the C&nbsp;function, that\ncalled the callback, copes with the forced stack unwinding and doesn't\nleak resources.\n</p>\n<p>\nOne thing that's not allowed, is to let an FFI call into a C&nbsp;function\nget JIT-compiled, which in turn calls a callback, calling into Lua again.\nUsually this attempt is caught by the interpreter first and the\nC&nbsp;function is blacklisted for compilation.\n</p>\n<p>\nHowever, this heuristic may fail under specific circumstances: e.g. a\nmessage polling function might not run Lua callbacks right away and the call\ngets JIT-compiled. If it later happens to call back into Lua (e.g. a rarely\ninvoked error callback), you'll get a VM PANIC with the message\n<tt>\"bad callback\"</tt>. Then you'll need to manually turn off\nJIT-compilation with\n<a href=\"ext_jit.html#jit_onoff_func\"><tt>jit.off()</tt></a> for the\nsurrounding Lua function that invokes such a message polling function (or\nsimilar).\n</p>\n\n<h3 id=\"callback_resources\">Callback resource handling</h3>\n<p>\nCallbacks take up resources &mdash; you can only have a limited number\nof them at the same time (500&nbsp;-&nbsp;1000, depending on the\narchitecture). The associated Lua functions are anchored to prevent\ngarbage collection, too.\n</p>\n<p>\n<b>Callbacks due to implicit conversions are permanent!</b> There is no\nway to guess their lifetime, since the C&nbsp;side might store the\nfunction pointer for later use (typical for GUI toolkits). The associated\nresources cannot be reclaimed until termination:\n</p>\n<pre class=\"code\">\nffi.cdef[[\ntypedef int (__stdcall *WNDENUMPROC)(void *hwnd, intptr_t l);\nint EnumWindows(WNDENUMPROC func, intptr_t l);\n]]\n\n-- Implicit conversion to a callback via function pointer argument.\nlocal count = 0\nffi.C.EnumWindows(function(hwnd, l)\n  count = count + 1\n  return true\nend, 0)\n-- The callback is permanent and its resources cannot be reclaimed!\n-- Ok, so this may not be a problem, if you do this only once.\n</pre>\n<p>\nNote: this example shows that you <em>must</em> properly declare\n<tt>__stdcall</tt> callbacks on Windows/x86 systems. The calling\nconvention cannot be automatically detected, unlike for\n<tt>__stdcall</tt> calls <em>to</em> Windows functions.\n</p>\n<p>\nFor some use cases, it's necessary to free up the resources or to\ndynamically redirect callbacks. Use an explicit cast to a\nC&nbsp;function pointer and keep the resulting cdata object. Then use\nthe <a href=\"ext_ffi_api.html#callback_free\"><tt>cb:free()</tt></a>\nor <a href=\"ext_ffi_api.html#callback_set\"><tt>cb:set()</tt></a> methods\non the cdata object:\n</p>\n<pre class=\"code\">\n-- Explicitly convert to a callback via cast.\nlocal count = 0\nlocal cb = ffi.cast(\"WNDENUMPROC\", function(hwnd, l)\n  count = count + 1\n  return true\nend)\n\n-- Pass it to a C function.\nffi.C.EnumWindows(cb, 0)\n-- EnumWindows doesn't need the callback after it returns, so free it.\n\ncb:free()\n-- The callback function pointer is no longer valid and its resources\n-- will be reclaimed. The created Lua closure will be garbage collected.\n</pre>\n\n<h3 id=\"callback_performance\">Callback performance</h3>\n<p>\n<b>Callbacks are slow!</b> First, the C&nbsp;to Lua transition itself\nhas an unavoidable cost, similar to a <tt>lua_call()</tt> or\n<tt>lua_pcall()</tt>. Argument and result marshalling add to that cost.\nAnd finally, neither the C&nbsp;compiler nor LuaJIT can inline or\noptimize across the language barrier and hoist repeated computations out\nof a callback function.\n</p>\n<p>\nDo not use callbacks for performance-sensitive work: e.g. consider a\nnumerical integration routine which takes a user-defined function to\nintegrate over. It's a bad idea to call a user-defined Lua function from\nC&nbsp;code millions of times. The callback overhead will be absolutely\ndetrimental for performance.\n</p>\n<p>\nIt's considerably faster to write the numerical integration routine\nitself in Lua &mdash; the JIT compiler will be able to inline the\nuser-defined function and optimize it together with its calling context,\nwith very competitive performance.\n</p>\n<p>\nAs a general guideline: <b>use callbacks only when you must</b>, because\nof existing C&nbsp;APIs. E.g. callback performance is irrelevant for a\nGUI application, which waits for user input most of the time, anyway.\n</p>\n<p>\nFor new designs <b>avoid push-style APIs</b>: a C&nbsp;function repeatedly\ncalling a callback for each result. Instead, <b>use pull-style APIs</b>:\ncall a C&nbsp;function repeatedly to get a new result. Calls from Lua\nto C via the FFI are much faster than the other way round. Most well-designed\nlibraries already use pull-style APIs (read/write, get/put).\n</p>\n\n<h2 id=\"clib\">C Library Namespaces</h2>\n<p>\nA C&nbsp;library namespace is a special kind of object which allows\naccess to the symbols contained in shared libraries or the default\nsymbol namespace. The default\n<a href=\"ext_ffi_api.html#ffi_C\"><tt>ffi.C</tt></a> namespace is\nautomatically created when the FFI library is loaded. C&nbsp;library\nnamespaces for specific shared libraries may be created with the\n<a href=\"ext_ffi_api.html#ffi_load\"><tt>ffi.load()</tt></a> API\nfunction.\n</p>\n<p>\nIndexing a C&nbsp;library namespace object with a symbol name (a Lua\nstring) automatically binds it to the library. First, the symbol type\nis resolved &mdash; it must have been declared with\n<a href=\"ext_ffi_api.html#ffi_cdef\"><tt>ffi.cdef</tt></a>. Then the\nsymbol address is resolved by searching for the symbol name in the\nassociated shared libraries or the default symbol namespace. Finally,\nthe resulting binding between the symbol name, the symbol type and its\naddress is cached. Missing symbol declarations or nonexistent symbol\nnames cause an error.\n</p>\n<p>\nThis is what happens on a <b>read access</b> for the different kinds of\nsymbols:\n</p>\n<ul>\n\n<li>External functions: a cdata object with the type of the function\nand its address is returned.</li>\n\n<li>External variables: the symbol address is dereferenced and the\nloaded value is <a href=\"#convert_tolua\">converted to a Lua object</a>\nand returned.</li>\n\n<li>Constant values (<tt>static&nbsp;const</tt> or <tt>enum</tt>\nconstants): the constant is <a href=\"#convert_tolua\">converted to a\nLua object</a> and returned.</li>\n\n</ul>\n<p>\nThis is what happens on a <b>write access</b>:\n</p>\n<ul>\n\n<li>External variables: the value to be written is\n<a href=\"#convert_fromlua\">converted to the C&nbsp;type</a> of the\nvariable and then stored at the symbol address.</li>\n\n<li>Writing to constant variables or to any other symbol type causes\nan error, like any other attempted write to a constant location.</li>\n\n</ul>\n<p>\nC&nbsp;library namespaces themselves are garbage collected objects. If\nthe last reference to the namespace object is gone, the garbage\ncollector will eventually release the shared library reference and\nremove all memory associated with the namespace. Since this may\ntrigger the removal of the shared library from the memory of the\nrunning process, it's generally <em>not safe</em> to use function\ncdata objects obtained from a library if the namespace object may be\nunreferenced.\n</p>\n<p>\nPerformance notice: the JIT compiler specializes to the identity of\nnamespace objects and to the strings used to index it. This\neffectively turns function cdata objects into constants. It's not\nuseful and actually counter-productive to explicitly cache these\nfunction objects, e.g. <tt>local strlen = ffi.C.strlen</tt>. OTOH, it\n<em>is</em> useful to cache the namespace itself, e.g. <tt>local C =\nffi.C</tt>.\n</p>\n\n<h2 id=\"policy\">No Hand-holding!</h2>\n<p>\nThe FFI library has been designed as <b>a low-level library</b>. The\ngoal is to interface with C&nbsp;code and C&nbsp;data types with a\nminimum of overhead. This means <b>you can do anything you can do\nfrom&nbsp;C</b>: access all memory, overwrite anything in memory, call\nmachine code at any memory address and so on.\n</p>\n<p>\nThe FFI library provides <b>no memory safety</b>, unlike regular Lua\ncode. It will happily allow you to dereference a <tt>NULL</tt>\npointer, to access arrays out of bounds or to misdeclare\nC&nbsp;functions. If you make a mistake, your application might crash,\njust like equivalent C&nbsp;code would.\n</p>\n<p>\nThis behavior is inevitable, since the goal is to provide full\ninteroperability with C&nbsp;code. Adding extra safety measures, like\nbounds checks, would be futile. There's no way to detect\nmisdeclarations of C&nbsp;functions, since shared libraries only\nprovide symbol names, but no type information. Likewise, there's no way\nto infer the valid range of indexes for a returned pointer.\n</p>\n<p>\nAgain: the FFI library is a low-level library. This implies it needs\nto be used with care, but it's flexibility and performance often\noutweigh this concern. If you're a C or C++ developer, it'll be easy\nto apply your existing knowledge. OTOH, writing code for the FFI\nlibrary is not for the faint of heart and probably shouldn't be the\nfirst exercise for someone with little experience in Lua, C or C++.\n</p>\n<p>\nAs a corollary of the above, the FFI library is <b>not safe for use by\nuntrusted Lua code</b>. If you're sandboxing untrusted Lua code, you\ndefinitely don't want to give this code access to the FFI library or\nto <em>any</em> cdata object (except 64&nbsp;bit integers or complex\nnumbers). Any properly engineered Lua sandbox needs to provide safety\nwrappers for many of the standard Lua library functions &mdash;\nsimilar wrappers need to be written for high-level operations on FFI\ndata types, too.\n</p>\n\n<h2 id=\"status\">Current Status</h2>\n<p>\nThe initial release of the FFI library has some limitations and is\nmissing some features. Most of these will be fixed in future releases.\n</p>\n<p>\n<a href=\"#clang\">C language support</a> is\ncurrently incomplete:\n</p>\n<ul>\n<li>C&nbsp;declarations are not passed through a C&nbsp;pre-processor,\nyet.</li>\n<li>The C&nbsp;parser is able to evaluate most constant expressions\ncommonly found in C&nbsp;header files. However, it doesn't handle the\nfull range of C&nbsp;expression semantics and may fail for some\nobscure constructs.</li>\n<li><tt>static const</tt> declarations only work for integer types\nup to 32&nbsp;bits. Neither declaring string constants nor\nfloating-point constants is supported.</li>\n<li>Packed <tt>struct</tt> bitfields that cross container boundaries\nare not implemented.</li>\n<li>Native vector types may be defined with the GCC <tt>mode</tt> or\n<tt>vector_size</tt> attribute. But no operations other than loading,\nstoring and initializing them are supported, yet.</li>\n<li>The <tt>volatile</tt> type qualifier is currently ignored by\ncompiled code.</li>\n<li><a href=\"ext_ffi_api.html#ffi_cdef\"><tt>ffi.cdef</tt></a> silently\nignores most re-declarations. Note: avoid re-declarations which do not\nconform to C99. The implementation will eventually be changed to\nperform strict checks.</li>\n</ul>\n<p>\nThe JIT compiler already handles a large subset of all FFI operations.\nIt automatically falls back to the interpreter for unimplemented\noperations (you can check for this with the\n<a href=\"running.html#opt_j\"><tt>-jv</tt></a> command line option).\nThe following operations are currently not compiled and may exhibit\nsuboptimal performance, especially when used in inner loops:\n</p>\n<ul>\n<li>Vector operations.</li>\n<li>Table initializers.</li>\n<li>Initialization of nested <tt>struct</tt>/<tt>union</tt> types.</li>\n<li>Non-default initialization of VLA/VLS or large C&nbsp;types\n(&gt; 128&nbsp;bytes or &gt; 16 array elements).</li>\n<li>Bitfield initializations.</li>\n<li>Pointer differences for element sizes that are not a power of\ntwo.</li>\n<li>Calls to C&nbsp;functions with aggregates passed or returned by\nvalue.</li>\n<li>Calls to ctype metamethods which are not plain functions.</li>\n<li>ctype <tt>__newindex</tt> tables and non-string lookups in ctype\n<tt>__index</tt> tables.</li>\n<li><tt>tostring()</tt> for cdata types.</li>\n<li>Calls to <tt>ffi.cdef()</tt>, <tt>ffi.load()</tt> and\n<tt>ffi.metatype()</tt>.</li>\n</ul>\n<p>\nOther missing features:\n</p>\n<ul>\n<li>Arithmetic for <tt>complex</tt> numbers.</li>\n<li>Passing structs by value to vararg C&nbsp;functions.</li>\n<li><a href=\"extensions.html#exceptions\">C++ exception interoperability</a>\ndoes not extend to C&nbsp;functions called via the FFI, if the call is\ncompiled.</li>\n</ul>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_ffi_tutorial.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>FFI Tutorial</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ntable.idiomtable { font-size: 90%; line-height: 1.2; }\ntable.idiomtable tt { font-size: 100%; }\ntable.idiomtable td { vertical-align: top; }\ntr.idiomhead td { font-weight: bold; }\ntd.idiomlua b { font-weight: normal; color: #2142bf; }\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>FFI Tutorial</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a class=\"current\" href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nThis page is intended to give you an overview of the features of the FFI\nlibrary by presenting a few use cases and guidelines.\n</p>\n<p>\nThis page makes no attempt to explain all of the FFI library, though.\nYou'll want to have a look at the <a href=\"ext_ffi_api.html\">ffi.* API\nfunction reference</a> and the <a href=\"ext_ffi_semantics.html\">FFI\nsemantics</a> to learn more.\n</p>\n\n<h2 id=\"load\">Loading the FFI Library</h2>\n<p>\nThe FFI library is built into LuaJIT by default, but it's not loaded\nand initialized by default. The suggested way to use the FFI library\nis to add the following to the start of every Lua file that needs one\nof its functions:\n</p>\n<pre class=\"code\">\nlocal ffi = require(\"ffi\")\n</pre>\n<p>\nPlease note, this doesn't define an <tt>ffi</tt> variable in the table\nof globals &mdash; you really need to use the local variable. The\n<tt>require</tt> function ensures the library is only loaded once.\n</p>\n<p style=\"font-size: 8pt;\">\nNote: If you want to experiment with the FFI from the interactive prompt\nof the command line executable, omit the <tt>local</tt>, as it doesn't\npreserve local variables across lines.\n</p>\n\n<h2 id=\"sleep\">Accessing Standard System Functions</h2>\n<p>\nThe following code explains how to access standard system functions.\nWe slowly print two lines of dots by sleeping for 10&nbsp;milliseconds\nafter each dot:\n</p>\n<pre class=\"code mark\">\n<span class=\"codemark\">&nbsp;\n&#9312;\n\n\n\n\n\n&#9313;\n&#9314;\n&#9315;\n\n\n\n&#9316;\n\n\n\n\n\n&#9317;</span>local ffi = require(\"ffi\")\nffi.cdef[[\n<span style=\"color:#00a000;\">void Sleep(int ms);\nint poll(struct pollfd *fds, unsigned long nfds, int timeout);</span>\n]]\n\nlocal sleep\nif ffi.os == \"Windows\" then\n  function sleep(s)\n    ffi.C.Sleep(s*1000)\n  end\nelse\n  function sleep(s)\n    ffi.C.poll(nil, 0, s*1000)\n  end\nend\n\nfor i=1,160 do\n  io.write(\".\"); io.flush()\n  sleep(0.01)\nend\nio.write(\"\\n\")\n</pre>\n<p>\nHere's the step-by-step explanation:\n</p>\n<p>\n<span class=\"mark\">&#9312;</span> This defines the\nC&nbsp;library functions we're going to use. The part inside the\ndouble-brackets (in green) is just standard C&nbsp;syntax. You can\nusually get this info from the C&nbsp;header files or the\ndocumentation provided by each C&nbsp;library or C&nbsp;compiler.\n</p>\n<p>\n<span class=\"mark\">&#9313;</span> The difficulty we're\nfacing here, is that there are different standards to choose from.\nWindows has a simple <tt>Sleep()</tt> function. On other systems there\nare a variety of functions available to achieve sub-second sleeps, but\nwith no clear consensus. Thankfully <tt>poll()</tt> can be used for\nthis task, too, and it's present on most non-Windows systems. The\ncheck for <tt>ffi.os</tt> makes sure we use the Windows-specific\nfunction only on Windows systems.\n</p>\n<p>\n<span class=\"mark\">&#9314;</span> Here we're wrapping the\ncall to the C&nbsp;function in a Lua function. This isn't strictly\nnecessary, but it's helpful to deal with system-specific issues only\nin one part of the code. The way we're wrapping it ensures the check\nfor the OS is only done during initialization and not for every call.\n</p>\n<p>\n<span class=\"mark\">&#9315;</span> A more subtle point is\nthat we defined our <tt>sleep()</tt> function (for the sake of this\nexample) as taking the number of seconds, but accepting fractional\nseconds. Multiplying this by 1000 gets us milliseconds, but that still\nleaves it a Lua number, which is a floating-point value. Alas, the\n<tt>Sleep()</tt> function only accepts an integer value. Luckily for\nus, the FFI library automatically performs the conversion when calling\nthe function (truncating the FP value towards zero, like in C).\n</p>\n<p style=\"font-size: 8pt;\">\nSome readers will notice that <tt>Sleep()</tt> is part of\n<tt>KERNEL32.DLL</tt> and is also a <tt>stdcall</tt> function. So how\ncan this possibly work? The FFI library provides the <tt>ffi.C</tt>\ndefault C&nbsp;library namespace, which allows calling functions from\nthe default set of libraries, like a C&nbsp;compiler would. Also, the\nFFI library automatically detects <tt>stdcall</tt> functions, so you\ndon't need to declare them as such.\n</p>\n<p>\n<span class=\"mark\">&#9316;</span> The <tt>poll()</tt>\nfunction takes a couple more arguments we're not going to use. You can\nsimply use <tt>nil</tt> to pass a <tt>NULL</tt> pointer and <tt>0</tt>\nfor the <tt>nfds</tt> parameter. Please note, that the\nnumber&nbsp;<tt>0</tt> <em>does not convert to a pointer value</em>,\nunlike in C++. You really have to pass pointers to pointer arguments\nand numbers to number arguments.\n</p>\n<p style=\"font-size: 8pt;\">\nThe page on <a href=\"ext_ffi_semantics.html\">FFI semantics</a> has all\nof the gory details about\n<a href=\"ext_ffi_semantics.html#convert\">conversions between Lua\nobjects and C&nbsp;types</a>. For the most part you don't have to deal\nwith this, as it's performed automatically and it's carefully designed\nto bridge the semantic differences between Lua and C.\n</p>\n<p>\n<span class=\"mark\">&#9317;</span> Now that we have defined\nour own <tt>sleep()</tt> function, we can just call it from plain Lua\ncode. That wasn't so bad, huh? Turning these boring animated dots into\na fascinating best-selling game is left as an exercise for the reader.\n:-)\n</p>\n\n<h2 id=\"zlib\">Accessing the zlib Compression Library</h2>\n<p>\nThe following code shows how to access the <a\nhref=\"https://zlib.net/\"><span class=\"ext\">&raquo;</span>&nbsp;zlib</a> compression library from Lua code.\nWe'll define two convenience wrapper functions that take a string and\ncompress or uncompress it to another string:\n</p>\n<pre class=\"code mark\">\n<span class=\"codemark\">&nbsp;\n&#9312;\n\n\n\n\n\n\n&#9313;\n\n\n&#9314;\n\n&#9315;\n\n\n&#9316;\n\n\n&#9317;\n\n\n\n\n\n\n\n&#9318;</span>local ffi = require(\"ffi\")\nffi.cdef[[\n<span style=\"color:#00a000;\">unsigned long compressBound(unsigned long sourceLen);\nint compress2(uint8_t *dest, unsigned long *destLen,\n\t      const uint8_t *source, unsigned long sourceLen, int level);\nint uncompress(uint8_t *dest, unsigned long *destLen,\n\t       const uint8_t *source, unsigned long sourceLen);</span>\n]]\nlocal zlib = ffi.load(ffi.os == \"Windows\" and \"zlib1\" or \"z\")\n\nlocal function compress(txt)\n  local n = zlib.compressBound(#txt)\n  local buf = ffi.new(\"uint8_t[?]\", n)\n  local buflen = ffi.new(\"unsigned long[1]\", n)\n  local res = zlib.compress2(buf, buflen, txt, #txt, 9)\n  assert(res == 0)\n  return ffi.string(buf, buflen[0])\nend\n\nlocal function uncompress(comp, n)\n  local buf = ffi.new(\"uint8_t[?]\", n)\n  local buflen = ffi.new(\"unsigned long[1]\", n)\n  local res = zlib.uncompress(buf, buflen, comp, #comp)\n  assert(res == 0)\n  return ffi.string(buf, buflen[0])\nend\n\n-- Simple test code.\nlocal txt = string.rep(\"abcd\", 1000)\nprint(\"Uncompressed size: \", #txt)\nlocal c = compress(txt)\nprint(\"Compressed size: \", #c)\nlocal txt2 = uncompress(c, #txt)\nassert(txt2 == txt)\n</pre>\n<p>\nHere's the step-by-step explanation:\n</p>\n<p>\n<span class=\"mark\">&#9312;</span> This defines some of the\nC&nbsp;functions provided by zlib. For the sake of this example, some\ntype indirections have been reduced and it uses the predefined\nfixed-size integer types, while still adhering to the zlib API/ABI.\n</p>\n<p>\n<span class=\"mark\">&#9313;</span> This loads the zlib shared\nlibrary. On POSIX systems, it's named <tt>libz.so</tt> and usually\ncomes pre-installed. Since <tt>ffi.load()</tt> automatically adds any\nmissing standard prefixes/suffixes, we can simply load the\n<tt>\"z\"</tt> library. On Windows it's named <tt>zlib1.dll</tt> and\nyou'll have to download it first from the\n<a href=\"https://zlib.net/\"><span class=\"ext\">&raquo;</span>&nbsp;zlib site</a>. The check for\n<tt>ffi.os</tt> makes sure we pass the right name to\n<tt>ffi.load()</tt>.\n</p>\n<p>\n<span class=\"mark\">&#9314;</span> First, the maximum size of\nthe compression buffer is obtained by calling the\n<tt>zlib.compressBound</tt> function with the length of the\nuncompressed string. The next line allocates a byte buffer of this\nsize. The <tt>[?]</tt> in the type specification indicates a\nvariable-length array (VLA). The actual number of elements of this\narray is given as the 2nd argument to <tt>ffi.new()</tt>.\n</p>\n<p>\n<span class=\"mark\">&#9315;</span> This may look strange at\nfirst, but have a look at the declaration of the <tt>compress2</tt>\nfunction from zlib: the destination length is defined as a pointer!\nThis is because you pass in the maximum buffer size and get back the\nactual length that was used.\n</p>\n<p>\nIn C you'd pass in the address of a local variable\n(<tt>&amp;buflen</tt>). But since there's no address-of operator in\nLua, we'll just pass in a one-element array. Conveniently, it can be\ninitialized with the maximum buffer size in one step. Calling the\nactual <tt>zlib.compress2</tt> function is then straightforward.\n</p>\n<p>\n<span class=\"mark\">&#9316;</span> We want to return the\ncompressed data as a Lua string, so we'll use <tt>ffi.string()</tt>.\nIt needs a pointer to the start of the data and the actual length. The\nlength has been returned in the <tt>buflen</tt> array, so we'll just\nget it from there.\n</p>\n<p style=\"font-size: 8pt;\">\nNote that since the function returns now, the <tt>buf</tt> and\n<tt>buflen</tt> variables will eventually be garbage collected. This\nis fine, because <tt>ffi.string()</tt> has copied the contents to a\nnewly created (interned) Lua string. If you plan to call this function\nlots of times, consider reusing the buffers and/or handing back the\nresults in buffers instead of strings. This will reduce the overhead\nfor garbage collection and string interning.\n</p>\n<p>\n<span class=\"mark\">&#9317;</span> The <tt>uncompress</tt>\nfunctions does the exact opposite of the <tt>compress</tt> function.\nThe compressed data doesn't include the size of the original string,\nso this needs to be passed in. Otherwise, no surprises here.\n</p>\n<p>\n<span class=\"mark\">&#9318;</span> The code, that makes use\nof the functions we just defined, is just plain Lua code. It doesn't\nneed to know anything about the LuaJIT FFI &mdash; the convenience\nwrapper functions completely hide it.\n</p>\n<p>\nOne major advantage of the LuaJIT FFI is that you are now able to\nwrite those wrappers <em>in Lua</em>. And at a fraction of the time it\nwould cost you to create an extra C&nbsp;module using the Lua/C API.\nMany of the simpler C&nbsp;functions can probably be used directly\nfrom your Lua code, without any wrappers.\n</p>\n<p style=\"font-size: 8pt;\">\nSide note: the zlib API uses the <tt>long</tt> type for passing\nlengths and sizes around. But all those zlib functions actually only\ndeal with 32&nbsp;bit values. This is an unfortunate choice for a\npublic API, but may be explained by zlib's history &mdash; we'll just\nhave to deal with it.\n</p>\n<p style=\"font-size: 8pt;\">\nFirst, you should know that a <tt>long</tt> is a 64&nbsp;bit type e.g.\non POSIX/x64 systems, but a 32&nbsp;bit type on Windows/x64 and on\n32&nbsp;bit systems. Thus a <tt>long</tt> result can be either a plain\nLua number or a boxed 64&nbsp;bit integer cdata object, depending on\nthe target system.\n</p>\n<p style=\"font-size: 8pt;\">\nOk, so the <tt>ffi.*</tt> functions generally accept cdata objects\nwherever you'd want to use a number. That's why we get a away with\npassing <tt>n</tt> to <tt>ffi.string()</tt> above. But other Lua\nlibrary functions or modules don't know how to deal with this. So for\nmaximum portability, one needs to use <tt>tonumber()</tt> on returned\n<tt>long</tt> results before passing them on. Otherwise the\napplication might work on some systems, but would fail in a POSIX/x64\nenvironment.\n</p>\n\n<h2 id=\"metatype\">Defining Metamethods for a C&nbsp;Type</h2>\n<p>\nThe following code explains how to define metamethods for a C type.\nWe define a simple point type and add some operations to it:\n</p>\n<pre class=\"code mark\">\n<span class=\"codemark\">&nbsp;\n&#9312;\n\n\n\n&#9313;\n\n&#9314;\n\n&#9315;\n\n\n\n&#9316;\n\n&#9317;</span>local ffi = require(\"ffi\")\nffi.cdef[[\n<span style=\"color:#00a000;\">typedef struct { double x, y; } point_t;</span>\n]]\n\nlocal point\nlocal mt = {\n  __add = function(a, b) return point(a.x+b.x, a.y+b.y) end,\n  __len = function(a) return math.sqrt(a.x*a.x + a.y*a.y) end,\n  __index = {\n    area = function(a) return a.x*a.x + a.y*a.y end,\n  },\n}\npoint = ffi.metatype(\"point_t\", mt)\n\nlocal a = point(3, 4)\nprint(a.x, a.y)  --> 3  4\nprint(#a)        --> 5\nprint(a:area())  --> 25\nlocal b = a + point(0.5, 8)\nprint(#b)        --> 12.5\n</pre>\n<p>\nHere's the step-by-step explanation:\n</p>\n<p>\n<span class=\"mark\">&#9312;</span> This defines the C&nbsp;type for a\ntwo-dimensional point object.\n</p>\n<p>\n<span class=\"mark\">&#9313;</span> We have to declare the variable\nholding the point constructor first, because it's used inside of a\nmetamethod.\n</p>\n<p>\n<span class=\"mark\">&#9314;</span> Let's define an <tt>__add</tt>\nmetamethod which adds the coordinates of two points and creates a new\npoint object. For simplicity, this function assumes that both arguments\nare points. But it could be any mix of objects, if at least one operand\nis of the required type (e.g. adding a point plus a number or vice\nversa). Our <tt>__len</tt> metamethod returns the distance of a point to\nthe origin.\n</p>\n<p>\n<span class=\"mark\">&#9315;</span> If we run out of operators, we can\ndefine named methods, too. Here, the <tt>__index</tt> table defines an\n<tt>area</tt> function. For custom indexing needs, one might want to\ndefine <tt>__index</tt> and <tt>__newindex</tt> <em>functions</em> instead.\n</p>\n<p>\n<span class=\"mark\">&#9316;</span> This associates the metamethods with\nour C&nbsp;type. This only needs to be done once. For convenience, a\nconstructor is returned by\n<a href=\"ext_ffi_api.html#ffi_metatype\"><tt>ffi.metatype()</tt></a>.\nWe're not required to use it, though. The original C&nbsp;type can still\nbe used e.g. to create an array of points. The metamethods automatically\napply to any and all uses of this type.\n</p>\n<p>\nPlease note, that the association with a metatable is permanent and\n<b>the metatable must not be modified afterwards!</b> Ditto for the\n<tt>__index</tt> table.\n</p>\n<p>\n<span class=\"mark\">&#9317;</span> Here are some simple usage examples\nfor the point type and their expected results. The predefined\noperations (such as <tt>a.x</tt>) can be freely mixed with the newly\ndefined metamethods. Note that <tt>area</tt> is a method and must be\ncalled with the Lua syntax for methods: <tt>a:area()</tt>, not\n<tt>a.area()</tt>.\n</p>\n<p>\nThe C&nbsp;type metamethod mechanism is most useful when used in\nconjunction with C&nbsp;libraries that are written in an object-oriented\nstyle. Creators return a pointer to a new instance, and methods take an\ninstance pointer as the first argument. Sometimes you can just point\n<tt>__index</tt> to the library namespace and <tt>__gc</tt> to the\ndestructor and you're done. But often enough you'll want to add\nconvenience wrappers, e.g. to return actual Lua strings or when\nreturning multiple values.\n</p>\n<p>\nSome C libraries only declare instance pointers as an opaque\n<tt>void&nbsp;*</tt> type. In this case you can use a fake type for all\ndeclarations, e.g. a pointer to a named (incomplete) struct will do:\n<tt>typedef struct foo_type *foo_handle</tt>. The C&nbsp;side doesn't\nknow what you declare with the LuaJIT FFI, but as long as the underlying\ntypes are compatible, everything still works.\n</p>\n\n<h2 id=\"idioms\">Translating C&nbsp;Idioms</h2>\n<p>\nHere's a list of common C&nbsp;idioms and their translation to the\nLuaJIT FFI:\n</p>\n<table class=\"idiomtable\">\n<tr class=\"idiomhead\">\n<td class=\"idiomdesc\">Idiom</td>\n<td class=\"idiomc\">C&nbsp;code</td>\n<td class=\"idiomlua\">Lua code</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"idiomdesc\">Pointer dereference<br><tt>int *p;</tt></td><td class=\"idiomc\"><tt>x = *p;<br>*p = y;</tt></td><td class=\"idiomlua\"><tt>x = <b>p[0]</b><br><b>p[0]</b> = y</tt></td></tr>\n<tr class=\"even\">\n<td class=\"idiomdesc\">Pointer indexing<br><tt>int i, *p;</tt></td><td class=\"idiomc\"><tt>x = p[i];<br>p[i+1] = y;</tt></td><td class=\"idiomlua\"><tt>x = p[i]<br>p[i+1] = y</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"idiomdesc\">Array indexing<br><tt>int i, a[];</tt></td><td class=\"idiomc\"><tt>x = a[i];<br>a[i+1] = y;</tt></td><td class=\"idiomlua\"><tt>x = a[i]<br>a[i+1] = y</tt></td></tr>\n<tr class=\"even separate\">\n<td class=\"idiomdesc\"><tt>struct</tt>/<tt>union</tt> dereference<br><tt>struct foo s;</tt></td><td class=\"idiomc\"><tt>x = s.field;<br>s.field = y;</tt></td><td class=\"idiomlua\"><tt>x = s.field<br>s.field = y</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"idiomdesc\"><tt>struct</tt>/<tt>union</tt> pointer deref.<br><tt>struct foo *sp;</tt></td><td class=\"idiomc\"><tt>x = sp->field;<br>sp->field = y;</tt></td><td class=\"idiomlua\"><tt>x = <b>s.field</b><br><b>s.field</b> = y</tt></td></tr>\n<tr class=\"even separate\">\n<td class=\"idiomdesc\">Pointer arithmetic<br><tt>int i, *p;</tt></td><td class=\"idiomc\"><tt>x = p + i;<br>y = p - i;</tt></td><td class=\"idiomlua\"><tt>x = p + i<br>y = p - i</tt></td></tr>\n<tr class=\"odd\">\n<td class=\"idiomdesc\">Pointer difference<br><tt>int *p1, *p2;</tt></td><td class=\"idiomc\"><tt>x = p1 - p2;</tt></td><td class=\"idiomlua\"><tt>x = p1 - p2</tt></td></tr>\n<tr class=\"even\">\n<td class=\"idiomdesc\">Array element pointer<br><tt>int i, a[];</tt></td><td class=\"idiomc\"><tt>x = &amp;a[i];</tt></td><td class=\"idiomlua\"><tt>x = <b>a+i</b></tt></td></tr>\n<tr class=\"odd\">\n<td class=\"idiomdesc\">Cast pointer to address<br><tt>int *p;</tt></td><td class=\"idiomc\"><tt>x = (intptr_t)p;</tt></td><td class=\"idiomlua\"><tt>x = <b>tonumber(<br>&nbsp;ffi.cast(\"intptr_t\",<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;p))</b></tt></td></tr>\n<tr class=\"even separate\">\n<td class=\"idiomdesc\">Functions with outargs<br><tt>void foo(int *inoutlen);</tt></td><td class=\"idiomc\"><tt>int len = x;<br>foo(&amp;len);<br>y = len;</tt></td><td class=\"idiomlua\"><tt><b>local len =<br>&nbsp;&nbsp;ffi.new(\"int[1]\", x)<br>foo(len)<br>y = len[0]</b></tt></td></tr>\n<tr class=\"odd\">\n<td class=\"idiomdesc\"><a href=\"ext_ffi_semantics.html#convert_vararg\">Vararg conversions</a><br><tt>int printf(char *fmt, ...);</tt></td><td class=\"idiomc\"><tt>printf(\"%g\", 1.0);<br>printf(\"%d\", 1);<br>&nbsp;</tt></td><td class=\"idiomlua\"><tt>printf(\"%g\", 1);<br>printf(\"%d\",<br>&nbsp;&nbsp;<b>ffi.new(\"int\", 1)</b>)</tt></td></tr>\n</table>\n\n<h2 id=\"cache\">To Cache or Not to Cache</h2>\n<p>\nIt's a common Lua idiom to cache library functions in local variables\nor upvalues, e.g.:\n</p>\n<pre class=\"code\">\nlocal byte, char = string.byte, string.char\nlocal function foo(x)\n  return char(byte(x)+1)\nend\n</pre>\n<p>\nThis replaces several hash-table lookups with a (faster) direct use of\na local or an upvalue. This is less important with LuaJIT, since the\nJIT compiler optimizes hash-table lookups a lot and is even able to\nhoist most of them out of the inner loops. It can't eliminate\n<em>all</em> of them, though, and it saves some typing for often-used\nfunctions. So there's still a place for this, even with LuaJIT.\n</p>\n<p>\nThe situation is a bit different with C&nbsp;function calls via the\nFFI library. The JIT compiler has special logic to eliminate <em>all\nof the lookup overhead</em> for functions resolved from a\n<a href=\"ext_ffi_semantics.html#clib\">C&nbsp;library namespace</a>!\nThus it's not helpful and actually counter-productive to cache\nindividual C&nbsp;functions like this:\n</p>\n<pre class=\"code\">\nlocal <b>funca</b>, <b>funcb</b> = ffi.C.funca, ffi.C.funcb -- <span style=\"color:#c00000;\">Not helpful!</span>\nlocal function foo(x, n)\n  for i=1,n do <b>funcb</b>(<b>funca</b>(x, i), 1) end\nend\n</pre>\n<p>\nThis turns them into indirect calls and generates bigger and slower\nmachine code. Instead, you'll want to cache the namespace itself and\nrely on the JIT compiler to eliminate the lookups:\n</p>\n<pre class=\"code\">\nlocal <b>C</b> = ffi.C          -- <span style=\"color:#00a000;\">Instead use this!</span>\nlocal function foo(x, n)\n  for i=1,n do <b>C.funcb</b>(<b>C.funca</b>(x, i), 1) end\nend\n</pre>\n<p>\nThis generates both shorter and faster code. So <b>don't cache\nC&nbsp;functions</b>, but <b>do</b> cache namespaces! Most often the\nnamespace is already in a local variable at an outer scope, e.g. from\n<tt>local&nbsp;lib&nbsp;=&nbsp;ffi.load(...)</tt>. Note that copying\nit to a local variable in the function scope is unnecessary.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_jit.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>jit.* Library</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1><tt>jit.*</tt> Library</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a class=\"current\" href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nThe functions in this built-in module control the behavior of the JIT\ncompiler engine. Note that JIT-compilation is fully automatic &mdash;\nyou probably won't need to use any of the following functions unless\nyou have special needs.\n</p>\n\n<h3 id=\"jit_onoff\"><tt>jit.on()<br>\njit.off()</tt></h3>\n<p>\nTurns the whole JIT compiler on (default) or off.\n</p>\n<p>\nThese functions are typically used with the command line options\n<tt>-j on</tt> or <tt>-j off</tt>.\n</p>\n\n<h3 id=\"jit_flush\"><tt>jit.flush()</tt></h3>\n<p>\nFlushes the whole cache of compiled code.\n</p>\n\n<h3 id=\"jit_onoff_func\"><tt>jit.on(func|true [,true|false])<br>\njit.off(func|true [,true|false])<br>\njit.flush(func|true [,true|false])</tt></h3>\n<p>\n<tt>jit.on</tt> enables JIT compilation for a Lua function (this is\nthe default).\n</p>\n<p>\n<tt>jit.off</tt> disables JIT compilation for a Lua function and\nflushes any already compiled code from the code cache.\n</p>\n<p>\n<tt>jit.flush</tt> flushes the code, but doesn't affect the\nenable/disable status.\n</p>\n<p>\nThe current function, i.e. the Lua function calling this library\nfunction, can also be specified by passing <tt>true</tt> as the first\nargument.\n</p>\n<p>\nIf the second argument is <tt>true</tt>, JIT compilation is also\nenabled, disabled or flushed recursively for all sub-functions of a\nfunction. With <tt>false</tt> only the sub-functions are affected.\n</p>\n<p>\nThe <tt>jit.on</tt> and <tt>jit.off</tt> functions only set a flag\nwhich is checked when the function is about to be compiled. They do\nnot trigger immediate compilation.\n</p>\n<p>\nTypical usage is <tt>jit.off(true, true)</tt> in the main chunk\nof a module to turn off JIT compilation for the whole module for\ndebugging purposes.\n</p>\n\n<h3 id=\"jit_flush_tr\"><tt>jit.flush(tr)</tt></h3>\n<p>\nFlushes the root trace, specified by its number, and all of its side\ntraces from the cache. The code for the trace will be retained as long\nas there are any other traces which link to it.\n</p>\n\n<h3 id=\"jit_status\"><tt>status, ... = jit.status()</tt></h3>\n<p>\nReturns the current status of the JIT compiler. The first result is\neither <tt>true</tt> or <tt>false</tt> if the JIT compiler is turned\non or off. The remaining results are strings for CPU-specific features\nand enabled optimizations.\n</p>\n\n<h3 id=\"jit_version\"><tt>jit.version</tt></h3>\n<p>\nContains the LuaJIT version string.\n</p>\n\n<h3 id=\"jit_version_num\"><tt>jit.version_num</tt></h3>\n<p>\nContains the version number of the LuaJIT core. Version xx.yy.zz\nis represented by the decimal number xxyyzz.\n</p>\n\n<h3 id=\"jit_os\"><tt>jit.os</tt></h3>\n<p>\nContains the target OS name:\n\"Windows\", \"Linux\", \"OSX\", \"BSD\", \"POSIX\" or \"Other\".\n</p>\n\n<h3 id=\"jit_arch\"><tt>jit.arch</tt></h3>\n<p>\nContains the target architecture name:\n\"x86\", \"x64\", \"arm\", \"arm64\", \"arm64be\", \"ppc\", \"mips\", \"mipsel\", \"mips64\", \"mips64el\", \"mips64r6\", \"mips64r6el\".\n</p>\n\n<h2 id=\"jit_opt\"><tt>jit.opt.*</tt> &mdash; JIT compiler optimization control</h2>\n<p>\nThis submodule provides the backend for the <tt>-O</tt> command line\noption.\n</p>\n<p>\nYou can also use it programmatically, e.g.:\n</p>\n<pre class=\"code\">\njit.opt.start(2) -- same as -O2\njit.opt.start(\"-dce\")\njit.opt.start(\"hotloop=10\", \"hotexit=2\")\n</pre>\n<p>\nUnlike in LuaJIT 1.x, the module is built-in and\n<b>optimization is turned on by default!</b>\nIt's no longer necessary to run <tt>require(\"jit.opt\").start()</tt>,\nwhich was one of the ways to enable optimization.\n</p>\n\n<h2 id=\"jit_util\"><tt>jit.util.*</tt> &mdash; JIT compiler introspection</h2>\n<p>\nThis submodule holds functions to introspect the bytecode, generated\ntraces, the IR and the generated machine code. The functionality\nprovided by this module is still in flux and therefore undocumented.\n</p>\n<p>\nThe debug modules <tt>-jbc</tt>, <tt>-jv</tt> and <tt>-jdump</tt> make\nextensive use of these functions. Please check out their source code,\nif you want to know more.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/ext_profiler.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Profiler</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Profiler</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a class=\"current\" href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nLuaJIT has an integrated statistical profiler with very low overhead. It\nallows sampling the currently executing stack and other parameters in\nregular intervals.\n</p>\n<p>\nThe integrated profiler can be accessed from three levels:\n</p>\n<ul>\n<li>The <a href=\"#hl_profiler\">bundled high-level profiler</a>, invoked by the\n<a href=\"#j_p\"><tt>-jp</tt></a> command line option.</li>\n<li>A <a href=\"#ll_lua_api\">low-level Lua API</a> to control the profiler.</li>\n<li>A <a href=\"#ll_c_api\">low-level C API</a> to control the profiler.</li>\n</ul>\n\n<h2 id=\"hl_profiler\">High-Level Profiler</h2>\n<p>\nThe bundled high-level profiler offers basic profiling functionality. It\ngenerates simple textual summaries or source code annotations. It can be\naccessed with the <a href=\"#j_p\"><tt>-jp</tt></a> command line option\nor from Lua code by loading the underlying <tt>jit.p</tt> module.\n</p>\n<p>\nTo cut to the chase &mdash; run this to get a CPU usage profile by\nfunction name:\n</p>\n<pre class=\"code\">\nluajit -jp myapp.lua\n</pre>\n<p>\nIt's <em>not</em> a stated goal of the bundled profiler to add every\npossible option or to cater for special profiling needs. The low-level\nprofiler APIs are documented below. They may be used by third-party\nauthors to implement advanced functionality, e.g. IDE integration or\ngraphical profilers.\n</p>\n<p>\nNote: Sampling works for both interpreted and JIT-compiled code. The\nresults for JIT-compiled code may sometimes be surprising. LuaJIT\nheavily optimizes and inlines Lua code &mdash; there's no simple\none-to-one correspondence between source code lines and the sampled\nmachine code.\n</p>\n\n<h3 id=\"j_p\"><tt>-jp=[options[,output]]</tt></h3>\n<p>\nThe <tt>-jp</tt> command line option starts the high-level profiler.\nWhen the application run by the command line terminates, the profiler\nstops and writes the results to <tt>stdout</tt> or to the specified\n<tt>output</tt> file.\n</p>\n<p>\nThe <tt>options</tt> argument specifies how the profiling is to be\nperformed:\n</p>\n<ul>\n<li><tt>f</tt> &mdash; Stack dump: function name, otherwise module:line.\nThis is the default mode.</li>\n<li><tt>F</tt> &mdash; Stack dump: ditto, but dump module:name.</li>\n<li><tt>l</tt> &mdash; Stack dump: module:line.</li>\n<li><tt>&lt;number&gt;</tt> &mdash; stack dump depth (callee &larr;\ncaller). Default: 1.</li>\n<li><tt>-&lt;number&gt;</tt> &mdash; Inverse stack dump depth (caller\n&rarr; callee).</li>\n<li><tt>s</tt> &mdash; Split stack dump after first stack level. Implies\ndepth&nbsp;&ge;&nbsp;2 or depth&nbsp;&le;&nbsp;-2.</li>\n<li><tt>p</tt> &mdash; Show full path for module names.</li>\n<li><tt>v</tt> &mdash; Show VM states.</li>\n<li><tt>z</tt> &mdash; Show <a href=\"#jit_zone\">zones</a>.</li>\n<li><tt>r</tt> &mdash; Show raw sample counts. Default: show percentages.</li>\n<li><tt>a</tt> &mdash; Annotate excerpts from source code files.</li>\n<li><tt>A</tt> &mdash; Annotate complete source code files.</li>\n<li><tt>G</tt> &mdash; Produce raw output suitable for graphical tools.</li>\n<li><tt>m&lt;number&gt;</tt> &mdash; Minimum sample percentage to be shown.\nDefault: 3%.</li>\n<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds.\nDefault: 10ms.<br>\nNote: The actual sampling precision is OS-dependent.</li>\n</ul>\n<p>\nThe default output for <tt>-jp</tt> is a list of the most CPU consuming\nspots in the application. Increasing the stack dump depth with (say)\n<tt>-jp=2</tt> may help to point out the main callers or callees of\nhotspots. But sample aggregation is still flat per unique stack dump.\n</p>\n<p>\nTo get a two-level view (split view) of callers/callees, use\n<tt>-jp=s</tt> or <tt>-jp=-s</tt>. The percentages shown for the second\nlevel are relative to the first level.\n</p>\n<p>\nTo see how much time is spent in each line relative to a function, use\n<tt>-jp=fl</tt>.\n</p>\n<p>\nTo see how much time is spent in different VM states or\n<a href=\"#jit_zone\">zones</a>, use <tt>-jp=v</tt> or <tt>-jp=z</tt>.\n</p>\n<p>\nCombinations of <tt>v/z</tt> with <tt>f/F/l</tt> produce two-level\nviews, e.g. <tt>-jp=vf</tt> or <tt>-jp=fv</tt>. This shows the time\nspent in a VM state or zone vs. hotspots. This can be used to answer\nquestions like \"Which time-consuming functions are only interpreted?\" or\n\"What's the garbage collector overhead for a specific function?\".\n</p>\n<p>\nMultiple options can be combined &mdash; but not all combinations make\nsense, see above. E.g. <tt>-jp=3si4m1</tt> samples three stack levels\ndeep in 4ms intervals and shows a split view of the CPU consuming\nfunctions and their callers with a 1% threshold.\n</p>\n<p>\nSource code annotations produced by <tt>-jp=a</tt> or <tt>-jp=A</tt> are\nalways flat and at the line level. Obviously, the source code files need\nto be readable by the profiler script.\n</p>\n<p>\nThe high-level profiler can also be started and stopped from Lua code with:\n</p>\n<pre class=\"code\">\nrequire(\"jit.p\").start(options, output)\n...\nrequire(\"jit.p\").stop()\n</pre>\n\n<h3 id=\"jit_zone\"><tt>jit.zone</tt> &mdash; Zones</h3>\n<p>\nZones can be used to provide information about different parts of an\napplication to the high-level profiler. E.g. a game could make use of an\n<tt>\"AI\"</tt> zone, a <tt>\"PHYS\"</tt> zone, etc. Zones are hierarchical,\norganized as a stack.\n</p>\n<p>\nThe <tt>jit.zone</tt> module needs to be loaded explicitly:\n</p>\n<pre class=\"code\">\nlocal zone = require(\"jit.zone\")\n</pre>\n<ul>\n<li><tt>zone(\"name\")</tt> pushes a named zone to the zone stack.</li>\n<li><tt>zone()</tt> pops the current zone from the zone stack and\nreturns its name.</li>\n<li><tt>zone:get()</tt> returns the current zone name or <tt>nil</tt>.</li>\n<li><tt>zone:flush()</tt> flushes the zone stack.</li>\n</ul>\n<p>\nTo show the time spent in each zone use <tt>-jp=z</tt>. To show the time\nspent relative to hotspots use e.g. <tt>-jp=zf</tt> or <tt>-jp=fz</tt>.\n</p>\n\n<h2 id=\"ll_lua_api\">Low-level Lua API</h2>\n<p>\nThe <tt>jit.profile</tt> module gives access to the low-level API of the\nprofiler from Lua code. This module needs to be loaded explicitly:\n<pre class=\"code\">\nlocal profile = require(\"jit.profile\")\n</pre>\n<p>\nThis module can be used to implement your own higher-level profiler.\nA typical profiling run starts the profiler, captures stack dumps in\nthe profiler callback, adds them to a hash table to aggregate the number\nof samples, stops the profiler and then analyzes all captured\nstack dumps. Other parameters can be sampled in the profiler callback,\ntoo. But it's important not to spend too much time in the callback,\nsince this may skew the statistics.\n</p>\n\n<h3 id=\"profile_start\"><tt>profile.start(mode, cb)</tt>\n&mdash; Start profiler</h3>\n<p>\nThis function starts the profiler. The <tt>mode</tt> argument is a\nstring holding options:\n</p>\n<ul>\n<li><tt>f</tt> &mdash; Profile with precision down to the function level.</li>\n<li><tt>l</tt> &mdash; Profile with precision down to the line level.</li>\n<li><tt>i&lt;number&gt;</tt> &mdash; Sampling interval in milliseconds (default\n10ms).</br>\nNote: The actual sampling precision is OS-dependent.\n</li>\n</ul>\n<p>\nThe <tt>cb</tt> argument is a callback function which is called with\nthree arguments: <tt>(thread, samples, vmstate)</tt>. The callback is\ncalled on a separate coroutine, the <tt>thread</tt> argument is the\nstate that holds the stack to sample for profiling. Note: do\n<em>not</em> modify the stack of that state or call functions on it.\n</p>\n<p>\n<tt>samples</tt> gives the number of accumulated samples since the last\ncallback (usually 1).\n</p>\n<p>\n<tt>vmstate</tt> holds the VM state at the time the profiling timer\ntriggered. This may or may not correspond to the state of the VM when\nthe profiling callback is called. The state is either <tt>'N'</tt>\nnative (compiled) code, <tt>'I'</tt> interpreted code, <tt>'C'</tt>\nC&nbsp;code, <tt>'G'</tt> the garbage collector, or <tt>'J'</tt> the JIT\ncompiler.\n</p>\n\n<h3 id=\"profile_stop\"><tt>profile.stop()</tt>\n&mdash; Stop profiler</h3>\n<p>\nThis function stops the profiler.\n</p>\n\n<h3 id=\"profile_dump\"><tt>dump = profile.dumpstack([thread,] fmt, depth)</tt>\n&mdash; Dump stack </h3>\n<p>\nThis function allows taking stack dumps in an efficient manner. It\nreturns a string with a stack dump for the <tt>thread</tt> (coroutine),\nformatted according to the <tt>fmt</tt> argument:\n</p>\n<ul>\n<li><tt>p</tt> &mdash; Preserve the full path for module names. Otherwise,\nonly the file name is used.</li>\n<li><tt>f</tt> &mdash; Dump the function name if it can be derived. Otherwise,\nuse module:line.</li>\n<li><tt>F</tt> &mdash; Ditto, but dump module:name.</li>\n<li><tt>l</tt> &mdash; Dump module:line.</li>\n<li><tt>Z</tt> &mdash; Zap the following characters for the last dumped\nframe.</li>\n<li>All other characters are added verbatim to the output string.</li>\n</ul>\n<p>\nThe <tt>depth</tt> argument gives the number of frames to dump, starting\nat the topmost frame of the thread. A negative number dumps the frames in\ninverse order.\n</p>\n<p>\nThe first example prints a list of the current module names and line\nnumbers of up to 10 frames in separate lines. The second example prints\nsemicolon-separated function names for all frames (up to 100) in inverse\norder:\n</p>\n<pre class=\"code\">\nprint(profile.dumpstack(thread, \"l\\n\", 10))\nprint(profile.dumpstack(thread, \"lZ;\", -100))\n</pre>\n\n<h2 id=\"ll_c_api\">Low-level C API</h2>\n<p>\nThe profiler can be controlled directly from C&nbsp;code, e.g. for\nuse by IDEs. The declarations are in <tt>\"luajit.h\"</tt> (see\n<a href=\"ext_c_api.html\">Lua/C API</a> extensions).\n</p>\n\n<h3 id=\"luaJIT_profile_start\"><tt>luaJIT_profile_start(L, mode, cb, data)</tt>\n&mdash; Start profiler</h3>\n<p>\nThis function starts the profiler. <a href=\"#profile_start\">See\nabove</a> for a description of the <tt>mode</tt> argument.\n</p>\n<p>\nThe <tt>cb</tt> argument is a callback function with the following\ndeclaration:\n</p>\n<pre class=\"code\">\ntypedef void (*luaJIT_profile_callback)(void *data, lua_State *L,\n                                        int samples, int vmstate);\n</pre>\n<p>\n<tt>data</tt> is available for use by the callback. <tt>L</tt> is the\nstate that holds the stack to sample for profiling. Note: do\n<em>not</em> modify this stack or call functions on this stack &mdash;\nuse a separate coroutine for this purpose. <a href=\"#profile_start\">See\nabove</a> for a description of <tt>samples</tt> and <tt>vmstate</tt>.\n</p>\n\n<h3 id=\"luaJIT_profile_stop\"><tt>luaJIT_profile_stop(L)</tt>\n&mdash; Stop profiler</h3>\n<p>\nThis function stops the profiler.\n</p>\n\n<h3 id=\"luaJIT_profile_dumpstack\"><tt>p = luaJIT_profile_dumpstack(L, fmt, depth, len)</tt>\n&mdash; Dump stack </h3>\n<p>\nThis function allows taking stack dumps in an efficient manner.\n<a href=\"#profile_dump\">See above</a> for a description of <tt>fmt</tt>\nand <tt>depth</tt>.\n</p>\n<p>\nThis function returns a <tt>const&nbsp;char&nbsp;*</tt> pointing to a\nprivate string buffer of the profiler. The <tt>int&nbsp;*len</tt>\nargument returns the length of the output string. The buffer is\noverwritten on the next call and deallocated when the profiler stops.\nYou either need to consume the content immediately or copy it for later\nuse.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/extensions.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Extensions</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ntable.exc {\n  line-height: 1.2;\n}\ntr.exchead td {\n  font-weight: bold;\n}\ntd.excplatform {\n  width: 48%;\n}\ntd.exccompiler {\n  width: 29%;\n}\ntd.excinterop {\n  width: 23%;\n}\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Extensions</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a class=\"current\" href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nLuaJIT is fully upwards-compatible with Lua 5.1. It supports all\n<a href=\"https://www.lua.org/manual/5.1/manual.html#5\"><span class=\"ext\">&raquo;</span>&nbsp;standard Lua\nlibrary functions</a> and the full set of\n<a href=\"https://www.lua.org/manual/5.1/manual.html#3\"><span class=\"ext\">&raquo;</span>&nbsp;Lua/C API\nfunctions</a>.\n</p>\n<p>\nLuaJIT is also fully ABI-compatible to Lua 5.1 at the linker/dynamic\nloader level. This means you can compile a C&nbsp;module against the\nstandard Lua headers and load the same shared library from either Lua\nor LuaJIT.\n</p>\n<p>\nLuaJIT extends the standard Lua VM with new functionality and adds\nseveral extension modules. Please note, this page is only about\n<em>functional</em> enhancements and not about performance enhancements,\nsuch as the optimized VM, the faster interpreter or the JIT compiler.\n</p>\n\n<h2 id=\"modules\">Extensions Modules</h2>\n<p>\nLuaJIT comes with several built-in extension modules:\n</p>\n\n<h3 id=\"bit\"><tt>bit.*</tt> &mdash; Bitwise operations</h3>\n<p>\nLuaJIT supports all bitwise operations as defined by\n<a href=\"https://bitop.luajit.org\"><span class=\"ext\">&raquo;</span>&nbsp;Lua BitOp</a>:\n</p>\n<pre class=\"code\">\nbit.tobit  bit.tohex  bit.bnot    bit.band bit.bor  bit.bxor\nbit.lshift bit.rshift bit.arshift bit.rol  bit.ror  bit.bswap\n</pre>\n<p>\nThis module is a LuaJIT built-in &mdash; you don't need to download or\ninstall Lua BitOp. The Lua BitOp site has full documentation for all\n<a href=\"https://bitop.luajit.org/api.html\"><span class=\"ext\">&raquo;</span>&nbsp;Lua BitOp API functions</a>.\nThe FFI adds support for\n<a href=\"ext_ffi_semantics.html#cdata_arith\">64&nbsp;bit bitwise operations</a>,\nusing the same API functions.\n</p>\n<p>\nPlease make sure to <tt>require</tt> the module before using any of\nits functions:\n</p>\n<pre class=\"code\">\nlocal bit = require(\"bit\")\n</pre>\n<p>\nAn already installed Lua BitOp module is ignored by LuaJIT.\nThis way you can use bit operations from both Lua and LuaJIT on a\nshared installation.\n</p>\n\n<h3 id=\"ffi\"><tt>ffi.*</tt> &mdash; FFI library</h3>\n<p>\nThe <a href=\"ext_ffi.html\">FFI library</a> allows calling external\nC&nbsp;functions and the use of C&nbsp;data structures from pure Lua\ncode.\n</p>\n\n<h3 id=\"jit\"><tt>jit.*</tt> &mdash; JIT compiler control</h3>\n<p>\nThe functions in this module\n<a href=\"ext_jit.html\">control the behavior of the JIT compiler engine</a>.\n</p>\n\n<h3 id=\"c_api\">C API extensions</h3>\n<p>\nLuaJIT adds some\n<a href=\"ext_c_api.html\">extra functions to the Lua/C API</a>.\n</p>\n\n<h3 id=\"profiler\">Profiler</h3>\n<p>\nLuaJIT has an <a href=\"ext_profiler.html\">integrated profiler</a>.\n</p>\n\n<h2 id=\"library\">Enhanced Standard Library Functions</h2>\n\n<h3 id=\"xpcall\"><tt>xpcall(f, err [,args...])</tt> passes arguments</h3>\n<p>\nUnlike the standard implementation in Lua 5.1, <tt>xpcall()</tt>\npasses any arguments after the error function to the function\nwhich is called in a protected context.\n</p>\n\n<h3 id=\"load\"><tt>loadfile()</tt> etc. handle UTF-8 source code</h3>\n<p>\nNon-ASCII characters are handled transparently by the Lua source code parser.\nThis allows the use of UTF-8 characters in identifiers and strings.\nA UTF-8 BOM is skipped at the start of the source code.\n</p>\n\n<h3 id=\"tostring\"><tt>tostring()</tt> etc. canonicalize NaN and &plusmn;Inf</h3>\n<p>\nAll number-to-string conversions consistently convert non-finite numbers\nto the same strings on all platforms. NaN results in <tt>\"nan\"</tt>,\npositive infinity results in <tt>\"inf\"</tt> and negative infinity results\nin <tt>\"-inf\"</tt>.\n</p>\n\n<h3 id=\"tonumber\"><tt>tonumber()</tt> etc. use builtin string to number conversion</h3>\n<p>\nAll string-to-number conversions consistently convert integer and\nfloating-point inputs in decimal, hexadecimal and binary on all platforms.\n<tt>strtod()</tt> is <em>not</em> used anymore, which avoids numerous\nproblems with poor C library implementations. The builtin conversion\nfunction provides full precision according to the IEEE-754 standard, it\nworks independently of the current locale and it supports hex floating-point\nnumbers (e.g. <tt>0x1.5p-3</tt>).\n</p>\n\n<h3 id=\"string_dump\"><tt>string.dump(f [,strip])</tt> generates portable bytecode</h3>\n<p>\nAn extra argument has been added to <tt>string.dump()</tt>. If set to\n<tt>true</tt>, 'stripped' bytecode without debug information is\ngenerated. This speeds up later bytecode loading and reduces memory\nusage. See also the\n<a href=\"running.html#opt_b\"><tt>-b</tt> command line option</a>.\n</p>\n<p>\nThe generated bytecode is portable and can be loaded on any architecture\nthat LuaJIT supports, independent of word size or endianess. However, the\nbytecode compatibility versions must match. Bytecode stays compatible\nfor dot releases (x.y.0 &rarr; x.y.1), but may change with major or\nminor releases (2.0 &rarr; 2.1) or between any beta release. Foreign\nbytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.\n</p>\n<p>\nNote: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies\na different, incompatible bytecode format for all 64 bit ports. This may be\nrectified in the future.\n</p>\n\n<h3 id=\"table_new\"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>\n<p>\nAn extra library function <tt>table.new()</tt> can be made available via\n<tt>require(\"table.new\")</tt>. This creates a pre-sized table, just like\nthe C API equivalent <tt>lua_createtable()</tt>. This is useful for big\ntables if the final table size is known and automatic table resizing is\ntoo expensive.\n</p>\n\n<h3 id=\"table_clear\"><tt>table.clear(tab)</tt> clears a table</h3>\n<p>\nAn extra library function <tt>table.clear()</tt> can be made available\nvia <tt>require(\"table.clear\")</tt>. This clears all keys and values\nfrom a table, but preserves the allocated array/hash sizes. This is\nuseful when a table, which is linked from multiple places, needs to be\ncleared and/or when recycling a table for use by the same context. This\navoids managing backlinks, saves an allocation and the overhead of\nincremental array/hash part growth.\n</p>\n<p>\nPlease note, this function is meant for very specific situations. In most\ncases it's better to replace the (usually single) link with a new table\nand let the GC do its work.\n</p>\n\n<h3 id=\"math_random\">Enhanced PRNG for <tt>math.random()</tt></h3>\n<p>\nLuaJIT uses a Tausworthe PRNG with period 2^223 to implement\n<tt>math.random()</tt> and <tt>math.randomseed()</tt>. The quality of\nthe PRNG results is much superior compared to the standard Lua\nimplementation, which uses the platform-specific ANSI rand().\n</p>\n<p>\nThe PRNG generates the same sequences from the same seeds on all\nplatforms and makes use of all bits in the seed argument.\n<tt>math.random()</tt> without arguments generates 52 pseudo-random bits\nfor every call. The result is uniformly distributed between 0.0 and 1.0.\nIt's correctly scaled up and rounded for <tt>math.random(n&nbsp;[,m])</tt> to\npreserve uniformity.\n</p>\n<p>\nImportant: Neither this nor any other PRNG based on the simplistic\n<tt>math.random()</tt> API is suitable for cryptographic use.\n</p>\n\n<h3 id=\"io\"><tt>io.*</tt> functions handle 64&nbsp;bit file offsets</h3>\n<p>\nThe file I/O functions in the standard <tt>io.*</tt> library handle\n64&nbsp;bit file offsets. In particular, this means it's possible\nto open files larger than 2&nbsp;Gigabytes and to reposition or obtain\nthe current file position for offsets beyond 2&nbsp;GB\n(<tt>fp:seek()</tt> method).\n</p>\n\n<h3 id=\"debug_meta\"><tt>debug.*</tt> functions identify metamethods</h3>\n<p>\n<tt>debug.getinfo()</tt> and <tt>lua_getinfo()</tt> also return information\nabout invoked metamethods. The <tt>namewhat</tt> field is set to\n<tt>\"metamethod\"</tt> and the <tt>name</tt> field has the name of\nthe corresponding metamethod (e.g. <tt>\"__index\"</tt>).\n</p>\n\n<h2 id=\"resumable\">Fully Resumable VM</h2>\n<p>\nThe LuaJIT VM is fully resumable. This means you can yield from a\ncoroutine even across contexts, where this would not possible with\nthe standard Lua&nbsp;5.1 VM: e.g. you can yield across <tt>pcall()</tt>\nand <tt>xpcall()</tt>, across iterators and across metamethods.\n</p>\n\n<h2 id=\"lua52\">Extensions from Lua 5.2</h2>\n<p>\nLuaJIT supports some language and library extensions from Lua&nbsp;5.2.\nFeatures that are unlikely to break existing code are unconditionally\nenabled:\n</p>\n<ul>\n<li><tt>goto</tt> and <tt>::labels::</tt>.</li>\n<li>Hex escapes <tt>'\\x3F'</tt> and <tt>'\\*'</tt> escape in strings.</li>\n<li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li>\n<li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li>\n<li><tt>loadfile(filename [,mode [,env]])</tt>.</li>\n<li><tt>math.log(x [,base])</tt>.</li>\n<li><tt>string.rep(s, n [,sep])</tt>.</li>\n<li><tt>string.format()</tt>: <tt>%q</tt> reversible.\n<tt>%s</tt> checks <tt>__tostring</tt>.\n<tt>%a</tt> and <tt>\"%A</tt> added.</li>\n<li>String matching pattern <tt>%g</tt> added.</li>\n<li><tt>io.read(\"*L\")</tt>.</li>\n<li><tt>io.lines()</tt> and <tt>file:lines()</tt> process\n<tt>io.read()</tt> options.</li>\n<li><tt>os.exit(status|true|false [,close])</tt>.</li>\n<li><tt>package.searchpath(name, path [, sep [, rep]])</tt>.</li>\n<li><tt>package.loadlib(name, \"*\")</tt>.</li>\n<li><tt>debug.getinfo()</tt> returns <tt>nparams</tt> and <tt>isvararg</tt>\nfor option <tt>\"u\"</tt>.</li>\n<li><tt>debug.getlocal()</tt> accepts function instead of level.</li>\n<li><tt>debug.getlocal()</tt> and <tt>debug.setlocal()</tt> accept negative\nindexes for varargs.</li>\n<li><tt>debug.getupvalue()</tt> and <tt>debug.setupvalue()</tt> handle\nC&nbsp;functions.</li>\n<li><tt>debug.upvalueid()</tt> and <tt>debug.upvaluejoin()</tt>.</li>\n<li>Lua/C API extensions:\n<tt>lua_version()</tt>\n<tt>lua_upvalueid()</tt>\n<tt>lua_upvaluejoin()</tt>\n<tt>lua_loadx()</tt>\n<tt>lua_copy()</tt>\n<tt>lua_tonumberx()</tt>\n<tt>lua_tointegerx()</tt>\n<tt>luaL_fileresult()</tt>\n<tt>luaL_execresult()</tt>\n<tt>luaL_loadfilex()</tt>\n<tt>luaL_loadbufferx()</tt>\n<tt>luaL_traceback()</tt>\n<tt>luaL_setfuncs()</tt>\n<tt>luaL_pushmodule()</tt>\n<tt>luaL_newlibtable()</tt>\n<tt>luaL_newlib()</tt>\n<tt>luaL_testudata()</tt>\n<tt>luaL_setmetatable()</tt>\n</li>\n<li>Command line option <tt>-E</tt>.</li>\n<li>Command line checks <tt>__tostring</tt> for errors.</li>\n</ul>\n<p>\nOther features are only enabled, if LuaJIT is built with\n<tt>-DLUAJIT_ENABLE_LUA52COMPAT</tt>:\n</p>\n<ul>\n<li><tt>goto</tt> is a keyword and not a valid variable name anymore.</li>\n<li><tt>break</tt> can be placed anywhere. Empty statements (<tt>;;</tt>)\nare allowed.</li>\n<li><tt>__lt</tt>, <tt>__le</tt> are invoked for mixed types.</li>\n<li><tt>__len</tt> for tables. <tt>rawlen()</tt> library function.</li>\n<li><tt>pairs()</tt> and <tt>ipairs()</tt> check for <tt>__pairs</tt> and\n<tt>__ipairs</tt>.</li>\n<li><tt>coroutine.running()</tt> returns two results.</li>\n<li><tt>table.pack()</tt> and <tt>table.unpack()</tt>\n(same as <tt>unpack()</tt>).</li>\n<li><tt>io.write()</tt> and <tt>file:write()</tt> return file handle\ninstead of <tt>true</tt>.</li>\n<li><tt>os.execute()</tt> and <tt>pipe:close()</tt> return detailed\nexit status.</li>\n<li><tt>debug.setmetatable()</tt> returns object.</li>\n<li><tt>debug.getuservalue()</tt> and <tt>debug.setuservalue()</tt>.</li>\n<li>Remove <tt>math.mod()</tt>, <tt>string.gfind()</tt>.</li>\n<li><tt>package.searchers</tt>.</li>\n<li><tt>module()</tt> returns the module table.</li>\n</ul>\n<p>\nNote: this provides only partial compatibility with Lua 5.2 at the\nlanguage and Lua library level. LuaJIT is API+ABI-compatible with\nLua&nbsp;5.1, which prevents implementing features that would otherwise\nbreak the Lua/C API and ABI (e.g. <tt>_ENV</tt>).\n</p>\n\n<h2 id=\"lua53\">Extensions from Lua 5.3</h2>\n<p>\nLuaJIT supports some extensions from Lua&nbsp;5.3:\n<ul>\n<li>Unicode escape <tt>'\\u{XX...}'</tt> embeds the UTF-8 encoding in string literals.</li>\n<li>The argument table <tt>arg</tt> can be read (and modified) by <tt>LUA_INIT</tt> and <tt>-e</tt> chunks.</li>\n<li><tt>io.read()</tt> and <tt>file:read()</tt> accept formats with or without a leading <tt>*</tt>.</li>\n<li><tt>assert()</tt> accepts any type of error object.</li>\n<li><tt>table.move(a1, f, e, t [,a2])</tt>.</li>\n<li><tt>coroutine.isyieldable()</tt>.</li>\n<li>Lua/C API extensions:\n<tt>lua_isyieldable()</tt>\n</li>\n</ul>\n\n<h2 id=\"exceptions\">C++ Exception Interoperability</h2>\n<p>\nLuaJIT has built-in support for interoperating with C++&nbsp;exceptions.\nThe available range of features depends on the target platform and\nthe toolchain used to compile LuaJIT:\n</p>\n<table class=\"exc\">\n<tr class=\"exchead\">\n<td class=\"excplatform\">Platform</td>\n<td class=\"exccompiler\">Compiler</td>\n<td class=\"excinterop\">Interoperability</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"excplatform\">External frame unwinding</td>\n<td class=\"exccompiler\">GCC, Clang, MSVC</td>\n<td class=\"excinterop\"><b style=\"color: #00a000;\">Full</b></td>\n</tr>\n<tr class=\"even\">\n<td class=\"excplatform\">Internal frame unwinding + DWARF2</td>\n<td class=\"exccompiler\">GCC, Clang</td>\n<td class=\"excinterop\"><b style=\"color: #c06000;\">Limited</b></td>\n</tr>\n<tr class=\"odd\">\n<td class=\"excplatform\">Windows 64 bit</td>\n<td class=\"exccompiler\">non-MSVC</td>\n<td class=\"excinterop\"><b style=\"color: #c06000;\">Limited</b></td>\n</tr>\n<tr class=\"even\">\n<td class=\"excplatform\">Other platforms</td>\n<td class=\"exccompiler\">Other compilers</td>\n<td class=\"excinterop\"><b style=\"color: #a00000;\">No</b></td>\n</tr>\n</table>\n<p>\n<b style=\"color: #00a000;\">Full interoperability</b> means:\n</p>\n<ul>\n<li>C++&nbsp;exceptions can be caught on the Lua side with <tt>pcall()</tt>,\n<tt>lua_pcall()</tt> etc.</li>\n<li>C++&nbsp;exceptions will be converted to the generic Lua error\n<tt>\"C++&nbsp;exception\"</tt>, unless you use the\n<a href=\"ext_c_api.html#mode_wrapcfunc\">C&nbsp;call wrapper</a> feature.</li>\n<li>It's safe to throw C++&nbsp;exceptions across non-protected Lua frames\non the C&nbsp;stack. The contents of the C++&nbsp;exception object\npass through unmodified.</li>\n<li>Lua errors can be caught on the C++ side with <tt>catch(...)</tt>.\nThe corresponding Lua error message can be retrieved from the Lua stack.<br>\nFor MSVC for Windows 64 bit this requires compilation of your C++ code\nwith <tt>/EHa</tt>.</li>\n<li>Throwing Lua errors across C++ frames is safe. C++ destructors\nwill be called.</li>\n</ul>\n<p>\n<b style=\"color: #c06000;\">Limited interoperability</b> means:\n</p>\n<ul>\n<li>C++&nbsp;exceptions can be caught on the Lua side with <tt>pcall()</tt>,\n<tt>lua_pcall()</tt> etc.</li>\n<li>C++&nbsp;exceptions will be converted to the generic Lua error\n<tt>\"C++&nbsp;exception\"</tt>, unless you use the\n<a href=\"ext_c_api.html#mode_wrapcfunc\">C&nbsp;call wrapper</a> feature.</li>\n<li>C++&nbsp;exceptions will be caught by non-protected Lua frames and\nare rethrown as a generic Lua error. The C++&nbsp;exception object will\nbe destroyed.</li>\n<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>\n<li>Throwing Lua errors across C++ frames will <b>not</b> call\nC++ destructors.</li>\n</ul>\n\n<p>\n<b style=\"color: #a00000;\">No interoperability</b> means:\n</p>\n<ul>\n<li>It's <b>not</b> safe to throw C++&nbsp;exceptions across Lua frames.</li>\n<li>C++&nbsp;exceptions <b>cannot</b> be caught on the Lua side.</li>\n<li>Lua errors <b>cannot</b> be caught on the C++ side.</li>\n<li>Throwing Lua errors across C++ frames will <b>not</b> call\nC++ destructors.</li>\n</ul>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/faq.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Frequently Asked Questions (FAQ)</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ndd { margin-left: 1.5em; }\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Frequently Asked Questions (FAQ)</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a class=\"current\" href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<dl id=\"info\">\n<dt>Q: Where can I learn more about LuaJIT and Lua?</dt>\n<dd>\n<ul style=\"padding: 0;\">\n<li>The <a href=\"https://luajit.org/list.html\"><span class=\"ext\">&raquo;</span>&nbsp;LuaJIT mailing list</a> focuses on topics\nrelated to LuaJIT.</li>\n<li>News about Lua itself can be found at the\n<a href=\"https://www.lua.org/lua-l.html\"><span class=\"ext\">&raquo;</span>&nbsp;Lua mailing list</a>.\nThe mailing list archives are worth checking out for older postings\nabout LuaJIT.</li>\n<li>The <a href=\"https://lua.org\"><span class=\"ext\">&raquo;</span>&nbsp;main Lua.org site</a> has complete\n<a href=\"https://www.lua.org/docs.html\"><span class=\"ext\">&raquo;</span>&nbsp;documentation</a> of the language\nand links to books and papers about Lua.</li>\n<li>The community-managed <a href=\"http://lua-users.org/wiki/\"><span class=\"ext\">&raquo;</span>&nbsp;Lua Wiki</a>\nhas information about diverse topics.</li>\n</ul></dd>\n</dl>\n\n<dl id=\"tech\">\n<dt>Q: Where can I learn more about the compiler technology used by LuaJIT?</dt>\n<dd>\nPlease use the following Google Scholar searches to find relevant papers:<br>\nSearch for: <a href=\"https://scholar.google.com/scholar?q=Trace+Compiler\"><span class=\"ext\">&raquo;</span>&nbsp;Trace Compiler</a><br>\nSearch for: <a href=\"https://scholar.google.com/scholar?q=JIT+Compiler\"><span class=\"ext\">&raquo;</span>&nbsp;JIT Compiler</a><br>\nSearch for: <a href=\"https://scholar.google.com/scholar?q=Dynamic+Language+Optimizations\"><span class=\"ext\">&raquo;</span>&nbsp;Dynamic Language Optimizations</a><br>\nSearch for: <a href=\"https://scholar.google.com/scholar?q=SSA+Form\"><span class=\"ext\">&raquo;</span>&nbsp;SSA Form</a><br>\nSearch for: <a href=\"https://scholar.google.com/scholar?q=Linear+Scan+Register+Allocation\"><span class=\"ext\">&raquo;</span>&nbsp;Linear Scan Register Allocation</a><br>\nHere is a list of the <a href=\"http://lua-users.org/lists/lua-l/2009-11/msg00089.html\"><span class=\"ext\">&raquo;</span>&nbsp;innovative features in LuaJIT</a>.<br>\nAnd, you know, reading the source is of course the only way to enlightenment.\n</dd>\n</dl>\n\n<dl id=\"arg\">\n<dt>Q: Why do I get this error: \"attempt to index global 'arg' (a nil value)\"?<br>\nQ: My vararg functions fail after switching to LuaJIT!</dt>\n<dd>LuaJIT is compatible to the Lua 5.1 language standard. It doesn't\nsupport the implicit <tt>arg</tt> parameter for old-style vararg\nfunctions from Lua 5.0.<br>Please convert your code to the\n<a href=\"https://www.lua.org/manual/5.1/manual.html#2.5.9\"><span class=\"ext\">&raquo;</span>&nbsp;Lua 5.1\nvararg syntax</a>.</dd>\n</dl>\n\n<dl id=\"x87\">\n<dt>Q: Why do I get this error: \"bad FPU precision\"?<br>\n<dt>Q: I get weird behavior after initializing Direct3D.<br>\n<dt>Q: Some FPU operations crash after I load a Delphi DLL.<br>\n</dt>\n<dd>\n\nDirectX/Direct3D (up to version 9) sets the x87 FPU to single-precision\nmode by default. This violates the Windows ABI and interferes with the\noperation of many programs &mdash; LuaJIT is affected, too. Please make\nsure you always use the <tt>D3DCREATE_FPU_PRESERVE</tt> flag when\ninitializing Direct3D.<br>\n\nDirect3D version 10 or higher do not show this behavior anymore.\nConsider testing your application with older versions, too.<br>\n\nSimilarly, the Borland/Delphi runtime modifies the FPU control word and\nenables FP exceptions. Of course, this violates the Windows ABI, too.\nPlease check the Delphi docs for the Set8087CW method.</dd>\n</dl>\n\n<dl id=\"ctrlc\">\n<dt>Q: Sometimes Ctrl-C fails to stop my Lua program. Why?</dt>\n<dd>The interrupt signal handler sets a Lua debug hook. But this is\nignored by compiled code. If your program is running in a tight loop\nand never falls back to the interpreter, the debug hook never runs and\ncan't throw the \"interrupted!\" error.<br>\nYou have to press Ctrl-C twice to stop your program. That's similar\nto when it's stuck running inside a C function under the Lua interpreter.</dd>\n</dl>\n\n<dl id=\"order\">\n<dt>Q: Table iteration with <tt>pairs()</tt> does not result in the same order?</dt>\n<dd>The order of table iteration is explicitly <b>undefined</b> by\nthe Lua language standard.<br>\nDifferent Lua implementations or versions may use different orders for\notherwise identical tables. Different ways of constructing a table may\nresult in different orders, too.<br>\nDue to improved VM security, LuaJIT 2.1 may even use a different order\non separate VM invocations or when string keys are newly interned.<br><br>\nIf your program relies on a deterministic order, it has a bug. Rewrite it,\nso it doesn't rely on the key order. Or sort the table keys, if you must.</dd>\n</dl>\n\n<dl id=\"sandbox\">\n<dt>Q: Can Lua code be safely sandboxed?</dt>\n<dd>\nMaybe for an extremely restricted subset of Lua and if you relentlessly\nscrutinize every single interface function you offer to the untrusted code.<br>\n\nAlthough Lua provides some sandboxing functionality (<tt>setfenv()</tt>, hooks),\nit's very hard to get this right even for the Lua core libraries. Of course,\nyou'll need to inspect any extension library, too. And there are libraries\nthat are inherently unsafe, e.g. the <a href=\"ext_ffi.html\">FFI library</a>.<br>\n\nMore reading material at the <a href=\"http://lua-users.org/wiki/SandBoxes\"><span class=\"ext\">&raquo;</span>&nbsp;Lua Wiki</a> and <a href=\"https://en.wikipedia.org/wiki/Sandbox_(computer_security)\"><span class=\"ext\">&raquo;</span>&nbsp;Wikipedia</a>.<br><br>\n\nRelatedly, <b>loading untrusted bytecode is not safe!</b><br>\n\nIt's trivial to crash the Lua or LuaJIT VM with maliciously crafted bytecode.\nThis is well known and there's no bytecode verification on purpose, so please\ndon't report a bug about it. Check the <tt>mode</tt> parameter for the\n<tt>load*()</tt> functions to disable loading of bytecode.<br><br>\n\n<b>In general, the only promising approach is to sandbox Lua code at the\nprocess level and not the VM level.</b>\n</dd>\n</dl>\n\n<dl id=\"arch\">\n<dt>Q: Lua runs everywhere. Why doesn't LuaJIT support my CPU?</dt>\n<dd>Because it's a compiler &mdash; it needs to generate native\nmachine code. This means the code generator must be ported to each\narchitecture. And the fast interpreter is written in assembler and\nmust be ported, too. This is quite an undertaking.<br>\nThe <a href=\"install.html\">install documentation</a> shows the supported\narchitectures.<br>\nOther architectures may follow based on sufficient user demand and\nmarket-relevance of the architecture. Sponsoring is required to develop\nthe port itself, to integrate it and to continuously maintain it in the\nactively developed branches.</dd>\n</dl>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/install.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Installation</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ntable.compat {\n  line-height: 1.2;\n  font-size: 80%;\n}\ntable.compat td {\n  border: 1px solid #bfcfff;\n  height: 1.5em;\n}\ntable.compat tr.compathead td {\n  font-weight: bold;\n  border-bottom: 2px solid #bfcfff;\n}\ntd.compatname, td.compatver {\n  width: 10%;\n}\ntd.compatbits {\n  width: 5%;\n}\ntd.compatx {\n  width: 21%;\n}\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Installation</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a class=\"current\" href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nLuaJIT is only distributed as a source package. This page explains\nhow to build and install LuaJIT with different operating systems\nand C&nbsp;compilers.\n</p>\n<p>\nFor the impatient (on POSIX systems):\n</p>\n<pre class=\"code\">\nmake &amp;&amp; sudo make install\n</pre>\n\n<h2 id=\"req\">Requirements</h2>\n<h3 id=\"systems\">Systems</h3>\n<p>\nLuaJIT currently builds out-of-the box on most systems:\n</p>\n<table class=\"compat\">\n<tr class=\"compathead\">\n<td class=\"compatname\">OS</td>\n<td class=\"compatver\">Min. Version</td>\n<td class=\"compatx\">Requirements</td>\n<td class=\"compatx\">LuaJIT Versions</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"compatname\"><a href=\"#windows\">Windows</a></td>\n<td class=\"compatver\">7</td>\n<td class=\"compatx\">x86 or x64, ARM64: TBA</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><a href=\"#posix\">Linux</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><a href=\"#posix\">*BSD</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><a href=\"#posix\">macOS (OSX)</a></td>\n<td class=\"compatver\">10.4</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><a href=\"#posix\">POSIX</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">mmap, dlopen</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even separate\">\n<td class=\"compatname\"><a href=\"#android\">Android</a></td>\n<td class=\"compatver\">4.0</td>\n<td class=\"compatx\">Recent Android NDK</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><a href=\"#ios\">iOS</a></td>\n<td class=\"compatver\">3.0</td>\n<td class=\"compatx\">Xcode iOS SDK</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n<tr class=\"even separate\">\n<td class=\"compatname\"><a href=\"#consoles\">PS3</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">PS3 SDK</td>\n<td class=\"compatx\">v2.0 &ndash; v2.1 EOL</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><a href=\"#consoles\">PS4</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">PS4 SDK (ORBIS)</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><a href=\"#consoles\">PS5</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">PS5 SDK (PROSPERO)</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><a href=\"#consoles\">PS Vita</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">PS Vita SDK (PSP2)</td>\n<td class=\"compatx\">v2.0 &ndash; v2.1 EOL</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><a href=\"#consoles\">Xbox 360</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">Xbox 360 SDK (XEDK)</td>\n<td class=\"compatx\">v2.0 &ndash; v2.1 EOL</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><a href=\"#consoles\">Xbox One</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">Xbox One SDK (DURANGO)</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><a href=\"#consoles\">Nintendo Switch</a></td>\n<td class=\"compatver\">&nbsp;</td>\n<td class=\"compatx\">NintendoSDK + NX Addon</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n</table>\n<p>\nThe codebase has compatibility defines for some more systems, but\nwithout official support.\n</p>\n<h3 id=\"toolchains\">Toolchains</h3>\n<p>\nBuilding LuaJIT requires a recent toolchain based on GCC, Clang/LLVM or\nMSVC++.\n</p>\n<p>\nThe Makefile-based build system requires GNU Make and supports\ncross-builds. Batch files are provided for MSVC++ builds and console\ncross-builds.\n</p>\n<h3 id=\"architectures\">CPU Architectures</h3>\n<table class=\"compat\">\n<tr class=\"compathead\">\n<td class=\"compatname\">CPU</td>\n<td class=\"compatbits\">Bits</td>\n<td class=\"compatx\">Requirements</td>\n<td class=\"compatx\">Variants</td>\n<td class=\"compatx\">LuaJIT Versions</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"compatname\">x86</td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\">v2.1+: SSE2</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\">x64</td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\">ARM</td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\">ARMv5+, ARM9E+</td>\n<td class=\"compatx\">hard-fp + soft-fp</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\">ARM64</td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">ARM64le + ARM64be</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\">PPC32</td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">hard-fp + soft-fp</td>\n<td class=\"compatx\">v2.0 &ndash; v2.1 EOL</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\">PPC/e500</td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\">e500v2</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">v2.0 EOL</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\">MIPS32</td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\">MIPS32r1 &ndash; r5</td>\n<td class=\"compatx\">hard-fp + soft-fp</td>\n<td class=\"compatx\">v2.0 &ndash;</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\">MIPS64</td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\">MIPS64r1 &ndash; r5</td>\n<td class=\"compatx\">hard-fp + soft-fp</td>\n<td class=\"compatx\">v2.1 &ndash;</td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\">MIPS64</td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\">MIPS64r6</td>\n<td class=\"compatx\">hard-fp + soft-fp</td>\n<td class=\"compatx\">v2.1 EOL</td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\">RISC-V</td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\">RVA22+</td>\n<td class=\"compatx\">&nbsp;</td>\n<td class=\"compatx\">TBA</td>\n</tr>\n</table>\n<p>\nThere are no plans to add historic architectures or to continue support\nfor end-of-life (EOL) architectures, for which no new CPUs are commonly\navailable anymore. Likewise, there are no plans to support marginal\nand/or de-facto-dead architectures.\n</p>\n\n<h2>Configuring LuaJIT</h2>\n<p>\nThe standard configuration should work fine for most installations.\nUsually there is no need to tweak the settings. The following files\nhold all user-configurable settings:\n</p>\n<ul>\n<li><tt>src/luaconf.h</tt> sets some configuration variables.</li>\n<li><tt>Makefile</tt> has settings for <b>installing</b> LuaJIT (POSIX\nonly).</li>\n<li><tt>src/Makefile</tt> has settings for <b>compiling</b> LuaJIT\nunder POSIX, MinGW or Cygwin.</li>\n<li><tt>src/msvcbuild.bat</tt> has settings for compiling LuaJIT with\nMSVC (Visual Studio).</li>\n</ul>\n<p>\nPlease read the instructions given in these files, before changing\nany settings.\n</p>\n<p>\nAll LuaJIT 64 bit ports use 64 bit GC objects by default (<tt>LJ_GC64</tt>).\nFor x64, you can select the old 32-on-64 bit mode by adding\n<tt>XCFLAGS=-DLUAJIT_DISABLE_GC64</tt> to the make command.\nPlease check the note about the\n<a href=\"extensions.html#string_dump\">bytecode format</a> differences, too.\n</p>\n\n<h2 id=\"posix\">POSIX Systems (Linux, macOS, *BSD etc.)</h2>\n<h3>Prerequisites</h3>\n<p>\nDepending on your distribution, you may need to install a package for\nGCC, the development headers and/or a complete SDK. E.g. on a current\nDebian/Ubuntu, install <tt>libc6-dev</tt> with the package manager.\n</p>\n<p>\nThe recommended way to fetch the latest version is to do a pull from\nthe git repository.\n</p>\n<p>\nAlternatively, download the latest source package of LuaJIT (pick the .tar.gz).\nMove it to a directory of your choice, open a terminal window and change\nto this directory. Now unpack the archive and change to the newly created\ndirectory (replace XX.YY.ZZ with the version you downloaded):\n</p>\n<pre class=\"code\">\ntar zxf LuaJIT-XX.YY.ZZ.tar.gz\ncd LuaJIT-XX.YY.ZZ\n</pre>\n<h3>Building LuaJIT</h3>\n<p>\nThe supplied Makefiles try to auto-detect the settings needed for your\noperating system and your compiler. They need to be run with GNU Make,\nwhich is probably the default on your system, anyway. Simply run:\n</p>\n<pre class=\"code\">\nmake\n</pre>\n<p>\nThis always builds a native binary, depending on the host OS\nyou're running this command on. Check the section on\n<a href=\"#cross\">cross-compilation</a> for more options.\n</p>\n<p>\nBy default, modules are only searched under the prefix <tt>/usr/local</tt>.\nYou can add an extra prefix to the search paths by appending the\n<tt>PREFIX</tt> option, e.g.:\n</p>\n<pre class=\"code\">\nmake PREFIX=/home/myself/lj2\n</pre>\n<p>\nNote for macOS: you <b>must</b> set the <tt>MACOSX_DEPLOYMENT_TARGET</tt>\nenvironment variable to a value supported by your toolchain:\n</p>\n<pre class=\"code\">\nMACOSX_DEPLOYMENT_TARGET=XX.YY make\n</pre>\n<h3>Installing LuaJIT</h3>\n<p>\nThe top-level Makefile installs LuaJIT by default under\n<tt>/usr/local</tt>, i.e. the executable ends up in\n<tt>/usr/local/bin</tt> and so on. You need root privileges\nto write to this path. So, assuming sudo is installed on your system,\nrun the following command and enter your sudo password:\n</p>\n<pre class=\"code\">\nsudo make install\n</pre>\n<p>\nOtherwise specify the directory prefix as an absolute path, e.g.:\n</p>\n<pre class=\"code\">\nmake install PREFIX=/home/myself/lj2\n</pre>\n<p>\nObviously the prefixes given during build and installation need to be the same.\n</p>\n\n<h2 id=\"windows\">Windows Systems</h2>\n<h3>Prerequisites</h3>\n<p>\nEither install one of the open source SDKs\n(<a href=\"http://mingw.org/\"><span class=\"ext\">&raquo;</span>&nbsp;MinGW</a> or\n<a href=\"https://www.cygwin.com/\"><span class=\"ext\">&raquo;</span>&nbsp;Cygwin</a>), which come with a modified\nGCC plus the required development headers.\nOr install Microsoft's Visual Studio (MSVC).\n</p>\n<p>\nNext, pull from the git repository or download the source package and\nunpack it using an archive manager (e.g. the Windows Explorer) to\na directory of your choice.\n</p>\n<h3>Building with MSVC</h3>\n<p>\nOpen a \"Visual Studio Command Prompt\" (either x86 or x64), <tt>cd</tt> to the\ndirectory where you've unpacked the sources and run these commands:\n</p>\n<pre class=\"code\">\ncd src\nmsvcbuild\n</pre>\n<p>\nCheck the <tt>msvcbuild.bat</tt> file for more options.\nThen follow the installation instructions below.\n</p>\n<h3>Building with MinGW or Cygwin</h3>\n<p>\nOpen a command prompt window and make sure the MinGW or Cygwin programs\nare in your path. Then <tt>cd</tt> to the directory of the git repository\nor where you've unpacked the sources. Then run this command for MinGW:\n</p>\n<pre class=\"code\">\nmingw32-make\n</pre>\n<p>\nOr this command for Cygwin:\n</p>\n<pre class=\"code\">\nmake\n</pre>\n<p>\nThen follow the installation instructions below.\n</p>\n<h3>Installing LuaJIT</h3>\n<p>\nCopy <tt>luajit.exe</tt> and <tt>lua51.dll</tt> (built in the <tt>src</tt>\ndirectory) to a newly created directory (any location is ok).\nAdd <tt>lua</tt> and <tt>lua\\jit</tt> directories below it and copy\nall Lua files from the <tt>src\\jit</tt> directory of the distribution\nto the latter directory.\n</p>\n<p>\nThere are no hardcoded\nabsolute path names &mdash; all modules are loaded relative to the\ndirectory where <tt>luajit.exe</tt> is installed\n(see <tt>src/luaconf.h</tt>).\n</p>\n\n<h2 id=\"cross\">Cross-compiling LuaJIT</h2>\n<p>\nFirst, let's clear up some terminology:\n</p>\n<ul>\n<li>Host: This is your development system, usually based on a x64 or x86 CPU.</li>\n<li>Target: This is the target system you want LuaJIT to run on, e.g. Android/ARM.</li>\n<li>Toolchain: This comprises a C compiler, linker, assembler and a matching C library.</li>\n<li>Host (or system) toolchain: This is the toolchain used to build native binaries for your host system.</li>\n<li>Cross-compile toolchain: This is the toolchain used to build binaries for the target system. They can only be run on the target system.</li>\n</ul>\n<p>\nThe GNU Makefile-based build system allows cross-compiling on any host\nfor any supported target:\n</p>\n<ul>\n<li>Yes, you need a toolchain for both your host <em>and</em> your target!</li>\n<li>Both host and target architectures must have the same pointer size.</li>\n<li>E.g. if you want to cross-compile to a 32 bit target on a 64 bit host, you need to install the multilib development package (e.g. <tt>libc6-dev-i386</tt> on Debian/Ubuntu) and build a 32 bit host part (<tt>HOST_CC=\"gcc -m32\"</tt>).</li>\n<li>64 bit targets always require compilation on a 64 bit host.</li>\n</ul>\n<p>\nYou need to specify <tt>TARGET_SYS</tt> whenever the host OS and the\ntarget OS differ, or you'll get assembler or linker errors:\n</p>\n<ul>\n<li>E.g. if you're compiling on a Windows or macOS host for embedded Linux or Android, you need to add <tt>TARGET_SYS=Linux</tt> to the examples below.</li>\n<li>For a minimal target OS, you may need to disable the built-in allocator in <tt>src/Makefile</tt> and use <tt>TARGET_SYS=Other</tt>.</li>\n<li>Don't forget to specify the same <tt>TARGET_SYS</tt> for the install step, too.</li>\n</ul>\n<p>\nHere are some examples where host and target have the same CPU:\n</p>\n<pre class=\"code\">\n# Cross-compile to a 32 bit binary on a multilib x64 OS\nmake CC=\"gcc -m32\"\n\n# Cross-compile on Debian/Ubuntu for Windows (mingw32 package)\nmake HOST_CC=\"gcc -m32\" CROSS=i586-mingw32msvc- TARGET_SYS=Windows\n</pre>\n<p id=\"cross2\">\nThe <tt>CROSS</tt> prefix allows specifying a standard GNU cross-compile\ntoolchain (Binutils, GCC and a matching libc). The prefix may vary\ndepending on the <tt>--target</tt> the toolchain was built for (note the\n<tt>CROSS</tt> prefix has a trailing <tt>\"-\"</tt>). The examples below\nuse the canonical toolchain triplets for Linux.\n</p>\n<p>\nSince there's often no easy way to detect CPU features at runtime, it's\nimportant to compile with the proper CPU or architecture settings:\n</o>\n<ul>\n<li>The best way to get consistent results is to specify the correct settings when building the toolchain yourself.</li>\n<li>For a pre-built, generic toolchain add <tt>-mcpu=...</tt> or <tt>-march=...</tt> and other necessary flags to <tt>TARGET_CFLAGS</tt>.</li>\n<li>For ARM it's important to have the correct <tt>-mfloat-abi=...</tt> setting, too. Otherwise LuaJIT may not run at the full performance of your target CPU.</li>\n<li>For MIPS it's important to select a supported ABI (o32 on MIPS32, n64 on MIPS64) and consistently compile your project either with hard-float or soft-float compiler settings.</li>\n</ul>\n<p>\nHere are some examples for targets with a different CPU than the host:\n</p>\n<pre class=\"code\">\n# ARM soft-float\nmake HOST_CC=\"gcc -m32\" CROSS=arm-linux-gnueabi- \\\n     TARGET_CFLAGS=\"-mfloat-abi=soft\"\n\n# ARM soft-float ABI with VFP (example for Cortex-A9)\nmake HOST_CC=\"gcc -m32\" CROSS=arm-linux-gnueabi- \\\n     TARGET_CFLAGS=\"-mcpu=cortex-a9 -mfloat-abi=softfp\"\n\n# ARM hard-float ABI with VFP (armhf, most modern toolchains)\nmake HOST_CC=\"gcc -m32\" CROSS=arm-linux-gnueabihf-\n\n# ARM64\nmake CROSS=aarch64-linux-\n\n# PPC\nmake HOST_CC=\"gcc -m32\" CROSS=powerpc-linux-gnu-\n\n# MIPS32 big-endian\nmake HOST_CC=\"gcc -m32\" CROSS=mips-linux-\n# MIPS32 little-endian\nmake HOST_CC=\"gcc -m32\" CROSS=mipsel-linux-\n\n# MIPS64 big-endian\nmake CROSS=mips-linux- TARGET_CFLAGS=\"-mips64r2 -mabi=64\"\n# MIPS64 little-endian\nmake CROSS=mipsel-linux- TARGET_CFLAGS=\"-mips64r2 -mabi=64\"\n</pre>\n<p>\nYou can cross-compile for <b id=\"android\">Android</b> using the <a href=\"https://developer.android.com/ndk/\"><span class=\"ext\">&raquo;</span>&nbsp;Android NDK</a>.\nPlease adapt the environment variables to match the install locations and the\ndesired target platform. E.g. Android&nbsp;4.1 corresponds to ABI level&nbsp;16.\n</p>\n<pre class=\"code\">\n# Android/ARM64, aarch64, Android 5.0+ (L)\nNDKDIR=/opt/android/ndk\nNDKBIN=$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin\nNDKCROSS=$NDKBIN/aarch64-linux-android-\nNDKCC=$NDKBIN/aarch64-linux-android21-clang\nmake CROSS=$NDKCROSS \\\n     STATIC_CC=$NDKCC DYNAMIC_CC=\"$NDKCC -fPIC\" \\\n     TARGET_LD=$NDKCC TARGET_AR=\"$NDKBIN/llvm-ar rcus\" \\\n     TARGET_STRIP=$NDKBIN/llvm-strip\n\n# Android/ARM, armeabi-v7a (ARMv7 VFP), Android 4.1+ (JB)\nNDKDIR=/opt/android/ndk\nNDKBIN=$NDKDIR/toolchains/llvm/prebuilt/linux-x86_64/bin\nNDKCROSS=$NDKBIN/arm-linux-androideabi-\nNDKCC=$NDKBIN/armv7a-linux-androideabi16-clang\nmake HOST_CC=\"gcc -m32\" CROSS=$NDKCROSS \\\n     STATIC_CC=$NDKCC DYNAMIC_CC=\"$NDKCC -fPIC\" \\\n     TARGET_LD=$NDKCC TARGET_AR=\"$NDKBIN/llvm-ar rcus\" \\\n     TARGET_STRIP=$NDKBIN/llvm-strip\n</pre>\n<p>\nYou can cross-compile for <b id=\"ios\">iOS 3.0+</b> (iPhone/iPad) using the <a href=\"https://developer.apple.com/ios/\"><span class=\"ext\">&raquo;</span>&nbsp;iOS SDK</a>:\n</p>\n<p style=\"font-size: 8pt;\">\nNote: <b>the JIT compiler is disabled for iOS</b>, because regular iOS Apps\nare not allowed to generate code at runtime. You'll only get the performance\nof the LuaJIT interpreter on iOS. This is still faster than plain Lua, but\nmuch slower than the JIT compiler. Please complain to Apple, not me.\nOr use Android. :-p\n</p>\n<pre class=\"code\">\n# iOS/ARM64\nISDKP=$(xcrun --sdk iphoneos --show-sdk-path)\nICC=$(xcrun --sdk iphoneos --find clang)\nISDKF=\"-arch arm64 -isysroot $ISDKP\"\nmake DEFAULT_CC=clang CROSS=\"$(dirname $ICC)/\" \\\n     TARGET_FLAGS=\"$ISDKF\" TARGET_SYS=iOS\n</pre>\n\n<h3 id=\"consoles\">Cross-compiling for consoles</h3>\n<p>\nBuilding LuaJIT for consoles requires both a supported host compiler\n(x86 or x64) and a cross-compiler from the official console SDK.\n</p>\n<p>\nDue to restrictions on consoles, the JIT compiler is disabled and only\nthe fast interpreter is built. This is still faster than plain Lua,\nbut much slower than the JIT compiler. The FFI is disabled, too, since\nit's not very useful in such an environment.\n</p>\n<p>\nThe following commands build a static library <tt>libluajit.a</tt>,\nwhich can be linked against your game, just like the Lua library.\n</p>\n<p>\nTo cross-compile for <b id=\"ps3\">PS3</b> from a Linux host (requires\n32&nbsp;bit GCC, i.e. multilib Linux/x64) or a Windows host (requires\n32&nbsp;bit MinGW), run this command:\n</p>\n<pre class=\"code\">\nmake HOST_CC=\"gcc -m32\" CROSS=ppu-lv2-\n</pre>\n<p>\nTo cross-compile for the other consoles from a Windows host, open a\n\"Native Tools Command Prompt for VS\". You need to choose either the 32\nor the 64&nbsp;bit version of the host compiler to match the target.\nThen <tt>cd</tt> to the <tt>src</tt> directory below where you've\nunpacked the sources and run the build command given in the table:\n</p>\n<table class=\"compat\">\n<tr class=\"compathead\">\n<td class=\"compatname\">Console</td>\n<td class=\"compatbits\">Bits</td>\n<td class=\"compatx\">Build Command</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"compatname\"><b id=\"ps4\">PS4</b></td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\"><tt>ps4build</tt></td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><b id=\"ps5\">PS5</b></td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\"><tt>ps5build</tt></td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><b id=\"psvita\">PS Vita</b></td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\"><tt>psvitabuild</tt></td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><b id=\"xbox360\">Xbox 360</b></td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\"><tt>xedkbuild</tt></td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><b id=\"xboxone\">Xbox One</b></td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\"><tt>xb1build</tt></td>\n</tr>\n<tr class=\"even\">\n<td class=\"compatname\"><b id=\"nx32\">Nintendo Switch NX32</b></td>\n<td class=\"compatbits\">32</td>\n<td class=\"compatx\"><tt>nxbuild</tt></td>\n</tr>\n<tr class=\"odd\">\n<td class=\"compatname\"><b id=\"nx64\">Nintendo Switch NX64</b></td>\n<td class=\"compatbits\">64</td>\n<td class=\"compatx\"><tt>nxbuild</tt></td>\n</tr>\n</table>\n<p>\nPlease check out the comments in the corresponding <tt>*.bat</tt>\nfile for more options.\n</p>\n\n<h2 id=\"embed\">Embedding LuaJIT</h2>\n<p>\nLuaJIT is API-compatible with Lua 5.1. If you've already embedded Lua\ninto your application, you probably don't need to do anything to switch\nto LuaJIT, except link with a different library:\n</p>\n<ul>\n<li>It's strongly suggested to build LuaJIT separately using the supplied\nbuild system. Please do <em>not</em> attempt to integrate the individual\nsource files into your build tree. You'll most likely get the internal build\ndependencies wrong or mess up the compiler flags. Treat LuaJIT like any\nother external library and link your application with either the dynamic\nor static library, depending on your needs.</li>\n<li>If you want to load C modules compiled for plain Lua\nwith <tt>require()</tt>, you need to make sure the public symbols\n(e.g. <tt>lua_pushnumber</tt>) are exported, too:\n<ul><li>On POSIX systems you can either link to the shared library\nor link the static library into your application. In the latter case\nyou'll need to export all public symbols from your main executable\n(e.g. <tt>-Wl,-E</tt> on Linux) and add the external dependencies\n(e.g. <tt>-lm -ldl</tt> on Linux).</li>\n<li>Since Windows symbols are bound to a specific DLL name, you need to\nlink to the <tt>lua51.dll</tt> created by the LuaJIT build (do not rename\nthe DLL). You may link LuaJIT statically on Windows only if you don't\nintend to load Lua/C modules at runtime.\n</li></ul>\n</li>\n</ul>\n<p>Additional hints for initializing LuaJIT using the C API functions:</p>\n<ul>\n<li>Here's a\n<a href=\"http://lua-users.org/wiki/SimpleLuaApiExample\"><span class=\"ext\">&raquo;</span>&nbsp;simple example</a>\nfor embedding Lua or LuaJIT into your application.</li>\n<li>Make sure you use <tt>luaL_newstate</tt>. Avoid using\n<tt>lua_newstate</tt>, since this uses the (slower) default memory\nallocator from your system (no support for this on 64&nbsp;bit architectures).</li>\n<li>Make sure you use <tt>luaL_openlibs</tt> and not the old Lua 5.0 style\nof calling <tt>luaopen_base</tt> etc. directly.</li>\n<li>To change or extend the list of standard libraries to load, copy\n<tt>src/lib_init.c</tt> to your project and modify it accordingly.\nMake sure the <tt>jit</tt> library is loaded, or the JIT compiler\nwill not be activated.</li>\n<li>The <tt>bit.*</tt> module for bitwise operations\nis already built-in. There's no need to statically link\n<a href=\"https://bitop.luajit.org/\"><span class=\"ext\">&raquo;</span>&nbsp;Lua BitOp</a> to your application.</li>\n</ul>\n\n<h2 id=\"distro\">Hints for Distribution Maintainers</h2>\n<p>\nThe LuaJIT build system has extra provisions for the needs of most\nPOSIX-based distributions. If you're a package maintainer for\na distribution, <em>please</em> make use of these features and\navoid patching, subverting, autotoolizing or messing up the build system\nin unspeakable ways.\n</p>\n<p>\nThere should be absolutely no need to patch <tt>luaconf.h</tt> or any\nof the Makefiles. And please do not hand-pick files for your packages &mdash;\nsimply use whatever <tt>make install</tt> creates. There's a reason\nfor all the files <em>and</em> directories it creates.\n</p>\n<p>\nThe build system uses GNU make and auto-detects most settings based on\nthe host you're building it on. This should work fine for native builds,\neven when sandboxed. You may need to pass some of the following flags to\n<em>both</em> the <tt>make</tt> and the <tt>make install</tt> command lines\nfor a regular distribution build:\n</p>\n<ul>\n<li><tt>PREFIX</tt> overrides the installation path and should usually\nbe set to <tt>/usr</tt>. Setting this also changes the module paths and\nthe paths needed to locate the shared library.</li>\n<li><tt>DESTDIR</tt> is an absolute path which allows you to install\nto a shadow tree instead of the root tree of the build system.</li>\n<li><tt>MULTILIB</tt> sets the architecture-specific library path component\nfor multilib systems. The default is <tt>lib</tt>.</li>\n<li>Have a look at the top-level <tt>Makefile</tt> and <tt>src/Makefile</tt>\nfor additional variables to tweak. The following variables <em>may</em> be\noverridden, but it's <em>not</em> recommended, except for special needs\nlike cross-builds:\n<tt>BUILDMODE, CC, HOST_CC, STATIC_CC, DYNAMIC_CC, CFLAGS, HOST_CFLAGS,\nTARGET_CFLAGS, LDFLAGS, HOST_LDFLAGS, TARGET_LDFLAGS, TARGET_SHLDFLAGS,\nTARGET_FLAGS, LIBS, HOST_LIBS, TARGET_LIBS, CROSS, HOST_SYS, TARGET_SYS\n</tt></li>\n</ul>\n<p>\nThe build system has a special target for an amalgamated build, i.e.\n<tt>make amalg</tt>. This compiles the LuaJIT core as one huge C file\nand allows GCC to generate faster and shorter code. Alas, this requires\nlots of memory during the build. This may be a problem for some users,\nthat's why it's not enabled by default. But it shouldn't be a problem for\nmost build farms. It's recommended that binary distributions use this\ntarget for their LuaJIT builds.\n</p>\n<p>\nThe tl;dr version of the above:\n</p>\n<pre class=\"code\">\nmake amalg PREFIX=/usr && \\\nmake install PREFIX=/usr DESTDIR=/tmp/buildroot\n</pre>\n<p>\nFinally, if you encounter any difficulties, please\n<a href=\"contact.html\">contact me</a> first, instead of releasing a broken\npackage onto unsuspecting users. Because they'll usually gonna complain\nto me (the upstream) and not you (the package maintainer), anyway.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/luajit.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>LuaJIT</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<meta name=\"description\" content=\"LuaJIT is a Just-In-Time (JIT) compiler for the Lua language.\">\n<style type=\"text/css\">\ntable.feature {\n  width: inherit;\n  line-height: 1.2;\n  margin: 0;\n}\ntable.feature td {\n  width: 80px;\n  height: 40px;\n  vertical-align: middle;\n  text-align: center;\n  font-weight: bold;\n  border: 4px solid #e6ecff;\n  border-radius: 12px;\n}\ntable.os td {\n  background: #7080d0;\n  background-image: linear-gradient(#4060c0 10%, #b0b0ff 95%);\n  background-image: -moz-linear-gradient(#4060c0 10%, #b0b0ff 95%);\n  background-image: -webkit-linear-gradient(#4060c0 10%, #b0b0ff 95%);\n  background-image: -o-linear-gradient(#4060c0 10%, #b0b0ff 95%);\n  background-image: -ms-linear-gradient(#4060c0 10%, #b0b0ff 95%);\n}\ntable.os1 td {\n  color: #ffff80;\n}\ntable.os2 td {\n  color: #ffa040;\n}\ntable.os3 td {\n  color: #40ffff;\n}\ntable.compiler td {\n  color: #2080ff;\n  background: #62bf41;\n  background-image: linear-gradient(#62bf41 10%, #b0ffb0 95%);\n  background-image: -moz-linear-gradient(#62bf41 10%, #b0ffb0 95%);\n  background-image: -webkit-linear-gradient(#62bf41 10%, #b0ffb0 95%);\n  background-image: -o-linear-gradient(#62bf41 10%, #b0ffb0 95%);\n  background-image: -ms-linear-gradient(#62bf41 10%, #b0ffb0 95%);\n}\ntable.cpu td {\n  color: #ffff00;\n  background: #cf7251;\n  background-image: linear-gradient(#bf6241 10%, #ffb0b0 95%);\n  background-image: -moz-linear-gradient(#bf6241 10%, #ffb0b0 95%);\n  background-image: -webkit-linear-gradient(#bf6241 10%, #ffb0b0 95%);\n  background-image: -o-linear-gradient(#bf6241 10%, #ffb0b0 95%);\n  background-image: -ms-linear-gradient(#bf6241 10%, #ffb0b0 95%);\n}\ntable.fcompat td {\n  color: #2060e0;\n  background: #61cfcf;\n  background-image: linear-gradient(#41bfbf 10%, #b0ffff 95%);\n  background-image: -moz-linear-gradient(#41bfbf 10%, #b0ffff 95%);\n  background-image: -webkit-linear-gradient(#41bfbf 10%, #b0ffff 95%);\n  background-image: -o-linear-gradient(#41bfbf 10%, #b0ffff 95%);\n  background-image: -ms-linear-gradient(#41bfbf 10%, #b0ffff 95%);\n}\ntable.stats td {\n  color: #ffffff;\n  background: #a0a0a0;\n  background-image: linear-gradient(#808080 10%, #d0d0d0 95%);\n  background-image: -moz-linear-gradient(#808080 10%, #d0d0d0 95%);\n  background-image: -webkit-linear-gradient(#808080 10%, #d0d0d0 95%);\n  background-image: -o-linear-gradient(#808080 10%, #d0d0d0 95%);\n  background-image: -ms-linear-gradient(#808080 10%, #d0d0d0 95%);\n}\ntable.stats td.speed {\n  color: #ff4020;\n}\ntable.stats td.kb {\n  color: #ffff80;\n  background: #808080;\n  background-image: linear-gradient(#606060 10%, #c0c0c0 95%);\n  background-image: -moz-linear-gradient(#606060 10%, #c0c0c0 95%);\n  background-image: -webkit-linear-gradient(#606060 10%, #c0c0c0 95%);\n  background-image: -o-linear-gradient(#606060 10%, #c0c0c0 95%);\n  background-image: -ms-linear-gradient(#606060 10%, #c0c0c0 95%);\n}\ntable.feature small {\n  font-size: 50%;\n}\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>LuaJIT</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a class=\"current\" href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nLuaJIT is a <b>Just-In-Time Compiler</b> (JIT) for the\n<a href=\"https://www.lua.org/\"><span class=\"ext\">&raquo;</span>&nbsp;Lua</a> programming language.\nLua is a powerful, dynamic and light-weight programming language.\nIt may be embedded or used as a general-purpose, stand-alone language.\n</p>\n<p>\nLuaJIT is Copyright &copy; 2005-2022 Mike Pall, released under the\n<a href=\"https://www.opensource.org/licenses/mit-license.php\"><span class=\"ext\">&raquo;</span>&nbsp;MIT open source license</a>.\n</p>\n<p>\n</p>\n\n<h2>Compatibility</h2>\n<table class=\"feature os os1\">\n<tr><td>Windows</td><td>Linux</td><td>BSD</td><td>macOS</td><td>POSIX</td></tr>\n</table>\n<table class=\"feature os os2\">\n<tr><td><span style=\"font-size:90%;\">Embedded</span></td><td>Android</td><td>iOS</td></tr>\n</table>\n<table class=\"feature os os3\">\n<tr><td>PS3</td><td>PS4<br>PS5</td><td>PS Vita</td><td>Xbox 360</td><td>Xbox One</td><td>Nintendo<br>Switch</td></tr>\n</table>\n<table class=\"feature compiler\">\n<tr><td>GCC</td><td>Clang<br>LLVM</td><td>MSVC</td></tr>\n</table>\n<table class=\"feature cpu\">\n<tr><td>x86<br>x64</td><td>ARM<br>ARM64</td><td>PPC</td><td>MIPS32<br>MIPS64</td></tr>\n</table>\n<table class=\"feature fcompat\">\n<tr><td>Lua&nbsp;5.1<br>API+ABI</td><td>+&nbsp;JIT</td><td>+&nbsp;BitOp</td><td>+&nbsp;FFI</td><td>Drop-in<br>DLL/.so</td></tr>\n</table>\n\n<h2>Overview</h2>\n<table class=\"feature stats\">\n<tr>\n<td class=\"speed\">3x<br>-&nbsp;&nbsp;100x</td>\n<td class=\"kb\">115&nbsp;<small>KB</small><br>VM</td>\n<td class=\"kb\">90&nbsp;<small>KB</small><br>JIT</td>\n<td class=\"kloc\">63&nbsp;<small>KLOC</small><br>C</td>\n<td class=\"kloc\">24&nbsp;<small>KLOC</small><br>ASM</td>\n<td class=\"kloc\">11&nbsp;<small>KLOC</small><br>Lua</td>\n</tr>\n</table>\n<p style=\"margin-top: 1em;\">\nLuaJIT has been successfully used as a <b>scripting middleware</b> in\ngames, appliances, network and graphics apps, numerical simulations,\ntrading platforms and many other specialty applications. It scales from\nembedded devices, smartphones, desktops up to server farms. It combines\nhigh flexibility with high performance\nand an unmatched <b>low memory footprint</b>.\n</p>\n<p>\nLuaJIT has been in continuous development since 2005. It's widely\nconsidered to be <b>one of the fastest dynamic language\nimplementations</b>. It has outperformed other dynamic languages on many\ncross-language benchmarks since its first release &mdash; often by a\nsubstantial margin.\n</p>\n<p>\nFor <b>LuaJIT 2.0</b>, the whole VM has been rewritten from the ground up\nand relentlessly optimized for performance. It combines a <b>high-speed\ninterpreter</b>, written in assembler, with a <b>state-of-the-art JIT\ncompiler</b>.\n</p>\n<p>\nAn innovative <b>trace compiler</b> is integrated with advanced,\nSSA-based optimizations and highly tuned code generation backends.\nA substantial reduction of the overhead associated with dynamic languages\nallows it to break into the performance range traditionally reserved for\noffline, static language compilers.\n</p>\n\n<h2>More ...</h2>\n<p>\nPlease select a sub-topic in the navigation bar to learn more about LuaJIT.\n</p>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/running.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Running LuaJIT</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\ntable.opt {\n  line-height: 1.2;\n}\ntr.opthead td {\n  font-weight: bold;\n}\ntd.flag_name {\n  width: 4em;\n}\ntd.flag_level {\n  width: 2em;\n  text-align: center;\n}\ntd.param_name {\n  width: 6em;\n}\ntd.param_default {\n  width: 4em;\n  text-align: right;\n}\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Running LuaJIT</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a class=\"current\" href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nLuaJIT has only a single stand-alone executable, called <tt>luajit</tt> on\nPOSIX systems or <tt>luajit.exe</tt> on Windows. It can be used to run simple\nLua statements or whole Lua applications from the command line. It has an\ninteractive mode, too.\n</p>\n\n<h2 id=\"options\">Command Line Options</h2>\n<p>\nThe <tt>luajit</tt> stand-alone executable is just a slightly modified\nversion of the regular <tt>lua</tt> stand-alone executable.\nIt supports the same basic options, too. <tt>luajit&nbsp;-h</tt>\nprints a short list of the available options. Please have a look at the\n<a href=\"https://www.lua.org/manual/5.1/manual.html#6\"><span class=\"ext\">&raquo;</span>&nbsp;Lua manual</a>\nfor details.\n</p>\n<p>\nLuaJIT has some additional options:\n</p>\n\n<h3 id=\"opt_b\"><tt>-b[options] input output</tt></h3>\n<p>\nThis option saves or lists bytecode. The following additional options\nare accepted:\n</p>\n<ul>\n<li><tt>-l</tt> &mdash; Only list bytecode.</li>\n<li><tt>-s</tt> &mdash; Strip debug info (this is the default).</li>\n<li><tt>-g</tt> &mdash; Keep debug info.</li>\n<li><tt>-n name</tt> &mdash; Set module name (default: auto-detect from input name)</li>\n<li><tt>-t type</tt> &mdash; Set output file type (default: auto-detect from output name).</li>\n<li><tt>-a arch</tt> &mdash; Override architecture for object files (default: native).</li>\n<li><tt>-o os</tt> &mdash; Override OS for object files (default: native).</li>\n<li><tt>-F name</tt> &mdash; Override filename (default: input filename).</li>\n<li><tt>-e chunk</tt> &mdash; Use chunk string as input.</li>\n<li><tt>-</tt> (a single minus sign) &mdash; Use stdin as input and/or stdout as output.</li>\n</ul>\n<p>\nThe output file type is auto-detected from the extension of the output\nfile name:\n</p>\n<ul>\n<li><tt>c</tt> &mdash; C source file, exported bytecode data.</li>\n<li><tt>h</tt> &mdash; C header file, static bytecode data.</li>\n<li><tt>obj</tt> or <tt>o</tt> &mdash; Object file, exported bytecode data\n(OS- and architecture-specific).</li>\n<li><tt>raw</tt> or any other extension &mdash; Raw bytecode file (portable).\n</ul>\n<p>\nNotes:\n</p>\n<ul>\n<li>See also <a href=\"extensions.html#string_dump\">string.dump()</a>\nfor information on bytecode portability and compatibility.</li>\n<li>A file in raw bytecode format is auto-detected and can be loaded like\nany Lua source file. E.g. directly from the command line or with\n<tt>loadfile()</tt>, <tt>dofile()</tt> etc.</li>\n<li>To statically embed the bytecode of a module in your application,\ngenerate an object file and just link it with your application.</li>\n<li>On most ELF-based systems (e.g. Linux) you need to explicitly export the\nglobal symbols when linking your application, e.g. with: <tt>-Wl,-E</tt></li>\n<li><tt>require()</tt> tries to load embedded bytecode data from exported\nsymbols (in <tt>*.exe</tt> or <tt>lua51.dll</tt> on Windows) and from\nshared libraries in <tt>package.cpath</tt>.</li>\n</ul>\n<p>\nTypical usage examples:\n</p>\n<pre class=\"code\">\nluajit -b test.lua test.out                 # Save bytecode to test.out\nluajit -bg test.lua test.out                # Keep debug info\nluajit -be \"print('hello world')\" test.out  # Save cmdline script\n\nluajit -bl test.lua                         # List to stdout\nluajit -bl test.lua test.txt                # List to test.txt\nluajit -ble \"print('hello world')\"          # List cmdline script\n\nluajit -b test.lua test.obj                 # Generate object file\n# Link test.obj with your application and load it with require(\"test\")\n</pre>\n\n<h3 id=\"opt_j\"><tt>-j cmd[=arg[,arg...]]</tt></h3>\n<p>\nThis option performs a LuaJIT control command or activates one of the\nloadable extension modules. The command is first looked up in the\n<tt>jit.*</tt> library. If no matching function is found, a module\nnamed <tt>jit.&lt;cmd&gt;</tt> is loaded and the <tt>start()</tt>\nfunction of the module is called with the specified arguments (if\nany). The space between <tt>-j</tt> and <tt>cmd</tt> is optional.\n</p>\n<p>\nHere are the available LuaJIT control commands:\n</p>\n<ul>\n<li id=\"j_on\"><tt>-jon</tt> &mdash; Turns the JIT compiler on (default).</li>\n<li id=\"j_off\"><tt>-joff</tt> &mdash; Turns the JIT compiler off (only use the interpreter).</li>\n<li id=\"j_flush\"><tt>-jflush</tt> &mdash; Flushes the whole cache of compiled code.</li>\n<li id=\"j_v\"><tt>-jv</tt> &mdash; Shows verbose information about the progress of the JIT compiler.</li>\n<li id=\"j_dump\"><tt>-jdump</tt> &mdash; Dumps the code and structures used in various compiler stages.</li>\n<li id=\"j_p\"><tt>-jp</tt> &mdash; Start the <a href=\"ext_profiler.html\">integrated profiler</a>.</li>\n</ul>\n<p>\nThe <tt>-jv</tt> and <tt>-jdump</tt> commands are extension modules\nwritten in Lua. They are mainly used for debugging the JIT compiler\nitself. For a description of their options and output format, please\nread the comment block at the start of their source.\nThey can be found in the <tt>lib</tt> directory of the source\ndistribution or installed under the <tt>jit</tt> directory. By default,\nthis is <tt>/usr/local/share/luajit-XX.YY.ZZ>/jit</tt> on POSIX\nsystems (replace XX.YY.ZZ by the installed version).\n</p>\n\n<h3 id=\"opt_O\"><tt>-O[level]</tt><br>\n<tt>-O[+]flag</tt>&nbsp;&nbsp;&nbsp;<tt>-O-flag</tt><br>\n<tt>-Oparam=value</tt></h3>\n<p>\nThis options allows fine-tuned control of the optimizations used by\nthe JIT compiler. This is mainly intended for debugging LuaJIT itself.\nPlease note that the JIT compiler is extremely fast (we are talking\nabout the microsecond to millisecond range). Disabling optimizations\ndoesn't have any visible impact on its overhead, but usually generates\ncode that runs slower.\n</p>\n<p>\nThe first form sets an optimization level &mdash; this enables a\nspecific mix of optimization flags. <tt>-O0</tt> turns off all\noptimizations and higher numbers enable more optimizations. Omitting\nthe level (i.e. just <tt>-O</tt>) sets the default optimization level,\nwhich is <tt>-O3</tt> in the current version.\n</p>\n<p>\nThe second form adds or removes individual optimization flags.\nThe third form sets a parameter for the VM or the JIT compiler\nto a specific value.\n</p>\n<p>\nYou can either use this option multiple times (like <tt>-Ocse\n-O-dce -Ohotloop=10</tt>) or separate several settings with a comma\n(like <tt>-O+cse,-dce,hotloop=10</tt>). The settings are applied from\nleft to right, and later settings override earlier ones. You can freely\nmix the three forms, but note that setting an optimization level\noverrides all earlier flags.\n</p>\n<p>\nNote that <tt>-Ofma</tt> is not enabled by default at any level,\nbecause it affects floating-point result accuracy. Only enable this,\nif you fully understand the trade-offs of FMA for performance (higher),\ndeterminism (lower) and numerical accuracy (higher).\n</p>\n<p>\nHere are the available flags and at what optimization levels they\nare enabled:\n</p>\n<table class=\"opt\">\n<tr class=\"opthead\">\n<td class=\"flag_name\">Flag</td>\n<td class=\"flag_level\">-O1</td>\n<td class=\"flag_level\">-O2</td>\n<td class=\"flag_level\">-O3</td>\n<td class=\"flag_desc\">&nbsp;</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"flag_name\">fold</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Constant Folding, Simplifications and Reassociation</td></tr>\n<tr class=\"even\">\n<td class=\"flag_name\">cse</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Common-Subexpression Elimination</td></tr>\n<tr class=\"odd\">\n<td class=\"flag_name\">dce</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Dead-Code Elimination</td></tr>\n<tr class=\"even\">\n<td class=\"flag_name\">narrow</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Narrowing of numbers to integers</td></tr>\n<tr class=\"odd\">\n<td class=\"flag_name\">loop</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Loop Optimizations (code hoisting)</td></tr>\n<tr class=\"even\">\n<td class=\"flag_name\">fwd</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Load Forwarding (L2L) and Store Forwarding (S2L)</td></tr>\n<tr class=\"odd\">\n<td class=\"flag_name\">dse</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Dead-Store Elimination</td></tr>\n<tr class=\"even\">\n<td class=\"flag_name\">abc</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Array Bounds Check Elimination</td></tr>\n<tr class=\"odd\">\n<td class=\"flag_name\">sink</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Allocation/Store Sinking</td></tr>\n<tr class=\"even\">\n<td class=\"flag_name\">fuse</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&bull;</td><td class=\"flag_desc\">Fusion of operands into instructions</td></tr>\n<tr class=\"odd\">\n<td class=\"flag_name\">fma </td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_level\">&nbsp;</td><td class=\"flag_desc\">Fused multiply-add</td></tr>\n</table>\n<p>\nHere are the parameters and their default settings:\n</p>\n<table class=\"opt\">\n<tr class=\"opthead\">\n<td class=\"param_name\">Parameter</td>\n<td class=\"param_default\">Default</td>\n<td class=\"param_desc\">&nbsp;</td>\n</tr>\n<tr class=\"odd separate\">\n<td class=\"param_name\">maxtrace</td><td class=\"param_default\">1000</td><td class=\"param_desc\">Max. number of traces in the cache</td></tr>\n<tr class=\"even\">\n<td class=\"param_name\">maxrecord</td><td class=\"param_default\">4000</td><td class=\"param_desc\">Max. number of recorded IR instructions</td></tr>\n<tr class=\"odd\">\n<td class=\"param_name\">maxirconst</td><td class=\"param_default\">500</td><td class=\"param_desc\">Max. number of IR constants of a trace</td></tr>\n<tr class=\"even\">\n<td class=\"param_name\">maxside</td><td class=\"param_default\">100</td><td class=\"param_desc\">Max. number of side traces of a root trace</td></tr>\n<tr class=\"odd\">\n<td class=\"param_name\">maxsnap</td><td class=\"param_default\">500</td><td class=\"param_desc\">Max. number of snapshots for a trace</td></tr>\n<tr class=\"even separate\">\n<td class=\"param_name\">hotloop</td><td class=\"param_default\">56</td><td class=\"param_desc\">Number of iterations to detect a hot loop or hot call</td></tr>\n<tr class=\"odd\">\n<td class=\"param_name\">hotexit</td><td class=\"param_default\">10</td><td class=\"param_desc\">Number of taken exits to start a side trace</td></tr>\n<tr class=\"even\">\n<td class=\"param_name\">tryside</td><td class=\"param_default\">4</td><td class=\"param_desc\">Number of attempts to compile a side trace</td></tr>\n<tr class=\"odd separate\">\n<td class=\"param_name\">instunroll</td><td class=\"param_default\">4</td><td class=\"param_desc\">Max. unroll factor for instable loops</td></tr>\n<tr class=\"even\">\n<td class=\"param_name\">loopunroll</td><td class=\"param_default\">15</td><td class=\"param_desc\">Max. unroll factor for loop ops in side traces</td></tr>\n<tr class=\"odd\">\n<td class=\"param_name\">callunroll</td><td class=\"param_default\">3</td><td class=\"param_desc\">Max. unroll factor for pseudo-recursive calls</td></tr>\n<tr class=\"even\">\n<td class=\"param_name\">recunroll</td><td class=\"param_default\">2</td><td class=\"param_desc\">Min. unroll factor for true recursion</td></tr>\n<tr class=\"odd separate\">\n<td class=\"param_name\">sizemcode</td><td class=\"param_default\">32</td><td class=\"param_desc\">Size of each machine code area in KBytes (Windows: 64K)</td></tr>\n<tr class=\"even\">\n<td class=\"param_name\">maxmcode</td><td class=\"param_default\">512</td><td class=\"param_desc\">Max. total size of all machine code areas in KBytes</td></tr>\n</table>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/doc/status.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n<title>Status</title>\n<meta charset=\"utf-8\">\n<meta name=\"Copyright\" content=\"Copyright (C) 2005-2022\">\n<meta name=\"Language\" content=\"en\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad.css\" media=\"screen\">\n<link rel=\"stylesheet\" type=\"text/css\" href=\"bluequad-print.css\" media=\"print\">\n<style type=\"text/css\">\nul li { padding-bottom: 0.3em; }\n</style>\n</head>\n<body>\n<div id=\"site\">\n<a href=\"https://luajit.org\"><span>Lua<span id=\"logo\">JIT</span></span></a>\n</div>\n<div id=\"head\">\n<h1>Status</h1>\n</div>\n<div id=\"nav\">\n<ul><li>\n<a href=\"luajit.html\">LuaJIT</a>\n<ul><li>\n<a href=\"https://luajit.org/download.html\">Download <span class=\"ext\">&raquo;</span></a>\n</li><li>\n<a href=\"install.html\">Installation</a>\n</li><li>\n<a href=\"running.html\">Running</a>\n</li></ul>\n</li><li>\n<a href=\"extensions.html\">Extensions</a>\n<ul><li>\n<a href=\"ext_ffi.html\">FFI Library</a>\n<ul><li>\n<a href=\"ext_ffi_tutorial.html\">FFI Tutorial</a>\n</li><li>\n<a href=\"ext_ffi_api.html\">ffi.* API</a>\n</li><li>\n<a href=\"ext_ffi_semantics.html\">FFI Semantics</a>\n</li></ul>\n</li><li>\n<a href=\"ext_buffer.html\">String Buffers</a>\n</li><li>\n<a href=\"ext_jit.html\">jit.* Library</a>\n</li><li>\n<a href=\"ext_c_api.html\">Lua/C API</a>\n</li><li>\n<a href=\"ext_profiler.html\">Profiler</a>\n</li></ul>\n</li><li>\n<a class=\"current\" href=\"status.html\">Status</a>\n</li><li>\n<a href=\"faq.html\">FAQ</a>\n</li><li>\n<a href=\"https://luajit.org/list.html\">Mailing List <span class=\"ext\">&raquo;</span></a>\n</li></ul>\n</div>\n<div id=\"main\">\n<p>\nThis documentation is for LuaJIT 2.1.0-beta3. Please check the <tt>doc</tt>\ndirectory in each git branch for the version-specific documentation.\n</p>\n<p>\nThe currently developed branches are LuaJIT&nbsp;2.1 and LuaJIT&nbsp;2.0.\n</p>\n<p>\nLuaJIT&nbsp;2.0 is in feature-freeze &mdash; new features will only\nbe added to LuaJIT&nbsp;2.1.\n</p>\n\n<h2>Current Status</h2>\n<p>\nLuaJIT ought to run all Lua&nbsp;5.1-compatible source code just fine.\nIt's considered a serious bug if the VM crashes or produces unexpected\nresults &mdash; please report this.\n</p>\n<p>\nKnown incompatibilities and issues in LuaJIT&nbsp;2.0:\n</p>\n<ul>\n<li>\nThere are some differences in <b>implementation-defined</b> behavior.\nThese either have a good reason, are arbitrary design choices,\nor are due to quirks in the VM. The latter cases may get fixed if a\ndemonstrable need is shown.\n</li>\n<li>\nThe Lua <b>debug API</b> is missing a couple of features (return\nhooks for non-Lua functions) and shows slightly different behavior\nin LuaJIT (no per-coroutine hooks, no tail call counting).\n</li>\n</ul>\n<br class=\"flush\">\n</div>\n<div id=\"foot\">\n<hr class=\"hide\">\nCopyright &copy; 2005-2022\n<span class=\"noprint\">\n&middot;\n<a href=\"contact.html\">Contact</a>\n</span>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_arm.h",
    "content": "/*\n** DynASM ARM encoding engine.\n** Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n** Released under the MIT license. See dynasm.lua for full copyright notice.\n*/\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define DASM_ARCH\t\t\"arm\"\n\n#ifndef DASM_EXTERN\n#define DASM_EXTERN(a,b,c,d)\t0\n#endif\n\n/* Action definitions. */\nenum {\n  DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,\n  /* The following actions need a buffer position. */\n  DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,\n  /* The following actions also have an argument. */\n  DASM_REL_PC, DASM_LABEL_PC,\n  DASM_IMM, DASM_IMM12, DASM_IMM16, DASM_IMML8, DASM_IMML12, DASM_IMMV8,\n  DASM__MAX\n};\n\n/* Maximum number of section buffer positions for a single dasm_put() call. */\n#define DASM_MAXSECPOS\t\t25\n\n/* DynASM encoder status codes. Action list offset or number are or'ed in. */\n#define DASM_S_OK\t\t0x00000000\n#define DASM_S_NOMEM\t\t0x01000000\n#define DASM_S_PHASE\t\t0x02000000\n#define DASM_S_MATCH_SEC\t0x03000000\n#define DASM_S_RANGE_I\t\t0x11000000\n#define DASM_S_RANGE_SEC\t0x12000000\n#define DASM_S_RANGE_LG\t\t0x13000000\n#define DASM_S_RANGE_PC\t\t0x14000000\n#define DASM_S_RANGE_REL\t0x15000000\n#define DASM_S_UNDEF_LG\t\t0x21000000\n#define DASM_S_UNDEF_PC\t\t0x22000000\n\n/* Macros to convert positions (8 bit section + 24 bit index). */\n#define DASM_POS2IDX(pos)\t((pos)&0x00ffffff)\n#define DASM_POS2BIAS(pos)\t((pos)&0xff000000)\n#define DASM_SEC2POS(sec)\t((sec)<<24)\n#define DASM_POS2SEC(pos)\t((pos)>>24)\n#define DASM_POS2PTR(D, pos)\t(D->sections[DASM_POS2SEC(pos)].rbuf + (pos))\n\n/* Action list type. */\ntypedef const unsigned int *dasm_ActList;\n\n/* Per-section structure. */\ntypedef struct dasm_Section {\n  int *rbuf;\t\t/* Biased buffer pointer (negative section bias). */\n  int *buf;\t\t/* True buffer pointer. */\n  size_t bsize;\t\t/* Buffer size in bytes. */\n  int pos;\t\t/* Biased buffer position. */\n  int epos;\t\t/* End of biased buffer position - max single put. */\n  int ofs;\t\t/* Byte offset into section. */\n} dasm_Section;\n\n/* Core structure holding the DynASM encoding state. */\nstruct dasm_State {\n  size_t psize;\t\t\t/* Allocated size of this structure. */\n  dasm_ActList actionlist;\t/* Current actionlist pointer. */\n  int *lglabels;\t\t/* Local/global chain/pos ptrs. */\n  size_t lgsize;\n  int *pclabels;\t\t/* PC label chains/pos ptrs. */\n  size_t pcsize;\n  void **globals;\t\t/* Array of globals (bias -10). */\n  dasm_Section *section;\t/* Pointer to active section. */\n  size_t codesize;\t\t/* Total size of all code sections. */\n  int maxsection;\t\t/* 0 <= sectionidx < maxsection. */\n  int status;\t\t\t/* Status code. */\n  dasm_Section sections[1];\t/* All sections. Alloc-extended. */\n};\n\n/* The size of the core structure depends on the max. number of sections. */\n#define DASM_PSZ(ms)\t(sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))\n\n\n/* Initialize DynASM state. */\nvoid dasm_init(Dst_DECL, int maxsection)\n{\n  dasm_State *D;\n  size_t psz = 0;\n  int i;\n  Dst_REF = NULL;\n  DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));\n  D = Dst_REF;\n  D->psize = psz;\n  D->lglabels = NULL;\n  D->lgsize = 0;\n  D->pclabels = NULL;\n  D->pcsize = 0;\n  D->globals = NULL;\n  D->maxsection = maxsection;\n  for (i = 0; i < maxsection; i++) {\n    D->sections[i].buf = NULL;  /* Need this for pass3. */\n    D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);\n    D->sections[i].bsize = 0;\n    D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */\n  }\n}\n\n/* Free DynASM state. */\nvoid dasm_free(Dst_DECL)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  for (i = 0; i < D->maxsection; i++)\n    if (D->sections[i].buf)\n      DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);\n  if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);\n  if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);\n  DASM_M_FREE(Dst, D, D->psize);\n}\n\n/* Setup global label array. Must be called before dasm_setup(). */\nvoid dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)\n{\n  dasm_State *D = Dst_REF;\n  D->globals = gl - 10;  /* Negative bias to compensate for locals. */\n  DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));\n}\n\n/* Grow PC label array. Can be called after dasm_setup(), too. */\nvoid dasm_growpc(Dst_DECL, unsigned int maxpc)\n{\n  dasm_State *D = Dst_REF;\n  size_t osz = D->pcsize;\n  DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));\n  memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);\n}\n\n/* Setup encoder. */\nvoid dasm_setup(Dst_DECL, const void *actionlist)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  D->actionlist = (dasm_ActList)actionlist;\n  D->status = DASM_S_OK;\n  D->section = &D->sections[0];\n  memset((void *)D->lglabels, 0, D->lgsize);\n  if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);\n  for (i = 0; i < D->maxsection; i++) {\n    D->sections[i].pos = DASM_SEC2POS(i);\n    D->sections[i].ofs = 0;\n  }\n}\n\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) { \\\n    D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)\n#define CKPL(kind, st) \\\n  do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \\\n    D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#define CKPL(kind, st)\t((void)0)\n#endif\n\nstatic int dasm_imm12(unsigned int n)\n{\n  int i;\n  for (i = 0; i < 16; i++, n = (n << 2) | (n >> 30))\n    if (n <= 255) return (int)(n + (i << 8));\n  return -1;\n}\n\n/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */\nvoid dasm_put(Dst_DECL, int start, ...)\n{\n  va_list ap;\n  dasm_State *D = Dst_REF;\n  dasm_ActList p = D->actionlist + start;\n  dasm_Section *sec = D->section;\n  int pos = sec->pos, ofs = sec->ofs;\n  int *b;\n\n  if (pos >= sec->epos) {\n    DASM_M_GROW(Dst, int, sec->buf, sec->bsize,\n      sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));\n    sec->rbuf = sec->buf - DASM_POS2BIAS(pos);\n    sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);\n  }\n\n  b = sec->rbuf;\n  b[pos++] = start;\n\n  va_start(ap, start);\n  while (1) {\n    unsigned int ins = *p++;\n    unsigned int action = (ins >> 16);\n    if (action >= DASM__MAX) {\n      ofs += 4;\n    } else {\n      int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;\n      switch (action) {\n      case DASM_STOP: goto stop;\n      case DASM_SECTION:\n\tn = (ins & 255); CK(n < D->maxsection, RANGE_SEC);\n\tD->section = &D->sections[n]; goto stop;\n      case DASM_ESC: p++; ofs += 4; break;\n      case DASM_REL_EXT: break;\n      case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;\n      case DASM_REL_LG:\n\tn = (ins & 2047) - 10; pl = D->lglabels + n;\n\t/* Bkwd rel or global. */\n\tif (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }\n\tpl += 10; n = *pl;\n\tif (n < 0) n = 0;  /* Start new chain for fwd rel if label exists. */\n\tgoto linkrel;\n      case DASM_REL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putrel:\n\tn = *pl;\n\tif (n < 0) {  /* Label exists. Get label pos and store it. */\n\t  b[pos] = -n;\n\t} else {\n      linkrel:\n\t  b[pos] = n;  /* Else link to rel chain, anchored at label. */\n\t  *pl = pos;\n\t}\n\tpos++;\n\tbreak;\n      case DASM_LABEL_LG:\n\tpl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;\n      case DASM_LABEL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putlabel:\n\tn = *pl;  /* n > 0: Collapse rel chain and replace with label pos. */\n\twhile (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;\n\t}\n\t*pl = -pos;  /* Label exists now. */\n\tb[pos++] = ofs;  /* Store pass1 offset estimate. */\n\tbreak;\n      case DASM_IMM:\n      case DASM_IMM16:\n#ifdef DASM_CHECKS\n\tCK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);\n\tif ((ins & 0x8000))\n\t  CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);\n\telse\n\t  CK((n>>((ins>>5)&31)) == 0, RANGE_I);\n#endif\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMMV8:\n\tCK((n & 3) == 0, RANGE_I);\n\tn >>= 2;\n\t/* fallthrough */\n      case DASM_IMML8:\n      case DASM_IMML12:\n\tCK(n >= 0 ? ((n>>((ins>>5)&31)) == 0) :\n\t\t    (((-n)>>((ins>>5)&31)) == 0), RANGE_I);\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMM12:\n\tCK(dasm_imm12((unsigned int)n) != -1, RANGE_I);\n\tb[pos++] = n;\n\tbreak;\n      }\n    }\n  }\nstop:\n  va_end(ap);\n  sec->pos = pos;\n  sec->ofs = ofs;\n}\n#undef CK\n\n/* Pass 2: Link sections, shrink aligns, fix label offsets. */\nint dasm_link(Dst_DECL, size_t *szp)\n{\n  dasm_State *D = Dst_REF;\n  int secnum;\n  int ofs = 0;\n\n#ifdef DASM_CHECKS\n  *szp = 0;\n  if (D->status != DASM_S_OK) return D->status;\n  {\n    int pc;\n    for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)\n      if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;\n  }\n#endif\n\n  { /* Handle globals not defined in this translation unit. */\n    int idx;\n    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {\n      int n = D->lglabels[idx];\n      /* Undefined label: Collapse rel chain and replace with marker (< 0). */\n      while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }\n    }\n  }\n\n  /* Combine all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->rbuf;\n    int pos = DASM_SEC2POS(secnum);\n    int lastpos = sec->pos;\n\n    while (pos != lastpos) {\n      dasm_ActList p = D->actionlist + b[pos++];\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16);\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: p++; break;\n\tcase DASM_REL_EXT: break;\n\tcase DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;\n\tcase DASM_REL_LG: case DASM_REL_PC: pos++; break;\n\tcase DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;\n\tcase DASM_IMM: case DASM_IMM12: case DASM_IMM16:\n\tcase DASM_IMML8: case DASM_IMML12: case DASM_IMMV8: pos++; break;\n\t}\n      }\n      stop: (void)0;\n    }\n    ofs += sec->ofs;  /* Next section starts right after current section. */\n  }\n\n  D->codesize = ofs;  /* Total size of all code sections */\n  *szp = ofs;\n  return DASM_S_OK;\n}\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#endif\n\n/* Pass 3: Encode sections. */\nint dasm_encode(Dst_DECL, void *buffer)\n{\n  dasm_State *D = Dst_REF;\n  char *base = (char *)buffer;\n  unsigned int *cp = (unsigned int *)buffer;\n  int secnum;\n\n  /* Encode all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->buf;\n    int *endb = sec->rbuf + sec->pos;\n\n    while (b != endb) {\n      dasm_ActList p = D->actionlist + *b++;\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16);\n\tint n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: *cp++ = *p++; break;\n\tcase DASM_REL_EXT:\n\t  n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));\n\t  goto patchrel;\n\tcase DASM_ALIGN:\n\t  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xe1a00000;\n\t  break;\n\tcase DASM_REL_LG:\n\t  if (n < 0) {\n\t    n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp - 4);\n\t    goto patchrel;\n\t  }\n\t  /* fallthrough */\n\tcase DASM_REL_PC:\n\t  CK(n >= 0, UNDEF_PC);\n\t  n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) - 4;\n\tpatchrel:\n\t  if ((ins & 0x800) == 0) {\n\t    CK((n & 3) == 0 && ((n+0x02000000) >> 26) == 0, RANGE_REL);\n\t    cp[-1] |= ((n >> 2) & 0x00ffffff);\n\t  } else if ((ins & 0x1000)) {\n\t    CK((n & 3) == 0 && -256 <= n && n <= 256, RANGE_REL);\n\t    goto patchimml8;\n\t  } else if ((ins & 0x2000) == 0) {\n\t    CK((n & 3) == 0 && -4096 <= n && n <= 4096, RANGE_REL);\n\t    goto patchimml;\n\t  } else {\n\t    CK((n & 3) == 0 && -1020 <= n && n <= 1020, RANGE_REL);\n\t    n >>= 2;\n\t    goto patchimml;\n\t  }\n\t  break;\n\tcase DASM_LABEL_LG:\n\t  ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);\n\t  break;\n\tcase DASM_LABEL_PC: break;\n\tcase DASM_IMM:\n\t  cp[-1] |= ((n>>((ins>>10)&31)) & ((1<<((ins>>5)&31))-1)) << (ins&31);\n\t  break;\n\tcase DASM_IMM12:\n\t  cp[-1] |= dasm_imm12((unsigned int)n);\n\t  break;\n\tcase DASM_IMM16:\n\t  cp[-1] |= ((n & 0xf000) << 4) | (n & 0x0fff);\n\t  break;\n\tcase DASM_IMML8: patchimml8:\n\t  cp[-1] |= n >= 0 ? (0x00800000 | (n & 0x0f) | ((n & 0xf0) << 4)) :\n\t\t\t     ((-n & 0x0f) | ((-n & 0xf0) << 4));\n\t  break;\n\tcase DASM_IMML12: case DASM_IMMV8: patchimml:\n\t  cp[-1] |= n >= 0 ? (0x00800000 | n) : (-n);\n\t  break;\n\tdefault: *cp++ = ins; break;\n\t}\n      }\n      stop: (void)0;\n    }\n  }\n\n  if (base + D->codesize != (char *)cp)  /* Check for phase errors. */\n    return DASM_S_PHASE;\n  return DASM_S_OK;\n}\n#undef CK\n\n/* Get PC label offset. */\nint dasm_getpclabel(Dst_DECL, unsigned int pc)\n{\n  dasm_State *D = Dst_REF;\n  if (pc*sizeof(int) < D->pcsize) {\n    int pos = D->pclabels[pc];\n    if (pos < 0) return *DASM_POS2PTR(D, -pos);\n    if (pos > 0) return -1;  /* Undefined. */\n  }\n  return -2;  /* Unused or out of range. */\n}\n\n#ifdef DASM_CHECKS\n/* Optional sanity checker to call between isolated encoding steps. */\nint dasm_checkstep(Dst_DECL, int secmatch)\n{\n  dasm_State *D = Dst_REF;\n  if (D->status == DASM_S_OK) {\n    int i;\n    for (i = 1; i <= 9; i++) {\n      if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }\n      D->lglabels[i] = 0;\n    }\n  }\n  if (D->status == DASM_S_OK && secmatch >= 0 &&\n      D->section != &D->sections[secmatch])\n    D->status = DASM_S_MATCH_SEC|(D->section-D->sections);\n  return D->status;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_arm.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM ARM module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n------------------------------------------------------------------------------\n\n-- Module information:\nlocal _info = {\n  arch =\t\"arm\",\n  description =\t\"DynASM ARM module\",\n  version =\t\"1.5.0\",\n  vernum =\t 10500,\n  release =\t\"2021-05-02\",\n  author =\t\"Mike Pall\",\n  license =\t\"MIT\",\n}\n\n-- Exported glue functions for the arch-specific module.\nlocal _M = { _info = _info }\n\n-- Cache library functions.\nlocal type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs\nlocal assert, setmetatable, rawget = assert, setmetatable, rawget\nlocal _s = string\nlocal sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char\nlocal match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub\nlocal concat, sort, insert = table.concat, table.sort, table.insert\nlocal bit = bit or require(\"bit\")\nlocal band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift\nlocal ror, tohex = bit.ror, bit.tohex\n\n-- Inherited tables and callbacks.\nlocal g_opt, g_arch\nlocal wline, werror, wfatal, wwarn\n\n-- Action name list.\n-- CHECK: Keep this in sync with the C code!\nlocal action_names = {\n  \"STOP\", \"SECTION\", \"ESC\", \"REL_EXT\",\n  \"ALIGN\", \"REL_LG\", \"LABEL_LG\",\n  \"REL_PC\", \"LABEL_PC\", \"IMM\", \"IMM12\", \"IMM16\", \"IMML8\", \"IMML12\", \"IMMV8\",\n}\n\n-- Maximum number of section buffer positions for dasm_put().\n-- CHECK: Keep this in sync with the C code!\nlocal maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.\n\n-- Action name -> action number.\nlocal map_action = {}\nfor n,name in ipairs(action_names) do\n  map_action[name] = n-1\nend\n\n-- Action list buffer.\nlocal actlist = {}\n\n-- Argument list for next dasm_put(). Start with offset 0 into action list.\nlocal actargs = { 0 }\n\n-- Current number of section buffer positions for dasm_put().\nlocal secpos = 1\n\n------------------------------------------------------------------------------\n\n-- Dump action names and numbers.\nlocal function dumpactions(out)\n  out:write(\"DynASM encoding engine action codes:\\n\")\n  for n,name in ipairs(action_names) do\n    local num = map_action[name]\n    out:write(format(\"  %-10s %02X  %d\\n\", name, num, num))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write action list buffer as a huge static C array.\nlocal function writeactions(out, name)\n  local nn = #actlist\n  if nn == 0 then nn = 1; actlist[0] = map_action.STOP end\n  out:write(\"static const unsigned int \", name, \"[\", nn, \"] = {\\n\")\n  for i = 1,nn-1 do\n    assert(out:write(\"0x\", tohex(actlist[i]), \",\\n\"))\n  end\n  assert(out:write(\"0x\", tohex(actlist[nn]), \"\\n};\\n\\n\"))\nend\n\n------------------------------------------------------------------------------\n\n-- Add word to action list.\nlocal function wputxw(n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  actlist[#actlist+1] = n\nend\n\n-- Add action to list with optional arg. Advance buffer pos, too.\nlocal function waction(action, val, a, num)\n  local w = assert(map_action[action], \"bad action name `\"..action..\"'\")\n  wputxw(w * 0x10000 + (val or 0))\n  if a then actargs[#actargs+1] = a end\n  if a or num then secpos = secpos + (num or 1) end\nend\n\n-- Flush action list (intervening C code or buffer pos overflow).\nlocal function wflush(term)\n  if #actlist == actargs[1] then return end -- Nothing to flush.\n  if not term then waction(\"STOP\") end -- Terminate action list.\n  wline(format(\"dasm_put(Dst, %s);\", concat(actargs, \", \")), true)\n  actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().\n  secpos = 1 -- The actionlist offset occupies a buffer position, too.\nend\n\n-- Put escaped word.\nlocal function wputw(n)\n  if n <= 0x000fffff then waction(\"ESC\") end\n  wputxw(n)\nend\n\n-- Reserve position for word.\nlocal function wpos()\n  local pos = #actlist+1\n  actlist[pos] = \"\"\n  return pos\nend\n\n-- Store word to reserved position.\nlocal function wputpos(pos, n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  if n <= 0x000fffff then\n    insert(actlist, pos+1, n)\n    n = map_action.ESC * 0x10000\n  end\n  actlist[pos] = n\nend\n\n------------------------------------------------------------------------------\n\n-- Global label name -> global label number. With auto assignment on 1st use.\nlocal next_global = 20\nlocal map_global = setmetatable({}, { __index = function(t, name)\n  if not match(name, \"^[%a_][%w_]*$\") then werror(\"bad global label\") end\n  local n = next_global\n  if n > 2047 then werror(\"too many global labels\") end\n  next_global = n + 1\n  t[name] = n\n  return n\nend})\n\n-- Dump global labels.\nlocal function dumpglobals(out, lvl)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"Global labels:\\n\")\n  for i=20,next_global-1 do\n    out:write(format(\"  %s\\n\", t[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write global label enum.\nlocal function writeglobals(out, prefix)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"enum {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \", prefix, t[i], \",\\n\")\n  end\n  out:write(\"  \", prefix, \"_MAX\\n};\\n\")\nend\n\n-- Write global label names.\nlocal function writeglobalnames(out, name)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \\\"\", t[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Extern label name -> extern label number. With auto assignment on 1st use.\nlocal next_extern = 0\nlocal map_extern_ = {}\nlocal map_extern = setmetatable({}, { __index = function(t, name)\n  -- No restrictions on the name for now.\n  local n = next_extern\n  if n > 2047 then werror(\"too many extern labels\") end\n  next_extern = n + 1\n  t[name] = n\n  map_extern_[n] = name\n  return n\nend})\n\n-- Dump extern labels.\nlocal function dumpexterns(out, lvl)\n  out:write(\"Extern labels:\\n\")\n  for i=0,next_extern-1 do\n    out:write(format(\"  %s\\n\", map_extern_[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write extern label names.\nlocal function writeexternnames(out, name)\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=0,next_extern-1 do\n    out:write(\"  \\\"\", map_extern_[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Arch-specific maps.\n\n-- Ext. register name -> int. name.\nlocal map_archdef = { sp = \"r13\", lr = \"r14\", pc = \"r15\", }\n\n-- Int. register name -> ext. name.\nlocal map_reg_rev = { r13 = \"sp\", r14 = \"lr\", r15 = \"pc\", }\n\nlocal map_type = {}\t\t-- Type name -> { ctype, reg }\nlocal ctypenum = 0\t\t-- Type number (for Dt... macros).\n\n-- Reverse defines for registers.\nfunction _M.revdef(s)\n  return map_reg_rev[s] or s\nend\n\nlocal map_shift = { lsl = 0, lsr = 1, asr = 2, ror = 3, }\n\nlocal map_cond = {\n  eq = 0, ne = 1, cs = 2, cc = 3, mi = 4, pl = 5, vs = 6, vc = 7,\n  hi = 8, ls = 9, ge = 10, lt = 11, gt = 12, le = 13, al = 14,\n  hs = 2, lo = 3,\n}\n\n------------------------------------------------------------------------------\n\n-- Template strings for ARM instructions.\nlocal map_op = {\n  -- Basic data processing instructions.\n  and_3 = \"e0000000DNPs\",\n  eor_3 = \"e0200000DNPs\",\n  sub_3 = \"e0400000DNPs\",\n  rsb_3 = \"e0600000DNPs\",\n  add_3 = \"e0800000DNPs\",\n  adc_3 = \"e0a00000DNPs\",\n  sbc_3 = \"e0c00000DNPs\",\n  rsc_3 = \"e0e00000DNPs\",\n  tst_2 = \"e1100000NP\",\n  teq_2 = \"e1300000NP\",\n  cmp_2 = \"e1500000NP\",\n  cmn_2 = \"e1700000NP\",\n  orr_3 = \"e1800000DNPs\",\n  mov_2 = \"e1a00000DPs\",\n  bic_3 = \"e1c00000DNPs\",\n  mvn_2 = \"e1e00000DPs\",\n\n  and_4 = \"e0000000DNMps\",\n  eor_4 = \"e0200000DNMps\",\n  sub_4 = \"e0400000DNMps\",\n  rsb_4 = \"e0600000DNMps\",\n  add_4 = \"e0800000DNMps\",\n  adc_4 = \"e0a00000DNMps\",\n  sbc_4 = \"e0c00000DNMps\",\n  rsc_4 = \"e0e00000DNMps\",\n  tst_3 = \"e1100000NMp\",\n  teq_3 = \"e1300000NMp\",\n  cmp_3 = \"e1500000NMp\",\n  cmn_3 = \"e1700000NMp\",\n  orr_4 = \"e1800000DNMps\",\n  mov_3 = \"e1a00000DMps\",\n  bic_4 = \"e1c00000DNMps\",\n  mvn_3 = \"e1e00000DMps\",\n\n  lsl_3 = \"e1a00000DMws\",\n  lsr_3 = \"e1a00020DMws\",\n  asr_3 = \"e1a00040DMws\",\n  ror_3 = \"e1a00060DMws\",\n  rrx_2 = \"e1a00060DMs\",\n\n  -- Multiply and multiply-accumulate.\n  mul_3 = \"e0000090NMSs\",\n  mla_4 = \"e0200090NMSDs\",\n  umaal_4 = \"e0400090DNMSs\",\t-- v6\n  mls_4 = \"e0600090DNMSs\",\t-- v6T2\n  umull_4 = \"e0800090DNMSs\",\n  umlal_4 = \"e0a00090DNMSs\",\n  smull_4 = \"e0c00090DNMSs\",\n  smlal_4 = \"e0e00090DNMSs\",\n\n  -- Halfword multiply and multiply-accumulate.\n  smlabb_4 = \"e1000080NMSD\",\t-- v5TE\n  smlatb_4 = \"e10000a0NMSD\",\t-- v5TE\n  smlabt_4 = \"e10000c0NMSD\",\t-- v5TE\n  smlatt_4 = \"e10000e0NMSD\",\t-- v5TE\n  smlawb_4 = \"e1200080NMSD\",\t-- v5TE\n  smulwb_3 = \"e12000a0NMS\",\t-- v5TE\n  smlawt_4 = \"e12000c0NMSD\",\t-- v5TE\n  smulwt_3 = \"e12000e0NMS\",\t-- v5TE\n  smlalbb_4 = \"e1400080NMSD\",\t-- v5TE\n  smlaltb_4 = \"e14000a0NMSD\",\t-- v5TE\n  smlalbt_4 = \"e14000c0NMSD\",\t-- v5TE\n  smlaltt_4 = \"e14000e0NMSD\",\t-- v5TE\n  smulbb_3 = \"e1600080NMS\",\t-- v5TE\n  smultb_3 = \"e16000a0NMS\",\t-- v5TE\n  smulbt_3 = \"e16000c0NMS\",\t-- v5TE\n  smultt_3 = \"e16000e0NMS\",\t-- v5TE\n\n  -- Miscellaneous data processing instructions.\n  clz_2 = \"e16f0f10DM\", -- v5T\n  rev_2 = \"e6bf0f30DM\", -- v6\n  rev16_2 = \"e6bf0fb0DM\", -- v6\n  revsh_2 = \"e6ff0fb0DM\", -- v6\n  sel_3 = \"e6800fb0DNM\", -- v6\n  usad8_3 = \"e780f010NMS\", -- v6\n  usada8_4 = \"e7800010NMSD\", -- v6\n  rbit_2 = \"e6ff0f30DM\", -- v6T2\n  movw_2 = \"e3000000DW\", -- v6T2\n  movt_2 = \"e3400000DW\", -- v6T2\n  -- Note: the X encodes width-1, not width.\n  sbfx_4 = \"e7a00050DMvX\", -- v6T2\n  ubfx_4 = \"e7e00050DMvX\", -- v6T2\n  -- Note: the X encodes the msb field, not the width.\n  bfc_3 = \"e7c0001fDvX\", -- v6T2\n  bfi_4 = \"e7c00010DMvX\", -- v6T2\n\n  -- Packing and unpacking instructions.\n  pkhbt_3 = \"e6800010DNM\", pkhbt_4 = \"e6800010DNMv\", -- v6\n  pkhtb_3 = \"e6800050DNM\", pkhtb_4 = \"e6800050DNMv\", -- v6\n  sxtab_3 = \"e6a00070DNM\", sxtab_4 = \"e6a00070DNMv\", -- v6\n  sxtab16_3 = \"e6800070DNM\", sxtab16_4 = \"e6800070DNMv\", -- v6\n  sxtah_3 = \"e6b00070DNM\", sxtah_4 = \"e6b00070DNMv\", -- v6\n  sxtb_2 = \"e6af0070DM\", sxtb_3 = \"e6af0070DMv\", -- v6\n  sxtb16_2 = \"e68f0070DM\", sxtb16_3 = \"e68f0070DMv\", -- v6\n  sxth_2 = \"e6bf0070DM\", sxth_3 = \"e6bf0070DMv\", -- v6\n  uxtab_3 = \"e6e00070DNM\", uxtab_4 = \"e6e00070DNMv\", -- v6\n  uxtab16_3 = \"e6c00070DNM\", uxtab16_4 = \"e6c00070DNMv\", -- v6\n  uxtah_3 = \"e6f00070DNM\", uxtah_4 = \"e6f00070DNMv\", -- v6\n  uxtb_2 = \"e6ef0070DM\", uxtb_3 = \"e6ef0070DMv\", -- v6\n  uxtb16_2 = \"e6cf0070DM\", uxtb16_3 = \"e6cf0070DMv\", -- v6\n  uxth_2 = \"e6ff0070DM\", uxth_3 = \"e6ff0070DMv\", -- v6\n\n  -- Saturating instructions.\n  qadd_3 = \"e1000050DMN\",\t-- v5TE\n  qsub_3 = \"e1200050DMN\",\t-- v5TE\n  qdadd_3 = \"e1400050DMN\",\t-- v5TE\n  qdsub_3 = \"e1600050DMN\",\t-- v5TE\n  -- Note: the X for ssat* encodes sat_imm-1, not sat_imm.\n  ssat_3 = \"e6a00010DXM\", ssat_4 = \"e6a00010DXMp\", -- v6\n  usat_3 = \"e6e00010DXM\", usat_4 = \"e6e00010DXMp\", -- v6\n  ssat16_3 = \"e6a00f30DXM\", -- v6\n  usat16_3 = \"e6e00f30DXM\", -- v6\n\n  -- Parallel addition and subtraction.\n  sadd16_3 = \"e6100f10DNM\", -- v6\n  sasx_3 = \"e6100f30DNM\", -- v6\n  ssax_3 = \"e6100f50DNM\", -- v6\n  ssub16_3 = \"e6100f70DNM\", -- v6\n  sadd8_3 = \"e6100f90DNM\", -- v6\n  ssub8_3 = \"e6100ff0DNM\", -- v6\n  qadd16_3 = \"e6200f10DNM\", -- v6\n  qasx_3 = \"e6200f30DNM\", -- v6\n  qsax_3 = \"e6200f50DNM\", -- v6\n  qsub16_3 = \"e6200f70DNM\", -- v6\n  qadd8_3 = \"e6200f90DNM\", -- v6\n  qsub8_3 = \"e6200ff0DNM\", -- v6\n  shadd16_3 = \"e6300f10DNM\", -- v6\n  shasx_3 = \"e6300f30DNM\", -- v6\n  shsax_3 = \"e6300f50DNM\", -- v6\n  shsub16_3 = \"e6300f70DNM\", -- v6\n  shadd8_3 = \"e6300f90DNM\", -- v6\n  shsub8_3 = \"e6300ff0DNM\", -- v6\n  uadd16_3 = \"e6500f10DNM\", -- v6\n  uasx_3 = \"e6500f30DNM\", -- v6\n  usax_3 = \"e6500f50DNM\", -- v6\n  usub16_3 = \"e6500f70DNM\", -- v6\n  uadd8_3 = \"e6500f90DNM\", -- v6\n  usub8_3 = \"e6500ff0DNM\", -- v6\n  uqadd16_3 = \"e6600f10DNM\", -- v6\n  uqasx_3 = \"e6600f30DNM\", -- v6\n  uqsax_3 = \"e6600f50DNM\", -- v6\n  uqsub16_3 = \"e6600f70DNM\", -- v6\n  uqadd8_3 = \"e6600f90DNM\", -- v6\n  uqsub8_3 = \"e6600ff0DNM\", -- v6\n  uhadd16_3 = \"e6700f10DNM\", -- v6\n  uhasx_3 = \"e6700f30DNM\", -- v6\n  uhsax_3 = \"e6700f50DNM\", -- v6\n  uhsub16_3 = \"e6700f70DNM\", -- v6\n  uhadd8_3 = \"e6700f90DNM\", -- v6\n  uhsub8_3 = \"e6700ff0DNM\", -- v6\n\n  -- Load/store instructions.\n  str_2 = \"e4000000DL\", str_3 = \"e4000000DL\", str_4 = \"e4000000DL\",\n  strb_2 = \"e4400000DL\", strb_3 = \"e4400000DL\", strb_4 = \"e4400000DL\",\n  ldr_2 = \"e4100000DL\", ldr_3 = \"e4100000DL\", ldr_4 = \"e4100000DL\",\n  ldrb_2 = \"e4500000DL\", ldrb_3 = \"e4500000DL\", ldrb_4 = \"e4500000DL\",\n  strh_2 = \"e00000b0DL\", strh_3 = \"e00000b0DL\",\n  ldrh_2 = \"e01000b0DL\", ldrh_3 = \"e01000b0DL\",\n  ldrd_2 = \"e00000d0DL\", ldrd_3 = \"e00000d0DL\", -- v5TE\n  ldrsb_2 = \"e01000d0DL\", ldrsb_3 = \"e01000d0DL\",\n  strd_2 = \"e00000f0DL\", strd_3 = \"e00000f0DL\", -- v5TE\n  ldrsh_2 = \"e01000f0DL\", ldrsh_3 = \"e01000f0DL\",\n\n  ldm_2 = \"e8900000oR\", ldmia_2 = \"e8900000oR\", ldmfd_2 = \"e8900000oR\",\n  ldmda_2 = \"e8100000oR\", ldmfa_2 = \"e8100000oR\",\n  ldmdb_2 = \"e9100000oR\", ldmea_2 = \"e9100000oR\",\n  ldmib_2 = \"e9900000oR\", ldmed_2 = \"e9900000oR\",\n  stm_2 = \"e8800000oR\", stmia_2 = \"e8800000oR\", stmfd_2 = \"e8800000oR\",\n  stmda_2 = \"e8000000oR\", stmfa_2 = \"e8000000oR\",\n  stmdb_2 = \"e9000000oR\", stmea_2 = \"e9000000oR\",\n  stmib_2 = \"e9800000oR\", stmed_2 = \"e9800000oR\",\n  pop_1 = \"e8bd0000R\", push_1 = \"e92d0000R\",\n\n  -- Branch instructions.\n  b_1 = \"ea000000B\",\n  bl_1 = \"eb000000B\",\n  blx_1 = \"e12fff30C\",\n  bx_1 = \"e12fff10M\",\n\n  -- Miscellaneous instructions.\n  nop_0 = \"e1a00000\",\n  mrs_1 = \"e10f0000D\",\n  bkpt_1 = \"e1200070K\", -- v5T\n  svc_1 = \"ef000000T\", swi_1 = \"ef000000T\",\n  ud_0 = \"e7f001f0\",\n\n  -- VFP instructions.\n  [\"vadd.f32_3\"] = \"ee300a00dnm\",\n  [\"vadd.f64_3\"] = \"ee300b00Gdnm\",\n  [\"vsub.f32_3\"] = \"ee300a40dnm\",\n  [\"vsub.f64_3\"] = \"ee300b40Gdnm\",\n  [\"vmul.f32_3\"] = \"ee200a00dnm\",\n  [\"vmul.f64_3\"] = \"ee200b00Gdnm\",\n  [\"vnmul.f32_3\"] = \"ee200a40dnm\",\n  [\"vnmul.f64_3\"] = \"ee200b40Gdnm\",\n  [\"vmla.f32_3\"] = \"ee000a00dnm\",\n  [\"vmla.f64_3\"] = \"ee000b00Gdnm\",\n  [\"vmls.f32_3\"] = \"ee000a40dnm\",\n  [\"vmls.f64_3\"] = \"ee000b40Gdnm\",\n  [\"vnmla.f32_3\"] = \"ee100a40dnm\",\n  [\"vnmla.f64_3\"] = \"ee100b40Gdnm\",\n  [\"vnmls.f32_3\"] = \"ee100a00dnm\",\n  [\"vnmls.f64_3\"] = \"ee100b00Gdnm\",\n  [\"vdiv.f32_3\"] = \"ee800a00dnm\",\n  [\"vdiv.f64_3\"] = \"ee800b00Gdnm\",\n\n  [\"vabs.f32_2\"] = \"eeb00ac0dm\",\n  [\"vabs.f64_2\"] = \"eeb00bc0Gdm\",\n  [\"vneg.f32_2\"] = \"eeb10a40dm\",\n  [\"vneg.f64_2\"] = \"eeb10b40Gdm\",\n  [\"vsqrt.f32_2\"] = \"eeb10ac0dm\",\n  [\"vsqrt.f64_2\"] = \"eeb10bc0Gdm\",\n  [\"vcmp.f32_2\"] = \"eeb40a40dm\",\n  [\"vcmp.f64_2\"] = \"eeb40b40Gdm\",\n  [\"vcmpe.f32_2\"] = \"eeb40ac0dm\",\n  [\"vcmpe.f64_2\"] = \"eeb40bc0Gdm\",\n  [\"vcmpz.f32_1\"] = \"eeb50a40d\",\n  [\"vcmpz.f64_1\"] = \"eeb50b40Gd\",\n  [\"vcmpze.f32_1\"] = \"eeb50ac0d\",\n  [\"vcmpze.f64_1\"] = \"eeb50bc0Gd\",\n\n  vldr_2 = \"ed100a00dl|ed100b00Gdl\",\n  vstr_2 = \"ed000a00dl|ed000b00Gdl\",\n  vldm_2 = \"ec900a00or\",\n  vldmia_2 = \"ec900a00or\",\n  vldmdb_2 = \"ed100a00or\",\n  vpop_1 = \"ecbd0a00r\",\n  vstm_2 = \"ec800a00or\",\n  vstmia_2 = \"ec800a00or\",\n  vstmdb_2 = \"ed000a00or\",\n  vpush_1 = \"ed2d0a00r\",\n\n  [\"vmov.f32_2\"] = \"eeb00a40dm|eeb00a00dY\",\t-- #imm is VFPv3 only\n  [\"vmov.f64_2\"] = \"eeb00b40Gdm|eeb00b00GdY\",\t-- #imm is VFPv3 only\n  vmov_2 = \"ee100a10Dn|ee000a10nD\",\n  vmov_3 = \"ec500a10DNm|ec400a10mDN|ec500b10GDNm|ec400b10GmDN\",\n\n  vmrs_0 = \"eef1fa10\",\n  vmrs_1 = \"eef10a10D\",\n  vmsr_1 = \"eee10a10D\",\n\n  [\"vcvt.s32.f32_2\"] = \"eebd0ac0dm\",\n  [\"vcvt.s32.f64_2\"] = \"eebd0bc0dGm\",\n  [\"vcvt.u32.f32_2\"] = \"eebc0ac0dm\",\n  [\"vcvt.u32.f64_2\"] = \"eebc0bc0dGm\",\n  [\"vcvtr.s32.f32_2\"] = \"eebd0a40dm\",\n  [\"vcvtr.s32.f64_2\"] = \"eebd0b40dGm\",\n  [\"vcvtr.u32.f32_2\"] = \"eebc0a40dm\",\n  [\"vcvtr.u32.f64_2\"] = \"eebc0b40dGm\",\n  [\"vcvt.f32.s32_2\"] = \"eeb80ac0dm\",\n  [\"vcvt.f64.s32_2\"] = \"eeb80bc0GdFm\",\n  [\"vcvt.f32.u32_2\"] = \"eeb80a40dm\",\n  [\"vcvt.f64.u32_2\"] = \"eeb80b40GdFm\",\n  [\"vcvt.f32.f64_2\"] = \"eeb70bc0dGm\",\n  [\"vcvt.f64.f32_2\"] = \"eeb70ac0GdFm\",\n\n  -- VFPv4 only:\n  [\"vfma.f32_3\"] = \"eea00a00dnm\",\n  [\"vfma.f64_3\"] = \"eea00b00Gdnm\",\n  [\"vfms.f32_3\"] = \"eea00a40dnm\",\n  [\"vfms.f64_3\"] = \"eea00b40Gdnm\",\n  [\"vfnma.f32_3\"] = \"ee900a40dnm\",\n  [\"vfnma.f64_3\"] = \"ee900b40Gdnm\",\n  [\"vfnms.f32_3\"] = \"ee900a00dnm\",\n  [\"vfnms.f64_3\"] = \"ee900b00Gdnm\",\n\n  -- NYI: Advanced SIMD instructions.\n\n  -- NYI: I have no need for these instructions right now:\n  -- swp, swpb, strex, ldrex, strexd, ldrexd, strexb, ldrexb, strexh, ldrexh\n  -- msr, nopv6, yield, wfe, wfi, sev, dbg, bxj, smc, srs, rfe\n  -- cps, setend, pli, pld, pldw, clrex, dsb, dmb, isb\n  -- stc, ldc, mcr, mcr2, mrc, mrc2, mcrr, mcrr2, mrrc, mrrc2, cdp, cdp2\n}\n\n-- Add mnemonics for \"s\" variants.\ndo\n  local t = {}\n  for k,v in pairs(map_op) do\n    if sub(v, -1) == \"s\" then\n      local v2 = sub(v, 1, 2)..char(byte(v, 3)+1)..sub(v, 4, -2)\n      t[sub(k, 1, -3)..\"s\"..sub(k, -2)] = v2\n    end\n  end\n  for k,v in pairs(t) do\n    map_op[k] = v\n  end\nend\n\n------------------------------------------------------------------------------\n\nlocal function parse_gpr(expr)\n  local tname, ovreg = match(expr, \"^([%w_]+):(r1?[0-9])$\")\n  local tp = map_type[tname or expr]\n  if tp then\n    local reg = ovreg or tp.reg\n    if not reg then\n      werror(\"type `\"..(tname or expr)..\"' needs a register override\")\n    end\n    expr = reg\n  end\n  local r = match(expr, \"^r(1?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 15 then return r, tp end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_gpr_pm(expr)\n  local pm, expr2 = match(expr, \"^([+-]?)(.*)$\")\n  return parse_gpr(expr2), (pm == \"-\")\nend\n\nlocal function parse_vr(expr, tp)\n  local t, r = match(expr, \"^([sd])([0-9]+)$\")\n  if t == tp then\n    r = tonumber(r)\n    if r <= 31 then\n      if t == \"s\" then return shr(r, 1), band(r, 1) end\n      return band(r, 15), shr(r, 4)\n    end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_reglist(reglist)\n  reglist = match(reglist, \"^{%s*([^}]*)}$\")\n  if not reglist then werror(\"register list expected\") end\n  local rr = 0\n  for p in gmatch(reglist..\",\", \"%s*([^,]*),\") do\n    local rbit = shl(1, parse_gpr(gsub(p, \"%s+$\", \"\")))\n    if band(rr, rbit) ~= 0 then\n      werror(\"duplicate register `\"..p..\"'\")\n    end\n    rr = rr + rbit\n  end\n  return rr\nend\n\nlocal function parse_vrlist(reglist)\n  local ta, ra, tb, rb = match(reglist,\n\t\t\t   \"^{%s*([sd])([0-9]+)%s*%-%s*([sd])([0-9]+)%s*}$\")\n  ra, rb = tonumber(ra), tonumber(rb)\n  if ta and ta == tb and ra and rb and ra <= 31 and rb <= 31 and ra <= rb then\n    local nr = rb+1 - ra\n    if ta == \"s\" then\n      return shl(shr(ra,1),12)+shl(band(ra,1),22) + nr\n    else\n      return shl(band(ra,15),12)+shl(shr(ra,4),22) + nr*2 + 0x100\n    end\n  end\n  werror(\"register list expected\")\nend\n\nlocal function parse_imm(imm, bits, shift, scale, signed)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = tonumber(imm)\n  if n then\n    local m = sar(n, scale)\n    if shl(m, scale) == n then\n      if signed then\n\tlocal s = sar(m, bits-1)\n\tif s == 0 then return shl(m, shift)\n\telseif s == -1 then return shl(m + shl(1, bits), shift) end\n      else\n\tif sar(m, bits) == 0 then return shl(m, shift) end\n      end\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMM\", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm12(imm)\n  local n = tonumber(imm)\n  if n then\n    local m = band(n)\n    for i=0,-15,-1 do\n      if shr(m, 8) == 0 then return m + shl(band(i, 15), 8) end\n      m = ror(m, 2)\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMM12\", 0, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm16(imm)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = tonumber(imm)\n  if n then\n    if shr(n, 16) == 0 then return band(n, 0x0fff) + shl(band(n, 0xf000), 4) end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMM16\", 32*16, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm_load(imm, ext)\n  local n = tonumber(imm)\n  if n then\n    if ext then\n      if n >= -255 and n <= 255 then\n\tlocal up = 0x00800000\n\tif n < 0 then n = -n; up = 0 end\n\treturn shl(band(n, 0xf0), 4) + band(n, 0x0f) + up\n      end\n    else\n      if n >= -4095 and n <= 4095 then\n\tif n >= 0 then return n+0x00800000 end\n\treturn -n\n      end\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(ext and \"IMML8\" or \"IMML12\", 32768 + shl(ext and 8 or 12, 5), imm)\n    return 0\n  end\nend\n\nlocal function parse_shift(shift, gprok)\n  if shift == \"rrx\" then\n    return 3 * 32\n  else\n    local s, s2 = match(shift, \"^(%S+)%s*(.*)$\")\n    s = map_shift[s]\n    if not s then werror(\"expected shift operand\") end\n    if sub(s2, 1, 1) == \"#\" then\n      return parse_imm(s2, 5, 7, 0, false) + shl(s, 5)\n    else\n      if not gprok then werror(\"expected immediate shift operand\") end\n      return shl(parse_gpr(s2), 8) + shl(s, 5) + 16\n    end\n  end\nend\n\nlocal function parse_label(label, def)\n  local prefix = sub(label, 1, 2)\n  -- =>label (pc label reference)\n  if prefix == \"=>\" then\n    return \"PC\", 0, sub(label, 3)\n  end\n  -- ->name (global label reference)\n  if prefix == \"->\" then\n    return \"LG\", map_global[sub(label, 3)]\n  end\n  if def then\n    -- [1-9] (local label definition)\n    if match(label, \"^[1-9]$\") then\n      return \"LG\", 10+tonumber(label)\n    end\n  else\n    -- [<>][1-9] (local label reference)\n    local dir, lnum = match(label, \"^([<>])([1-9])$\")\n    if dir then -- Fwd: 1-9, Bkwd: 11-19.\n      return \"LG\", lnum + (dir == \">\" and 0 or 10)\n    end\n    -- extern label (extern label reference)\n    local extname = match(label, \"^extern%s+(%S+)$\")\n    if extname then\n      return \"EXT\", map_extern[extname]\n    end\n  end\n  werror(\"bad label `\"..label..\"'\")\nend\n\nlocal function parse_load(params, nparams, n, op)\n  local oplo = band(op, 255)\n  local ext, ldrd = (oplo ~= 0), (oplo == 208)\n  local d\n  if (ldrd or oplo == 240) then\n    d = band(shr(op, 12), 15)\n    if band(d, 1) ~= 0 then werror(\"odd destination register\") end\n  end\n  local pn = params[n]\n  local p1, wb = match(pn, \"^%[%s*(.-)%s*%](!?)$\")\n  local p2 = params[n+1]\n  if not p1 then\n    if not p2 then\n      if match(pn, \"^[<>=%-]\") or match(pn, \"^extern%s+\") then\n\tlocal mode, n, s = parse_label(pn, false)\n\twaction(\"REL_\"..mode, n + (ext and 0x1800 or 0x0800), s, 1)\n\treturn op + 15 * 65536 + 0x01000000 + (ext and 0x00400000 or 0)\n      end\n      local reg, tailr = match(pn, \"^([%w_:]+)%s*(.*)$\")\n      if reg and tailr ~= \"\" then\n\tlocal d, tp = parse_gpr(reg)\n\tif tp then\n\t  waction(ext and \"IMML8\" or \"IMML12\", 32768 + 32*(ext and 8 or 12),\n\t\t  format(tp.ctypefmt, tailr))\n\t  return op + shl(d, 16) + 0x01000000 + (ext and 0x00400000 or 0)\n\tend\n      end\n    end\n    werror(\"expected address operand\")\n  end\n  if wb == \"!\" then op = op + 0x00200000 end\n  if p2 then\n    if wb == \"!\" then werror(\"bad use of '!'\") end\n    local p3 = params[n+2]\n    op = op + shl(parse_gpr(p1), 16)\n    local imm = match(p2, \"^#(.*)$\")\n    if imm then\n      local m = parse_imm_load(imm, ext)\n      if p3 then werror(\"too many parameters\") end\n      op = op + m + (ext and 0x00400000 or 0)\n    else\n      local m, neg = parse_gpr_pm(p2)\n      if ldrd and (m == d or m-1 == d) then werror(\"register conflict\") end\n      op = op + m + (neg and 0 or 0x00800000) + (ext and 0 or 0x02000000)\n      if p3 then op = op + parse_shift(p3) end\n    end\n  else\n    local p1a, p2 = match(p1, \"^([^,%s]*)%s*(.*)$\")\n    op = op + shl(parse_gpr(p1a), 16) + 0x01000000\n    if p2 ~= \"\" then\n      local imm = match(p2, \"^,%s*#(.*)$\")\n      if imm then\n\tlocal m = parse_imm_load(imm, ext)\n\top = op + m + (ext and 0x00400000 or 0)\n      else\n\tlocal p2a, p3 = match(p2, \"^,%s*([^,%s]*)%s*,?%s*(.*)$\")\n\tlocal m, neg = parse_gpr_pm(p2a)\n\tif ldrd and (m == d or m-1 == d) then werror(\"register conflict\") end\n\top = op + m + (neg and 0 or 0x00800000) + (ext and 0 or 0x02000000)\n\tif p3 ~= \"\" then\n\t  if ext then werror(\"too many parameters\") end\n\t  op = op + parse_shift(p3)\n\tend\n      end\n    else\n      if wb == \"!\" then werror(\"bad use of '!'\") end\n      op = op + (ext and 0x00c00000 or 0x00800000)\n    end\n  end\n  return op\nend\n\nlocal function parse_vload(q)\n  local reg, imm = match(q, \"^%[%s*([^,%s]*)%s*(.*)%]$\")\n  if reg then\n    local d = shl(parse_gpr(reg), 16)\n    if imm == \"\" then return d end\n    imm = match(imm, \"^,%s*#(.*)$\")\n    if imm then\n      local n = tonumber(imm)\n      if n then\n\tif n >= -1020 and n <= 1020 and n%4 == 0 then\n\t  return d + (n >= 0 and n/4+0x00800000 or -n/4)\n\tend\n\twerror(\"out of range immediate `\"..imm..\"'\")\n      else\n\twaction(\"IMMV8\", 32768 + 32*8, imm)\n\treturn d\n      end\n    end\n  else\n    if match(q, \"^[<>=%-]\") or match(q, \"^extern%s+\") then\n      local mode, n, s = parse_label(q, false)\n      waction(\"REL_\"..mode, n + 0x2800, s, 1)\n      return 15 * 65536\n    end\n    local reg, tailr = match(q, \"^([%w_:]+)%s*(.*)$\")\n    if reg and tailr ~= \"\" then\n      local d, tp = parse_gpr(reg)\n      if tp then\n\twaction(\"IMMV8\", 32768 + 32*8, format(tp.ctypefmt, tailr))\n\treturn shl(d, 16)\n      end\n    end\n  end\n  werror(\"expected address operand\")\nend\n\n------------------------------------------------------------------------------\n\n-- Handle opcodes defined with template strings.\nlocal function parse_template(params, template, nparams, pos)\n  local op = tonumber(sub(template, 1, 8), 16)\n  local n = 1\n  local vr = \"s\"\n\n  -- Process each character.\n  for p in gmatch(sub(template, 9), \".\") do\n    local q = params[n]\n    if p == \"D\" then\n      op = op + shl(parse_gpr(q), 12); n = n + 1\n    elseif p == \"N\" then\n      op = op + shl(parse_gpr(q), 16); n = n + 1\n    elseif p == \"S\" then\n      op = op + shl(parse_gpr(q), 8); n = n + 1\n    elseif p == \"M\" then\n      op = op + parse_gpr(q); n = n + 1\n    elseif p == \"d\" then\n      local r,h = parse_vr(q, vr); op = op+shl(r,12)+shl(h,22); n = n + 1\n    elseif p == \"n\" then\n      local r,h = parse_vr(q, vr); op = op+shl(r,16)+shl(h,7); n = n + 1\n    elseif p == \"m\" then\n      local r,h = parse_vr(q, vr); op = op+r+shl(h,5); n = n + 1\n    elseif p == \"P\" then\n      local imm = match(q, \"^#(.*)$\")\n      if imm then\n\top = op + parse_imm12(imm) + 0x02000000\n      else\n\top = op + parse_gpr(q)\n      end\n      n = n + 1\n    elseif p == \"p\" then\n      op = op + parse_shift(q, true); n = n + 1\n    elseif p == \"L\" then\n      op = parse_load(params, nparams, n, op)\n    elseif p == \"l\" then\n      op = op + parse_vload(q)\n    elseif p == \"B\" then\n      local mode, n, s = parse_label(q, false)\n      waction(\"REL_\"..mode, n, s, 1)\n    elseif p == \"C\" then -- blx gpr vs. blx label.\n      if match(q, \"^([%w_]+):(r1?[0-9])$\") or match(q, \"^r(1?[0-9])$\") then\n\top = op + parse_gpr(q)\n      else\n\tif op < 0xe0000000 then werror(\"unconditional instruction\") end\n\tlocal mode, n, s = parse_label(q, false)\n\twaction(\"REL_\"..mode, n, s, 1)\n\top = 0xfa000000\n      end\n    elseif p == \"F\" then\n      vr = \"s\"\n    elseif p == \"G\" then\n      vr = \"d\"\n    elseif p == \"o\" then\n      local r, wb = match(q, \"^([^!]*)(!?)$\")\n      op = op + shl(parse_gpr(r), 16) + (wb == \"!\" and 0x00200000 or 0)\n      n = n + 1\n    elseif p == \"R\" then\n      op = op + parse_reglist(q); n = n + 1\n    elseif p == \"r\" then\n      op = op + parse_vrlist(q); n = n + 1\n    elseif p == \"W\" then\n      op = op + parse_imm16(q); n = n + 1\n    elseif p == \"v\" then\n      op = op + parse_imm(q, 5, 7, 0, false); n = n + 1\n    elseif p == \"w\" then\n      local imm = match(q, \"^#(.*)$\")\n      if imm then\n\top = op + parse_imm(q, 5, 7, 0, false); n = n + 1\n      else\n\top = op + shl(parse_gpr(q), 8) + 16\n      end\n    elseif p == \"X\" then\n      op = op + parse_imm(q, 5, 16, 0, false); n = n + 1\n    elseif p == \"Y\" then\n      local imm = tonumber(match(q, \"^#(.*)$\")); n = n + 1\n      if not imm or shr(imm, 8) ~= 0 then\n\twerror(\"bad immediate operand\")\n      end\n      op = op + shl(band(imm, 0xf0), 12) + band(imm, 0x0f)\n    elseif p == \"K\" then\n      local imm = tonumber(match(q, \"^#(.*)$\")); n = n + 1\n      if not imm or shr(imm, 16) ~= 0 then\n\twerror(\"bad immediate operand\")\n      end\n      op = op + shl(band(imm, 0xfff0), 4) + band(imm, 0x000f)\n    elseif p == \"T\" then\n      op = op + parse_imm(q, 24, 0, 0, false); n = n + 1\n    elseif p == \"s\" then\n      -- Ignored.\n    else\n      assert(false)\n    end\n  end\n  wputpos(pos, op)\nend\n\nmap_op[\".template__\"] = function(params, template, nparams)\n  if not params then return template:gsub(\"%x%x%x%x%x%x%x%x\", \"\") end\n\n  -- Limit number of section buffer positions used by a single dasm_put().\n  -- A single opcode needs a maximum of 3 positions.\n  if secpos+3 > maxsecpos then wflush() end\n  local pos = wpos()\n  local lpos, apos, spos = #actlist, #actargs, secpos\n\n  local ok, err\n  for t in gmatch(template, \"[^|]+\") do\n    ok, err = pcall(parse_template, params, t, nparams, pos)\n    if ok then return end\n    secpos = spos\n    actlist[lpos+1] = nil\n    actlist[lpos+2] = nil\n    actlist[lpos+3] = nil\n    actargs[apos+1] = nil\n    actargs[apos+2] = nil\n    actargs[apos+3] = nil\n  end\n  error(err, 0)\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode to mark the position where the action list is to be emitted.\nmap_op[\".actionlist_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeactions(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the global enum is to be emitted.\nmap_op[\".globals_1\"] = function(params)\n  if not params then return \"prefix\" end\n  local prefix = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobals(out, prefix) end)\nend\n\n-- Pseudo-opcode to mark the position where the global names are to be emitted.\nmap_op[\".globalnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobalnames(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the extern names are to be emitted.\nmap_op[\".externnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeexternnames(out, name) end)\nend\n\n------------------------------------------------------------------------------\n\n-- Label pseudo-opcode (converted from trailing colon form).\nmap_op[\".label_1\"] = function(params)\n  if not params then return \"[1-9] | ->global | =>pcexpr\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local mode, n, s = parse_label(params[1], true)\n  if mode == \"EXT\" then werror(\"bad label definition\") end\n  waction(\"LABEL_\"..mode, n, s, 1)\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcodes for data storage.\nmap_op[\".long_*\"] = function(params)\n  if not params then return \"imm...\" end\n  for _,p in ipairs(params) do\n    local n = tonumber(p)\n    if not n then werror(\"bad immediate `\"..p..\"'\") end\n    if n < 0 then n = n + 2^32 end\n    wputw(n)\n    if secpos+2 > maxsecpos then wflush() end\n  end\nend\n\n-- Alignment pseudo-opcode.\nmap_op[\".align_1\"] = function(params)\n  if not params then return \"numpow2\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local align = tonumber(params[1])\n  if align then\n    local x = align\n    -- Must be a power of 2 in the range (2 ... 256).\n    for i=1,8 do\n      x = x / 2\n      if x == 1 then\n\twaction(\"ALIGN\", align-1, nil, 1) -- Action byte is 2**n-1.\n\treturn\n      end\n    end\n  end\n  werror(\"bad alignment\")\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode for (primitive) type definitions (map to C types).\nmap_op[\".type_3\"] = function(params, nparams)\n  if not params then\n    return nparams == 2 and \"name, ctype\" or \"name, ctype, reg\"\n  end\n  local name, ctype, reg = params[1], params[2], params[3]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    werror(\"bad type name `\"..name..\"'\")\n  end\n  local tp = map_type[name]\n  if tp then\n    werror(\"duplicate type `\"..name..\"'\")\n  end\n  -- Add #type to defines. A bit unclean to put it in map_archdef.\n  map_archdef[\"#\"..name] = \"sizeof(\"..ctype..\")\"\n  -- Add new type and emit shortcut define.\n  local num = ctypenum + 1\n  map_type[name] = {\n    ctype = ctype,\n    ctypefmt = format(\"Dt%X(%%s)\", num),\n    reg = reg,\n  }\n  wline(format(\"#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)\", num, ctype))\n  ctypenum = num\nend\nmap_op[\".type_2\"] = map_op[\".type_3\"]\n\n-- Dump type definitions.\nlocal function dumptypes(out, lvl)\n  local t = {}\n  for name in pairs(map_type) do t[#t+1] = name end\n  sort(t)\n  out:write(\"Type definitions:\\n\")\n  for _,name in ipairs(t) do\n    local tp = map_type[name]\n    local reg = tp.reg or \"\"\n    out:write(format(\"  %-20s %-20s %s\\n\", name, tp.ctype, reg))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Set the current section.\nfunction _M.section(num)\n  waction(\"SECTION\", num)\n  wflush(true) -- SECTION is a terminal action.\nend\n\n------------------------------------------------------------------------------\n\n-- Dump architecture description.\nfunction _M.dumparch(out)\n  out:write(format(\"DynASM %s version %s, released %s\\n\\n\",\n    _info.arch, _info.version, _info.release))\n  dumpactions(out)\nend\n\n-- Dump all user defined elements.\nfunction _M.dumpdef(out, lvl)\n  dumptypes(out, lvl)\n  dumpglobals(out, lvl)\n  dumpexterns(out, lvl)\nend\n\n------------------------------------------------------------------------------\n\n-- Pass callbacks from/to the DynASM core.\nfunction _M.passcb(wl, we, wf, ww)\n  wline, werror, wfatal, wwarn = wl, we, wf, ww\n  return wflush\nend\n\n-- Setup the arch-specific module.\nfunction _M.setup(arch, opt)\n  g_arch, g_opt = arch, opt\nend\n\n-- Merge the core maps and the arch-specific maps.\nfunction _M.mergemaps(map_coreop, map_def)\n  setmetatable(map_op, { __index = function(t, k)\n    local v = map_coreop[k]\n    if v then return v end\n    local k1, cc, k2 = match(k, \"^(.-)(..)([._].*)$\")\n    local cv = map_cond[cc]\n    if cv then\n      local v = rawget(t, k1..k2)\n      if type(v) == \"string\" then\n\tlocal scv = format(\"%x\", cv)\n\treturn gsub(scv..sub(v, 2), \"|e\", \"|\"..scv)\n      end\n    end\n  end })\n  setmetatable(map_def, { __index = map_archdef })\n  return map_op, map_def\nend\n\nreturn _M\n\n------------------------------------------------------------------------------\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_arm64.h",
    "content": "/*\n** DynASM ARM64 encoding engine.\n** Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n** Released under the MIT license. See dynasm.lua for full copyright notice.\n*/\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define DASM_ARCH\t\t\"arm64\"\n\n#ifndef DASM_EXTERN\n#define DASM_EXTERN(a,b,c,d)\t0\n#endif\n\n/* Action definitions. */\nenum {\n  DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,\n  /* The following actions need a buffer position. */\n  DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,\n  /* The following actions also have an argument. */\n  DASM_REL_PC, DASM_LABEL_PC, DASM_REL_A,\n  DASM_IMM, DASM_IMM6, DASM_IMM12, DASM_IMM13W, DASM_IMM13X, DASM_IMML,\n  DASM_IMMV, DASM_VREG,\n  DASM__MAX\n};\n\n/* Maximum number of section buffer positions for a single dasm_put() call. */\n#define DASM_MAXSECPOS\t\t25\n\n/* DynASM encoder status codes. Action list offset or number are or'ed in. */\n#define DASM_S_OK\t\t0x00000000\n#define DASM_S_NOMEM\t\t0x01000000\n#define DASM_S_PHASE\t\t0x02000000\n#define DASM_S_MATCH_SEC\t0x03000000\n#define DASM_S_RANGE_I\t\t0x11000000\n#define DASM_S_RANGE_SEC\t0x12000000\n#define DASM_S_RANGE_LG\t\t0x13000000\n#define DASM_S_RANGE_PC\t\t0x14000000\n#define DASM_S_RANGE_REL\t0x15000000\n#define DASM_S_RANGE_VREG\t0x16000000\n#define DASM_S_UNDEF_LG\t\t0x21000000\n#define DASM_S_UNDEF_PC\t\t0x22000000\n\n/* Macros to convert positions (8 bit section + 24 bit index). */\n#define DASM_POS2IDX(pos)\t((pos)&0x00ffffff)\n#define DASM_POS2BIAS(pos)\t((pos)&0xff000000)\n#define DASM_SEC2POS(sec)\t((sec)<<24)\n#define DASM_POS2SEC(pos)\t((pos)>>24)\n#define DASM_POS2PTR(D, pos)\t(D->sections[DASM_POS2SEC(pos)].rbuf + (pos))\n\n/* Action list type. */\ntypedef const unsigned int *dasm_ActList;\n\n/* Per-section structure. */\ntypedef struct dasm_Section {\n  int *rbuf;\t\t/* Biased buffer pointer (negative section bias). */\n  int *buf;\t\t/* True buffer pointer. */\n  size_t bsize;\t\t/* Buffer size in bytes. */\n  int pos;\t\t/* Biased buffer position. */\n  int epos;\t\t/* End of biased buffer position - max single put. */\n  int ofs;\t\t/* Byte offset into section. */\n} dasm_Section;\n\n/* Core structure holding the DynASM encoding state. */\nstruct dasm_State {\n  size_t psize;\t\t\t/* Allocated size of this structure. */\n  dasm_ActList actionlist;\t/* Current actionlist pointer. */\n  int *lglabels;\t\t/* Local/global chain/pos ptrs. */\n  size_t lgsize;\n  int *pclabels;\t\t/* PC label chains/pos ptrs. */\n  size_t pcsize;\n  void **globals;\t\t/* Array of globals (bias -10). */\n  dasm_Section *section;\t/* Pointer to active section. */\n  size_t codesize;\t\t/* Total size of all code sections. */\n  int maxsection;\t\t/* 0 <= sectionidx < maxsection. */\n  int status;\t\t\t/* Status code. */\n  dasm_Section sections[1];\t/* All sections. Alloc-extended. */\n};\n\n/* The size of the core structure depends on the max. number of sections. */\n#define DASM_PSZ(ms)\t(sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))\n\n\n/* Initialize DynASM state. */\nvoid dasm_init(Dst_DECL, int maxsection)\n{\n  dasm_State *D;\n  size_t psz = 0;\n  int i;\n  Dst_REF = NULL;\n  DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));\n  D = Dst_REF;\n  D->psize = psz;\n  D->lglabels = NULL;\n  D->lgsize = 0;\n  D->pclabels = NULL;\n  D->pcsize = 0;\n  D->globals = NULL;\n  D->maxsection = maxsection;\n  for (i = 0; i < maxsection; i++) {\n    D->sections[i].buf = NULL;  /* Need this for pass3. */\n    D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);\n    D->sections[i].bsize = 0;\n    D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */\n  }\n}\n\n/* Free DynASM state. */\nvoid dasm_free(Dst_DECL)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  for (i = 0; i < D->maxsection; i++)\n    if (D->sections[i].buf)\n      DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);\n  if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);\n  if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);\n  DASM_M_FREE(Dst, D, D->psize);\n}\n\n/* Setup global label array. Must be called before dasm_setup(). */\nvoid dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)\n{\n  dasm_State *D = Dst_REF;\n  D->globals = gl - 10;  /* Negative bias to compensate for locals. */\n  DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));\n}\n\n/* Grow PC label array. Can be called after dasm_setup(), too. */\nvoid dasm_growpc(Dst_DECL, unsigned int maxpc)\n{\n  dasm_State *D = Dst_REF;\n  size_t osz = D->pcsize;\n  DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));\n  memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);\n}\n\n/* Setup encoder. */\nvoid dasm_setup(Dst_DECL, const void *actionlist)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  D->actionlist = (dasm_ActList)actionlist;\n  D->status = DASM_S_OK;\n  D->section = &D->sections[0];\n  memset((void *)D->lglabels, 0, D->lgsize);\n  if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);\n  for (i = 0; i < D->maxsection; i++) {\n    D->sections[i].pos = DASM_SEC2POS(i);\n    D->sections[i].ofs = 0;\n  }\n}\n\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) { \\\n    D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)\n#define CKPL(kind, st) \\\n  do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \\\n    D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#define CKPL(kind, st)\t((void)0)\n#endif\n\nstatic int dasm_imm12(unsigned int n)\n{\n  if ((n >> 12) == 0)\n    return n;\n  else if ((n & 0xff000fff) == 0)\n    return (n >> 12) | 0x1000;\n  else\n    return -1;\n}\n\nstatic int dasm_ffs(unsigned long long x)\n{\n  int n = -1;\n  while (x) { x >>= 1; n++; }\n  return n;\n}\n\nstatic int dasm_imm13(int lo, int hi)\n{\n  int inv = 0, w = 64, s = 0xfff, xa, xb;\n  unsigned long long n = (((unsigned long long)hi) << 32) | (unsigned int)lo;\n  unsigned long long m = 1ULL, a, b, c;\n  if (n & 1) { n = ~n; inv = 1; }\n  a = n & (unsigned long long)-(long long)n;\n  b = (n+a)&(unsigned long long)-(long long)(n+a);\n  c = (n+a-b)&(unsigned long long)-(long long)(n+a-b);\n  xa = dasm_ffs(a); xb = dasm_ffs(b);\n  if (c) {\n    w = dasm_ffs(c) - xa;\n    if (w == 32) m = 0x0000000100000001UL;\n    else if (w == 16) m = 0x0001000100010001UL;\n    else if (w == 8) m = 0x0101010101010101UL;\n    else if (w == 4) m = 0x1111111111111111UL;\n    else if (w == 2) m = 0x5555555555555555UL;\n    else return -1;\n    s = (-2*w & 0x3f) - 1;\n  } else if (!a) {\n    return -1;\n  } else if (xb == -1) {\n    xb = 64;\n  }\n  if ((b-a) * m != n) return -1;\n  if (inv) {\n    return ((w - xb) << 6) | (s+w+xa-xb);\n  } else {\n    return ((w - xa) << 6) | (s+xb-xa);\n  }\n  return -1;\n}\n\n/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */\nvoid dasm_put(Dst_DECL, int start, ...)\n{\n  va_list ap;\n  dasm_State *D = Dst_REF;\n  dasm_ActList p = D->actionlist + start;\n  dasm_Section *sec = D->section;\n  int pos = sec->pos, ofs = sec->ofs;\n  int *b;\n\n  if (pos >= sec->epos) {\n    DASM_M_GROW(Dst, int, sec->buf, sec->bsize,\n      sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));\n    sec->rbuf = sec->buf - DASM_POS2BIAS(pos);\n    sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);\n  }\n\n  b = sec->rbuf;\n  b[pos++] = start;\n\n  va_start(ap, start);\n  while (1) {\n    unsigned int ins = *p++;\n    unsigned int action = (ins >> 16);\n    if (action >= DASM__MAX) {\n      ofs += 4;\n    } else {\n      int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;\n      switch (action) {\n      case DASM_STOP: goto stop;\n      case DASM_SECTION:\n\tn = (ins & 255); CK(n < D->maxsection, RANGE_SEC);\n\tD->section = &D->sections[n]; goto stop;\n      case DASM_ESC: p++; ofs += 4; break;\n      case DASM_REL_EXT: if ((ins & 0x8000)) ofs += 8; break;\n      case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;\n      case DASM_REL_LG:\n\tn = (ins & 2047) - 10; pl = D->lglabels + n;\n\t/* Bkwd rel or global. */\n\tif (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }\n\tpl += 10; n = *pl;\n\tif (n < 0) n = 0;  /* Start new chain for fwd rel if label exists. */\n\tgoto linkrel;\n      case DASM_REL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putrel:\n\tn = *pl;\n\tif (n < 0) {  /* Label exists. Get label pos and store it. */\n\t  b[pos] = -n;\n\t} else {\n      linkrel:\n\t  b[pos] = n;  /* Else link to rel chain, anchored at label. */\n\t  *pl = pos;\n\t}\n\tpos++;\n\tif ((ins & 0x8000)) ofs += 8;\n\tbreak;\n      case DASM_REL_A:\n\tb[pos++] = n;\n\tb[pos++] = va_arg(ap, int);\n\tbreak;\n      case DASM_LABEL_LG:\n\tpl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;\n      case DASM_LABEL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putlabel:\n\tn = *pl;  /* n > 0: Collapse rel chain and replace with label pos. */\n\twhile (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;\n\t}\n\t*pl = -pos;  /* Label exists now. */\n\tb[pos++] = ofs;  /* Store pass1 offset estimate. */\n\tbreak;\n      case DASM_IMM:\n\tCK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);\n\tn >>= ((ins>>10)&31);\n#ifdef DASM_CHECKS\n\tif ((ins & 0x8000))\n\t  CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);\n\telse\n\t  CK((n>>((ins>>5)&31)) == 0, RANGE_I);\n#endif\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMM6:\n\tCK((n >> 6) == 0, RANGE_I);\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMM12:\n\tCK(dasm_imm12((unsigned int)n) != -1, RANGE_I);\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMM13W:\n\tCK(dasm_imm13(n, n) != -1, RANGE_I);\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMM13X: {\n\tint m = va_arg(ap, int);\n\tCK(dasm_imm13(n, m) != -1, RANGE_I);\n\tb[pos++] = n;\n\tb[pos++] = m;\n\tbreak;\n\t}\n      case DASM_IMML: {\n#ifdef DASM_CHECKS\n\tint scale = (ins & 3);\n\tCK((!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ||\n\t   (unsigned int)(n+256) < 512, RANGE_I);\n#endif\n\tb[pos++] = n;\n\tbreak;\n\t}\n      case DASM_IMMV:\n\tofs += 4;\n\tb[pos++] = n;\n\tbreak;\n      case DASM_VREG:\n\tCK(n < 32, RANGE_VREG);\n\tb[pos++] = n;\n\tbreak;\n      }\n    }\n  }\nstop:\n  va_end(ap);\n  sec->pos = pos;\n  sec->ofs = ofs;\n}\n#undef CK\n\n/* Pass 2: Link sections, shrink aligns, fix label offsets. */\nint dasm_link(Dst_DECL, size_t *szp)\n{\n  dasm_State *D = Dst_REF;\n  int secnum;\n  int ofs = 0;\n\n#ifdef DASM_CHECKS\n  *szp = 0;\n  if (D->status != DASM_S_OK) return D->status;\n  {\n    int pc;\n    for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)\n      if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;\n  }\n#endif\n\n  { /* Handle globals not defined in this translation unit. */\n    int idx;\n    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {\n      int n = D->lglabels[idx];\n      /* Undefined label: Collapse rel chain and replace with marker (< 0). */\n      while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }\n    }\n  }\n\n  /* Combine all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->rbuf;\n    int pos = DASM_SEC2POS(secnum);\n    int lastpos = sec->pos;\n\n    while (pos != lastpos) {\n      dasm_ActList p = D->actionlist + b[pos++];\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16);\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: p++; break;\n\tcase DASM_REL_EXT: break;\n\tcase DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;\n\tcase DASM_REL_LG: case DASM_REL_PC: pos++; break;\n\tcase DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;\n\tcase DASM_IMM: case DASM_IMM6: case DASM_IMM12: case DASM_IMM13W:\n\tcase DASM_IMML: case DASM_IMMV: case DASM_VREG: pos++; break;\n\tcase DASM_IMM13X: case DASM_REL_A: pos += 2; break;\n\t}\n      }\n      stop: (void)0;\n    }\n    ofs += sec->ofs;  /* Next section starts right after current section. */\n  }\n\n  D->codesize = ofs;  /* Total size of all code sections */\n  *szp = ofs;\n  return DASM_S_OK;\n}\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#endif\n\n/* Pass 3: Encode sections. */\nint dasm_encode(Dst_DECL, void *buffer)\n{\n  dasm_State *D = Dst_REF;\n  char *base = (char *)buffer;\n  unsigned int *cp = (unsigned int *)buffer;\n  int secnum;\n\n  /* Encode all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->buf;\n    int *endb = sec->rbuf + sec->pos;\n\n    while (b != endb) {\n      dasm_ActList p = D->actionlist + *b++;\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16);\n\tint n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: *cp++ = *p++; break;\n\tcase DASM_REL_EXT:\n\t  n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins&2047), !(ins&2048));\n\t  goto patchrel;\n\tcase DASM_ALIGN:\n\t  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0xd503201f;\n\t  break;\n\tcase DASM_REL_LG:\n\t  if (n < 0) {\n\t    ptrdiff_t na = (ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp + 4;\n\t    n = (int)na;\n\t    CK((ptrdiff_t)n == na, RANGE_REL);\n\t    goto patchrel;\n\t  }\n\t  /* fallthrough */\n\tcase DASM_REL_PC:\n\t  CK(n >= 0, UNDEF_PC);\n\t  n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base) + 4;\n\tpatchrel:\n\t  if (!(ins & 0xf800)) {  /* B, BL */\n\t    CK((n & 3) == 0 && ((n+0x08000000) >> 28) == 0, RANGE_REL);\n\t    cp[-1] |= ((n >> 2) & 0x03ffffff);\n\t  } else if ((ins & 0x800)) {  /* B.cond, CBZ, CBNZ, LDR* literal */\n\t    CK((n & 3) == 0 && ((n+0x00100000) >> 21) == 0, RANGE_REL);\n\t    cp[-1] |= ((n << 3) & 0x00ffffe0);\n\t  } else if ((ins & 0x3000) == 0x2000) {  /* ADR */\n\t    CK(((n+0x00100000) >> 21) == 0, RANGE_REL);\n\t    cp[-1] |= ((n << 3) & 0x00ffffe0) | ((n & 3) << 29);\n\t  } else if ((ins & 0x3000) == 0x3000) {  /* ADRP */\n\t    cp[-1] |= ((n >> 9) & 0x00ffffe0) | (((n >> 12) & 3) << 29);\n\t  } else if ((ins & 0x1000)) {  /* TBZ, TBNZ */\n\t    CK((n & 3) == 0 && ((n+0x00008000) >> 16) == 0, RANGE_REL);\n\t    cp[-1] |= ((n << 3) & 0x0007ffe0);\n\t  } else if ((ins & 0x8000)) {  /* absolute */\n\t    cp[0] = (unsigned int)((ptrdiff_t)cp - 4 + n);\n\t    cp[1] = (unsigned int)(((ptrdiff_t)cp - 4 + n) >> 32);\n\t    cp += 2;\n\t  }\n\t  break;\n\tcase DASM_REL_A: {\n\t  ptrdiff_t na = (((ptrdiff_t)(*b++) << 32) | (unsigned int)n);\n\t  if ((ins & 0x3000) == 0x3000) {  /* ADRP */\n\t    ins &= ~0x1000;\n\t    na = (na >> 12) - (((ptrdiff_t)cp - 4) >> 12);\n\t  } else {\n\t    na = na - (ptrdiff_t)cp + 4;\n\t  }\n\t  n = (int)na;\n\t  CK((ptrdiff_t)n == na, RANGE_REL);\n\t  goto patchrel;\n\t}\n\tcase DASM_LABEL_LG:\n\t  ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);\n\t  break;\n\tcase DASM_LABEL_PC: break;\n\tcase DASM_IMM:\n\t  cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);\n\t  break;\n\tcase DASM_IMM6:\n\t  cp[-1] |= ((n&31) << 19) | ((n&32) << 26);\n\t  break;\n\tcase DASM_IMM12:\n\t  cp[-1] |= (dasm_imm12((unsigned int)n) << 10);\n\t  break;\n\tcase DASM_IMM13W:\n\t  cp[-1] |= (dasm_imm13(n, n) << 10);\n\t  break;\n\tcase DASM_IMM13X:\n\t  cp[-1] |= (dasm_imm13(n, *b++) << 10);\n\t  break;\n\tcase DASM_IMML: {\n\t  int scale = (ins & 3);\n\t  cp[-1] |= (!(n & ((1<<scale)-1)) && (unsigned int)(n>>scale) < 4096) ?\n\t    ((n << (10-scale)) | 0x01000000) : ((n & 511) << 12);\n\t  break;\n\t  }\n\tcase DASM_IMMV:\n\t  *cp++ = n;\n\t  break;\n\tcase DASM_VREG:\n\t  cp[-1] |= (n & 0x1f) << (ins & 0x1f);\n\t  break;\n\tdefault: *cp++ = ins; break;\n\t}\n      }\n      stop: (void)0;\n    }\n  }\n\n  if (base + D->codesize != (char *)cp)  /* Check for phase errors. */\n    return DASM_S_PHASE;\n  return DASM_S_OK;\n}\n#undef CK\n\n/* Get PC label offset. */\nint dasm_getpclabel(Dst_DECL, unsigned int pc)\n{\n  dasm_State *D = Dst_REF;\n  if (pc*sizeof(int) < D->pcsize) {\n    int pos = D->pclabels[pc];\n    if (pos < 0) return *DASM_POS2PTR(D, -pos);\n    if (pos > 0) return -1;  /* Undefined. */\n  }\n  return -2;  /* Unused or out of range. */\n}\n\n#ifdef DASM_CHECKS\n/* Optional sanity checker to call between isolated encoding steps. */\nint dasm_checkstep(Dst_DECL, int secmatch)\n{\n  dasm_State *D = Dst_REF;\n  if (D->status == DASM_S_OK) {\n    int i;\n    for (i = 1; i <= 9; i++) {\n      if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }\n      D->lglabels[i] = 0;\n    }\n  }\n  if (D->status == DASM_S_OK && secmatch >= 0 &&\n      D->section != &D->sections[secmatch])\n    D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);\n  return D->status;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_arm64.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM ARM64 module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n------------------------------------------------------------------------------\n\n-- Module information:\nlocal _info = {\n  arch =\t\"arm\",\n  description =\t\"DynASM ARM64 module\",\n  version =\t\"1.5.0\",\n  vernum =\t 10500,\n  release =\t\"2021-05-02\",\n  author =\t\"Mike Pall\",\n  license =\t\"MIT\",\n}\n\n-- Exported glue functions for the arch-specific module.\nlocal _M = { _info = _info }\n\n-- Cache library functions.\nlocal type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs\nlocal assert, setmetatable, rawget = assert, setmetatable, rawget\nlocal _s = string\nlocal format, byte, char = _s.format, _s.byte, _s.char\nlocal match, gmatch, gsub = _s.match, _s.gmatch, _s.gsub\nlocal concat, sort, insert = table.concat, table.sort, table.insert\nlocal bit = bit or require(\"bit\")\nlocal band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift\nlocal ror, tohex, tobit = bit.ror, bit.tohex, bit.tobit\n\n-- Inherited tables and callbacks.\nlocal g_opt, g_arch\nlocal wline, werror, wfatal, wwarn\n\n-- Action name list.\n-- CHECK: Keep this in sync with the C code!\nlocal action_names = {\n  \"STOP\", \"SECTION\", \"ESC\", \"REL_EXT\",\n  \"ALIGN\", \"REL_LG\", \"LABEL_LG\",\n  \"REL_PC\", \"LABEL_PC\", \"REL_A\",\n  \"IMM\", \"IMM6\", \"IMM12\", \"IMM13W\", \"IMM13X\", \"IMML\", \"IMMV\",\n  \"VREG\",\n}\n\n-- Maximum number of section buffer positions for dasm_put().\n-- CHECK: Keep this in sync with the C code!\nlocal maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.\n\n-- Action name -> action number.\nlocal map_action = {}\nfor n,name in ipairs(action_names) do\n  map_action[name] = n-1\nend\n\n-- Action list buffer.\nlocal actlist = {}\n\n-- Argument list for next dasm_put(). Start with offset 0 into action list.\nlocal actargs = { 0 }\n\n-- Current number of section buffer positions for dasm_put().\nlocal secpos = 1\n\n------------------------------------------------------------------------------\n\n-- Dump action names and numbers.\nlocal function dumpactions(out)\n  out:write(\"DynASM encoding engine action codes:\\n\")\n  for n,name in ipairs(action_names) do\n    local num = map_action[name]\n    out:write(format(\"  %-10s %02X  %d\\n\", name, num, num))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write action list buffer as a huge static C array.\nlocal function writeactions(out, name)\n  local nn = #actlist\n  if nn == 0 then nn = 1; actlist[0] = map_action.STOP end\n  out:write(\"static const unsigned int \", name, \"[\", nn, \"] = {\\n\")\n  for i = 1,nn-1 do\n    assert(out:write(\"0x\", tohex(actlist[i]), \",\\n\"))\n  end\n  assert(out:write(\"0x\", tohex(actlist[nn]), \"\\n};\\n\\n\"))\nend\n\n------------------------------------------------------------------------------\n\n-- Add word to action list.\nlocal function wputxw(n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  actlist[#actlist+1] = n\nend\n\n-- Add action to list with optional arg. Advance buffer pos, too.\nlocal function waction(action, val, a, num)\n  local w = assert(map_action[action], \"bad action name `\"..action..\"'\")\n  wputxw(w * 0x10000 + (val or 0))\n  if a then actargs[#actargs+1] = a end\n  if a or num then secpos = secpos + (num or 1) end\nend\n\n-- Flush action list (intervening C code or buffer pos overflow).\nlocal function wflush(term)\n  if #actlist == actargs[1] then return end -- Nothing to flush.\n  if not term then waction(\"STOP\") end -- Terminate action list.\n  wline(format(\"dasm_put(Dst, %s);\", concat(actargs, \", \")), true)\n  actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().\n  secpos = 1 -- The actionlist offset occupies a buffer position, too.\nend\n\n-- Put escaped word.\nlocal function wputw(n)\n  if n <= 0x000fffff then waction(\"ESC\") end\n  wputxw(n)\nend\n\n-- Reserve position for word.\nlocal function wpos()\n  local pos = #actlist+1\n  actlist[pos] = \"\"\n  return pos\nend\n\n-- Store word to reserved position.\nlocal function wputpos(pos, n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  if n <= 0x000fffff then\n    insert(actlist, pos+1, n)\n    n = map_action.ESC * 0x10000\n  end\n  actlist[pos] = n\nend\n\n------------------------------------------------------------------------------\n\n-- Global label name -> global label number. With auto assignment on 1st use.\nlocal next_global = 20\nlocal map_global = setmetatable({}, { __index = function(t, name)\n  if not match(name, \"^[%a_][%w_]*$\") then werror(\"bad global label\") end\n  local n = next_global\n  if n > 2047 then werror(\"too many global labels\") end\n  next_global = n + 1\n  t[name] = n\n  return n\nend})\n\n-- Dump global labels.\nlocal function dumpglobals(out, lvl)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"Global labels:\\n\")\n  for i=20,next_global-1 do\n    out:write(format(\"  %s\\n\", t[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write global label enum.\nlocal function writeglobals(out, prefix)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"enum {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \", prefix, t[i], \",\\n\")\n  end\n  out:write(\"  \", prefix, \"_MAX\\n};\\n\")\nend\n\n-- Write global label names.\nlocal function writeglobalnames(out, name)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \\\"\", t[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Extern label name -> extern label number. With auto assignment on 1st use.\nlocal next_extern = 0\nlocal map_extern_ = {}\nlocal map_extern = setmetatable({}, { __index = function(t, name)\n  -- No restrictions on the name for now.\n  local n = next_extern\n  if n > 2047 then werror(\"too many extern labels\") end\n  next_extern = n + 1\n  t[name] = n\n  map_extern_[n] = name\n  return n\nend})\n\n-- Dump extern labels.\nlocal function dumpexterns(out, lvl)\n  out:write(\"Extern labels:\\n\")\n  for i=0,next_extern-1 do\n    out:write(format(\"  %s\\n\", map_extern_[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write extern label names.\nlocal function writeexternnames(out, name)\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=0,next_extern-1 do\n    out:write(\"  \\\"\", map_extern_[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Arch-specific maps.\n\n-- Ext. register name -> int. name.\nlocal map_archdef = { xzr = \"@x31\", wzr = \"@w31\", lr = \"x30\", }\n\n-- Int. register name -> ext. name.\nlocal map_reg_rev = { [\"@x31\"] = \"xzr\", [\"@w31\"] = \"wzr\", x30 = \"lr\", }\n\nlocal map_type = {}\t\t-- Type name -> { ctype, reg }\nlocal ctypenum = 0\t\t-- Type number (for Dt... macros).\n\n-- Reverse defines for registers.\nfunction _M.revdef(s)\n  return map_reg_rev[s] or s\nend\n\nlocal map_shift = { lsl = 0, lsr = 1, asr = 2, }\n\nlocal map_extend = {\n  uxtb = 0, uxth = 1, uxtw = 2, uxtx = 3,\n  sxtb = 4, sxth = 5, sxtw = 6, sxtx = 7,\n}\n\nlocal map_cond = {\n  eq = 0, ne = 1, cs = 2, cc = 3, mi = 4, pl = 5, vs = 6, vc = 7,\n  hi = 8, ls = 9, ge = 10, lt = 11, gt = 12, le = 13, al = 14,\n  hs = 2, lo = 3,\n}\n\n------------------------------------------------------------------------------\n\nlocal parse_reg_type\n\nlocal function parse_reg(expr, shift, no_vreg)\n  if not expr then werror(\"expected register name\") end\n  local tname, ovreg = match(expr, \"^([%w_]+):(@?%l%d+)$\")\n  if not tname then\n    tname, ovreg = match(expr, \"^([%w_]+):(R[xwqdshb]%b())$\")\n  end\n  local tp = map_type[tname or expr]\n  if tp then\n    local reg = ovreg or tp.reg\n    if not reg then\n      werror(\"type `\"..(tname or expr)..\"' needs a register override\")\n    end\n    expr = reg\n  end\n  local ok31, rt, r = match(expr, \"^(@?)([xwqdshb])([123]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 30 or (r == 31 and ok31 ~= \"\" or (rt ~= \"w\" and rt ~= \"x\")) then\n      if not parse_reg_type then\n\tparse_reg_type = rt\n      elseif parse_reg_type ~= rt then\n\twerror(\"register size mismatch\")\n      end\n      return shl(r, shift), tp\n    end\n  end\n  local vrt, vreg = match(expr, \"^R([xwqdshb])(%b())$\")\n  if vreg then\n    if not parse_reg_type then\n      parse_reg_type = vrt\n    elseif parse_reg_type ~= vrt then\n      werror(\"register size mismatch\")\n    end\n    if not no_vreg then waction(\"VREG\", shift, vreg) end\n    return 0\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_reg_base(expr)\n  if expr == \"sp\" then return 0x3e0 end\n  local base, tp = parse_reg(expr, 5)\n  if parse_reg_type ~= \"x\" then werror(\"bad register type\") end\n  parse_reg_type = false\n  return base, tp\nend\n\nlocal parse_ctx = {}\n\nlocal loadenv = setfenv and function(s)\n  local code = loadstring(s, \"\")\n  if code then setfenv(code, parse_ctx) end\n  return code\nend or function(s)\n  return load(s, \"\", nil, parse_ctx)\nend\n\n-- Try to parse simple arithmetic, too, since some basic ops are aliases.\nlocal function parse_number(n)\n  local x = tonumber(n)\n  if x then return x end\n  local code = loadenv(\"return \"..n)\n  if code then\n    local ok, y = pcall(code)\n    if ok and type(y) == \"number\" then return y end\n  end\n  return nil\nend\n\nlocal function parse_imm(imm, bits, shift, scale, signed)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = parse_number(imm)\n  if n then\n    local m = sar(n, scale)\n    if shl(m, scale) == n then\n      if signed then\n\tlocal s = sar(m, bits-1)\n\tif s == 0 then return shl(m, shift)\n\telseif s == -1 then return shl(m + shl(1, bits), shift) end\n      else\n\tif sar(m, bits) == 0 then return shl(m, shift) end\n      end\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMM\", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm12(imm)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = parse_number(imm)\n  if n then\n    if shr(n, 12) == 0 then\n      return shl(n, 10)\n    elseif band(n, 0xff000fff) == 0 then\n      return shr(n, 2) + 0x00400000\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMM12\", 0, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm13(imm)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = parse_number(imm)\n  local r64 = parse_reg_type == \"x\"\n  if n and n % 1 == 0 and n >= 0 and n <= 0xffffffff then\n    local inv = false\n    if band(n, 1) == 1 then n = bit.bnot(n); inv = true end\n    local t = {}\n    for i=1,32 do t[i] = band(n, 1); n = shr(n, 1) end\n    local b = table.concat(t)\n    b = b..(r64 and (inv and \"1\" or \"0\"):rep(32) or b)\n    local p0, p1, p0a, p1a = b:match(\"^(0+)(1+)(0*)(1*)\")\n    if p0 then\n      local w = p1a == \"\" and (r64 and 64 or 32) or #p1+#p0a\n      if band(w, w-1) == 0 and b == b:sub(1, w):rep(64/w) then\n\tlocal s = band(-2*w, 0x3f) - 1\n\tif w == 64 then s = s + 0x1000 end\n\tif inv then\n\t  return shl(w-#p1-#p0, 16) + shl(s+w-#p1, 10)\n\telse\n\t  return shl(w-#p0, 16) + shl(s+#p1, 10)\n\tend\n      end\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  elseif r64 then\n    waction(\"IMM13X\", 0, format(\"(unsigned int)(%s)\", imm))\n    actargs[#actargs+1] = format(\"(unsigned int)((unsigned long long)(%s)>>32)\", imm)\n    return 0\n  else\n    waction(\"IMM13W\", 0, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm6(imm)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = parse_number(imm)\n  if n then\n    if n >= 0 and n <= 63 then\n      return shl(band(n, 0x1f), 19) + (n >= 32 and 0x80000000 or 0)\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMM6\", 0, imm)\n    return 0\n  end\nend\n\nlocal function parse_imm_load(imm, scale)\n  local n = parse_number(imm)\n  if n then\n    local m = sar(n, scale)\n    if shl(m, scale) == n and m >= 0 and m < 0x1000 then\n      return shl(m, 10) + 0x01000000 -- Scaled, unsigned 12 bit offset.\n    elseif n >= -256 and n < 256 then\n      return shl(band(n, 511), 12) -- Unscaled, signed 9 bit offset.\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    waction(\"IMML\", scale, imm)\n    return 0\n  end\nend\n\nlocal function parse_fpimm(imm)\n  imm = match(imm, \"^#(.*)$\")\n  if not imm then werror(\"expected immediate operand\") end\n  local n = parse_number(imm)\n  if n then\n    local m, e = math.frexp(n)\n    local s, e2 = 0, band(e-2, 7)\n    if m < 0 then m = -m; s = 0x00100000 end\n    m = m*32-16\n    if m % 1 == 0 and m >= 0 and m <= 15 and sar(shl(e2, 29), 29)+2 == e then\n      return s + shl(e2, 17) + shl(m, 13)\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  else\n    werror(\"NYI fpimm action\")\n  end\nend\n\nlocal function parse_shift(expr)\n  local s, s2 = match(expr, \"^(%S+)%s*(.*)$\")\n  s = map_shift[s]\n  if not s then werror(\"expected shift operand\") end\n  return parse_imm(s2, 6, 10, 0, false) + shl(s, 22)\nend\n\nlocal function parse_lslx16(expr)\n  local n = match(expr, \"^lsl%s*#(%d+)$\")\n  n = tonumber(n)\n  if not n then werror(\"expected shift operand\") end\n  if band(n, parse_reg_type == \"x\" and 0xffffffcf or 0xffffffef) ~= 0 then\n    werror(\"bad shift amount\")\n  end\n  return shl(n, 17)\nend\n\nlocal function parse_extend(expr)\n  local s, s2 = match(expr, \"^(%S+)%s*(.*)$\")\n  if s == \"lsl\" then\n    s = parse_reg_type == \"x\" and 3 or 2\n  else\n    s = map_extend[s]\n  end\n  if not s then werror(\"expected extend operand\") end\n  return (s2 == \"\" and 0 or parse_imm(s2, 3, 10, 0, false)) + shl(s, 13)\nend\n\nlocal function parse_cond(expr, inv)\n  local c = map_cond[expr]\n  if not c then werror(\"expected condition operand\") end\n  return shl(bit.bxor(c, inv), 12)\nend\n\nlocal function parse_load(params, nparams, n, op)\n  if params[n+2] then werror(\"too many operands\") end\n  local scale = shr(op, 30)\n  local pn, p2 = params[n], params[n+1]\n  local p1, wb = match(pn, \"^%[%s*(.-)%s*%](!?)$\")\n  if not p1 then\n    if not p2 then\n      local reg, tailr = match(pn, \"^([%w_:]+)%s*(.*)$\")\n      if reg and tailr ~= \"\" then\n\tlocal base, tp = parse_reg_base(reg)\n\tif tp then\n\t  waction(\"IMML\", scale, format(tp.ctypefmt, tailr))\n\t  return op + base\n\tend\n      end\n    end\n    werror(\"expected address operand\")\n  end\n  if p2 then\n    if wb == \"!\" then werror(\"bad use of '!'\") end\n    op = op + parse_reg_base(p1) + parse_imm(p2, 9, 12, 0, true) + 0x400\n  elseif wb == \"!\" then\n    local p1a, p2a = match(p1, \"^([^,%s]*)%s*,%s*(.*)$\")\n    if not p1a then werror(\"bad use of '!'\") end\n    op = op + parse_reg_base(p1a) + parse_imm(p2a, 9, 12, 0, true) + 0xc00\n  else\n    local p1a, p2a = match(p1, \"^([^,%s]*)%s*(.*)$\")\n    op = op + parse_reg_base(p1a)\n    if p2a ~= \"\" then\n      local imm = match(p2a, \"^,%s*#(.*)$\")\n      if imm then\n\top = op + parse_imm_load(imm, scale)\n      else\n\tlocal p2b, p3b, p3s = match(p2a, \"^,%s*([^,%s]*)%s*,?%s*(%S*)%s*(.*)$\")\n\top = op + parse_reg(p2b, 16) + 0x00200800\n\tif parse_reg_type ~= \"x\" and parse_reg_type ~= \"w\" then\n\t  werror(\"bad index register type\")\n\tend\n\tif p3b == \"\" then\n\t  if parse_reg_type ~= \"x\" then werror(\"bad index register type\") end\n\t  op = op + 0x6000\n\telse\n\t  if p3s == \"\" or p3s == \"#0\" then\n\t  elseif p3s == \"#\"..scale then\n\t    op = op + 0x1000\n\t  else\n\t    werror(\"bad scale\")\n\t  end\n\t  if parse_reg_type == \"x\" then\n\t    if p3b == \"lsl\" and p3s ~= \"\" then op = op + 0x6000\n\t    elseif p3b == \"sxtx\" then op = op + 0xe000\n\t    else\n\t      werror(\"bad extend/shift specifier\")\n\t    end\n\t  else\n\t    if p3b == \"uxtw\" then op = op + 0x4000\n\t    elseif p3b == \"sxtw\" then op = op + 0xc000\n\t    else\n\t      werror(\"bad extend/shift specifier\")\n\t    end\n\t  end\n\tend\n      end\n    else\n      if wb == \"!\" then werror(\"bad use of '!'\") end\n      op = op + 0x01000000\n    end\n  end\n  return op\nend\n\nlocal function parse_load_pair(params, nparams, n, op)\n  if params[n+2] then werror(\"too many operands\") end\n  local pn, p2 = params[n], params[n+1]\n  local scale = shr(op, 30) == 0 and 2 or 3\n  local p1, wb = match(pn, \"^%[%s*(.-)%s*%](!?)$\")\n  if not p1 then\n    if not p2 then\n      local reg, tailr = match(pn, \"^([%w_:]+)%s*(.*)$\")\n      if reg and tailr ~= \"\" then\n\tlocal base, tp = parse_reg_base(reg)\n\tif tp then\n\t  waction(\"IMM\", 32768+7*32+15+scale*1024, format(tp.ctypefmt, tailr))\n\t  return op + base + 0x01000000\n\tend\n      end\n    end\n    werror(\"expected address operand\")\n  end\n  if p2 then\n    if wb == \"!\" then werror(\"bad use of '!'\") end\n    op = op + 0x00800000\n  else\n    local p1a, p2a = match(p1, \"^([^,%s]*)%s*,%s*(.*)$\")\n    if p1a then p1, p2 = p1a, p2a else p2 = \"#0\" end\n    op = op + (wb == \"!\" and 0x01800000 or 0x01000000)\n  end\n  return op + parse_reg_base(p1) + parse_imm(p2, 7, 15, scale, true)\nend\n\nlocal function parse_label(label, def)\n  local prefix = label:sub(1, 2)\n  -- =>label (pc label reference)\n  if prefix == \"=>\" then\n    return \"PC\", 0, label:sub(3)\n  end\n  -- ->name (global label reference)\n  if prefix == \"->\" then\n    return \"LG\", map_global[label:sub(3)]\n  end\n  if def then\n    -- [1-9] (local label definition)\n    if match(label, \"^[1-9]$\") then\n      return \"LG\", 10+tonumber(label)\n    end\n  else\n    -- [<>][1-9] (local label reference)\n    local dir, lnum = match(label, \"^([<>])([1-9])$\")\n    if dir then -- Fwd: 1-9, Bkwd: 11-19.\n      return \"LG\", lnum + (dir == \">\" and 0 or 10)\n    end\n    -- extern label (extern label reference)\n    local extname = match(label, \"^extern%s+(%S+)$\")\n    if extname then\n      return \"EXT\", map_extern[extname]\n    end\n    -- &expr (pointer)\n    if label:sub(1, 1) == \"&\" then\n      return \"A\", 0, format(\"(ptrdiff_t)(%s)\", label:sub(2))\n    end\n  end\nend\n\nlocal function branch_type(op)\n  if band(op, 0x7c000000) == 0x14000000 then return 0 -- B, BL\n  elseif shr(op, 24) == 0x54 or band(op, 0x7e000000) == 0x34000000 or\n\t band(op, 0x3b000000) == 0x18000000 then\n    return 0x800 -- B.cond, CBZ, CBNZ, LDR* literal\n  elseif band(op, 0x7e000000) == 0x36000000 then return 0x1000 -- TBZ, TBNZ\n  elseif band(op, 0x9f000000) == 0x10000000 then return 0x2000 -- ADR\n  elseif band(op, 0x9f000000) == band(0x90000000) then return 0x3000 -- ADRP\n  else\n    assert(false, \"unknown branch type\")\n  end\nend\n\n------------------------------------------------------------------------------\n\nlocal map_op, op_template\n\nlocal function op_alias(opname, f)\n  return function(params, nparams)\n    if not params then return \"-> \"..opname:sub(1, -3) end\n    f(params, nparams)\n    op_template(params, map_op[opname], nparams)\n  end\nend\n\nlocal function alias_bfx(p)\n  p[4] = \"#(\"..p[3]:sub(2)..\")+(\"..p[4]:sub(2)..\")-1\"\nend\n\nlocal function alias_bfiz(p)\n  parse_reg(p[1], 0, true)\n  if parse_reg_type == \"w\" then\n    p[3] = \"#(32-(\"..p[3]:sub(2)..\"))%32\"\n    p[4] = \"#(\"..p[4]:sub(2)..\")-1\"\n  else\n    p[3] = \"#(64-(\"..p[3]:sub(2)..\"))%64\"\n    p[4] = \"#(\"..p[4]:sub(2)..\")-1\"\n  end\nend\n\nlocal alias_lslimm = op_alias(\"ubfm_4\", function(p)\n  parse_reg(p[1], 0, true)\n  local sh = p[3]:sub(2)\n  if parse_reg_type == \"w\" then\n    p[3] = \"#(32-(\"..sh..\"))%32\"\n    p[4] = \"#31-(\"..sh..\")\"\n  else\n    p[3] = \"#(64-(\"..sh..\"))%64\"\n    p[4] = \"#63-(\"..sh..\")\"\n  end\nend)\n\n-- Template strings for ARM instructions.\nmap_op = {\n  -- Basic data processing instructions.\n  add_3  = \"0b000000DNMg|11000000pDpNIg|8b206000pDpNMx\",\n  add_4  = \"0b000000DNMSg|0b200000DNMXg|8b200000pDpNMXx|8b200000pDpNxMwX\",\n  adds_3 = \"2b000000DNMg|31000000DpNIg|ab206000DpNMx\",\n  adds_4 = \"2b000000DNMSg|2b200000DNMXg|ab200000DpNMXx|ab200000DpNxMwX\",\n  cmn_2  = \"2b00001fNMg|3100001fpNIg|ab20601fpNMx\",\n  cmn_3  = \"2b00001fNMSg|2b20001fNMXg|ab20001fpNMXx|ab20001fpNxMwX\",\n\n  sub_3  = \"4b000000DNMg|51000000pDpNIg|cb206000pDpNMx\",\n  sub_4  = \"4b000000DNMSg|4b200000DNMXg|cb200000pDpNMXx|cb200000pDpNxMwX\",\n  subs_3 = \"6b000000DNMg|71000000DpNIg|eb206000DpNMx\",\n  subs_4 = \"6b000000DNMSg|6b200000DNMXg|eb200000DpNMXx|eb200000DpNxMwX\",\n  cmp_2  = \"6b00001fNMg|7100001fpNIg|eb20601fpNMx\",\n  cmp_3  = \"6b00001fNMSg|6b20001fNMXg|eb20001fpNMXx|eb20001fpNxMwX\",\n\n  neg_2  = \"4b0003e0DMg\",\n  neg_3  = \"4b0003e0DMSg\",\n  negs_2 = \"6b0003e0DMg\",\n  negs_3 = \"6b0003e0DMSg\",\n\n  adc_3  = \"1a000000DNMg\",\n  adcs_3 = \"3a000000DNMg\",\n  sbc_3  = \"5a000000DNMg\",\n  sbcs_3 = \"7a000000DNMg\",\n  ngc_2  = \"5a0003e0DMg\",\n  ngcs_2 = \"7a0003e0DMg\",\n\n  and_3  = \"0a000000DNMg|12000000pDNig\",\n  and_4  = \"0a000000DNMSg\",\n  orr_3  = \"2a000000DNMg|32000000pDNig\",\n  orr_4  = \"2a000000DNMSg\",\n  eor_3  = \"4a000000DNMg|52000000pDNig\",\n  eor_4  = \"4a000000DNMSg\",\n  ands_3 = \"6a000000DNMg|72000000DNig\",\n  ands_4 = \"6a000000DNMSg\",\n  tst_2  = \"6a00001fNMg|7200001fNig\",\n  tst_3  = \"6a00001fNMSg\",\n\n  bic_3  = \"0a200000DNMg\",\n  bic_4  = \"0a200000DNMSg\",\n  orn_3  = \"2a200000DNMg\",\n  orn_4  = \"2a200000DNMSg\",\n  eon_3  = \"4a200000DNMg\",\n  eon_4  = \"4a200000DNMSg\",\n  bics_3 = \"6a200000DNMg\",\n  bics_4 = \"6a200000DNMSg\",\n\n  movn_2 = \"12800000DWg\",\n  movn_3 = \"12800000DWRg\",\n  movz_2 = \"52800000DWg\",\n  movz_3 = \"52800000DWRg\",\n  movk_2 = \"72800000DWg\",\n  movk_3 = \"72800000DWRg\",\n\n  -- TODO: this doesn't cover all valid immediates for mov reg, #imm.\n  mov_2  = \"2a0003e0DMg|52800000DW|320003e0pDig|11000000pDpNg\",\n  mov_3  = \"2a0003e0DMSg\",\n  mvn_2  = \"2a2003e0DMg\",\n  mvn_3  = \"2a2003e0DMSg\",\n\n  adr_2  = \"10000000DBx\",\n  adrp_2 = \"90000000DBx\",\n\n  csel_4  = \"1a800000DNMCg\",\n  csinc_4 = \"1a800400DNMCg\",\n  csinv_4 = \"5a800000DNMCg\",\n  csneg_4 = \"5a800400DNMCg\",\n  cset_2  = \"1a9f07e0Dcg\",\n  csetm_2 = \"5a9f03e0Dcg\",\n  cinc_3  = \"1a800400DNmcg\",\n  cinv_3  = \"5a800000DNmcg\",\n  cneg_3  = \"5a800400DNmcg\",\n\n  ccmn_4 = \"3a400000NMVCg|3a400800N5VCg\",\n  ccmp_4 = \"7a400000NMVCg|7a400800N5VCg\",\n\n  madd_4 = \"1b000000DNMAg\",\n  msub_4 = \"1b008000DNMAg\",\n  mul_3  = \"1b007c00DNMg\",\n  mneg_3 = \"1b00fc00DNMg\",\n\n  smaddl_4 = \"9b200000DxNMwAx\",\n  smsubl_4 = \"9b208000DxNMwAx\",\n  smull_3  = \"9b207c00DxNMw\",\n  smnegl_3 = \"9b20fc00DxNMw\",\n  smulh_3  = \"9b407c00DNMx\",\n  umaddl_4 = \"9ba00000DxNMwAx\",\n  umsubl_4 = \"9ba08000DxNMwAx\",\n  umull_3  = \"9ba07c00DxNMw\",\n  umnegl_3 = \"9ba0fc00DxNMw\",\n  umulh_3  = \"9bc07c00DNMx\",\n\n  udiv_3 = \"1ac00800DNMg\",\n  sdiv_3 = \"1ac00c00DNMg\",\n\n  -- Bit operations.\n  sbfm_4 = \"13000000DN12w|93400000DN12x\",\n  bfm_4  = \"33000000DN12w|b3400000DN12x\",\n  ubfm_4 = \"53000000DN12w|d3400000DN12x\",\n  extr_4 = \"13800000DNM2w|93c00000DNM2x\",\n\n  sxtb_2 = \"13001c00DNw|93401c00DNx\",\n  sxth_2 = \"13003c00DNw|93403c00DNx\",\n  sxtw_2 = \"93407c00DxNw\",\n  uxtb_2 = \"53001c00DNw\",\n  uxth_2 = \"53003c00DNw\",\n\n  sbfx_4  = op_alias(\"sbfm_4\", alias_bfx),\n  bfxil_4 = op_alias(\"bfm_4\", alias_bfx),\n  ubfx_4  = op_alias(\"ubfm_4\", alias_bfx),\n  sbfiz_4 = op_alias(\"sbfm_4\", alias_bfiz),\n  bfi_4   = op_alias(\"bfm_4\", alias_bfiz),\n  ubfiz_4 = op_alias(\"ubfm_4\", alias_bfiz),\n\n  lsl_3  = function(params, nparams)\n    if params and params[3]:byte() == 35 then\n      return alias_lslimm(params, nparams)\n    else\n      return op_template(params, \"1ac02000DNMg\", nparams)\n    end\n  end,\n  lsr_3  = \"1ac02400DNMg|53007c00DN1w|d340fc00DN1x\",\n  asr_3  = \"1ac02800DNMg|13007c00DN1w|9340fc00DN1x\",\n  ror_3  = \"1ac02c00DNMg|13800000DNm2w|93c00000DNm2x\",\n\n  clz_2   = \"5ac01000DNg\",\n  cls_2   = \"5ac01400DNg\",\n  rbit_2  = \"5ac00000DNg\",\n  rev_2   = \"5ac00800DNw|dac00c00DNx\",\n  rev16_2 = \"5ac00400DNg\",\n  rev32_2 = \"dac00800DNx\",\n\n  -- Loads and stores.\n  [\"strb_*\"]  = \"38000000DwL\",\n  [\"ldrb_*\"]  = \"38400000DwL\",\n  [\"ldrsb_*\"] = \"38c00000DwL|38800000DxL\",\n  [\"strh_*\"]  = \"78000000DwL\",\n  [\"ldrh_*\"]  = \"78400000DwL\",\n  [\"ldrsh_*\"] = \"78c00000DwL|78800000DxL\",\n  [\"str_*\"]   = \"b8000000DwL|f8000000DxL|bc000000DsL|fc000000DdL\",\n  [\"ldr_*\"]   = \"18000000DwB|58000000DxB|1c000000DsB|5c000000DdB|b8400000DwL|f8400000DxL|bc400000DsL|fc400000DdL\",\n  [\"ldrsw_*\"] = \"98000000DxB|b8800000DxL\",\n  -- NOTE: ldur etc. are handled by ldr et al.\n\n  [\"stp_*\"]   = \"28000000DAwP|a8000000DAxP|2c000000DAsP|6c000000DAdP\",\n  [\"ldp_*\"]   = \"28400000DAwP|a8400000DAxP|2c400000DAsP|6c400000DAdP\",\n  [\"ldpsw_*\"] = \"68400000DAxP\",\n\n  -- Branches.\n  b_1    = \"14000000B\",\n  bl_1   = \"94000000B\",\n  blr_1  = \"d63f0000Nx\",\n  br_1   = \"d61f0000Nx\",\n  ret_0  = \"d65f03c0\",\n  ret_1  = \"d65f0000Nx\",\n  -- b.cond is added below.\n  cbz_2  = \"34000000DBg\",\n  cbnz_2 = \"35000000DBg\",\n  tbz_3  = \"36000000DTBw|36000000DTBx\",\n  tbnz_3 = \"37000000DTBw|37000000DTBx\",\n\n  -- Miscellaneous instructions.\n  -- TODO: hlt, hvc, smc, svc, eret, dcps[123], drps, mrs, msr\n  -- TODO: sys, sysl, ic, dc, at, tlbi\n  -- TODO: hint, yield, wfe, wfi, sev, sevl\n  -- TODO: clrex, dsb, dmb, isb\n  nop_0  = \"d503201f\",\n  brk_0  = \"d4200000\",\n  brk_1  = \"d4200000W\",\n\n  -- Floating point instructions.\n  fmov_2  = \"1e204000DNf|1e260000DwNs|1e270000DsNw|9e660000DxNd|9e670000DdNx|1e201000DFf\",\n  fabs_2  = \"1e20c000DNf\",\n  fneg_2  = \"1e214000DNf\",\n  fsqrt_2 = \"1e21c000DNf\",\n\n  fcvt_2  = \"1e22c000DdNs|1e624000DsNd\",\n\n  -- TODO: half-precision and fixed-point conversions.\n  fcvtas_2 = \"1e240000DwNs|9e240000DxNs|1e640000DwNd|9e640000DxNd\",\n  fcvtau_2 = \"1e250000DwNs|9e250000DxNs|1e650000DwNd|9e650000DxNd\",\n  fcvtms_2 = \"1e300000DwNs|9e300000DxNs|1e700000DwNd|9e700000DxNd\",\n  fcvtmu_2 = \"1e310000DwNs|9e310000DxNs|1e710000DwNd|9e710000DxNd\",\n  fcvtns_2 = \"1e200000DwNs|9e200000DxNs|1e600000DwNd|9e600000DxNd\",\n  fcvtnu_2 = \"1e210000DwNs|9e210000DxNs|1e610000DwNd|9e610000DxNd\",\n  fcvtps_2 = \"1e280000DwNs|9e280000DxNs|1e680000DwNd|9e680000DxNd\",\n  fcvtpu_2 = \"1e290000DwNs|9e290000DxNs|1e690000DwNd|9e690000DxNd\",\n  fcvtzs_2 = \"1e380000DwNs|9e380000DxNs|1e780000DwNd|9e780000DxNd\",\n  fcvtzu_2 = \"1e390000DwNs|9e390000DxNs|1e790000DwNd|9e790000DxNd\",\n\n  scvtf_2  = \"1e220000DsNw|9e220000DsNx|1e620000DdNw|9e620000DdNx\",\n  ucvtf_2  = \"1e230000DsNw|9e230000DsNx|1e630000DdNw|9e630000DdNx\",\n\n  frintn_2 = \"1e244000DNf\",\n  frintp_2 = \"1e24c000DNf\",\n  frintm_2 = \"1e254000DNf\",\n  frintz_2 = \"1e25c000DNf\",\n  frinta_2 = \"1e264000DNf\",\n  frintx_2 = \"1e274000DNf\",\n  frinti_2 = \"1e27c000DNf\",\n\n  fadd_3   = \"1e202800DNMf\",\n  fsub_3   = \"1e203800DNMf\",\n  fmul_3   = \"1e200800DNMf\",\n  fnmul_3  = \"1e208800DNMf\",\n  fdiv_3   = \"1e201800DNMf\",\n\n  fmadd_4  = \"1f000000DNMAf\",\n  fmsub_4  = \"1f008000DNMAf\",\n  fnmadd_4 = \"1f200000DNMAf\",\n  fnmsub_4 = \"1f208000DNMAf\",\n\n  fmax_3   = \"1e204800DNMf\",\n  fmaxnm_3 = \"1e206800DNMf\",\n  fmin_3   = \"1e205800DNMf\",\n  fminnm_3 = \"1e207800DNMf\",\n\n  fcmp_2   = \"1e202000NMf|1e202008NZf\",\n  fcmpe_2  = \"1e202010NMf|1e202018NZf\",\n\n  fccmp_4  = \"1e200400NMVCf\",\n  fccmpe_4 = \"1e200410NMVCf\",\n\n  fcsel_4  = \"1e200c00DNMCf\",\n\n  -- TODO: crc32*, aes*, sha*, pmull\n  -- TODO: SIMD instructions.\n}\n\nfor cond,c in pairs(map_cond) do\n  map_op[\"b\"..cond..\"_1\"] = tohex(0x54000000+c)..\"B\"\nend\n\n------------------------------------------------------------------------------\n\n-- Handle opcodes defined with template strings.\nlocal function parse_template(params, template, nparams, pos)\n  local op = tonumber(template:sub(1, 8), 16)\n  local n = 1\n  local rtt = {}\n\n  parse_reg_type = false\n\n  -- Process each character.\n  for p in gmatch(template:sub(9), \".\") do\n    local q = params[n]\n    if p == \"D\" then\n      op = op + parse_reg(q, 0); n = n + 1\n    elseif p == \"N\" then\n      op = op + parse_reg(q, 5); n = n + 1\n    elseif p == \"M\" then\n      op = op + parse_reg(q, 16); n = n + 1\n    elseif p == \"A\" then\n      op = op + parse_reg(q, 10); n = n + 1\n    elseif p == \"m\" then\n      op = op + parse_reg(params[n-1], 16)\n\n    elseif p == \"p\" then\n      if q == \"sp\" then params[n] = \"@x31\" end\n    elseif p == \"g\" then\n      if parse_reg_type == \"x\" then\n\top = op + 0x80000000\n      elseif parse_reg_type ~= \"w\" then\n\twerror(\"bad register type\")\n      end\n      parse_reg_type = false\n    elseif p == \"f\" then\n      if parse_reg_type == \"d\" then\n\top = op + 0x00400000\n      elseif parse_reg_type ~= \"s\" then\n\twerror(\"bad register type\")\n      end\n      parse_reg_type = false\n    elseif p == \"x\" or p == \"w\" or p == \"d\" or p == \"s\" then\n      if parse_reg_type ~= p then\n\twerror(\"register size mismatch\")\n      end\n      parse_reg_type = false\n\n    elseif p == \"L\" then\n      op = parse_load(params, nparams, n, op)\n    elseif p == \"P\" then\n      op = parse_load_pair(params, nparams, n, op)\n\n    elseif p == \"B\" then\n      local mode, v, s = parse_label(q, false); n = n + 1\n      if not mode then werror(\"bad label `\"..q..\"'\") end\n      local m = branch_type(op)\n      if mode == \"A\" then\n\twaction(\"REL_\"..mode, v+m, format(\"(unsigned int)(%s)\", s))\n\tactargs[#actargs+1] = format(\"(unsigned int)((%s)>>32)\", s)\n      else\n\twaction(\"REL_\"..mode, v+m, s, 1)\n      end\n\n    elseif p == \"I\" then\n      op = op + parse_imm12(q); n = n + 1\n    elseif p == \"i\" then\n      op = op + parse_imm13(q); n = n + 1\n    elseif p == \"W\" then\n      op = op + parse_imm(q, 16, 5, 0, false); n = n + 1\n    elseif p == \"T\" then\n      op = op + parse_imm6(q); n = n + 1\n    elseif p == \"1\" then\n      op = op + parse_imm(q, 6, 16, 0, false); n = n + 1\n    elseif p == \"2\" then\n      op = op + parse_imm(q, 6, 10, 0, false); n = n + 1\n    elseif p == \"5\" then\n      op = op + parse_imm(q, 5, 16, 0, false); n = n + 1\n    elseif p == \"V\" then\n      op = op + parse_imm(q, 4, 0, 0, false); n = n + 1\n    elseif p == \"F\" then\n      op = op + parse_fpimm(q); n = n + 1\n    elseif p == \"Z\" then\n      if q ~= \"#0\" and q ~= \"#0.0\" then werror(\"expected zero immediate\") end\n      n = n + 1\n\n    elseif p == \"S\" then\n      op = op + parse_shift(q); n = n + 1\n    elseif p == \"X\" then\n      op = op + parse_extend(q); n = n + 1\n    elseif p == \"R\" then\n      op = op + parse_lslx16(q); n = n + 1\n    elseif p == \"C\" then\n      op = op + parse_cond(q, 0); n = n + 1\n    elseif p == \"c\" then\n      op = op + parse_cond(q, 1); n = n + 1\n\n    else\n      assert(false)\n    end\n  end\n  wputpos(pos, op)\nend\n\nfunction op_template(params, template, nparams)\n  if not params then return template:gsub(\"%x%x%x%x%x%x%x%x\", \"\") end\n\n  -- Limit number of section buffer positions used by a single dasm_put().\n  -- A single opcode needs a maximum of 4 positions.\n  if secpos+4 > maxsecpos then wflush() end\n  local pos = wpos()\n  local lpos, apos, spos = #actlist, #actargs, secpos\n\n  local ok, err\n  for t in gmatch(template, \"[^|]+\") do\n    ok, err = pcall(parse_template, params, t, nparams, pos)\n    if ok then return end\n    secpos = spos\n    actlist[lpos+1] = nil\n    actlist[lpos+2] = nil\n    actlist[lpos+3] = nil\n    actlist[lpos+4] = nil\n    actargs[apos+1] = nil\n    actargs[apos+2] = nil\n    actargs[apos+3] = nil\n    actargs[apos+4] = nil\n  end\n  error(err, 0)\nend\n\nmap_op[\".template__\"] = op_template\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode to mark the position where the action list is to be emitted.\nmap_op[\".actionlist_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeactions(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the global enum is to be emitted.\nmap_op[\".globals_1\"] = function(params)\n  if not params then return \"prefix\" end\n  local prefix = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobals(out, prefix) end)\nend\n\n-- Pseudo-opcode to mark the position where the global names are to be emitted.\nmap_op[\".globalnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobalnames(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the extern names are to be emitted.\nmap_op[\".externnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeexternnames(out, name) end)\nend\n\n------------------------------------------------------------------------------\n\n-- Label pseudo-opcode (converted from trailing colon form).\nmap_op[\".label_1\"] = function(params)\n  if not params then return \"[1-9] | ->global | =>pcexpr\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local mode, n, s = parse_label(params[1], true)\n  if not mode or mode == \"EXT\" then werror(\"bad label definition\") end\n  waction(\"LABEL_\"..mode, n, s, 1)\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcodes for data storage.\nlocal function op_data(params)\n  if not params then return \"imm...\" end\n  local sz = params.op == \".long\" and 4 or 8\n  for _,p in ipairs(params) do\n    local imm = parse_number(p)\n    if imm then\n      local n = tobit(imm)\n      if n == imm or (n < 0 and n + 2^32 == imm) then\n\twputw(n < 0 and n + 2^32 or n)\n\tif sz == 8 then\n\t  wputw(imm < 0 and 0xffffffff or 0)\n\tend\n      elseif sz == 4 then\n\twerror(\"bad immediate `\"..p..\"'\")\n      else\n\timm = nil\n      end\n    end\n    if not imm then\n      local mode, v, s = parse_label(p, false)\n      if sz == 4 then\n\tif mode then werror(\"label does not fit into .long\") end\n\twaction(\"IMMV\", 0, p)\n      elseif mode and mode ~= \"A\" then\n\twaction(\"REL_\"..mode, v+0x8000, s, 1)\n      else\n\tif mode == \"A\" then p = s end\n\twaction(\"IMMV\", 0, format(\"(unsigned int)(%s)\", p))\n\twaction(\"IMMV\", 0, format(\"(unsigned int)((unsigned long long)(%s)>>32)\", p))\n      end\n    end\n    if secpos+2 > maxsecpos then wflush() end\n  end\nend\nmap_op[\".long_*\"] = op_data\nmap_op[\".quad_*\"] = op_data\nmap_op[\".addr_*\"] = op_data\n\n-- Alignment pseudo-opcode.\nmap_op[\".align_1\"] = function(params)\n  if not params then return \"numpow2\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local align = tonumber(params[1])\n  if align then\n    local x = align\n    -- Must be a power of 2 in the range (2 ... 256).\n    for i=1,8 do\n      x = x / 2\n      if x == 1 then\n\twaction(\"ALIGN\", align-1, nil, 1) -- Action byte is 2**n-1.\n\treturn\n      end\n    end\n  end\n  werror(\"bad alignment\")\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode for (primitive) type definitions (map to C types).\nmap_op[\".type_3\"] = function(params, nparams)\n  if not params then\n    return nparams == 2 and \"name, ctype\" or \"name, ctype, reg\"\n  end\n  local name, ctype, reg = params[1], params[2], params[3]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    werror(\"bad type name `\"..name..\"'\")\n  end\n  local tp = map_type[name]\n  if tp then\n    werror(\"duplicate type `\"..name..\"'\")\n  end\n  -- Add #type to defines. A bit unclean to put it in map_archdef.\n  map_archdef[\"#\"..name] = \"sizeof(\"..ctype..\")\"\n  -- Add new type and emit shortcut define.\n  local num = ctypenum + 1\n  map_type[name] = {\n    ctype = ctype,\n    ctypefmt = format(\"Dt%X(%%s)\", num),\n    reg = reg,\n  }\n  wline(format(\"#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)\", num, ctype))\n  ctypenum = num\nend\nmap_op[\".type_2\"] = map_op[\".type_3\"]\n\n-- Dump type definitions.\nlocal function dumptypes(out, lvl)\n  local t = {}\n  for name in pairs(map_type) do t[#t+1] = name end\n  sort(t)\n  out:write(\"Type definitions:\\n\")\n  for _,name in ipairs(t) do\n    local tp = map_type[name]\n    local reg = tp.reg or \"\"\n    out:write(format(\"  %-20s %-20s %s\\n\", name, tp.ctype, reg))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Set the current section.\nfunction _M.section(num)\n  waction(\"SECTION\", num)\n  wflush(true) -- SECTION is a terminal action.\nend\n\n------------------------------------------------------------------------------\n\n-- Dump architecture description.\nfunction _M.dumparch(out)\n  out:write(format(\"DynASM %s version %s, released %s\\n\\n\",\n    _info.arch, _info.version, _info.release))\n  dumpactions(out)\nend\n\n-- Dump all user defined elements.\nfunction _M.dumpdef(out, lvl)\n  dumptypes(out, lvl)\n  dumpglobals(out, lvl)\n  dumpexterns(out, lvl)\nend\n\n------------------------------------------------------------------------------\n\n-- Pass callbacks from/to the DynASM core.\nfunction _M.passcb(wl, we, wf, ww)\n  wline, werror, wfatal, wwarn = wl, we, wf, ww\n  return wflush\nend\n\n-- Setup the arch-specific module.\nfunction _M.setup(arch, opt)\n  g_arch, g_opt = arch, opt\nend\n\n-- Merge the core maps and the arch-specific maps.\nfunction _M.mergemaps(map_coreop, map_def)\n  setmetatable(map_op, { __index = map_coreop })\n  setmetatable(map_def, { __index = map_archdef })\n  return map_op, map_def\nend\n\nreturn _M\n\n------------------------------------------------------------------------------\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_mips.h",
    "content": "/*\n** DynASM MIPS encoding engine.\n** Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n** Released under the MIT license. See dynasm.lua for full copyright notice.\n*/\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define DASM_ARCH\t\t\"mips\"\n\n#ifndef DASM_EXTERN\n#define DASM_EXTERN(a,b,c,d)\t0\n#endif\n\n/* Action definitions. */\nenum {\n  DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,\n  /* The following actions need a buffer position. */\n  DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,\n  /* The following actions also have an argument. */\n  DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMS,\n  DASM__MAX\n};\n\n/* Maximum number of section buffer positions for a single dasm_put() call. */\n#define DASM_MAXSECPOS\t\t25\n\n/* DynASM encoder status codes. Action list offset or number are or'ed in. */\n#define DASM_S_OK\t\t0x00000000\n#define DASM_S_NOMEM\t\t0x01000000\n#define DASM_S_PHASE\t\t0x02000000\n#define DASM_S_MATCH_SEC\t0x03000000\n#define DASM_S_RANGE_I\t\t0x11000000\n#define DASM_S_RANGE_SEC\t0x12000000\n#define DASM_S_RANGE_LG\t\t0x13000000\n#define DASM_S_RANGE_PC\t\t0x14000000\n#define DASM_S_RANGE_REL\t0x15000000\n#define DASM_S_UNDEF_LG\t\t0x21000000\n#define DASM_S_UNDEF_PC\t\t0x22000000\n\n/* Macros to convert positions (8 bit section + 24 bit index). */\n#define DASM_POS2IDX(pos)\t((pos)&0x00ffffff)\n#define DASM_POS2BIAS(pos)\t((pos)&0xff000000)\n#define DASM_SEC2POS(sec)\t((sec)<<24)\n#define DASM_POS2SEC(pos)\t((pos)>>24)\n#define DASM_POS2PTR(D, pos)\t(D->sections[DASM_POS2SEC(pos)].rbuf + (pos))\n\n/* Action list type. */\ntypedef const unsigned int *dasm_ActList;\n\n/* Per-section structure. */\ntypedef struct dasm_Section {\n  int *rbuf;\t\t/* Biased buffer pointer (negative section bias). */\n  int *buf;\t\t/* True buffer pointer. */\n  size_t bsize;\t\t/* Buffer size in bytes. */\n  int pos;\t\t/* Biased buffer position. */\n  int epos;\t\t/* End of biased buffer position - max single put. */\n  int ofs;\t\t/* Byte offset into section. */\n} dasm_Section;\n\n/* Core structure holding the DynASM encoding state. */\nstruct dasm_State {\n  size_t psize;\t\t\t/* Allocated size of this structure. */\n  dasm_ActList actionlist;\t/* Current actionlist pointer. */\n  int *lglabels;\t\t/* Local/global chain/pos ptrs. */\n  size_t lgsize;\n  int *pclabels;\t\t/* PC label chains/pos ptrs. */\n  size_t pcsize;\n  void **globals;\t\t/* Array of globals (bias -10). */\n  dasm_Section *section;\t/* Pointer to active section. */\n  size_t codesize;\t\t/* Total size of all code sections. */\n  int maxsection;\t\t/* 0 <= sectionidx < maxsection. */\n  int status;\t\t\t/* Status code. */\n  dasm_Section sections[1];\t/* All sections. Alloc-extended. */\n};\n\n/* The size of the core structure depends on the max. number of sections. */\n#define DASM_PSZ(ms)\t(sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))\n\n\n/* Initialize DynASM state. */\nvoid dasm_init(Dst_DECL, int maxsection)\n{\n  dasm_State *D;\n  size_t psz = 0;\n  int i;\n  Dst_REF = NULL;\n  DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));\n  D = Dst_REF;\n  D->psize = psz;\n  D->lglabels = NULL;\n  D->lgsize = 0;\n  D->pclabels = NULL;\n  D->pcsize = 0;\n  D->globals = NULL;\n  D->maxsection = maxsection;\n  for (i = 0; i < maxsection; i++) {\n    D->sections[i].buf = NULL;  /* Need this for pass3. */\n    D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);\n    D->sections[i].bsize = 0;\n    D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */\n  }\n}\n\n/* Free DynASM state. */\nvoid dasm_free(Dst_DECL)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  for (i = 0; i < D->maxsection; i++)\n    if (D->sections[i].buf)\n      DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);\n  if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);\n  if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);\n  DASM_M_FREE(Dst, D, D->psize);\n}\n\n/* Setup global label array. Must be called before dasm_setup(). */\nvoid dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)\n{\n  dasm_State *D = Dst_REF;\n  D->globals = gl - 10;  /* Negative bias to compensate for locals. */\n  DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));\n}\n\n/* Grow PC label array. Can be called after dasm_setup(), too. */\nvoid dasm_growpc(Dst_DECL, unsigned int maxpc)\n{\n  dasm_State *D = Dst_REF;\n  size_t osz = D->pcsize;\n  DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));\n  memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);\n}\n\n/* Setup encoder. */\nvoid dasm_setup(Dst_DECL, const void *actionlist)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  D->actionlist = (dasm_ActList)actionlist;\n  D->status = DASM_S_OK;\n  D->section = &D->sections[0];\n  memset((void *)D->lglabels, 0, D->lgsize);\n  if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);\n  for (i = 0; i < D->maxsection; i++) {\n    D->sections[i].pos = DASM_SEC2POS(i);\n    D->sections[i].ofs = 0;\n  }\n}\n\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) { \\\n    D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)\n#define CKPL(kind, st) \\\n  do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \\\n    D->status = DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#define CKPL(kind, st)\t((void)0)\n#endif\n\n/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */\nvoid dasm_put(Dst_DECL, int start, ...)\n{\n  va_list ap;\n  dasm_State *D = Dst_REF;\n  dasm_ActList p = D->actionlist + start;\n  dasm_Section *sec = D->section;\n  int pos = sec->pos, ofs = sec->ofs;\n  int *b;\n\n  if (pos >= sec->epos) {\n    DASM_M_GROW(Dst, int, sec->buf, sec->bsize,\n      sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));\n    sec->rbuf = sec->buf - DASM_POS2BIAS(pos);\n    sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);\n  }\n\n  b = sec->rbuf;\n  b[pos++] = start;\n\n  va_start(ap, start);\n  while (1) {\n    unsigned int ins = *p++;\n    unsigned int action = (ins >> 16) - 0xff00;\n    if (action >= DASM__MAX) {\n      ofs += 4;\n    } else {\n      int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;\n      switch (action) {\n      case DASM_STOP: goto stop;\n      case DASM_SECTION:\n\tn = (ins & 255); CK(n < D->maxsection, RANGE_SEC);\n\tD->section = &D->sections[n]; goto stop;\n      case DASM_ESC: p++; ofs += 4; break;\n      case DASM_REL_EXT: break;\n      case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;\n      case DASM_REL_LG:\n\tn = (ins & 2047) - 10; pl = D->lglabels + n;\n\t/* Bkwd rel or global. */\n\tif (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }\n\tpl += 10; n = *pl;\n\tif (n < 0) n = 0;  /* Start new chain for fwd rel if label exists. */\n\tgoto linkrel;\n      case DASM_REL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putrel:\n\tn = *pl;\n\tif (n < 0) {  /* Label exists. Get label pos and store it. */\n\t  b[pos] = -n;\n\t} else {\n      linkrel:\n\t  b[pos] = n;  /* Else link to rel chain, anchored at label. */\n\t  *pl = pos;\n\t}\n\tpos++;\n\tbreak;\n      case DASM_LABEL_LG:\n\tpl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;\n      case DASM_LABEL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putlabel:\n\tn = *pl;  /* n > 0: Collapse rel chain and replace with label pos. */\n\twhile (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;\n\t}\n\t*pl = -pos;  /* Label exists now. */\n\tb[pos++] = ofs;  /* Store pass1 offset estimate. */\n\tbreak;\n      case DASM_IMM: case DASM_IMMS:\n#ifdef DASM_CHECKS\n\tCK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);\n#endif\n\tn >>= ((ins>>10)&31);\n#ifdef DASM_CHECKS\n\tif (ins & 0x8000)\n\t  CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);\n\telse\n\t  CK((n>>((ins>>5)&31)) == 0, RANGE_I);\n#endif\n\tb[pos++] = n;\n\tbreak;\n      }\n    }\n  }\nstop:\n  va_end(ap);\n  sec->pos = pos;\n  sec->ofs = ofs;\n}\n#undef CK\n\n/* Pass 2: Link sections, shrink aligns, fix label offsets. */\nint dasm_link(Dst_DECL, size_t *szp)\n{\n  dasm_State *D = Dst_REF;\n  int secnum;\n  int ofs = 0;\n\n#ifdef DASM_CHECKS\n  *szp = 0;\n  if (D->status != DASM_S_OK) return D->status;\n  {\n    int pc;\n    for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)\n      if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;\n  }\n#endif\n\n  { /* Handle globals not defined in this translation unit. */\n    int idx;\n    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {\n      int n = D->lglabels[idx];\n      /* Undefined label: Collapse rel chain and replace with marker (< 0). */\n      while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }\n    }\n  }\n\n  /* Combine all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->rbuf;\n    int pos = DASM_SEC2POS(secnum);\n    int lastpos = sec->pos;\n\n    while (pos != lastpos) {\n      dasm_ActList p = D->actionlist + b[pos++];\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16) - 0xff00;\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: p++; break;\n\tcase DASM_REL_EXT: break;\n\tcase DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;\n\tcase DASM_REL_LG: case DASM_REL_PC: pos++; break;\n\tcase DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;\n\tcase DASM_IMM: case DASM_IMMS: pos++; break;\n\t}\n      }\n      stop: (void)0;\n    }\n    ofs += sec->ofs;  /* Next section starts right after current section. */\n  }\n\n  D->codesize = ofs;  /* Total size of all code sections */\n  *szp = ofs;\n  return DASM_S_OK;\n}\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) return DASM_S_##st|(int)(p-D->actionlist-1); } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#endif\n\n/* Pass 3: Encode sections. */\nint dasm_encode(Dst_DECL, void *buffer)\n{\n  dasm_State *D = Dst_REF;\n  char *base = (char *)buffer;\n  unsigned int *cp = (unsigned int *)buffer;\n  int secnum;\n\n  /* Encode all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->buf;\n    int *endb = sec->rbuf + sec->pos;\n\n    while (b != endb) {\n      dasm_ActList p = D->actionlist + *b++;\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16) - 0xff00;\n\tint n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: *cp++ = *p++; break;\n\tcase DASM_REL_EXT:\n\t  n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1);\n\t  goto patchrel;\n\tcase DASM_ALIGN:\n\t  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;\n\t  break;\n\tcase DASM_REL_LG:\n\t  if (n < 0) {\n\t    n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);\n\t    goto patchrel;\n\t  }\n\t  /* fallthrough */\n\tcase DASM_REL_PC:\n\t  CK(n >= 0, UNDEF_PC);\n\t  n = *DASM_POS2PTR(D, n);\n\t  if (ins & 2048)\n\t    n = (n + (int)(size_t)base) & 0x0fffffff;\n\t  else\n\t    n = n - (int)((char *)cp - base);\n\tpatchrel: {\n\t  unsigned int e = 16 + ((ins >> 12) & 15);\n\t  CK((n & 3) == 0 &&\n\t     ((n + ((ins & 2048) ? 0 : (1<<(e+1)))) >> (e+2)) == 0, RANGE_REL);\n\t  cp[-1] |= ((n>>2) & ((1<<e)-1));\n\t  }\n\t  break;\n\tcase DASM_LABEL_LG:\n\t  ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);\n\t  break;\n\tcase DASM_LABEL_PC: break;\n\tcase DASM_IMMS:\n\t  cp[-1] |= ((n>>3) & 4); n &= 0x1f;\n\t  /* fallthrough */\n\tcase DASM_IMM:\n\t  cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);\n\t  break;\n\tdefault: *cp++ = ins; break;\n\t}\n      }\n      stop: (void)0;\n    }\n  }\n\n  if (base + D->codesize != (char *)cp)  /* Check for phase errors. */\n    return DASM_S_PHASE;\n  return DASM_S_OK;\n}\n#undef CK\n\n/* Get PC label offset. */\nint dasm_getpclabel(Dst_DECL, unsigned int pc)\n{\n  dasm_State *D = Dst_REF;\n  if (pc*sizeof(int) < D->pcsize) {\n    int pos = D->pclabels[pc];\n    if (pos < 0) return *DASM_POS2PTR(D, -pos);\n    if (pos > 0) return -1;  /* Undefined. */\n  }\n  return -2;  /* Unused or out of range. */\n}\n\n#ifdef DASM_CHECKS\n/* Optional sanity checker to call between isolated encoding steps. */\nint dasm_checkstep(Dst_DECL, int secmatch)\n{\n  dasm_State *D = Dst_REF;\n  if (D->status == DASM_S_OK) {\n    int i;\n    for (i = 1; i <= 9; i++) {\n      if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }\n      D->lglabels[i] = 0;\n    }\n  }\n  if (D->status == DASM_S_OK && secmatch >= 0 &&\n      D->section != &D->sections[secmatch])\n    D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);\n  return D->status;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_mips.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM MIPS32/MIPS64 module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n------------------------------------------------------------------------------\n\nlocal mips64 = mips64\nlocal mipsr6 = _map_def.MIPSR6\n\n-- Module information:\nlocal _info = {\n  arch =\tmips64 and \"mips64\" or \"mips\",\n  description =\t\"DynASM MIPS32/MIPS64 module\",\n  version =\t\"1.5.0\",\n  vernum =\t 10500,\n  release =\t\"2021-05-02\",\n  author =\t\"Mike Pall\",\n  license =\t\"MIT\",\n}\n\n-- Exported glue functions for the arch-specific module.\nlocal _M = { _info = _info }\n\n-- Cache library functions.\nlocal type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs\nlocal assert, setmetatable = assert, setmetatable\nlocal _s = string\nlocal sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char\nlocal match, gmatch = _s.match, _s.gmatch\nlocal concat, sort = table.concat, table.sort\nlocal bit = bit or require(\"bit\")\nlocal band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift\nlocal tohex = bit.tohex\n\n-- Inherited tables and callbacks.\nlocal g_opt, g_arch\nlocal wline, werror, wfatal, wwarn\n\n-- Action name list.\n-- CHECK: Keep this in sync with the C code!\nlocal action_names = {\n  \"STOP\", \"SECTION\", \"ESC\", \"REL_EXT\",\n  \"ALIGN\", \"REL_LG\", \"LABEL_LG\",\n  \"REL_PC\", \"LABEL_PC\", \"IMM\", \"IMMS\",\n}\n\n-- Maximum number of section buffer positions for dasm_put().\n-- CHECK: Keep this in sync with the C code!\nlocal maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.\n\n-- Action name -> action number.\nlocal map_action = {}\nfor n,name in ipairs(action_names) do\n  map_action[name] = n-1\nend\n\n-- Action list buffer.\nlocal actlist = {}\n\n-- Argument list for next dasm_put(). Start with offset 0 into action list.\nlocal actargs = { 0 }\n\n-- Current number of section buffer positions for dasm_put().\nlocal secpos = 1\n\n------------------------------------------------------------------------------\n\n-- Dump action names and numbers.\nlocal function dumpactions(out)\n  out:write(\"DynASM encoding engine action codes:\\n\")\n  for n,name in ipairs(action_names) do\n    local num = map_action[name]\n    out:write(format(\"  %-10s %02X  %d\\n\", name, num, num))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write action list buffer as a huge static C array.\nlocal function writeactions(out, name)\n  local nn = #actlist\n  if nn == 0 then nn = 1; actlist[0] = map_action.STOP end\n  out:write(\"static const unsigned int \", name, \"[\", nn, \"] = {\\n\")\n  for i = 1,nn-1 do\n    assert(out:write(\"0x\", tohex(actlist[i]), \",\\n\"))\n  end\n  assert(out:write(\"0x\", tohex(actlist[nn]), \"\\n};\\n\\n\"))\nend\n\n------------------------------------------------------------------------------\n\n-- Add word to action list.\nlocal function wputxw(n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  actlist[#actlist+1] = n\nend\n\n-- Add action to list with optional arg. Advance buffer pos, too.\nlocal function waction(action, val, a, num)\n  local w = assert(map_action[action], \"bad action name `\"..action..\"'\")\n  wputxw(0xff000000 + w * 0x10000 + (val or 0))\n  if a then actargs[#actargs+1] = a end\n  if a or num then secpos = secpos + (num or 1) end\nend\n\n-- Flush action list (intervening C code or buffer pos overflow).\nlocal function wflush(term)\n  if #actlist == actargs[1] then return end -- Nothing to flush.\n  if not term then waction(\"STOP\") end -- Terminate action list.\n  wline(format(\"dasm_put(Dst, %s);\", concat(actargs, \", \")), true)\n  actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().\n  secpos = 1 -- The actionlist offset occupies a buffer position, too.\nend\n\n-- Put escaped word.\nlocal function wputw(n)\n  if n >= 0xff000000 then waction(\"ESC\") end\n  wputxw(n)\nend\n\n-- Reserve position for word.\nlocal function wpos()\n  local pos = #actlist+1\n  actlist[pos] = \"\"\n  return pos\nend\n\n-- Store word to reserved position.\nlocal function wputpos(pos, n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  actlist[pos] = n\nend\n\n------------------------------------------------------------------------------\n\n-- Global label name -> global label number. With auto assignment on 1st use.\nlocal next_global = 20\nlocal map_global = setmetatable({}, { __index = function(t, name)\n  if not match(name, \"^[%a_][%w_]*$\") then werror(\"bad global label\") end\n  local n = next_global\n  if n > 2047 then werror(\"too many global labels\") end\n  next_global = n + 1\n  t[name] = n\n  return n\nend})\n\n-- Dump global labels.\nlocal function dumpglobals(out, lvl)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"Global labels:\\n\")\n  for i=20,next_global-1 do\n    out:write(format(\"  %s\\n\", t[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write global label enum.\nlocal function writeglobals(out, prefix)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"enum {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \", prefix, t[i], \",\\n\")\n  end\n  out:write(\"  \", prefix, \"_MAX\\n};\\n\")\nend\n\n-- Write global label names.\nlocal function writeglobalnames(out, name)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \\\"\", t[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Extern label name -> extern label number. With auto assignment on 1st use.\nlocal next_extern = 0\nlocal map_extern_ = {}\nlocal map_extern = setmetatable({}, { __index = function(t, name)\n  -- No restrictions on the name for now.\n  local n = next_extern\n  if n > 2047 then werror(\"too many extern labels\") end\n  next_extern = n + 1\n  t[name] = n\n  map_extern_[n] = name\n  return n\nend})\n\n-- Dump extern labels.\nlocal function dumpexterns(out, lvl)\n  out:write(\"Extern labels:\\n\")\n  for i=0,next_extern-1 do\n    out:write(format(\"  %s\\n\", map_extern_[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write extern label names.\nlocal function writeexternnames(out, name)\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=0,next_extern-1 do\n    out:write(\"  \\\"\", map_extern_[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Arch-specific maps.\nlocal map_archdef = { sp=\"r29\", ra=\"r31\" } -- Ext. register name -> int. name.\n\nlocal map_type = {}\t\t-- Type name -> { ctype, reg }\nlocal ctypenum = 0\t\t-- Type number (for Dt... macros).\n\n-- Reverse defines for registers.\nfunction _M.revdef(s)\n  if s == \"r29\" then return \"sp\"\n  elseif s == \"r31\" then return \"ra\" end\n  return s\nend\n\n------------------------------------------------------------------------------\n\n-- Template strings for MIPS instructions.\nlocal map_op = {\n  -- First-level opcodes.\n  j_1 =\t\t\"08000000J\",\n  jal_1 =\t\"0c000000J\",\n  b_1 =\t\t\"10000000B\",\n  beqz_2 =\t\"10000000SB\",\n  beq_3 =\t\"10000000STB\",\n  bnez_2 =\t\"14000000SB\",\n  bne_3 =\t\"14000000STB\",\n  blez_2 =\t\"18000000SB\",\n  bgtz_2 =\t\"1c000000SB\",\n  li_2 =\t\"24000000TI\",\n  addiu_3 =\t\"24000000TSI\",\n  slti_3 =\t\"28000000TSI\",\n  sltiu_3 =\t\"2c000000TSI\",\n  andi_3 =\t\"30000000TSU\",\n  lu_2 =\t\"34000000TU\",\n  ori_3 =\t\"34000000TSU\",\n  xori_3 =\t\"38000000TSU\",\n  lui_2 =\t\"3c000000TU\",\n  daddiu_3 =\tmips64 and \"64000000TSI\",\n  ldl_2 =\tmips64 and \"68000000TO\",\n  ldr_2 =\tmips64 and \"6c000000TO\",\n  lb_2 =\t\"80000000TO\",\n  lh_2 =\t\"84000000TO\",\n  lw_2 =\t\"8c000000TO\",\n  lbu_2 =\t\"90000000TO\",\n  lhu_2 =\t\"94000000TO\",\n  lwu_2 =\tmips64 and \"9c000000TO\",\n  sb_2 =\t\"a0000000TO\",\n  sh_2 =\t\"a4000000TO\",\n  sw_2 =\t\"ac000000TO\",\n  lwc1_2 =\t\"c4000000HO\",\n  ldc1_2 =\t\"d4000000HO\",\n  ld_2 =\tmips64 and \"dc000000TO\",\n  swc1_2 =\t\"e4000000HO\",\n  sdc1_2 =\t\"f4000000HO\",\n  sd_2 =\tmips64 and \"fc000000TO\",\n\n  -- Opcode SPECIAL.\n  nop_0 =\t\"00000000\",\n  sll_3 =\t\"00000000DTA\",\n  sextw_2 =\t\"00000000DT\",\n  srl_3 =\t\"00000002DTA\",\n  rotr_3 =\t\"00200002DTA\",\n  sra_3 =\t\"00000003DTA\",\n  sllv_3 =\t\"00000004DTS\",\n  srlv_3 =\t\"00000006DTS\",\n  rotrv_3 =\t\"00000046DTS\",\n  drotrv_3 =\tmips64 and \"00000056DTS\",\n  srav_3 =\t\"00000007DTS\",\n  jalr_1 =\t\"0000f809S\",\n  jalr_2 =\t\"00000009DS\",\n  syscall_0 =\t\"0000000c\",\n  syscall_1 =\t\"0000000cY\",\n  break_0 =\t\"0000000d\",\n  break_1 =\t\"0000000dY\",\n  sync_0 =\t\"0000000f\",\n  dsllv_3 =\tmips64 and \"00000014DTS\",\n  dsrlv_3 =\tmips64 and \"00000016DTS\",\n  dsrav_3 =\tmips64 and \"00000017DTS\",\n  add_3 =\t\"00000020DST\",\n  move_2 =\tmips64 and \"00000025DS\" or \"00000021DS\",\n  addu_3 =\t\"00000021DST\",\n  sub_3 =\t\"00000022DST\",\n  negu_2 =\tmips64 and \"0000002fDT\" or \"00000023DT\",\n  subu_3 =\t\"00000023DST\",\n  and_3 =\t\"00000024DST\",\n  or_3 =\t\"00000025DST\",\n  xor_3 =\t\"00000026DST\",\n  not_2 =\t\"00000027DS\",\n  nor_3 =\t\"00000027DST\",\n  slt_3 =\t\"0000002aDST\",\n  sltu_3 =\t\"0000002bDST\",\n  dadd_3 =\tmips64 and \"0000002cDST\",\n  daddu_3 =\tmips64 and \"0000002dDST\",\n  dsub_3 =\tmips64 and \"0000002eDST\",\n  dsubu_3 =\tmips64 and \"0000002fDST\",\n  tge_2 =\t\"00000030ST\",\n  tge_3 =\t\"00000030STZ\",\n  tgeu_2 =\t\"00000031ST\",\n  tgeu_3 =\t\"00000031STZ\",\n  tlt_2 =\t\"00000032ST\",\n  tlt_3 =\t\"00000032STZ\",\n  tltu_2 =\t\"00000033ST\",\n  tltu_3 =\t\"00000033STZ\",\n  teq_2 =\t\"00000034ST\",\n  teq_3 =\t\"00000034STZ\",\n  tne_2 =\t\"00000036ST\",\n  tne_3 =\t\"00000036STZ\",\n  dsll_3 =\tmips64 and \"00000038DTa\",\n  dsrl_3 =\tmips64 and \"0000003aDTa\",\n  drotr_3 =\tmips64 and \"0020003aDTa\",\n  dsra_3 =\tmips64 and \"0000003bDTa\",\n  dsll32_3 =\tmips64 and \"0000003cDTA\",\n  dsrl32_3 =\tmips64 and \"0000003eDTA\",\n  drotr32_3 =\tmips64 and \"0020003eDTA\",\n  dsra32_3 =\tmips64 and \"0000003fDTA\",\n\n  -- Opcode REGIMM.\n  bltz_2 =\t\"04000000SB\",\n  bgez_2 =\t\"04010000SB\",\n  bltzl_2 =\t\"04020000SB\",\n  bgezl_2 =\t\"04030000SB\",\n  bal_1 =\t\"04110000B\",\n  synci_1 =\t\"041f0000O\",\n\n  -- Opcode SPECIAL3.\n  ext_4 =\t\"7c000000TSAM\", -- Note: last arg is msbd = size-1\n  dextm_4 =\tmips64 and \"7c000001TSAM\", -- Args: pos    | size-1-32\n  dextu_4 =\tmips64 and \"7c000002TSAM\", -- Args: pos-32 | size-1\n  dext_4 =\tmips64 and \"7c000003TSAM\", -- Args: pos    | size-1\n  zextw_2 =\tmips64 and \"7c00f803TS\",\n  ins_4 =\t\"7c000004TSAM\", -- Note: last arg is msb = pos+size-1\n  dinsm_4 =\tmips64 and \"7c000005TSAM\", -- Args: pos    | pos+size-33\n  dinsu_4 =\tmips64 and \"7c000006TSAM\", -- Args: pos-32 | pos+size-33\n  dins_4 =\tmips64 and \"7c000007TSAM\", -- Args: pos    | pos+size-1\n  wsbh_2 =\t\"7c0000a0DT\",\n  dsbh_2 =\tmips64 and \"7c0000a4DT\",\n  dshd_2 =\tmips64 and \"7c000164DT\",\n  seb_2 =\t\"7c000420DT\",\n  seh_2 =\t\"7c000620DT\",\n  rdhwr_2 =\t\"7c00003bTD\",\n\n  -- Opcode COP0.\n  mfc0_2 =\t\"40000000TD\",\n  mfc0_3 =\t\"40000000TDW\",\n  dmfc0_2 =\tmips64 and \"40200000TD\",\n  dmfc0_3 =\tmips64 and \"40200000TDW\",\n  mtc0_2 =\t\"40800000TD\",\n  mtc0_3 =\t\"40800000TDW\",\n  dmtc0_2 =\tmips64 and \"40a00000TD\",\n  dmtc0_3 =\tmips64 and \"40a00000TDW\",\n  rdpgpr_2 =\t\"41400000DT\",\n  di_0 =\t\"41606000\",\n  di_1 =\t\"41606000T\",\n  ei_0 =\t\"41606020\",\n  ei_1 =\t\"41606020T\",\n  wrpgpr_2 =\t\"41c00000DT\",\n  tlbr_0 =\t\"42000001\",\n  tlbwi_0 =\t\"42000002\",\n  tlbwr_0 =\t\"42000006\",\n  tlbp_0 =\t\"42000008\",\n  eret_0 =\t\"42000018\",\n  deret_0 =\t\"4200001f\",\n  wait_0 =\t\"42000020\",\n\n  -- Opcode COP1.\n  mfc1_2 =\t\"44000000TG\",\n  dmfc1_2 =\tmips64 and \"44200000TG\",\n  cfc1_2 =\t\"44400000TG\",\n  mfhc1_2 =\t\"44600000TG\",\n  mtc1_2 =\t\"44800000TG\",\n  dmtc1_2 =\tmips64 and \"44a00000TG\",\n  ctc1_2 =\t\"44c00000TG\",\n  mthc1_2 =\t\"44e00000TG\",\n\n  [\"add.s_3\"] =\t\t\"46000000FGH\",\n  [\"sub.s_3\"] =\t\t\"46000001FGH\",\n  [\"mul.s_3\"] =\t\t\"46000002FGH\",\n  [\"div.s_3\"] =\t\t\"46000003FGH\",\n  [\"sqrt.s_2\"] =\t\"46000004FG\",\n  [\"abs.s_2\"] =\t\t\"46000005FG\",\n  [\"mov.s_2\"] =\t\t\"46000006FG\",\n  [\"neg.s_2\"] =\t\t\"46000007FG\",\n  [\"round.l.s_2\"] =\t\"46000008FG\",\n  [\"trunc.l.s_2\"] =\t\"46000009FG\",\n  [\"ceil.l.s_2\"] =\t\"4600000aFG\",\n  [\"floor.l.s_2\"] =\t\"4600000bFG\",\n  [\"round.w.s_2\"] =\t\"4600000cFG\",\n  [\"trunc.w.s_2\"] =\t\"4600000dFG\",\n  [\"ceil.w.s_2\"] =\t\"4600000eFG\",\n  [\"floor.w.s_2\"] =\t\"4600000fFG\",\n  [\"recip.s_2\"] =\t\"46000015FG\",\n  [\"rsqrt.s_2\"] =\t\"46000016FG\",\n  [\"cvt.d.s_2\"] =\t\"46000021FG\",\n  [\"cvt.w.s_2\"] =\t\"46000024FG\",\n  [\"cvt.l.s_2\"] =\t\"46000025FG\",\n  [\"add.d_3\"] =\t\t\"46200000FGH\",\n  [\"sub.d_3\"] =\t\t\"46200001FGH\",\n  [\"mul.d_3\"] =\t\t\"46200002FGH\",\n  [\"div.d_3\"] =\t\t\"46200003FGH\",\n  [\"sqrt.d_2\"] =\t\"46200004FG\",\n  [\"abs.d_2\"] =\t\t\"46200005FG\",\n  [\"mov.d_2\"] =\t\t\"46200006FG\",\n  [\"neg.d_2\"] =\t\t\"46200007FG\",\n  [\"round.l.d_2\"] =\t\"46200008FG\",\n  [\"trunc.l.d_2\"] =\t\"46200009FG\",\n  [\"ceil.l.d_2\"] =\t\"4620000aFG\",\n  [\"floor.l.d_2\"] =\t\"4620000bFG\",\n  [\"round.w.d_2\"] =\t\"4620000cFG\",\n  [\"trunc.w.d_2\"] =\t\"4620000dFG\",\n  [\"ceil.w.d_2\"] =\t\"4620000eFG\",\n  [\"floor.w.d_2\"] =\t\"4620000fFG\",\n  [\"recip.d_2\"] =\t\"46200015FG\",\n  [\"rsqrt.d_2\"] =\t\"46200016FG\",\n  [\"cvt.s.d_2\"] =\t\"46200020FG\",\n  [\"cvt.w.d_2\"] =\t\"46200024FG\",\n  [\"cvt.l.d_2\"] =\t\"46200025FG\",\n  [\"cvt.s.w_2\"] =\t\"46800020FG\",\n  [\"cvt.d.w_2\"] =\t\"46800021FG\",\n  [\"cvt.s.l_2\"] =\t\"46a00020FG\",\n  [\"cvt.d.l_2\"] =\t\"46a00021FG\",\n}\n\nif mipsr6 then -- Instructions added with MIPSR6.\n\n  for k,v in pairs({\n\n    -- Add immediate to upper bits.\n    aui_3 =\t\"3c000000TSI\",\n    daui_3 =\tmips64 and \"74000000TSI\",\n    dahi_2 =\tmips64 and \"04060000SI\",\n    dati_2 =\tmips64 and \"041e0000SI\",\n\n    -- TODO: addiupc, auipc, aluipc, lwpc, lwupc, ldpc.\n\n    -- Compact branches.\n    blezalc_2 =\t\"18000000TB\",\t-- rt != 0.\n    bgezalc_2 =\t\"18000000T=SB\",\t-- rt != 0.\n    bgtzalc_2 =\t\"1c000000TB\",\t-- rt != 0.\n    bltzalc_2 =\t\"1c000000T=SB\",\t-- rt != 0.\n\n    blezc_2 =\t\"58000000TB\",\t-- rt != 0.\n    bgezc_2 =\t\"58000000T=SB\",\t-- rt != 0.\n    bgec_3 =\t\"58000000STB\",\t-- rs != rt.\n    blec_3 =\t\"58000000TSB\",\t-- rt != rs.\n\n    bgtzc_2 =\t\"5c000000TB\",\t-- rt != 0.\n    bltzc_2 =\t\"5c000000T=SB\",\t-- rt != 0.\n    bltc_3 =\t\"5c000000STB\",\t-- rs != rt.\n    bgtc_3 =\t\"5c000000TSB\",\t-- rt != rs.\n\n    bgeuc_3 =\t\"18000000STB\",\t-- rs != rt.\n    bleuc_3 =\t\"18000000TSB\",\t-- rt != rs.\n    bltuc_3 =\t\"1c000000STB\",\t-- rs != rt.\n    bgtuc_3 =\t\"1c000000TSB\",\t-- rt != rs.\n\n    beqzalc_2 =\t\"20000000TB\",\t-- rt != 0.\n    bnezalc_2 =\t\"60000000TB\",\t-- rt != 0.\n    beqc_3 =\t\"20000000STB\",\t-- rs < rt.\n    bnec_3 =\t\"60000000STB\",\t-- rs < rt.\n    bovc_3 =\t\"20000000STB\",\t-- rs >= rt.\n    bnvc_3 =\t\"60000000STB\",\t-- rs >= rt.\n\n    beqzc_2 =\t\"d8000000SK\",\t-- rs != 0.\n    bnezc_2 =\t\"f8000000SK\",\t-- rs != 0.\n    jic_2 =\t\"d8000000TI\",\n    jialc_2 =\t\"f8000000TI\",\n    bc_1 =\t\"c8000000L\",\n    balc_1 =\t\"e8000000L\",\n\n    -- Opcode SPECIAL.\n    jr_1 =\t\"00000009S\",\n    sdbbp_0 =\t\"0000000e\",\n    sdbbp_1 =\t\"0000000eY\",\n    lsa_4 =\t\"00000005DSTA\",\n    dlsa_4 =\tmips64 and \"00000015DSTA\",\n    seleqz_3 =\t\"00000035DST\",\n    selnez_3 =\t\"00000037DST\",\n    clz_2 =\t\"00000050DS\",\n    clo_2 =\t\"00000051DS\",\n    dclz_2 =\tmips64 and \"00000052DS\",\n    dclo_2 =\tmips64 and \"00000053DS\",\n    mul_3 =\t\"00000098DST\",\n    muh_3 =\t\"000000d8DST\",\n    mulu_3 =\t\"00000099DST\",\n    muhu_3 =\t\"000000d9DST\",\n    div_3 =\t\"0000009aDST\",\n    mod_3 =\t\"000000daDST\",\n    divu_3 =\t\"0000009bDST\",\n    modu_3 =\t\"000000dbDST\",\n    dmul_3 =\tmips64 and \"0000009cDST\",\n    dmuh_3 =\tmips64 and \"000000dcDST\",\n    dmulu_3 =\tmips64 and \"0000009dDST\",\n    dmuhu_3 =\tmips64 and \"000000ddDST\",\n    ddiv_3 =\tmips64 and \"0000009eDST\",\n    dmod_3 =\tmips64 and \"000000deDST\",\n    ddivu_3 =\tmips64 and \"0000009fDST\",\n    dmodu_3 =\tmips64 and \"000000dfDST\",\n\n    -- Opcode SPECIAL3.\n    align_4 =\t\t\"7c000220DSTA\",\n    dalign_4 =\t\tmips64 and \"7c000224DSTA\",\n    bitswap_2 =\t\t\"7c000020DT\",\n    dbitswap_2 =\tmips64 and \"7c000024DT\",\n\n    -- Opcode COP1.\n    bc1eqz_2 =\t\"45200000HB\",\n    bc1nez_2 =\t\"45a00000HB\",\n\n    [\"sel.s_3\"] =\t\"46000010FGH\",\n    [\"seleqz.s_3\"] =\t\"46000014FGH\",\n    [\"selnez.s_3\"] =\t\"46000017FGH\",\n    [\"maddf.s_3\"] =\t\"46000018FGH\",\n    [\"msubf.s_3\"] =\t\"46000019FGH\",\n    [\"rint.s_2\"] =\t\"4600001aFG\",\n    [\"class.s_2\"] =\t\"4600001bFG\",\n    [\"min.s_3\"] =\t\"4600001cFGH\",\n    [\"mina.s_3\"] =\t\"4600001dFGH\",\n    [\"max.s_3\"] =\t\"4600001eFGH\",\n    [\"maxa.s_3\"] =\t\"4600001fFGH\",\n    [\"cmp.af.s_3\"] =\t\"46800000FGH\",\n    [\"cmp.un.s_3\"] =\t\"46800001FGH\",\n    [\"cmp.or.s_3\"] =\t\"46800011FGH\",\n    [\"cmp.eq.s_3\"] =\t\"46800002FGH\",\n    [\"cmp.une.s_3\"] =\t\"46800012FGH\",\n    [\"cmp.ueq.s_3\"] =\t\"46800003FGH\",\n    [\"cmp.ne.s_3\"] =\t\"46800013FGH\",\n    [\"cmp.lt.s_3\"] =\t\"46800004FGH\",\n    [\"cmp.ult.s_3\"] =\t\"46800005FGH\",\n    [\"cmp.le.s_3\"] =\t\"46800006FGH\",\n    [\"cmp.ule.s_3\"] =\t\"46800007FGH\",\n    [\"cmp.saf.s_3\"] =\t\"46800008FGH\",\n    [\"cmp.sun.s_3\"] =\t\"46800009FGH\",\n    [\"cmp.sor.s_3\"] =\t\"46800019FGH\",\n    [\"cmp.seq.s_3\"] =\t\"4680000aFGH\",\n    [\"cmp.sune.s_3\"] =\t\"4680001aFGH\",\n    [\"cmp.sueq.s_3\"] =\t\"4680000bFGH\",\n    [\"cmp.sne.s_3\"] =\t\"4680001bFGH\",\n    [\"cmp.slt.s_3\"] =\t\"4680000cFGH\",\n    [\"cmp.sult.s_3\"] =\t\"4680000dFGH\",\n    [\"cmp.sle.s_3\"] =\t\"4680000eFGH\",\n    [\"cmp.sule.s_3\"] =\t\"4680000fFGH\",\n\n    [\"sel.d_3\"] =\t\"46200010FGH\",\n    [\"seleqz.d_3\"] =\t\"46200014FGH\",\n    [\"selnez.d_3\"] =\t\"46200017FGH\",\n    [\"maddf.d_3\"] =\t\"46200018FGH\",\n    [\"msubf.d_3\"] =\t\"46200019FGH\",\n    [\"rint.d_2\"] =\t\"4620001aFG\",\n    [\"class.d_2\"] =\t\"4620001bFG\",\n    [\"min.d_3\"] =\t\"4620001cFGH\",\n    [\"mina.d_3\"] =\t\"4620001dFGH\",\n    [\"max.d_3\"] =\t\"4620001eFGH\",\n    [\"maxa.d_3\"] =\t\"4620001fFGH\",\n    [\"cmp.af.d_3\"] =\t\"46a00000FGH\",\n    [\"cmp.un.d_3\"] =\t\"46a00001FGH\",\n    [\"cmp.or.d_3\"] =\t\"46a00011FGH\",\n    [\"cmp.eq.d_3\"] =\t\"46a00002FGH\",\n    [\"cmp.une.d_3\"] =\t\"46a00012FGH\",\n    [\"cmp.ueq.d_3\"] =\t\"46a00003FGH\",\n    [\"cmp.ne.d_3\"] =\t\"46a00013FGH\",\n    [\"cmp.lt.d_3\"] =\t\"46a00004FGH\",\n    [\"cmp.ult.d_3\"] =\t\"46a00005FGH\",\n    [\"cmp.le.d_3\"] =\t\"46a00006FGH\",\n    [\"cmp.ule.d_3\"] =\t\"46a00007FGH\",\n    [\"cmp.saf.d_3\"] =\t\"46a00008FGH\",\n    [\"cmp.sun.d_3\"] =\t\"46a00009FGH\",\n    [\"cmp.sor.d_3\"] =\t\"46a00019FGH\",\n    [\"cmp.seq.d_3\"] =\t\"46a0000aFGH\",\n    [\"cmp.sune.d_3\"] =\t\"46a0001aFGH\",\n    [\"cmp.sueq.d_3\"] =\t\"46a0000bFGH\",\n    [\"cmp.sne.d_3\"] =\t\"46a0001bFGH\",\n    [\"cmp.slt.d_3\"] =\t\"46a0000cFGH\",\n    [\"cmp.sult.d_3\"] =\t\"46a0000dFGH\",\n    [\"cmp.sle.d_3\"] =\t\"46a0000eFGH\",\n    [\"cmp.sule.d_3\"] =\t\"46a0000fFGH\",\n\n  }) do map_op[k] = v end\n\nelse -- Instructions removed by MIPSR6.\n\n  for k,v in pairs({\n    -- Traps, don't use.\n    addi_3 =\t\"20000000TSI\",\n    daddi_3 =\tmips64 and \"60000000TSI\",\n\n    -- Branch on likely, don't use.\n    beqzl_2 =\t\"50000000SB\",\n    beql_3 =\t\"50000000STB\",\n    bnezl_2 =\t\"54000000SB\",\n    bnel_3 =\t\"54000000STB\",\n    blezl_2 =\t\"58000000SB\",\n    bgtzl_2 =\t\"5c000000SB\",\n\n    lwl_2 =\t\"88000000TO\",\n    lwr_2 =\t\"98000000TO\",\n    swl_2 =\t\"a8000000TO\",\n    sdl_2 =\tmips64 and \"b0000000TO\",\n    sdr_2 =\tmips64 and \"b1000000TO\",\n    swr_2 =\t\"b8000000TO\",\n    cache_2 =\t\"bc000000NO\",\n    ll_2 =\t\"c0000000TO\",\n    pref_2 =\t\"cc000000NO\",\n    sc_2 =\t\"e0000000TO\",\n    scd_2 =\tmips64 and \"f0000000TO\",\n\n    -- Opcode SPECIAL.\n    movf_2 =\t\"00000001DS\",\n    movf_3 =\t\"00000001DSC\",\n    movt_2 =\t\"00010001DS\",\n    movt_3 =\t\"00010001DSC\",\n    jr_1 =\t\"00000008S\",\n    movz_3 =\t\"0000000aDST\",\n    movn_3 =\t\"0000000bDST\",\n    mfhi_1 =\t\"00000010D\",\n    mthi_1 =\t\"00000011S\",\n    mflo_1 =\t\"00000012D\",\n    mtlo_1 =\t\"00000013S\",\n    mult_2 =\t\"00000018ST\",\n    multu_2 =\t\"00000019ST\",\n    div_3 =\t\"0000001aST\",\n    divu_3 =\t\"0000001bST\",\n    ddiv_3 =\tmips64 and \"0000001eST\",\n    ddivu_3 =\tmips64 and \"0000001fST\",\n    dmult_2 =\tmips64 and \"0000001cST\",\n    dmultu_2 =\tmips64 and \"0000001dST\",\n\n    -- Opcode REGIMM.\n    tgei_2 =\t\"04080000SI\",\n    tgeiu_2 =\t\"04090000SI\",\n    tlti_2 =\t\"040a0000SI\",\n    tltiu_2 =\t\"040b0000SI\",\n    teqi_2 =\t\"040c0000SI\",\n    tnei_2 =\t\"040e0000SI\",\n    bltzal_2 =\t\"04100000SB\",\n    bgezal_2 =\t\"04110000SB\",\n    bltzall_2 =\t\"04120000SB\",\n    bgezall_2 =\t\"04130000SB\",\n\n    -- Opcode SPECIAL2.\n    madd_2 =\t\"70000000ST\",\n    maddu_2 =\t\"70000001ST\",\n    mul_3 =\t\"70000002DST\",\n    msub_2 =\t\"70000004ST\",\n    msubu_2 =\t\"70000005ST\",\n    clz_2 =\t\"70000020D=TS\",\n    clo_2 =\t\"70000021D=TS\",\n    dclz_2 =\tmips64 and \"70000024D=TS\",\n    dclo_2 =\tmips64 and \"70000025D=TS\",\n    sdbbp_0 =\t\"7000003f\",\n    sdbbp_1 =\t\"7000003fY\",\n\n    -- Opcode COP1.\n    bc1f_1 =\t\"45000000B\",\n    bc1f_2 =\t\"45000000CB\",\n    bc1t_1 =\t\"45010000B\",\n    bc1t_2 =\t\"45010000CB\",\n    bc1fl_1 =\t\"45020000B\",\n    bc1fl_2 =\t\"45020000CB\",\n    bc1tl_1 =\t\"45030000B\",\n    bc1tl_2 =\t\"45030000CB\",\n\n    [\"movf.s_2\"] =\t\"46000011FG\",\n    [\"movf.s_3\"] =\t\"46000011FGC\",\n    [\"movt.s_2\"] =\t\"46010011FG\",\n    [\"movt.s_3\"] =\t\"46010011FGC\",\n    [\"movz.s_3\"] =\t\"46000012FGT\",\n    [\"movn.s_3\"] =\t\"46000013FGT\",\n    [\"cvt.ps.s_3\"] =\t\"46000026FGH\",\n    [\"c.f.s_2\"] =\t\"46000030GH\",\n    [\"c.f.s_3\"] =\t\"46000030VGH\",\n    [\"c.un.s_2\"] =\t\"46000031GH\",\n    [\"c.un.s_3\"] =\t\"46000031VGH\",\n    [\"c.eq.s_2\"] =\t\"46000032GH\",\n    [\"c.eq.s_3\"] =\t\"46000032VGH\",\n    [\"c.ueq.s_2\"] =\t\"46000033GH\",\n    [\"c.ueq.s_3\"] =\t\"46000033VGH\",\n    [\"c.olt.s_2\"] =\t\"46000034GH\",\n    [\"c.olt.s_3\"] =\t\"46000034VGH\",\n    [\"c.ult.s_2\"] =\t\"46000035GH\",\n    [\"c.ult.s_3\"] =\t\"46000035VGH\",\n    [\"c.ole.s_2\"] =\t\"46000036GH\",\n    [\"c.ole.s_3\"] =\t\"46000036VGH\",\n    [\"c.ule.s_2\"] =\t\"46000037GH\",\n    [\"c.ule.s_3\"] =\t\"46000037VGH\",\n    [\"c.sf.s_2\"] =\t\"46000038GH\",\n    [\"c.sf.s_3\"] =\t\"46000038VGH\",\n    [\"c.ngle.s_2\"] =\t\"46000039GH\",\n    [\"c.ngle.s_3\"] =\t\"46000039VGH\",\n    [\"c.seq.s_2\"] =\t\"4600003aGH\",\n    [\"c.seq.s_3\"] =\t\"4600003aVGH\",\n    [\"c.ngl.s_2\"] =\t\"4600003bGH\",\n    [\"c.ngl.s_3\"] =\t\"4600003bVGH\",\n    [\"c.lt.s_2\"] =\t\"4600003cGH\",\n    [\"c.lt.s_3\"] =\t\"4600003cVGH\",\n    [\"c.nge.s_2\"] =\t\"4600003dGH\",\n    [\"c.nge.s_3\"] =\t\"4600003dVGH\",\n    [\"c.le.s_2\"] =\t\"4600003eGH\",\n    [\"c.le.s_3\"] =\t\"4600003eVGH\",\n    [\"c.ngt.s_2\"] =\t\"4600003fGH\",\n    [\"c.ngt.s_3\"] =\t\"4600003fVGH\",\n    [\"movf.d_2\"] =\t\"46200011FG\",\n    [\"movf.d_3\"] =\t\"46200011FGC\",\n    [\"movt.d_2\"] =\t\"46210011FG\",\n    [\"movt.d_3\"] =\t\"46210011FGC\",\n    [\"movz.d_3\"] =\t\"46200012FGT\",\n    [\"movn.d_3\"] =\t\"46200013FGT\",\n    [\"c.f.d_2\"] =\t\"46200030GH\",\n    [\"c.f.d_3\"] =\t\"46200030VGH\",\n    [\"c.un.d_2\"] =\t\"46200031GH\",\n    [\"c.un.d_3\"] =\t\"46200031VGH\",\n    [\"c.eq.d_2\"] =\t\"46200032GH\",\n    [\"c.eq.d_3\"] =\t\"46200032VGH\",\n    [\"c.ueq.d_2\"] =\t\"46200033GH\",\n    [\"c.ueq.d_3\"] =\t\"46200033VGH\",\n    [\"c.olt.d_2\"] =\t\"46200034GH\",\n    [\"c.olt.d_3\"] =\t\"46200034VGH\",\n    [\"c.ult.d_2\"] =\t\"46200035GH\",\n    [\"c.ult.d_3\"] =\t\"46200035VGH\",\n    [\"c.ole.d_2\"] =\t\"46200036GH\",\n    [\"c.ole.d_3\"] =\t\"46200036VGH\",\n    [\"c.ule.d_2\"] =\t\"46200037GH\",\n    [\"c.ule.d_3\"] =\t\"46200037VGH\",\n    [\"c.sf.d_2\"] =\t\"46200038GH\",\n    [\"c.sf.d_3\"] =\t\"46200038VGH\",\n    [\"c.ngle.d_2\"] =\t\"46200039GH\",\n    [\"c.ngle.d_3\"] =\t\"46200039VGH\",\n    [\"c.seq.d_2\"] =\t\"4620003aGH\",\n    [\"c.seq.d_3\"] =\t\"4620003aVGH\",\n    [\"c.ngl.d_2\"] =\t\"4620003bGH\",\n    [\"c.ngl.d_3\"] =\t\"4620003bVGH\",\n    [\"c.lt.d_2\"] =\t\"4620003cGH\",\n    [\"c.lt.d_3\"] =\t\"4620003cVGH\",\n    [\"c.nge.d_2\"] =\t\"4620003dGH\",\n    [\"c.nge.d_3\"] =\t\"4620003dVGH\",\n    [\"c.le.d_2\"] =\t\"4620003eGH\",\n    [\"c.le.d_3\"] =\t\"4620003eVGH\",\n    [\"c.ngt.d_2\"] =\t\"4620003fGH\",\n    [\"c.ngt.d_3\"] =\t\"4620003fVGH\",\n    [\"add.ps_3\"] =\t\"46c00000FGH\",\n    [\"sub.ps_3\"] =\t\"46c00001FGH\",\n    [\"mul.ps_3\"] =\t\"46c00002FGH\",\n    [\"abs.ps_2\"] =\t\"46c00005FG\",\n    [\"mov.ps_2\"] =\t\"46c00006FG\",\n    [\"neg.ps_2\"] =\t\"46c00007FG\",\n    [\"movf.ps_2\"] =\t\"46c00011FG\",\n    [\"movf.ps_3\"] =\t\"46c00011FGC\",\n    [\"movt.ps_2\"] =\t\"46c10011FG\",\n    [\"movt.ps_3\"] =\t\"46c10011FGC\",\n    [\"movz.ps_3\"] =\t\"46c00012FGT\",\n    [\"movn.ps_3\"] =\t\"46c00013FGT\",\n    [\"cvt.s.pu_2\"] =\t\"46c00020FG\",\n    [\"cvt.s.pl_2\"] =\t\"46c00028FG\",\n    [\"pll.ps_3\"] =\t\"46c0002cFGH\",\n    [\"plu.ps_3\"] =\t\"46c0002dFGH\",\n    [\"pul.ps_3\"] =\t\"46c0002eFGH\",\n    [\"puu.ps_3\"] =\t\"46c0002fFGH\",\n    [\"c.f.ps_2\"] =\t\"46c00030GH\",\n    [\"c.f.ps_3\"] =\t\"46c00030VGH\",\n    [\"c.un.ps_2\"] =\t\"46c00031GH\",\n    [\"c.un.ps_3\"] =\t\"46c00031VGH\",\n    [\"c.eq.ps_2\"] =\t\"46c00032GH\",\n    [\"c.eq.ps_3\"] =\t\"46c00032VGH\",\n    [\"c.ueq.ps_2\"] =\t\"46c00033GH\",\n    [\"c.ueq.ps_3\"] =\t\"46c00033VGH\",\n    [\"c.olt.ps_2\"] =\t\"46c00034GH\",\n    [\"c.olt.ps_3\"] =\t\"46c00034VGH\",\n    [\"c.ult.ps_2\"] =\t\"46c00035GH\",\n    [\"c.ult.ps_3\"] =\t\"46c00035VGH\",\n    [\"c.ole.ps_2\"] =\t\"46c00036GH\",\n    [\"c.ole.ps_3\"] =\t\"46c00036VGH\",\n    [\"c.ule.ps_2\"] =\t\"46c00037GH\",\n    [\"c.ule.ps_3\"] =\t\"46c00037VGH\",\n    [\"c.sf.ps_2\"] =\t\"46c00038GH\",\n    [\"c.sf.ps_3\"] =\t\"46c00038VGH\",\n    [\"c.ngle.ps_2\"] =\t\"46c00039GH\",\n    [\"c.ngle.ps_3\"] =\t\"46c00039VGH\",\n    [\"c.seq.ps_2\"] =\t\"46c0003aGH\",\n    [\"c.seq.ps_3\"] =\t\"46c0003aVGH\",\n    [\"c.ngl.ps_2\"] =\t\"46c0003bGH\",\n    [\"c.ngl.ps_3\"] =\t\"46c0003bVGH\",\n    [\"c.lt.ps_2\"] =\t\"46c0003cGH\",\n    [\"c.lt.ps_3\"] =\t\"46c0003cVGH\",\n    [\"c.nge.ps_2\"] =\t\"46c0003dGH\",\n    [\"c.nge.ps_3\"] =\t\"46c0003dVGH\",\n    [\"c.le.ps_2\"] =\t\"46c0003eGH\",\n    [\"c.le.ps_3\"] =\t\"46c0003eVGH\",\n    [\"c.ngt.ps_2\"] =\t\"46c0003fGH\",\n    [\"c.ngt.ps_3\"] =\t\"46c0003fVGH\",\n\n    -- Opcode COP1X.\n    lwxc1_2 =\t\"4c000000FX\",\n    ldxc1_2 =\t\"4c000001FX\",\n    luxc1_2 =\t\"4c000005FX\",\n    swxc1_2 =\t\"4c000008FX\",\n    sdxc1_2 =\t\"4c000009FX\",\n    suxc1_2 =\t\"4c00000dFX\",\n    prefx_2 =\t\"4c00000fMX\",\n    [\"alnv.ps_4\"] =\t\"4c00001eFGHS\",\n    [\"madd.s_4\"] =\t\"4c000020FRGH\",\n    [\"madd.d_4\"] =\t\"4c000021FRGH\",\n    [\"madd.ps_4\"] =\t\"4c000026FRGH\",\n    [\"msub.s_4\"] =\t\"4c000028FRGH\",\n    [\"msub.d_4\"] =\t\"4c000029FRGH\",\n    [\"msub.ps_4\"] =\t\"4c00002eFRGH\",\n    [\"nmadd.s_4\"] =\t\"4c000030FRGH\",\n    [\"nmadd.d_4\"] =\t\"4c000031FRGH\",\n    [\"nmadd.ps_4\"] =\t\"4c000036FRGH\",\n    [\"nmsub.s_4\"] =\t\"4c000038FRGH\",\n    [\"nmsub.d_4\"] =\t\"4c000039FRGH\",\n    [\"nmsub.ps_4\"] =\t\"4c00003eFRGH\",\n\n  }) do map_op[k] = v end\n\nend\n\n------------------------------------------------------------------------------\n\nlocal function parse_gpr(expr)\n  local tname, ovreg = match(expr, \"^([%w_]+):(r[1-3]?[0-9])$\")\n  local tp = map_type[tname or expr]\n  if tp then\n    local reg = ovreg or tp.reg\n    if not reg then\n      werror(\"type `\"..(tname or expr)..\"' needs a register override\")\n    end\n    expr = reg\n  end\n  local r = match(expr, \"^r([1-3]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 31 then return r, tp end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_fpr(expr)\n  local r = match(expr, \"^f([1-3]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 31 then return r end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_imm(imm, bits, shift, scale, signed, action)\n  local n = tonumber(imm)\n  if n then\n    local m = sar(n, scale)\n    if shl(m, scale) == n then\n      if signed then\n\tlocal s = sar(m, bits-1)\n\tif s == 0 then return shl(m, shift)\n\telseif s == -1 then return shl(m + shl(1, bits), shift) end\n      else\n\tif sar(m, bits) == 0 then return shl(m, shift) end\n      end\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  elseif match(imm, \"^[rf]([1-3]?[0-9])$\") or\n\t match(imm, \"^([%w_]+):([rf][1-3]?[0-9])$\") then\n    werror(\"expected immediate operand, got register\")\n  else\n    waction(action or \"IMM\",\n\t    (signed and 32768 or 0)+shl(scale, 10)+shl(bits, 5)+shift, imm)\n    return 0\n  end\nend\n\nlocal function parse_disp(disp)\n  local imm, reg = match(disp, \"^(.*)%(([%w_:]+)%)$\")\n  if imm then\n    local r = shl(parse_gpr(reg), 21)\n    local extname = match(imm, \"^extern%s+(%S+)$\")\n    if extname then\n      waction(\"REL_EXT\", map_extern[extname], nil, 1)\n      return r\n    else\n      return r + parse_imm(imm, 16, 0, 0, true)\n    end\n  end\n  local reg, tailr = match(disp, \"^([%w_:]+)%s*(.*)$\")\n  if reg and tailr ~= \"\" then\n    local r, tp = parse_gpr(reg)\n    if tp then\n      waction(\"IMM\", 32768+16*32, format(tp.ctypefmt, tailr))\n      return shl(r, 21)\n    end\n  end\n  werror(\"bad displacement `\"..disp..\"'\")\nend\n\nlocal function parse_index(idx)\n  local rt, rs = match(idx, \"^(.*)%(([%w_:]+)%)$\")\n  if rt then\n    rt = parse_gpr(rt)\n    rs = parse_gpr(rs)\n    return shl(rt, 16) + shl(rs, 21)\n  end\n  werror(\"bad index `\"..idx..\"'\")\nend\n\nlocal function parse_label(label, def)\n  local prefix = sub(label, 1, 2)\n  -- =>label (pc label reference)\n  if prefix == \"=>\" then\n    return \"PC\", 0, sub(label, 3)\n  end\n  -- ->name (global label reference)\n  if prefix == \"->\" then\n    return \"LG\", map_global[sub(label, 3)]\n  end\n  if def then\n    -- [1-9] (local label definition)\n    if match(label, \"^[1-9]$\") then\n      return \"LG\", 10+tonumber(label)\n    end\n  else\n    -- [<>][1-9] (local label reference)\n    local dir, lnum = match(label, \"^([<>])([1-9])$\")\n    if dir then -- Fwd: 1-9, Bkwd: 11-19.\n      return \"LG\", lnum + (dir == \">\" and 0 or 10)\n    end\n    -- extern label (extern label reference)\n    local extname = match(label, \"^extern%s+(%S+)$\")\n    if extname then\n      return \"EXT\", map_extern[extname]\n    end\n  end\n  werror(\"bad label `\"..label..\"'\")\nend\n\n------------------------------------------------------------------------------\n\n-- Handle opcodes defined with template strings.\nmap_op[\".template__\"] = function(params, template, nparams)\n  if not params then return sub(template, 9) end\n  local op = tonumber(sub(template, 1, 8), 16)\n  local n = 1\n\n  -- Limit number of section buffer positions used by a single dasm_put().\n  -- A single opcode needs a maximum of 2 positions (ins/ext).\n  if secpos+2 > maxsecpos then wflush() end\n  local pos = wpos()\n\n  -- Process each character.\n  for p in gmatch(sub(template, 9), \".\") do\n    if p == \"D\" then\n      op = op + shl(parse_gpr(params[n]), 11); n = n + 1\n    elseif p == \"T\" then\n      op = op + shl(parse_gpr(params[n]), 16); n = n + 1\n    elseif p == \"S\" then\n      op = op + shl(parse_gpr(params[n]), 21); n = n + 1\n    elseif p == \"F\" then\n      op = op + shl(parse_fpr(params[n]), 6); n = n + 1\n    elseif p == \"G\" then\n      op = op + shl(parse_fpr(params[n]), 11); n = n + 1\n    elseif p == \"H\" then\n      op = op + shl(parse_fpr(params[n]), 16); n = n + 1\n    elseif p == \"R\" then\n      op = op + shl(parse_fpr(params[n]), 21); n = n + 1\n    elseif p == \"I\" then\n      op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1\n    elseif p == \"U\" then\n      op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1\n    elseif p == \"O\" then\n      op = op + parse_disp(params[n]); n = n + 1\n    elseif p == \"X\" then\n      op = op + parse_index(params[n]); n = n + 1\n    elseif p == \"B\" or p == \"J\" or p == \"K\" or p == \"L\" then\n      local mode, m, s = parse_label(params[n], false)\n      if p == \"J\" then m = m + 0xa800\n      elseif p == \"K\" then m = m + 0x5000\n      elseif p == \"L\" then m = m + 0xa000 end\n      waction(\"REL_\"..mode, m, s, 1)\n      n = n + 1\n    elseif p == \"A\" then\n      op = op + parse_imm(params[n], 5, 6, 0, false); n = n + 1\n    elseif p == \"a\" then\n      local m = parse_imm(params[n], 6, 6, 0, false, \"IMMS\"); n = n + 1\n      op = op + band(m, 0x7c0) + band(shr(m, 9), 4)\n    elseif p == \"M\" then\n      op = op + parse_imm(params[n], 5, 11, 0, false); n = n + 1\n    elseif p == \"N\" then\n      op = op + parse_imm(params[n], 5, 16, 0, false); n = n + 1\n    elseif p == \"C\" then\n      op = op + parse_imm(params[n], 3, 18, 0, false); n = n + 1\n    elseif p == \"V\" then\n      op = op + parse_imm(params[n], 3, 8, 0, false); n = n + 1\n    elseif p == \"W\" then\n      op = op + parse_imm(params[n], 3, 0, 0, false); n = n + 1\n    elseif p == \"Y\" then\n      op = op + parse_imm(params[n], 20, 6, 0, false); n = n + 1\n    elseif p == \"Z\" then\n      op = op + parse_imm(params[n], 10, 6, 0, false); n = n + 1\n    elseif p == \"=\" then\n      n = n - 1 -- Re-use previous parameter for next template char.\n    else\n      assert(false)\n    end\n  end\n  wputpos(pos, op)\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode to mark the position where the action list is to be emitted.\nmap_op[\".actionlist_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeactions(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the global enum is to be emitted.\nmap_op[\".globals_1\"] = function(params)\n  if not params then return \"prefix\" end\n  local prefix = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobals(out, prefix) end)\nend\n\n-- Pseudo-opcode to mark the position where the global names are to be emitted.\nmap_op[\".globalnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobalnames(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the extern names are to be emitted.\nmap_op[\".externnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeexternnames(out, name) end)\nend\n\n------------------------------------------------------------------------------\n\n-- Label pseudo-opcode (converted from trailing colon form).\nmap_op[\".label_1\"] = function(params)\n  if not params then return \"[1-9] | ->global | =>pcexpr\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local mode, n, s = parse_label(params[1], true)\n  if mode == \"EXT\" then werror(\"bad label definition\") end\n  waction(\"LABEL_\"..mode, n, s, 1)\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcodes for data storage.\nmap_op[\".long_*\"] = function(params)\n  if not params then return \"imm...\" end\n  for _,p in ipairs(params) do\n    local n = tonumber(p)\n    if not n then werror(\"bad immediate `\"..p..\"'\") end\n    if n < 0 then n = n + 2^32 end\n    wputw(n)\n    if secpos+2 > maxsecpos then wflush() end\n  end\nend\n\n-- Alignment pseudo-opcode.\nmap_op[\".align_1\"] = function(params)\n  if not params then return \"numpow2\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local align = tonumber(params[1])\n  if align then\n    local x = align\n    -- Must be a power of 2 in the range (2 ... 256).\n    for i=1,8 do\n      x = x / 2\n      if x == 1 then\n\twaction(\"ALIGN\", align-1, nil, 1) -- Action byte is 2**n-1.\n\treturn\n      end\n    end\n  end\n  werror(\"bad alignment\")\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode for (primitive) type definitions (map to C types).\nmap_op[\".type_3\"] = function(params, nparams)\n  if not params then\n    return nparams == 2 and \"name, ctype\" or \"name, ctype, reg\"\n  end\n  local name, ctype, reg = params[1], params[2], params[3]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    werror(\"bad type name `\"..name..\"'\")\n  end\n  local tp = map_type[name]\n  if tp then\n    werror(\"duplicate type `\"..name..\"'\")\n  end\n  -- Add #type to defines. A bit unclean to put it in map_archdef.\n  map_archdef[\"#\"..name] = \"sizeof(\"..ctype..\")\"\n  -- Add new type and emit shortcut define.\n  local num = ctypenum + 1\n  map_type[name] = {\n    ctype = ctype,\n    ctypefmt = format(\"Dt%X(%%s)\", num),\n    reg = reg,\n  }\n  wline(format(\"#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)\", num, ctype))\n  ctypenum = num\nend\nmap_op[\".type_2\"] = map_op[\".type_3\"]\n\n-- Dump type definitions.\nlocal function dumptypes(out, lvl)\n  local t = {}\n  for name in pairs(map_type) do t[#t+1] = name end\n  sort(t)\n  out:write(\"Type definitions:\\n\")\n  for _,name in ipairs(t) do\n    local tp = map_type[name]\n    local reg = tp.reg or \"\"\n    out:write(format(\"  %-20s %-20s %s\\n\", name, tp.ctype, reg))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Set the current section.\nfunction _M.section(num)\n  waction(\"SECTION\", num)\n  wflush(true) -- SECTION is a terminal action.\nend\n\n------------------------------------------------------------------------------\n\n-- Dump architecture description.\nfunction _M.dumparch(out)\n  out:write(format(\"DynASM %s version %s, released %s\\n\\n\",\n    _info.arch, _info.version, _info.release))\n  dumpactions(out)\nend\n\n-- Dump all user defined elements.\nfunction _M.dumpdef(out, lvl)\n  dumptypes(out, lvl)\n  dumpglobals(out, lvl)\n  dumpexterns(out, lvl)\nend\n\n------------------------------------------------------------------------------\n\n-- Pass callbacks from/to the DynASM core.\nfunction _M.passcb(wl, we, wf, ww)\n  wline, werror, wfatal, wwarn = wl, we, wf, ww\n  return wflush\nend\n\n-- Setup the arch-specific module.\nfunction _M.setup(arch, opt)\n  g_arch, g_opt = arch, opt\nend\n\n-- Merge the core maps and the arch-specific maps.\nfunction _M.mergemaps(map_coreop, map_def)\n  setmetatable(map_op, { __index = map_coreop })\n  setmetatable(map_def, { __index = map_archdef })\n  return map_op, map_def\nend\n\nreturn _M\n\n------------------------------------------------------------------------------\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_mips64.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM MIPS64 module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n------------------------------------------------------------------------------\n-- This module just sets 64 bit mode for the combined MIPS/MIPS64 module.\n-- All the interesting stuff is there.\n------------------------------------------------------------------------------\n\nmips64 = true -- Using a global is an ugly, but effective solution.\nreturn require(\"dasm_mips\")\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_ppc.h",
    "content": "/*\n** DynASM PPC/PPC64 encoding engine.\n** Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n** Released under the MIT license. See dynasm.lua for full copyright notice.\n*/\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define DASM_ARCH\t\t\"ppc\"\n\n#ifndef DASM_EXTERN\n#define DASM_EXTERN(a,b,c,d)\t0\n#endif\n\n/* Action definitions. */\nenum {\n  DASM_STOP, DASM_SECTION, DASM_ESC, DASM_REL_EXT,\n  /* The following actions need a buffer position. */\n  DASM_ALIGN, DASM_REL_LG, DASM_LABEL_LG,\n  /* The following actions also have an argument. */\n  DASM_REL_PC, DASM_LABEL_PC, DASM_IMM, DASM_IMMSH,\n  DASM__MAX\n};\n\n/* Maximum number of section buffer positions for a single dasm_put() call. */\n#define DASM_MAXSECPOS\t\t25\n\n/* DynASM encoder status codes. Action list offset or number are or'ed in. */\n#define DASM_S_OK\t\t0x00000000\n#define DASM_S_NOMEM\t\t0x01000000\n#define DASM_S_PHASE\t\t0x02000000\n#define DASM_S_MATCH_SEC\t0x03000000\n#define DASM_S_RANGE_I\t\t0x11000000\n#define DASM_S_RANGE_SEC\t0x12000000\n#define DASM_S_RANGE_LG\t\t0x13000000\n#define DASM_S_RANGE_PC\t\t0x14000000\n#define DASM_S_RANGE_REL\t0x15000000\n#define DASM_S_UNDEF_LG\t\t0x21000000\n#define DASM_S_UNDEF_PC\t\t0x22000000\n\n/* Macros to convert positions (8 bit section + 24 bit index). */\n#define DASM_POS2IDX(pos)\t((pos)&0x00ffffff)\n#define DASM_POS2BIAS(pos)\t((pos)&0xff000000)\n#define DASM_SEC2POS(sec)\t((sec)<<24)\n#define DASM_POS2SEC(pos)\t((pos)>>24)\n#define DASM_POS2PTR(D, pos)\t(D->sections[DASM_POS2SEC(pos)].rbuf + (pos))\n\n/* Action list type. */\ntypedef const unsigned int *dasm_ActList;\n\n/* Per-section structure. */\ntypedef struct dasm_Section {\n  int *rbuf;\t\t/* Biased buffer pointer (negative section bias). */\n  int *buf;\t\t/* True buffer pointer. */\n  size_t bsize;\t\t/* Buffer size in bytes. */\n  int pos;\t\t/* Biased buffer position. */\n  int epos;\t\t/* End of biased buffer position - max single put. */\n  int ofs;\t\t/* Byte offset into section. */\n} dasm_Section;\n\n/* Core structure holding the DynASM encoding state. */\nstruct dasm_State {\n  size_t psize;\t\t\t/* Allocated size of this structure. */\n  dasm_ActList actionlist;\t/* Current actionlist pointer. */\n  int *lglabels;\t\t/* Local/global chain/pos ptrs. */\n  size_t lgsize;\n  int *pclabels;\t\t/* PC label chains/pos ptrs. */\n  size_t pcsize;\n  void **globals;\t\t/* Array of globals (bias -10). */\n  dasm_Section *section;\t/* Pointer to active section. */\n  size_t codesize;\t\t/* Total size of all code sections. */\n  int maxsection;\t\t/* 0 <= sectionidx < maxsection. */\n  int status;\t\t\t/* Status code. */\n  dasm_Section sections[1];\t/* All sections. Alloc-extended. */\n};\n\n/* The size of the core structure depends on the max. number of sections. */\n#define DASM_PSZ(ms)\t(sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))\n\n\n/* Initialize DynASM state. */\nvoid dasm_init(Dst_DECL, int maxsection)\n{\n  dasm_State *D;\n  size_t psz = 0;\n  int i;\n  Dst_REF = NULL;\n  DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));\n  D = Dst_REF;\n  D->psize = psz;\n  D->lglabels = NULL;\n  D->lgsize = 0;\n  D->pclabels = NULL;\n  D->pcsize = 0;\n  D->globals = NULL;\n  D->maxsection = maxsection;\n  for (i = 0; i < maxsection; i++) {\n    D->sections[i].buf = NULL;  /* Need this for pass3. */\n    D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);\n    D->sections[i].bsize = 0;\n    D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */\n  }\n}\n\n/* Free DynASM state. */\nvoid dasm_free(Dst_DECL)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  for (i = 0; i < D->maxsection; i++)\n    if (D->sections[i].buf)\n      DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);\n  if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);\n  if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);\n  DASM_M_FREE(Dst, D, D->psize);\n}\n\n/* Setup global label array. Must be called before dasm_setup(). */\nvoid dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)\n{\n  dasm_State *D = Dst_REF;\n  D->globals = gl - 10;  /* Negative bias to compensate for locals. */\n  DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));\n}\n\n/* Grow PC label array. Can be called after dasm_setup(), too. */\nvoid dasm_growpc(Dst_DECL, unsigned int maxpc)\n{\n  dasm_State *D = Dst_REF;\n  size_t osz = D->pcsize;\n  DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));\n  memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);\n}\n\n/* Setup encoder. */\nvoid dasm_setup(Dst_DECL, const void *actionlist)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  D->actionlist = (dasm_ActList)actionlist;\n  D->status = DASM_S_OK;\n  D->section = &D->sections[0];\n  memset((void *)D->lglabels, 0, D->lgsize);\n  if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);\n  for (i = 0; i < D->maxsection; i++) {\n    D->sections[i].pos = DASM_SEC2POS(i);\n    D->sections[i].ofs = 0;\n  }\n}\n\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) { \\\n    D->status = DASM_S_##st|(p-D->actionlist-1); return; } } while (0)\n#define CKPL(kind, st) \\\n  do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \\\n    D->status = DASM_S_RANGE_##st|(p-D->actionlist-1); return; } } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#define CKPL(kind, st)\t((void)0)\n#endif\n\n/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */\nvoid dasm_put(Dst_DECL, int start, ...)\n{\n  va_list ap;\n  dasm_State *D = Dst_REF;\n  dasm_ActList p = D->actionlist + start;\n  dasm_Section *sec = D->section;\n  int pos = sec->pos, ofs = sec->ofs;\n  int *b;\n\n  if (pos >= sec->epos) {\n    DASM_M_GROW(Dst, int, sec->buf, sec->bsize,\n      sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));\n    sec->rbuf = sec->buf - DASM_POS2BIAS(pos);\n    sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);\n  }\n\n  b = sec->rbuf;\n  b[pos++] = start;\n\n  va_start(ap, start);\n  while (1) {\n    unsigned int ins = *p++;\n    unsigned int action = (ins >> 16);\n    if (action >= DASM__MAX) {\n      ofs += 4;\n    } else {\n      int *pl, n = action >= DASM_REL_PC ? va_arg(ap, int) : 0;\n      switch (action) {\n      case DASM_STOP: goto stop;\n      case DASM_SECTION:\n\tn = (ins & 255); CK(n < D->maxsection, RANGE_SEC);\n\tD->section = &D->sections[n]; goto stop;\n      case DASM_ESC: p++; ofs += 4; break;\n      case DASM_REL_EXT: break;\n      case DASM_ALIGN: ofs += (ins & 255); b[pos++] = ofs; break;\n      case DASM_REL_LG:\n\tn = (ins & 2047) - 10; pl = D->lglabels + n;\n\t/* Bkwd rel or global. */\n\tif (n >= 0) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }\n\tpl += 10; n = *pl;\n\tif (n < 0) n = 0;  /* Start new chain for fwd rel if label exists. */\n\tgoto linkrel;\n      case DASM_REL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putrel:\n\tn = *pl;\n\tif (n < 0) {  /* Label exists. Get label pos and store it. */\n\t  b[pos] = -n;\n\t} else {\n      linkrel:\n\t  b[pos] = n;  /* Else link to rel chain, anchored at label. */\n\t  *pl = pos;\n\t}\n\tpos++;\n\tbreak;\n      case DASM_LABEL_LG:\n\tpl = D->lglabels + (ins & 2047) - 10; CKPL(lg, LG); goto putlabel;\n      case DASM_LABEL_PC:\n\tpl = D->pclabels + n; CKPL(pc, PC);\n      putlabel:\n\tn = *pl;  /* n > 0: Collapse rel chain and replace with label pos. */\n\twhile (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos;\n\t}\n\t*pl = -pos;  /* Label exists now. */\n\tb[pos++] = ofs;  /* Store pass1 offset estimate. */\n\tbreak;\n      case DASM_IMM:\n#ifdef DASM_CHECKS\n\tCK((n & ((1<<((ins>>10)&31))-1)) == 0, RANGE_I);\n#endif\n\tn >>= ((ins>>10)&31);\n#ifdef DASM_CHECKS\n\tif (ins & 0x8000)\n\t  CK(((n + (1<<(((ins>>5)&31)-1)))>>((ins>>5)&31)) == 0, RANGE_I);\n\telse\n\t  CK((n>>((ins>>5)&31)) == 0, RANGE_I);\n#endif\n\tb[pos++] = n;\n\tbreak;\n      case DASM_IMMSH:\n\tCK((n >> 6) == 0, RANGE_I);\n\tb[pos++] = n;\n\tbreak;\n      }\n    }\n  }\nstop:\n  va_end(ap);\n  sec->pos = pos;\n  sec->ofs = ofs;\n}\n#undef CK\n\n/* Pass 2: Link sections, shrink aligns, fix label offsets. */\nint dasm_link(Dst_DECL, size_t *szp)\n{\n  dasm_State *D = Dst_REF;\n  int secnum;\n  int ofs = 0;\n\n#ifdef DASM_CHECKS\n  *szp = 0;\n  if (D->status != DASM_S_OK) return D->status;\n  {\n    int pc;\n    for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)\n      if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;\n  }\n#endif\n\n  { /* Handle globals not defined in this translation unit. */\n    int idx;\n    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {\n      int n = D->lglabels[idx];\n      /* Undefined label: Collapse rel chain and replace with marker (< 0). */\n      while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }\n    }\n  }\n\n  /* Combine all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->rbuf;\n    int pos = DASM_SEC2POS(secnum);\n    int lastpos = sec->pos;\n\n    while (pos != lastpos) {\n      dasm_ActList p = D->actionlist + b[pos++];\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16);\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: p++; break;\n\tcase DASM_REL_EXT: break;\n\tcase DASM_ALIGN: ofs -= (b[pos++] + ofs) & (ins & 255); break;\n\tcase DASM_REL_LG: case DASM_REL_PC: pos++; break;\n\tcase DASM_LABEL_LG: case DASM_LABEL_PC: b[pos++] += ofs; break;\n\tcase DASM_IMM: case DASM_IMMSH: pos++; break;\n\t}\n      }\n      stop: (void)0;\n    }\n    ofs += sec->ofs;  /* Next section starts right after current section. */\n  }\n\n  D->codesize = ofs;  /* Total size of all code sections */\n  *szp = ofs;\n  return DASM_S_OK;\n}\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) return DASM_S_##st|(p-D->actionlist-1); } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#endif\n\n/* Pass 3: Encode sections. */\nint dasm_encode(Dst_DECL, void *buffer)\n{\n  dasm_State *D = Dst_REF;\n  char *base = (char *)buffer;\n  unsigned int *cp = (unsigned int *)buffer;\n  int secnum;\n\n  /* Encode all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->buf;\n    int *endb = sec->rbuf + sec->pos;\n\n    while (b != endb) {\n      dasm_ActList p = D->actionlist + *b++;\n      while (1) {\n\tunsigned int ins = *p++;\n\tunsigned int action = (ins >> 16);\n\tint n = (action >= DASM_ALIGN && action < DASM__MAX) ? *b++ : 0;\n\tswitch (action) {\n\tcase DASM_STOP: case DASM_SECTION: goto stop;\n\tcase DASM_ESC: *cp++ = *p++; break;\n\tcase DASM_REL_EXT:\n\t  n = DASM_EXTERN(Dst, (unsigned char *)cp, (ins & 2047), 1) - 4;\n\t  goto patchrel;\n\tcase DASM_ALIGN:\n\t  ins &= 255; while ((((char *)cp - base) & ins)) *cp++ = 0x60000000;\n\t  break;\n\tcase DASM_REL_LG:\n\t  if (n < 0) {\n\t    n = (int)((ptrdiff_t)D->globals[-n] - (ptrdiff_t)cp);\n\t    goto patchrel;\n\t  }\n\t  /* fallthrough */\n\tcase DASM_REL_PC:\n\t  CK(n >= 0, UNDEF_PC);\n\t  n = *DASM_POS2PTR(D, n) - (int)((char *)cp - base);\n\tpatchrel:\n\t  CK((n & 3) == 0 &&\n\t      (((n+4) + ((ins & 2048) ? 0x00008000 : 0x02000000)) >>\n\t       ((ins & 2048) ? 16 : 26)) == 0, RANGE_REL);\n\t  cp[-1] |= ((n+4) & ((ins & 2048) ? 0x0000fffc: 0x03fffffc));\n\t  break;\n\tcase DASM_LABEL_LG:\n\t  ins &= 2047; if (ins >= 20) D->globals[ins-10] = (void *)(base + n);\n\t  break;\n\tcase DASM_LABEL_PC: break;\n\tcase DASM_IMM:\n\t  cp[-1] |= (n & ((1<<((ins>>5)&31))-1)) << (ins&31);\n\t  break;\n\tcase DASM_IMMSH:\n\t  cp[-1] |= (ins & 1) ? ((n&31)<<11)|((n&32)>>4) : ((n&31)<<6)|(n&32);\n\t  break;\n\tdefault: *cp++ = ins; break;\n\t}\n      }\n      stop: (void)0;\n    }\n  }\n\n  if (base + D->codesize != (char *)cp)  /* Check for phase errors. */\n    return DASM_S_PHASE;\n  return DASM_S_OK;\n}\n#undef CK\n\n/* Get PC label offset. */\nint dasm_getpclabel(Dst_DECL, unsigned int pc)\n{\n  dasm_State *D = Dst_REF;\n  if (pc*sizeof(int) < D->pcsize) {\n    int pos = D->pclabels[pc];\n    if (pos < 0) return *DASM_POS2PTR(D, -pos);\n    if (pos > 0) return -1;  /* Undefined. */\n  }\n  return -2;  /* Unused or out of range. */\n}\n\n#ifdef DASM_CHECKS\n/* Optional sanity checker to call between isolated encoding steps. */\nint dasm_checkstep(Dst_DECL, int secmatch)\n{\n  dasm_State *D = Dst_REF;\n  if (D->status == DASM_S_OK) {\n    int i;\n    for (i = 1; i <= 9; i++) {\n      if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_LG|i; break; }\n      D->lglabels[i] = 0;\n    }\n  }\n  if (D->status == DASM_S_OK && secmatch >= 0 &&\n      D->section != &D->sections[secmatch])\n    D->status = DASM_S_MATCH_SEC|(D->section-D->sections);\n  return D->status;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_ppc.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM PPC/PPC64 module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n--\n-- Support for various extensions contributed by Caio Souza Oliveira.\n------------------------------------------------------------------------------\n\n-- Module information:\nlocal _info = {\n  arch =\t\"ppc\",\n  description =\t\"DynASM PPC module\",\n  version =\t\"1.5.0\",\n  vernum =\t 10500,\n  release =\t\"2021-05-02\",\n  author =\t\"Mike Pall\",\n  license =\t\"MIT\",\n}\n\n-- Exported glue functions for the arch-specific module.\nlocal _M = { _info = _info }\n\n-- Cache library functions.\nlocal type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs\nlocal assert, setmetatable = assert, setmetatable\nlocal _s = string\nlocal sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char\nlocal match, gmatch = _s.match, _s.gmatch\nlocal concat, sort = table.concat, table.sort\nlocal bit = bit or require(\"bit\")\nlocal band, shl, shr, sar = bit.band, bit.lshift, bit.rshift, bit.arshift\nlocal tohex = bit.tohex\n\n-- Inherited tables and callbacks.\nlocal g_opt, g_arch\nlocal wline, werror, wfatal, wwarn\n\n-- Action name list.\n-- CHECK: Keep this in sync with the C code!\nlocal action_names = {\n  \"STOP\", \"SECTION\", \"ESC\", \"REL_EXT\",\n  \"ALIGN\", \"REL_LG\", \"LABEL_LG\",\n  \"REL_PC\", \"LABEL_PC\", \"IMM\", \"IMMSH\"\n}\n\n-- Maximum number of section buffer positions for dasm_put().\n-- CHECK: Keep this in sync with the C code!\nlocal maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.\n\n-- Action name -> action number.\nlocal map_action = {}\nfor n,name in ipairs(action_names) do\n  map_action[name] = n-1\nend\n\n-- Action list buffer.\nlocal actlist = {}\n\n-- Argument list for next dasm_put(). Start with offset 0 into action list.\nlocal actargs = { 0 }\n\n-- Current number of section buffer positions for dasm_put().\nlocal secpos = 1\n\n------------------------------------------------------------------------------\n\n-- Dump action names and numbers.\nlocal function dumpactions(out)\n  out:write(\"DynASM encoding engine action codes:\\n\")\n  for n,name in ipairs(action_names) do\n    local num = map_action[name]\n    out:write(format(\"  %-10s %02X  %d\\n\", name, num, num))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write action list buffer as a huge static C array.\nlocal function writeactions(out, name)\n  local nn = #actlist\n  if nn == 0 then nn = 1; actlist[0] = map_action.STOP end\n  out:write(\"static const unsigned int \", name, \"[\", nn, \"] = {\\n\")\n  for i = 1,nn-1 do\n    assert(out:write(\"0x\", tohex(actlist[i]), \",\\n\"))\n  end\n  assert(out:write(\"0x\", tohex(actlist[nn]), \"\\n};\\n\\n\"))\nend\n\n------------------------------------------------------------------------------\n\n-- Add word to action list.\nlocal function wputxw(n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  actlist[#actlist+1] = n\nend\n\n-- Add action to list with optional arg. Advance buffer pos, too.\nlocal function waction(action, val, a, num)\n  local w = assert(map_action[action], \"bad action name `\"..action..\"'\")\n  wputxw(w * 0x10000 + (val or 0))\n  if a then actargs[#actargs+1] = a end\n  if a or num then secpos = secpos + (num or 1) end\nend\n\n-- Flush action list (intervening C code or buffer pos overflow).\nlocal function wflush(term)\n  if #actlist == actargs[1] then return end -- Nothing to flush.\n  if not term then waction(\"STOP\") end -- Terminate action list.\n  wline(format(\"dasm_put(Dst, %s);\", concat(actargs, \", \")), true)\n  actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().\n  secpos = 1 -- The actionlist offset occupies a buffer position, too.\nend\n\n-- Put escaped word.\nlocal function wputw(n)\n  if n <= 0xffffff then waction(\"ESC\") end\n  wputxw(n)\nend\n\n-- Reserve position for word.\nlocal function wpos()\n  local pos = #actlist+1\n  actlist[pos] = \"\"\n  return pos\nend\n\n-- Store word to reserved position.\nlocal function wputpos(pos, n)\n  assert(n >= 0 and n <= 0xffffffff and n % 1 == 0, \"word out of range\")\n  actlist[pos] = n\nend\n\n------------------------------------------------------------------------------\n\n-- Global label name -> global label number. With auto assignment on 1st use.\nlocal next_global = 20\nlocal map_global = setmetatable({}, { __index = function(t, name)\n  if not match(name, \"^[%a_][%w_]*$\") then werror(\"bad global label\") end\n  local n = next_global\n  if n > 2047 then werror(\"too many global labels\") end\n  next_global = n + 1\n  t[name] = n\n  return n\nend})\n\n-- Dump global labels.\nlocal function dumpglobals(out, lvl)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"Global labels:\\n\")\n  for i=20,next_global-1 do\n    out:write(format(\"  %s\\n\", t[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write global label enum.\nlocal function writeglobals(out, prefix)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"enum {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \", prefix, t[i], \",\\n\")\n  end\n  out:write(\"  \", prefix, \"_MAX\\n};\\n\")\nend\n\n-- Write global label names.\nlocal function writeglobalnames(out, name)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=20,next_global-1 do\n    out:write(\"  \\\"\", t[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Extern label name -> extern label number. With auto assignment on 1st use.\nlocal next_extern = 0\nlocal map_extern_ = {}\nlocal map_extern = setmetatable({}, { __index = function(t, name)\n  -- No restrictions on the name for now.\n  local n = next_extern\n  if n > 2047 then werror(\"too many extern labels\") end\n  next_extern = n + 1\n  t[name] = n\n  map_extern_[n] = name\n  return n\nend})\n\n-- Dump extern labels.\nlocal function dumpexterns(out, lvl)\n  out:write(\"Extern labels:\\n\")\n  for i=0,next_extern-1 do\n    out:write(format(\"  %s\\n\", map_extern_[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write extern label names.\nlocal function writeexternnames(out, name)\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=0,next_extern-1 do\n    out:write(\"  \\\"\", map_extern_[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Arch-specific maps.\nlocal map_archdef = { sp = \"r1\" } -- Ext. register name -> int. name.\n\nlocal map_type = {}\t\t-- Type name -> { ctype, reg }\nlocal ctypenum = 0\t\t-- Type number (for Dt... macros).\n\n-- Reverse defines for registers.\nfunction _M.revdef(s)\n  if s == \"r1\" then return \"sp\" end\n  return s\nend\n\nlocal map_cond = {\n  lt = 0, gt = 1, eq = 2, so = 3,\n  ge = 4, le = 5, ne = 6, ns = 7,\n}\n\n------------------------------------------------------------------------------\n\nlocal map_op, op_template\n\nlocal function op_alias(opname, f)\n  return function(params, nparams)\n    if not params then return \"-> \"..opname:sub(1, -3) end\n    f(params, nparams)\n    op_template(params, map_op[opname], nparams)\n  end\nend\n\n-- Template strings for PPC instructions.\nmap_op = {\n  tdi_3 =\t\"08000000ARI\",\n  twi_3 =\t\"0c000000ARI\",\n  mulli_3 =\t\"1c000000RRI\",\n  subfic_3 =\t\"20000000RRI\",\n  cmplwi_3 =\t\"28000000XRU\",\n  cmplwi_2 =\t\"28000000-RU\",\n  cmpldi_3 =\t\"28200000XRU\",\n  cmpldi_2 =\t\"28200000-RU\",\n  cmpwi_3 =\t\"2c000000XRI\",\n  cmpwi_2 =\t\"2c000000-RI\",\n  cmpdi_3 =\t\"2c200000XRI\",\n  cmpdi_2 =\t\"2c200000-RI\",\n  addic_3 =\t\"30000000RRI\",\n  [\"addic._3\"] = \"34000000RRI\",\n  addi_3 =\t\"38000000RR0I\",\n  li_2 =\t\"38000000RI\",\n  la_2 =\t\"38000000RD\",\n  addis_3 =\t\"3c000000RR0I\",\n  lis_2 =\t\"3c000000RI\",\n  lus_2 =\t\"3c000000RU\",\n  bc_3 =\t\"40000000AAK\",\n  bcl_3 =\t\"40000001AAK\",\n  bdnz_1 =\t\"42000000K\",\n  bdz_1 =\t\"42400000K\",\n  sc_0 =\t\"44000000\",\n  b_1 =\t\t\"48000000J\",\n  bl_1 =\t\"48000001J\",\n  rlwimi_5 =\t\"50000000RR~AAA.\",\n  rlwinm_5 =\t\"54000000RR~AAA.\",\n  rlwnm_5 =\t\"5c000000RR~RAA.\",\n  ori_3 =\t\"60000000RR~U\",\n  nop_0 =\t\"60000000\",\n  oris_3 =\t\"64000000RR~U\",\n  xori_3 =\t\"68000000RR~U\",\n  xoris_3 =\t\"6c000000RR~U\",\n  [\"andi._3\"] =\t\"70000000RR~U\",\n  [\"andis._3\"] = \"74000000RR~U\",\n  lwz_2 =\t\"80000000RD\",\n  lwzu_2 =\t\"84000000RD\",\n  lbz_2 =\t\"88000000RD\",\n  lbzu_2 =\t\"8c000000RD\",\n  stw_2 =\t\"90000000RD\",\n  stwu_2 =\t\"94000000RD\",\n  stb_2 =\t\"98000000RD\",\n  stbu_2 =\t\"9c000000RD\",\n  lhz_2 =\t\"a0000000RD\",\n  lhzu_2 =\t\"a4000000RD\",\n  lha_2 =\t\"a8000000RD\",\n  lhau_2 =\t\"ac000000RD\",\n  sth_2 =\t\"b0000000RD\",\n  sthu_2 =\t\"b4000000RD\",\n  lmw_2 =\t\"b8000000RD\",\n  stmw_2 =\t\"bc000000RD\",\n  lfs_2 =\t\"c0000000FD\",\n  lfsu_2 =\t\"c4000000FD\",\n  lfd_2 =\t\"c8000000FD\",\n  lfdu_2 =\t\"cc000000FD\",\n  stfs_2 =\t\"d0000000FD\",\n  stfsu_2 =\t\"d4000000FD\",\n  stfd_2 =\t\"d8000000FD\",\n  stfdu_2 =\t\"dc000000FD\",\n  ld_2 =\t\"e8000000RD\", -- NYI: displacement must be divisible by 4.\n  ldu_2 =\t\"e8000001RD\",\n  lwa_2 =\t\"e8000002RD\",\n  std_2 =\t\"f8000000RD\",\n  stdu_2 =\t\"f8000001RD\",\n\n  subi_3 =\top_alias(\"addi_3\", function(p) p[3] = \"-(\"..p[3]..\")\" end),\n  subis_3 =\top_alias(\"addis_3\", function(p) p[3] = \"-(\"..p[3]..\")\" end),\n  subic_3 =\top_alias(\"addic_3\", function(p) p[3] = \"-(\"..p[3]..\")\" end),\n  [\"subic._3\"] = op_alias(\"addic._3\", function(p) p[3] = \"-(\"..p[3]..\")\" end),\n\n  rotlwi_3 =\top_alias(\"rlwinm_5\", function(p)\n    p[4] = \"0\"; p[5] = \"31\"\n  end),\n  rotrwi_3 =\top_alias(\"rlwinm_5\", function(p)\n    p[3] = \"32-(\"..p[3]..\")\"; p[4] = \"0\"; p[5] = \"31\"\n  end),\n  rotlw_3 =\top_alias(\"rlwnm_5\", function(p)\n    p[4] = \"0\"; p[5] = \"31\"\n  end),\n  slwi_3 =\top_alias(\"rlwinm_5\", function(p)\n    p[5] = \"31-(\"..p[3]..\")\"; p[4] = \"0\"\n  end),\n  srwi_3 =\top_alias(\"rlwinm_5\", function(p)\n    p[4] = p[3]; p[3] = \"32-(\"..p[3]..\")\"; p[5] = \"31\"\n  end),\n  clrlwi_3 =\top_alias(\"rlwinm_5\", function(p)\n    p[4] = p[3]; p[3] = \"0\"; p[5] = \"31\"\n  end),\n  clrrwi_3 =\top_alias(\"rlwinm_5\", function(p)\n    p[5] = \"31-(\"..p[3]..\")\"; p[3] = \"0\"; p[4] = \"0\"\n  end),\n\n  -- Primary opcode 4:\n  mulhhwu_3 =\t\t\"10000010RRR.\",\n  machhwu_3 =\t\t\"10000018RRR.\",\n  mulhhw_3 =\t\t\"10000050RRR.\",\n  nmachhw_3 =\t\t\"1000005cRRR.\",\n  machhwsu_3 =\t\t\"10000098RRR.\",\n  machhws_3 =\t\t\"100000d8RRR.\",\n  nmachhws_3 =\t\t\"100000dcRRR.\",\n  mulchwu_3 =\t\t\"10000110RRR.\",\n  macchwu_3 =\t\t\"10000118RRR.\",\n  mulchw_3 =\t\t\"10000150RRR.\",\n  macchw_3 =\t\t\"10000158RRR.\",\n  nmacchw_3 =\t\t\"1000015cRRR.\",\n  macchwsu_3 =\t\t\"10000198RRR.\",\n  macchws_3 =\t\t\"100001d8RRR.\",\n  nmacchws_3 =\t\t\"100001dcRRR.\",\n  mullhw_3 =\t\t\"10000350RRR.\",\n  maclhw_3 =\t\t\"10000358RRR.\",\n  nmaclhw_3 =\t\t\"1000035cRRR.\",\n  maclhwsu_3 =\t\t\"10000398RRR.\",\n  maclhws_3 =\t\t\"100003d8RRR.\",\n  nmaclhws_3 =\t\t\"100003dcRRR.\",\n  machhwuo_3 =\t\t\"10000418RRR.\",\n  nmachhwo_3 =\t\t\"1000045cRRR.\",\n  machhwsuo_3 =\t\t\"10000498RRR.\",\n  machhwso_3 =\t\t\"100004d8RRR.\",\n  nmachhwso_3 =\t\t\"100004dcRRR.\",\n  macchwuo_3 =\t\t\"10000518RRR.\",\n  macchwo_3 =\t\t\"10000558RRR.\",\n  nmacchwo_3 =\t\t\"1000055cRRR.\",\n  macchwsuo_3 =\t\t\"10000598RRR.\",\n  macchwso_3 =\t\t\"100005d8RRR.\",\n  nmacchwso_3 =\t\t\"100005dcRRR.\",\n  maclhwo_3 =\t\t\"10000758RRR.\",\n  nmaclhwo_3 =\t\t\"1000075cRRR.\",\n  maclhwsuo_3 =\t\t\"10000798RRR.\",\n  maclhwso_3 =\t\t\"100007d8RRR.\",\n  nmaclhwso_3 =\t\t\"100007dcRRR.\",\n\n  vaddubm_3 =\t\t\"10000000VVV\",\n  vmaxub_3 =\t\t\"10000002VVV\",\n  vrlb_3 =\t\t\"10000004VVV\",\n  vcmpequb_3 =\t\t\"10000006VVV\",\n  vmuloub_3 =\t\t\"10000008VVV\",\n  vaddfp_3 =\t\t\"1000000aVVV\",\n  vmrghb_3 =\t\t\"1000000cVVV\",\n  vpkuhum_3 =\t\t\"1000000eVVV\",\n  vmhaddshs_4 =\t\t\"10000020VVVV\",\n  vmhraddshs_4 =\t\"10000021VVVV\",\n  vmladduhm_4 =\t\t\"10000022VVVV\",\n  vmsumubm_4 =\t\t\"10000024VVVV\",\n  vmsummbm_4 =\t\t\"10000025VVVV\",\n  vmsumuhm_4 =\t\t\"10000026VVVV\",\n  vmsumuhs_4 =\t\t\"10000027VVVV\",\n  vmsumshm_4 =\t\t\"10000028VVVV\",\n  vmsumshs_4 =\t\t\"10000029VVVV\",\n  vsel_4 =\t\t\"1000002aVVVV\",\n  vperm_4 =\t\t\"1000002bVVVV\",\n  vsldoi_4 =\t\t\"1000002cVVVP\",\n  vpermxor_4 =\t\t\"1000002dVVVV\",\n  vmaddfp_4 =\t\t\"1000002eVVVV~\",\n  vnmsubfp_4 =\t\t\"1000002fVVVV~\",\n  vaddeuqm_4 =\t\t\"1000003cVVVV\",\n  vaddecuq_4 =\t\t\"1000003dVVVV\",\n  vsubeuqm_4 =\t\t\"1000003eVVVV\",\n  vsubecuq_4 =\t\t\"1000003fVVVV\",\n  vadduhm_3 =\t\t\"10000040VVV\",\n  vmaxuh_3 =\t\t\"10000042VVV\",\n  vrlh_3 =\t\t\"10000044VVV\",\n  vcmpequh_3 =\t\t\"10000046VVV\",\n  vmulouh_3 =\t\t\"10000048VVV\",\n  vsubfp_3 =\t\t\"1000004aVVV\",\n  vmrghh_3 =\t\t\"1000004cVVV\",\n  vpkuwum_3 =\t\t\"1000004eVVV\",\n  vadduwm_3 =\t\t\"10000080VVV\",\n  vmaxuw_3 =\t\t\"10000082VVV\",\n  vrlw_3 =\t\t\"10000084VVV\",\n  vcmpequw_3 =\t\t\"10000086VVV\",\n  vmulouw_3 =\t\t\"10000088VVV\",\n  vmuluwm_3 =\t\t\"10000089VVV\",\n  vmrghw_3 =\t\t\"1000008cVVV\",\n  vpkuhus_3 =\t\t\"1000008eVVV\",\n  vaddudm_3 =\t\t\"100000c0VVV\",\n  vmaxud_3 =\t\t\"100000c2VVV\",\n  vrld_3 =\t\t\"100000c4VVV\",\n  vcmpeqfp_3 =\t\t\"100000c6VVV\",\n  vcmpequd_3 =\t\t\"100000c7VVV\",\n  vpkuwus_3 =\t\t\"100000ceVVV\",\n  vadduqm_3 =\t\t\"10000100VVV\",\n  vmaxsb_3 =\t\t\"10000102VVV\",\n  vslb_3 =\t\t\"10000104VVV\",\n  vmulosb_3 =\t\t\"10000108VVV\",\n  vrefp_2 =\t\t\"1000010aV-V\",\n  vmrglb_3 =\t\t\"1000010cVVV\",\n  vpkshus_3 =\t\t\"1000010eVVV\",\n  vaddcuq_3 =\t\t\"10000140VVV\",\n  vmaxsh_3 =\t\t\"10000142VVV\",\n  vslh_3 =\t\t\"10000144VVV\",\n  vmulosh_3 =\t\t\"10000148VVV\",\n  vrsqrtefp_2 =\t\t\"1000014aV-V\",\n  vmrglh_3 =\t\t\"1000014cVVV\",\n  vpkswus_3 =\t\t\"1000014eVVV\",\n  vaddcuw_3 =\t\t\"10000180VVV\",\n  vmaxsw_3 =\t\t\"10000182VVV\",\n  vslw_3 =\t\t\"10000184VVV\",\n  vmulosw_3 =\t\t\"10000188VVV\",\n  vexptefp_2 =\t\t\"1000018aV-V\",\n  vmrglw_3 =\t\t\"1000018cVVV\",\n  vpkshss_3 =\t\t\"1000018eVVV\",\n  vmaxsd_3 =\t\t\"100001c2VVV\",\n  vsl_3 =\t\t\"100001c4VVV\",\n  vcmpgefp_3 =\t\t\"100001c6VVV\",\n  vlogefp_2 =\t\t\"100001caV-V\",\n  vpkswss_3 =\t\t\"100001ceVVV\",\n  vadduhs_3 =\t\t\"10000240VVV\",\n  vminuh_3 =\t\t\"10000242VVV\",\n  vsrh_3 =\t\t\"10000244VVV\",\n  vcmpgtuh_3 =\t\t\"10000246VVV\",\n  vmuleuh_3 =\t\t\"10000248VVV\",\n  vrfiz_2 =\t\t\"1000024aV-V\",\n  vsplth_3 =\t\t\"1000024cVV3\",\n  vupkhsh_2 =\t\t\"1000024eV-V\",\n  vminuw_3 =\t\t\"10000282VVV\",\n  vminud_3 =\t\t\"100002c2VVV\",\n  vcmpgtud_3 =\t\t\"100002c7VVV\",\n  vrfim_2 =\t\t\"100002caV-V\",\n  vcmpgtsb_3 =\t\t\"10000306VVV\",\n  vcfux_3 =\t\t\"1000030aVVA~\",\n  vaddshs_3 =\t\t\"10000340VVV\",\n  vminsh_3 =\t\t\"10000342VVV\",\n  vsrah_3 =\t\t\"10000344VVV\",\n  vcmpgtsh_3 =\t\t\"10000346VVV\",\n  vmulesh_3 =\t\t\"10000348VVV\",\n  vcfsx_3 =\t\t\"1000034aVVA~\",\n  vspltish_2 =\t\t\"1000034cVS\",\n  vupkhpx_2 =\t\t\"1000034eV-V\",\n  vaddsws_3 =\t\t\"10000380VVV\",\n  vminsw_3 =\t\t\"10000382VVV\",\n  vsraw_3 =\t\t\"10000384VVV\",\n  vcmpgtsw_3 =\t\t\"10000386VVV\",\n  vmulesw_3 =\t\t\"10000388VVV\",\n  vctuxs_3 =\t\t\"1000038aVVA~\",\n  vspltisw_2 =\t\t\"1000038cVS\",\n  vminsd_3 =\t\t\"100003c2VVV\",\n  vsrad_3 =\t\t\"100003c4VVV\",\n  vcmpbfp_3 =\t\t\"100003c6VVV\",\n  vcmpgtsd_3 =\t\t\"100003c7VVV\",\n  vctsxs_3 =\t\t\"100003caVVA~\",\n  vupklpx_2 =\t\t\"100003ceV-V\",\n  vsububm_3 =\t\t\"10000400VVV\",\n  [\"bcdadd._4\"] =\t\"10000401VVVy.\",\n  vavgub_3 =\t\t\"10000402VVV\",\n  vand_3 =\t\t\"10000404VVV\",\n  [\"vcmpequb._3\"] =\t\"10000406VVV\",\n  vmaxfp_3 =\t\t\"1000040aVVV\",\n  vsubuhm_3 =\t\t\"10000440VVV\",\n  [\"bcdsub._4\"] =\t\"10000441VVVy.\",\n  vavguh_3 =\t\t\"10000442VVV\",\n  vandc_3 =\t\t\"10000444VVV\",\n  [\"vcmpequh._3\"] =\t\"10000446VVV\",\n  vminfp_3 =\t\t\"1000044aVVV\",\n  vpkudum_3 =\t\t\"1000044eVVV\",\n  vsubuwm_3 =\t\t\"10000480VVV\",\n  vavguw_3 =\t\t\"10000482VVV\",\n  vor_3 =\t\t\"10000484VVV\",\n  [\"vcmpequw._3\"] =\t\"10000486VVV\",\n  vpmsumw_3 =\t\t\"10000488VVV\",\n  [\"vcmpeqfp._3\"] =\t\"100004c6VVV\",\n  [\"vcmpequd._3\"] =\t\"100004c7VVV\",\n  vpkudus_3 =\t\t\"100004ceVVV\",\n  vavgsb_3 =\t\t\"10000502VVV\",\n  vavgsh_3 =\t\t\"10000542VVV\",\n  vorc_3 =\t\t\"10000544VVV\",\n  vbpermq_3 =\t\t\"1000054cVVV\",\n  vpksdus_3 =\t\t\"1000054eVVV\",\n  vavgsw_3 =\t\t\"10000582VVV\",\n  vsld_3 =\t\t\"100005c4VVV\",\n  [\"vcmpgefp._3\"] =\t\"100005c6VVV\",\n  vpksdss_3 =\t\t\"100005ceVVV\",\n  vsububs_3 =\t\t\"10000600VVV\",\n  mfvscr_1 =\t\t\"10000604V--\",\n  vsum4ubs_3 =\t\t\"10000608VVV\",\n  vsubuhs_3 =\t\t\"10000640VVV\",\n  mtvscr_1 =\t\t\"10000644--V\",\n  [\"vcmpgtuh._3\"] =\t\"10000646VVV\",\n  vsum4shs_3 =\t\t\"10000648VVV\",\n  vupkhsw_2 =\t\t\"1000064eV-V\",\n  vsubuws_3 =\t\t\"10000680VVV\",\n  vshasigmaw_4 =\t\"10000682VVYp\",\n  veqv_3 =\t\t\"10000684VVV\",\n  vsum2sws_3 =\t\t\"10000688VVV\",\n  vmrgow_3 =\t\t\"1000068cVVV\",\n  vshasigmad_4 =\t\"100006c2VVYp\",\n  vsrd_3 =\t\t\"100006c4VVV\",\n  [\"vcmpgtud._3\"] =\t\"100006c7VVV\",\n  vupklsw_2 =\t\t\"100006ceV-V\",\n  vupkslw_2 =\t\t\"100006ceV-V\",\n  vsubsbs_3 =\t\t\"10000700VVV\",\n  vclzb_2 =\t\t\"10000702V-V\",\n  vpopcntb_2 =\t\t\"10000703V-V\",\n  [\"vcmpgtsb._3\"] =\t\"10000706VVV\",\n  vsum4sbs_3 =\t\t\"10000708VVV\",\n  vsubshs_3 =\t\t\"10000740VVV\",\n  vclzh_2 =\t\t\"10000742V-V\",\n  vpopcnth_2 =\t\t\"10000743V-V\",\n  [\"vcmpgtsh._3\"] =\t\"10000746VVV\",\n  vsubsws_3 =\t\t\"10000780VVV\",\n  vclzw_2 =\t\t\"10000782V-V\",\n  vpopcntw_2 =\t\t\"10000783V-V\",\n  [\"vcmpgtsw._3\"] =\t\"10000786VVV\",\n  vsumsws_3 =\t\t\"10000788VVV\",\n  vmrgew_3 =\t\t\"1000078cVVV\",\n  vclzd_2 =\t\t\"100007c2V-V\",\n  vpopcntd_2 =\t\t\"100007c3V-V\",\n  [\"vcmpbfp._3\"] =\t\"100007c6VVV\",\n  [\"vcmpgtsd._3\"] =\t\"100007c7VVV\",\n\n  -- Primary opcode 19:\n  mcrf_2 =\t\"4c000000XX\",\n  isync_0 =\t\"4c00012c\",\n  crnor_3 =\t\"4c000042CCC\",\n  crnot_2 =\t\"4c000042CC=\",\n  crandc_3 =\t\"4c000102CCC\",\n  crxor_3 =\t\"4c000182CCC\",\n  crclr_1 =\t\"4c000182C==\",\n  crnand_3 =\t\"4c0001c2CCC\",\n  crand_3 =\t\"4c000202CCC\",\n  creqv_3 =\t\"4c000242CCC\",\n  crset_1 =\t\"4c000242C==\",\n  crorc_3 =\t\"4c000342CCC\",\n  cror_3 =\t\"4c000382CCC\",\n  crmove_2 =\t\"4c000382CC=\",\n  bclr_2 =\t\"4c000020AA\",\n  bclrl_2 =\t\"4c000021AA\",\n  bcctr_2 =\t\"4c000420AA\",\n  bcctrl_2 =\t\"4c000421AA\",\n  bctar_2 =\t\"4c000460AA\",\n  bctarl_2 =\t\"4c000461AA\",\n  blr_0 =\t\"4e800020\",\n  blrl_0 =\t\"4e800021\",\n  bctr_0 =\t\"4e800420\",\n  bctrl_0 =\t\"4e800421\",\n\n  -- Primary opcode 31:\n  cmpw_3 =\t\"7c000000XRR\",\n  cmpw_2 =\t\"7c000000-RR\",\n  cmpd_3 =\t\"7c200000XRR\",\n  cmpd_2 =\t\"7c200000-RR\",\n  tw_3 =\t\"7c000008ARR\",\n  lvsl_3 =\t\"7c00000cVRR\",\n  subfc_3 =\t\"7c000010RRR.\",\n  subc_3 =\t\"7c000010RRR~.\",\n  mulhdu_3 =\t\"7c000012RRR.\",\n  addc_3 =\t\"7c000014RRR.\",\n  mulhwu_3 =\t\"7c000016RRR.\",\n  isel_4 =\t\"7c00001eRRRC\",\n  isellt_3 =\t\"7c00001eRRR\",\n  iselgt_3 =\t\"7c00005eRRR\",\n  iseleq_3 =\t\"7c00009eRRR\",\n  mfcr_1 =\t\"7c000026R\",\n  mfocrf_2 =\t\"7c100026RG\",\n  mtcrf_2 =\t\"7c000120GR\",\n  mtocrf_2 =\t\"7c100120GR\",\n  lwarx_3 =\t\"7c000028RR0R\",\n  ldx_3 =\t\"7c00002aRR0R\",\n  lwzx_3 =\t\"7c00002eRR0R\",\n  slw_3 =\t\"7c000030RR~R.\",\n  cntlzw_2 =\t\"7c000034RR~\",\n  sld_3 =\t\"7c000036RR~R.\",\n  and_3 =\t\"7c000038RR~R.\",\n  cmplw_3 =\t\"7c000040XRR\",\n  cmplw_2 =\t\"7c000040-RR\",\n  cmpld_3 =\t\"7c200040XRR\",\n  cmpld_2 =\t\"7c200040-RR\",\n  lvsr_3 =\t\"7c00004cVRR\",\n  subf_3 =\t\"7c000050RRR.\",\n  sub_3 =\t\"7c000050RRR~.\",\n  lbarx_3 =\t\"7c000068RR0R\",\n  ldux_3 =\t\"7c00006aRR0R\",\n  dcbst_2 =\t\"7c00006c-RR\",\n  lwzux_3 =\t\"7c00006eRR0R\",\n  cntlzd_2 =\t\"7c000074RR~\",\n  andc_3 =\t\"7c000078RR~R.\",\n  td_3 =\t\"7c000088ARR\",\n  lvewx_3 =\t\"7c00008eVRR\",\n  mulhd_3 =\t\"7c000092RRR.\",\n  addg6s_3 =\t\"7c000094RRR\",\n  mulhw_3 =\t\"7c000096RRR.\",\n  dlmzb_3 =\t\"7c00009cRR~R.\",\n  ldarx_3 =\t\"7c0000a8RR0R\",\n  dcbf_2 =\t\"7c0000ac-RR\",\n  lbzx_3 =\t\"7c0000aeRR0R\",\n  lvx_3 =\t\"7c0000ceVRR\",\n  neg_2 =\t\"7c0000d0RR.\",\n  lharx_3 =\t\"7c0000e8RR0R\",\n  lbzux_3 =\t\"7c0000eeRR0R\",\n  popcntb_2 =\t\"7c0000f4RR~\",\n  not_2 =\t\"7c0000f8RR~%.\",\n  nor_3 =\t\"7c0000f8RR~R.\",\n  stvebx_3 =\t\"7c00010eVRR\",\n  subfe_3 =\t\"7c000110RRR.\",\n  sube_3 =\t\"7c000110RRR~.\",\n  adde_3 =\t\"7c000114RRR.\",\n  stdx_3 =\t\"7c00012aRR0R\",\n  [\"stwcx._3\"] =\t\"7c00012dRR0R.\",\n  stwx_3 =\t\"7c00012eRR0R\",\n  prtyw_2 =\t\"7c000134RR~\",\n  stvehx_3 =\t\"7c00014eVRR\",\n  stdux_3 =\t\"7c00016aRR0R\",\n  [\"stqcx._3\"] =\t\"7c00016dR:R0R.\",\n  stwux_3 =\t\"7c00016eRR0R\",\n  prtyd_2 =\t\"7c000174RR~\",\n  stvewx_3 =\t\"7c00018eVRR\",\n  subfze_2 =\t\"7c000190RR.\",\n  addze_2 =\t\"7c000194RR.\",\n  [\"stdcx._3\"] =\t\"7c0001adRR0R.\",\n  stbx_3 =\t\"7c0001aeRR0R\",\n  stvx_3 =\t\"7c0001ceVRR\",\n  subfme_2 =\t\"7c0001d0RR.\",\n  mulld_3 =\t\"7c0001d2RRR.\",\n  addme_2 =\t\"7c0001d4RR.\",\n  mullw_3 =\t\"7c0001d6RRR.\",\n  dcbtst_2 =\t\"7c0001ec-RR\",\n  stbux_3 =\t\"7c0001eeRR0R\",\n  bpermd_3 =\t\"7c0001f8RR~R\",\n  lvepxl_3 =\t\"7c00020eVRR\",\n  add_3 =\t\"7c000214RRR.\",\n  lqarx_3 =\t\"7c000228R:R0R\",\n  dcbt_2 =\t\"7c00022c-RR\",\n  lhzx_3 =\t\"7c00022eRR0R\",\n  cdtbcd_2 =\t\"7c000234RR~\",\n  eqv_3 =\t\"7c000238RR~R.\",\n  lvepx_3 =\t\"7c00024eVRR\",\n  eciwx_3 =\t\"7c00026cRR0R\",\n  lhzux_3 =\t\"7c00026eRR0R\",\n  cbcdtd_2 =\t\"7c000274RR~\",\n  xor_3 =\t\"7c000278RR~R.\",\n  mfspefscr_1 =\t\"7c0082a6R\",\n  mfxer_1 =\t\"7c0102a6R\",\n  mflr_1 =\t\"7c0802a6R\",\n  mfctr_1 =\t\"7c0902a6R\",\n  lwax_3 =\t\"7c0002aaRR0R\",\n  lhax_3 =\t\"7c0002aeRR0R\",\n  mftb_1 =\t\"7c0c42e6R\",\n  mftbu_1 =\t\"7c0d42e6R\",\n  lvxl_3 =\t\"7c0002ceVRR\",\n  lwaux_3 =\t\"7c0002eaRR0R\",\n  lhaux_3 =\t\"7c0002eeRR0R\",\n  popcntw_2 =\t\"7c0002f4RR~\",\n  divdeu_3 =\t\"7c000312RRR.\",\n  divweu_3 =\t\"7c000316RRR.\",\n  sthx_3 =\t\"7c00032eRR0R\",\n  orc_3 =\t\"7c000338RR~R.\",\n  ecowx_3 =\t\"7c00036cRR0R\",\n  sthux_3 =\t\"7c00036eRR0R\",\n  or_3 =\t\"7c000378RR~R.\",\n  mr_2 =\t\"7c000378RR~%.\",\n  divdu_3 =\t\"7c000392RRR.\",\n  divwu_3 =\t\"7c000396RRR.\",\n  mtspefscr_1 =\t\"7c0083a6R\",\n  mtxer_1 =\t\"7c0103a6R\",\n  mtlr_1 =\t\"7c0803a6R\",\n  mtctr_1 =\t\"7c0903a6R\",\n  dcbi_2 =\t\"7c0003ac-RR\",\n  nand_3 =\t\"7c0003b8RR~R.\",\n  dsn_2 =\t\"7c0003c6-RR\",\n  stvxl_3 =\t\"7c0003ceVRR\",\n  divd_3 =\t\"7c0003d2RRR.\",\n  divw_3 =\t\"7c0003d6RRR.\",\n  popcntd_2 =\t\"7c0003f4RR~\",\n  cmpb_3 =\t\"7c0003f8RR~R.\",\n  mcrxr_1 =\t\"7c000400X\",\n  lbdx_3 =\t\"7c000406RRR\",\n  subfco_3 =\t\"7c000410RRR.\",\n  subco_3 =\t\"7c000410RRR~.\",\n  addco_3 =\t\"7c000414RRR.\",\n  ldbrx_3 =\t\"7c000428RR0R\",\n  lswx_3 =\t\"7c00042aRR0R\",\n  lwbrx_3 =\t\"7c00042cRR0R\",\n  lfsx_3 =\t\"7c00042eFR0R\",\n  srw_3 =\t\"7c000430RR~R.\",\n  srd_3 =\t\"7c000436RR~R.\",\n  lhdx_3 =\t\"7c000446RRR\",\n  subfo_3 =\t\"7c000450RRR.\",\n  subo_3 =\t\"7c000450RRR~.\",\n  lfsux_3 =\t\"7c00046eFR0R\",\n  lwdx_3 =\t\"7c000486RRR\",\n  lswi_3 =\t\"7c0004aaRR0A\",\n  sync_0 =\t\"7c0004ac\",\n  lwsync_0 =\t\"7c2004ac\",\n  ptesync_0 =\t\"7c4004ac\",\n  lfdx_3 =\t\"7c0004aeFR0R\",\n  lddx_3 =\t\"7c0004c6RRR\",\n  nego_2 =\t\"7c0004d0RR.\",\n  lfdux_3 =\t\"7c0004eeFR0R\",\n  stbdx_3 =\t\"7c000506RRR\",\n  subfeo_3 =\t\"7c000510RRR.\",\n  subeo_3 =\t\"7c000510RRR~.\",\n  addeo_3 =\t\"7c000514RRR.\",\n  stdbrx_3 =\t\"7c000528RR0R\",\n  stswx_3 =\t\"7c00052aRR0R\",\n  stwbrx_3 =\t\"7c00052cRR0R\",\n  stfsx_3 =\t\"7c00052eFR0R\",\n  sthdx_3 =\t\"7c000546RRR\",\n  [\"stbcx._3\"] =\t\"7c00056dRRR\",\n  stfsux_3 =\t\"7c00056eFR0R\",\n  stwdx_3 =\t\"7c000586RRR\",\n  subfzeo_2 =\t\"7c000590RR.\",\n  addzeo_2 =\t\"7c000594RR.\",\n  stswi_3 =\t\"7c0005aaRR0A\",\n  [\"sthcx._3\"] =\t\"7c0005adRRR\",\n  stfdx_3 =\t\"7c0005aeFR0R\",\n  stddx_3 =\t\"7c0005c6RRR\",\n  subfmeo_2 =\t\"7c0005d0RR.\",\n  mulldo_3 =\t\"7c0005d2RRR.\",\n  addmeo_2 =\t\"7c0005d4RR.\",\n  mullwo_3 =\t\"7c0005d6RRR.\",\n  dcba_2 =\t\"7c0005ec-RR\",\n  stfdux_3 =\t\"7c0005eeFR0R\",\n  stvepxl_3 =\t\"7c00060eVRR\",\n  addo_3 =\t\"7c000614RRR.\",\n  lhbrx_3 =\t\"7c00062cRR0R\",\n  lfdpx_3 =\t\"7c00062eF:RR\",\n  sraw_3 =\t\"7c000630RR~R.\",\n  srad_3 =\t\"7c000634RR~R.\",\n  lfddx_3 =\t\"7c000646FRR\",\n  stvepx_3 =\t\"7c00064eVRR\",\n  srawi_3 =\t\"7c000670RR~A.\",\n  sradi_3 =\t\"7c000674RR~H.\",\n  eieio_0 =\t\"7c0006ac\",\n  lfiwax_3 =\t\"7c0006aeFR0R\",\n  divdeuo_3 =\t\"7c000712RRR.\",\n  divweuo_3 =\t\"7c000716RRR.\",\n  sthbrx_3 =\t\"7c00072cRR0R\",\n  stfdpx_3 =\t\"7c00072eF:RR\",\n  extsh_2 =\t\"7c000734RR~.\",\n  stfddx_3 =\t\"7c000746FRR\",\n  divdeo_3 =\t\"7c000752RRR.\",\n  divweo_3 =\t\"7c000756RRR.\",\n  extsb_2 =\t\"7c000774RR~.\",\n  divduo_3 =\t\"7c000792RRR.\",\n  divwou_3 =\t\"7c000796RRR.\",\n  icbi_2 =\t\"7c0007ac-RR\",\n  stfiwx_3 =\t\"7c0007aeFR0R\",\n  extsw_2 =\t\"7c0007b4RR~.\",\n  divdo_3 =\t\"7c0007d2RRR.\",\n  divwo_3 =\t\"7c0007d6RRR.\",\n  dcbz_2 =\t\"7c0007ec-RR\",\n\n  [\"tbegin._1\"] =\t\"7c00051d1\",\n  [\"tbegin._0\"] =\t\"7c00051d\",\n  [\"tend._1\"] =\t\t\"7c00055dY\",\n  [\"tend._0\"] =\t\t\"7c00055d\",\n  [\"tendall._0\"] =\t\"7e00055d\",\n  tcheck_1 =\t\t\"7c00059cX\",\n  [\"tsr._1\"] =\t\t\"7c0005dd1\",\n  [\"tsuspend._0\"] =\t\"7c0005dd\",\n  [\"tresume._0\"] =\t\"7c2005dd\",\n  [\"tabortwc._3\"] =\t\"7c00061dARR\",\n  [\"tabortdc._3\"] =\t\"7c00065dARR\",\n  [\"tabortwci._3\"] =\t\"7c00069dARS\",\n  [\"tabortdci._3\"] =\t\"7c0006ddARS\",\n  [\"tabort._1\"] =\t\"7c00071d-R-\",\n  [\"treclaim._1\"] =\t\"7c00075d-R\",\n  [\"trechkpt._0\"] =\t\"7c0007dd\",\n\n  lxsiwzx_3 =\t\"7c000018QRR\",\n  lxsiwax_3 =\t\"7c000098QRR\",\n  mfvsrd_2 =\t\"7c000066-Rq\",\n  mfvsrwz_2 =\t\"7c0000e6-Rq\",\n  stxsiwx_3 =\t\"7c000118QRR\",\n  mtvsrd_2 =\t\"7c000166QR\",\n  mtvsrwa_2 =\t\"7c0001a6QR\",\n  lxvdsx_3 =\t\"7c000298QRR\",\n  lxsspx_3 =\t\"7c000418QRR\",\n  lxsdx_3 =\t\"7c000498QRR\",\n  stxsspx_3 =\t\"7c000518QRR\",\n  stxsdx_3 =\t\"7c000598QRR\",\n  lxvw4x_3 =\t\"7c000618QRR\",\n  lxvd2x_3 =\t\"7c000698QRR\",\n  stxvw4x_3 =\t\"7c000718QRR\",\n  stxvd2x_3 =\t\"7c000798QRR\",\n\n  -- Primary opcode 30:\n  rldicl_4 =\t\"78000000RR~HM.\",\n  rldicr_4 =\t\"78000004RR~HM.\",\n  rldic_4 =\t\"78000008RR~HM.\",\n  rldimi_4 =\t\"7800000cRR~HM.\",\n  rldcl_4 =\t\"78000010RR~RM.\",\n  rldcr_4 =\t\"78000012RR~RM.\",\n\n  rotldi_3 =\top_alias(\"rldicl_4\", function(p)\n    p[4] = \"0\"\n  end),\n  rotrdi_3 =\top_alias(\"rldicl_4\", function(p)\n    p[3] = \"64-(\"..p[3]..\")\"; p[4] = \"0\"\n  end),\n  rotld_3 =\top_alias(\"rldcl_4\", function(p)\n    p[4] = \"0\"\n  end),\n  sldi_3 =\top_alias(\"rldicr_4\", function(p)\n    p[4] = \"63-(\"..p[3]..\")\"\n  end),\n  srdi_3 =\top_alias(\"rldicl_4\", function(p)\n    p[4] = p[3]; p[3] = \"64-(\"..p[3]..\")\"\n  end),\n  clrldi_3 =\top_alias(\"rldicl_4\", function(p)\n    p[4] = p[3]; p[3] = \"0\"\n  end),\n  clrrdi_3 =\top_alias(\"rldicr_4\", function(p)\n    p[4] = \"63-(\"..p[3]..\")\"; p[3] = \"0\"\n  end),\n\n  -- Primary opcode 56:\n  lq_2 =\t\"e0000000R:D\", -- NYI: displacement must be divisible by 8.\n\n  -- Primary opcode 57:\n  lfdp_2 =\t\"e4000000F:D\", -- NYI: displacement must be divisible by 4.\n\n  -- Primary opcode 59:\n  fdivs_3 =\t\"ec000024FFF.\",\n  fsubs_3 =\t\"ec000028FFF.\",\n  fadds_3 =\t\"ec00002aFFF.\",\n  fsqrts_2 =\t\"ec00002cF-F.\",\n  fres_2 =\t\"ec000030F-F.\",\n  fmuls_3 =\t\"ec000032FF-F.\",\n  frsqrtes_2 =\t\"ec000034F-F.\",\n  fmsubs_4 =\t\"ec000038FFFF~.\",\n  fmadds_4 =\t\"ec00003aFFFF~.\",\n  fnmsubs_4 =\t\"ec00003cFFFF~.\",\n  fnmadds_4 =\t\"ec00003eFFFF~.\",\n  fcfids_2 =\t\"ec00069cF-F.\",\n  fcfidus_2 =\t\"ec00079cF-F.\",\n\n  dadd_3 =\t\"ec000004FFF.\",\n  dqua_4 =\t\"ec000006FFFZ.\",\n  dmul_3 =\t\"ec000044FFF.\",\n  drrnd_4 =\t\"ec000046FFFZ.\",\n  dscli_3 =\t\"ec000084FF6.\",\n  dquai_4 =\t\"ec000086SF~FZ.\",\n  dscri_3 =\t\"ec0000c4FF6.\",\n  drintx_4 =\t\"ec0000c61F~FZ.\",\n  dcmpo_3 =\t\"ec000104XFF\",\n  dtstex_3 =\t\"ec000144XFF\",\n  dtstdc_3 =\t\"ec000184XF6\",\n  dtstdg_3 =\t\"ec0001c4XF6\",\n  drintn_4 =\t\"ec0001c61F~FZ.\",\n  dctdp_2 =\t\"ec000204F-F.\",\n  dctfix_2 =\t\"ec000244F-F.\",\n  ddedpd_3 =\t\"ec000284ZF~F.\",\n  dxex_2 =\t\"ec0002c4F-F.\",\n  dsub_3 =\t\"ec000404FFF.\",\n  ddiv_3 =\t\"ec000444FFF.\",\n  dcmpu_3 =\t\"ec000504XFF\",\n  dtstsf_3 =\t\"ec000544XFF\",\n  drsp_2 =\t\"ec000604F-F.\",\n  dcffix_2 =\t\"ec000644F-F.\",\n  denbcd_3 =\t\"ec000684YF~F.\",\n  diex_3 =\t\"ec0006c4FFF.\",\n\n  -- Primary opcode 60:\n  xsaddsp_3 =\t\t\"f0000000QQQ\",\n  xsmaddasp_3 =\t\t\"f0000008QQQ\",\n  xxsldwi_4 =\t\t\"f0000010QQQz\",\n  xsrsqrtesp_2 =\t\"f0000028Q-Q\",\n  xssqrtsp_2 =\t\t\"f000002cQ-Q\",\n  xxsel_4 =\t\t\"f0000030QQQQ\",\n  xssubsp_3 =\t\t\"f0000040QQQ\",\n  xsmaddmsp_3 =\t\t\"f0000048QQQ\",\n  xxpermdi_4 =\t\t\"f0000050QQQz\",\n  xsresp_2 =\t\t\"f0000068Q-Q\",\n  xsmulsp_3 =\t\t\"f0000080QQQ\",\n  xsmsubasp_3 =\t\t\"f0000088QQQ\",\n  xxmrghw_3 =\t\t\"f0000090QQQ\",\n  xsdivsp_3 =\t\t\"f00000c0QQQ\",\n  xsmsubmsp_3 =\t\t\"f00000c8QQQ\",\n  xsadddp_3 =\t\t\"f0000100QQQ\",\n  xsmaddadp_3 =\t\t\"f0000108QQQ\",\n  xscmpudp_3 =\t\t\"f0000118XQQ\",\n  xscvdpuxws_2 =\t\"f0000120Q-Q\",\n  xsrdpi_2 =\t\t\"f0000124Q-Q\",\n  xsrsqrtedp_2 =\t\"f0000128Q-Q\",\n  xssqrtdp_2 =\t\t\"f000012cQ-Q\",\n  xssubdp_3 =\t\t\"f0000140QQQ\",\n  xsmaddmdp_3 =\t\t\"f0000148QQQ\",\n  xscmpodp_3 =\t\t\"f0000158XQQ\",\n  xscvdpsxws_2 =\t\"f0000160Q-Q\",\n  xsrdpiz_2 =\t\t\"f0000164Q-Q\",\n  xsredp_2 =\t\t\"f0000168Q-Q\",\n  xsmuldp_3 =\t\t\"f0000180QQQ\",\n  xsmsubadp_3 =\t\t\"f0000188QQQ\",\n  xxmrglw_3 =\t\t\"f0000190QQQ\",\n  xsrdpip_2 =\t\t\"f00001a4Q-Q\",\n  xstsqrtdp_2 =\t\t\"f00001a8X-Q\",\n  xsrdpic_2 =\t\t\"f00001acQ-Q\",\n  xsdivdp_3 =\t\t\"f00001c0QQQ\",\n  xsmsubmdp_3 =\t\t\"f00001c8QQQ\",\n  xsrdpim_2 =\t\t\"f00001e4Q-Q\",\n  xstdivdp_3 =\t\t\"f00001e8XQQ\",\n  xvaddsp_3 =\t\t\"f0000200QQQ\",\n  xvmaddasp_3 =\t\t\"f0000208QQQ\",\n  xvcmpeqsp_3 =\t\t\"f0000218QQQ\",\n  xvcvspuxws_2 =\t\"f0000220Q-Q\",\n  xvrspi_2 =\t\t\"f0000224Q-Q\",\n  xvrsqrtesp_2 =\t\"f0000228Q-Q\",\n  xvsqrtsp_2 =\t\t\"f000022cQ-Q\",\n  xvsubsp_3 =\t\t\"f0000240QQQ\",\n  xvmaddmsp_3 =\t\t\"f0000248QQQ\",\n  xvcmpgtsp_3 =\t\t\"f0000258QQQ\",\n  xvcvspsxws_2 =\t\"f0000260Q-Q\",\n  xvrspiz_2 =\t\t\"f0000264Q-Q\",\n  xvresp_2 =\t\t\"f0000268Q-Q\",\n  xvmulsp_3 =\t\t\"f0000280QQQ\",\n  xvmsubasp_3 =\t\t\"f0000288QQQ\",\n  xxspltw_3 =\t\t\"f0000290QQg~\",\n  xvcmpgesp_3 =\t\t\"f0000298QQQ\",\n  xvcvuxwsp_2 =\t\t\"f00002a0Q-Q\",\n  xvrspip_2 =\t\t\"f00002a4Q-Q\",\n  xvtsqrtsp_2 =\t\t\"f00002a8X-Q\",\n  xvrspic_2 =\t\t\"f00002acQ-Q\",\n  xvdivsp_3 =\t\t\"f00002c0QQQ\",\n  xvmsubmsp_3 =\t\t\"f00002c8QQQ\",\n  xvcvsxwsp_2 =\t\t\"f00002e0Q-Q\",\n  xvrspim_2 =\t\t\"f00002e4Q-Q\",\n  xvtdivsp_3 =\t\t\"f00002e8XQQ\",\n  xvadddp_3 =\t\t\"f0000300QQQ\",\n  xvmaddadp_3 =\t\t\"f0000308QQQ\",\n  xvcmpeqdp_3 =\t\t\"f0000318QQQ\",\n  xvcvdpuxws_2 =\t\"f0000320Q-Q\",\n  xvrdpi_2 =\t\t\"f0000324Q-Q\",\n  xvrsqrtedp_2 =\t\"f0000328Q-Q\",\n  xvsqrtdp_2 =\t\t\"f000032cQ-Q\",\n  xvsubdp_3 =\t\t\"f0000340QQQ\",\n  xvmaddmdp_3 =\t\t\"f0000348QQQ\",\n  xvcmpgtdp_3 =\t\t\"f0000358QQQ\",\n  xvcvdpsxws_2 =\t\"f0000360Q-Q\",\n  xvrdpiz_2 =\t\t\"f0000364Q-Q\",\n  xvredp_2 =\t\t\"f0000368Q-Q\",\n  xvmuldp_3 =\t\t\"f0000380QQQ\",\n  xvmsubadp_3 =\t\t\"f0000388QQQ\",\n  xvcmpgedp_3 =\t\t\"f0000398QQQ\",\n  xvcvuxwdp_2 =\t\t\"f00003a0Q-Q\",\n  xvrdpip_2 =\t\t\"f00003a4Q-Q\",\n  xvtsqrtdp_2 =\t\t\"f00003a8X-Q\",\n  xvrdpic_2 =\t\t\"f00003acQ-Q\",\n  xvdivdp_3 =\t\t\"f00003c0QQQ\",\n  xvmsubmdp_3 =\t\t\"f00003c8QQQ\",\n  xvcvsxwdp_2 =\t\t\"f00003e0Q-Q\",\n  xvrdpim_2 =\t\t\"f00003e4Q-Q\",\n  xvtdivdp_3 =\t\t\"f00003e8XQQ\",\n  xsnmaddasp_3 =\t\"f0000408QQQ\",\n  xxland_3 =\t\t\"f0000410QQQ\",\n  xscvdpsp_2 =\t\t\"f0000424Q-Q\",\n  xscvdpspn_2 =\t\t\"f000042cQ-Q\",\n  xsnmaddmsp_3 =\t\"f0000448QQQ\",\n  xxlandc_3 =\t\t\"f0000450QQQ\",\n  xsrsp_2 =\t\t\"f0000464Q-Q\",\n  xsnmsubasp_3 =\t\"f0000488QQQ\",\n  xxlor_3 =\t\t\"f0000490QQQ\",\n  xscvuxdsp_2 =\t\t\"f00004a0Q-Q\",\n  xsnmsubmsp_3 =\t\"f00004c8QQQ\",\n  xxlxor_3 =\t\t\"f00004d0QQQ\",\n  xscvsxdsp_2 =\t\t\"f00004e0Q-Q\",\n  xsmaxdp_3 =\t\t\"f0000500QQQ\",\n  xsnmaddadp_3 =\t\"f0000508QQQ\",\n  xxlnor_3 =\t\t\"f0000510QQQ\",\n  xscvdpuxds_2 =\t\"f0000520Q-Q\",\n  xscvspdp_2 =\t\t\"f0000524Q-Q\",\n  xscvspdpn_2 =\t\t\"f000052cQ-Q\",\n  xsmindp_3 =\t\t\"f0000540QQQ\",\n  xsnmaddmdp_3 =\t\"f0000548QQQ\",\n  xxlorc_3 =\t\t\"f0000550QQQ\",\n  xscvdpsxds_2 =\t\"f0000560Q-Q\",\n  xsabsdp_2 =\t\t\"f0000564Q-Q\",\n  xscpsgndp_3 =\t\t\"f0000580QQQ\",\n  xsnmsubadp_3 =\t\"f0000588QQQ\",\n  xxlnand_3 =\t\t\"f0000590QQQ\",\n  xscvuxddp_2 =\t\t\"f00005a0Q-Q\",\n  xsnabsdp_2 =\t\t\"f00005a4Q-Q\",\n  xsnmsubmdp_3 =\t\"f00005c8QQQ\",\n  xxleqv_3 =\t\t\"f00005d0QQQ\",\n  xscvsxddp_2 =\t\t\"f00005e0Q-Q\",\n  xsnegdp_2 =\t\t\"f00005e4Q-Q\",\n  xvmaxsp_3 =\t\t\"f0000600QQQ\",\n  xvnmaddasp_3 =\t\"f0000608QQQ\",\n  [\"xvcmpeqsp._3\"] =\t\"f0000618QQQ\",\n  xvcvspuxds_2 =\t\"f0000620Q-Q\",\n  xvcvdpsp_2 =\t\t\"f0000624Q-Q\",\n  xvminsp_3 =\t\t\"f0000640QQQ\",\n  xvnmaddmsp_3 =\t\"f0000648QQQ\",\n  [\"xvcmpgtsp._3\"] =\t\"f0000658QQQ\",\n  xvcvspsxds_2 =\t\"f0000660Q-Q\",\n  xvabssp_2 =\t\t\"f0000664Q-Q\",\n  xvcpsgnsp_3 =\t\t\"f0000680QQQ\",\n  xvnmsubasp_3 =\t\"f0000688QQQ\",\n  [\"xvcmpgesp._3\"] =\t\"f0000698QQQ\",\n  xvcvuxdsp_2 =\t\t\"f00006a0Q-Q\",\n  xvnabssp_2 =\t\t\"f00006a4Q-Q\",\n  xvnmsubmsp_3 =\t\"f00006c8QQQ\",\n  xvcvsxdsp_2 =\t\t\"f00006e0Q-Q\",\n  xvnegsp_2 =\t\t\"f00006e4Q-Q\",\n  xvmaxdp_3 =\t\t\"f0000700QQQ\",\n  xvnmaddadp_3 =\t\"f0000708QQQ\",\n  [\"xvcmpeqdp._3\"] =\t\"f0000718QQQ\",\n  xvcvdpuxds_2 =\t\"f0000720Q-Q\",\n  xvcvspdp_2 =\t\t\"f0000724Q-Q\",\n  xvmindp_3 =\t\t\"f0000740QQQ\",\n  xvnmaddmdp_3 =\t\"f0000748QQQ\",\n  [\"xvcmpgtdp._3\"] =\t\"f0000758QQQ\",\n  xvcvdpsxds_2 =\t\"f0000760Q-Q\",\n  xvabsdp_2 =\t\t\"f0000764Q-Q\",\n  xvcpsgndp_3 =\t\t\"f0000780QQQ\",\n  xvnmsubadp_3 =\t\"f0000788QQQ\",\n  [\"xvcmpgedp._3\"] =\t\"f0000798QQQ\",\n  xvcvuxddp_2 =\t\t\"f00007a0Q-Q\",\n  xvnabsdp_2 =\t\t\"f00007a4Q-Q\",\n  xvnmsubmdp_3 =\t\"f00007c8QQQ\",\n  xvcvsxddp_2 =\t\t\"f00007e0Q-Q\",\n  xvnegdp_2 =\t\t\"f00007e4Q-Q\",\n\n  -- Primary opcode 61:\n  stfdp_2 =\t\"f4000000F:D\", -- NYI: displacement must be divisible by 4.\n\n  -- Primary opcode 62:\n  stq_2 =\t\"f8000002R:D\", -- NYI: displacement must be divisible by 8.\n\n  -- Primary opcode 63:\n  fdiv_3 =\t\"fc000024FFF.\",\n  fsub_3 =\t\"fc000028FFF.\",\n  fadd_3 =\t\"fc00002aFFF.\",\n  fsqrt_2 =\t\"fc00002cF-F.\",\n  fsel_4 =\t\"fc00002eFFFF~.\",\n  fre_2 =\t\"fc000030F-F.\",\n  fmul_3 =\t\"fc000032FF-F.\",\n  frsqrte_2 =\t\"fc000034F-F.\",\n  fmsub_4 =\t\"fc000038FFFF~.\",\n  fmadd_4 =\t\"fc00003aFFFF~.\",\n  fnmsub_4 =\t\"fc00003cFFFF~.\",\n  fnmadd_4 =\t\"fc00003eFFFF~.\",\n  fcmpu_3 =\t\"fc000000XFF\",\n  fcpsgn_3 =\t\"fc000010FFF.\",\n  fcmpo_3 =\t\"fc000040XFF\",\n  mtfsb1_1 =\t\"fc00004cA\",\n  fneg_2 =\t\"fc000050F-F.\",\n  mcrfs_2 =\t\"fc000080XX\",\n  mtfsb0_1 =\t\"fc00008cA\",\n  fmr_2 =\t\"fc000090F-F.\",\n  frsp_2 =\t\"fc000018F-F.\",\n  fctiw_2 =\t\"fc00001cF-F.\",\n  fctiwz_2 =\t\"fc00001eF-F.\",\n  ftdiv_2 =\t\"fc000100X-F.\",\n  fctiwu_2 =\t\"fc00011cF-F.\",\n  fctiwuz_2 =\t\"fc00011eF-F.\",\n  mtfsfi_2 =\t\"fc00010cAA\", -- NYI: upshift.\n  fnabs_2 =\t\"fc000110F-F.\",\n  ftsqrt_2 =\t\"fc000140X-F.\",\n  fabs_2 =\t\"fc000210F-F.\",\n  frin_2 =\t\"fc000310F-F.\",\n  friz_2 =\t\"fc000350F-F.\",\n  frip_2 =\t\"fc000390F-F.\",\n  frim_2 =\t\"fc0003d0F-F.\",\n  mffs_1 =\t\"fc00048eF.\",\n  -- NYI: mtfsf, mtfsb0, mtfsb1.\n  fctid_2 =\t\"fc00065cF-F.\",\n  fctidz_2 =\t\"fc00065eF-F.\",\n  fmrgow_3 =\t\"fc00068cFFF\",\n  fcfid_2 =\t\"fc00069cF-F.\",\n  fctidu_2 =\t\"fc00075cF-F.\",\n  fctiduz_2 =\t\"fc00075eF-F.\",\n  fmrgew_3 =\t\"fc00078cFFF\",\n  fcfidu_2 =\t\"fc00079cF-F.\",\n\n  daddq_3 =\t\"fc000004F:F:F:.\",\n  dquaq_4 =\t\"fc000006F:F:F:Z.\",\n  dmulq_3 =\t\"fc000044F:F:F:.\",\n  drrndq_4 =\t\"fc000046F:F:F:Z.\",\n  dscliq_3 =\t\"fc000084F:F:6.\",\n  dquaiq_4 =\t\"fc000086SF:~F:Z.\",\n  dscriq_3 =\t\"fc0000c4F:F:6.\",\n  drintxq_4 =\t\"fc0000c61F:~F:Z.\",\n  dcmpoq_3 =\t\"fc000104XF:F:\",\n  dtstexq_3 =\t\"fc000144XF:F:\",\n  dtstdcq_3 =\t\"fc000184XF:6\",\n  dtstdgq_3 =\t\"fc0001c4XF:6\",\n  drintnq_4 =\t\"fc0001c61F:~F:Z.\",\n  dctqpq_2 =\t\"fc000204F:-F:.\",\n  dctfixq_2 =\t\"fc000244F:-F:.\",\n  ddedpdq_3 =\t\"fc000284ZF:~F:.\",\n  dxexq_2 =\t\"fc0002c4F:-F:.\",\n  dsubq_3 =\t\"fc000404F:F:F:.\",\n  ddivq_3 =\t\"fc000444F:F:F:.\",\n  dcmpuq_3 =\t\"fc000504XF:F:\",\n  dtstsfq_3 =\t\"fc000544XF:F:\",\n  drdpq_2 =\t\"fc000604F:-F:.\",\n  dcffixq_2 =\t\"fc000644F:-F:.\",\n  denbcdq_3 =\t\"fc000684YF:~F:.\",\n  diexq_3 =\t\"fc0006c4F:FF:.\",\n\n  -- Primary opcode 4, SPE APU extension:\n  evaddw_3 =\t\t\"10000200RRR\",\n  evaddiw_3 =\t\t\"10000202RAR~\",\n  evsubw_3 =\t\t\"10000204RRR~\",\n  evsubiw_3 =\t\t\"10000206RAR~\",\n  evabs_2 =\t\t\"10000208RR\",\n  evneg_2 =\t\t\"10000209RR\",\n  evextsb_2 =\t\t\"1000020aRR\",\n  evextsh_2 =\t\t\"1000020bRR\",\n  evrndw_2 =\t\t\"1000020cRR\",\n  evcntlzw_2 =\t\t\"1000020dRR\",\n  evcntlsw_2 =\t\t\"1000020eRR\",\n  brinc_3 =\t\t\"1000020fRRR\",\n  evand_3 =\t\t\"10000211RRR\",\n  evandc_3 =\t\t\"10000212RRR\",\n  evxor_3 =\t\t\"10000216RRR\",\n  evor_3 =\t\t\"10000217RRR\",\n  evmr_2 =\t\t\"10000217RR=\",\n  evnor_3 =\t\t\"10000218RRR\",\n  evnot_2 =\t\t\"10000218RR=\",\n  eveqv_3 =\t\t\"10000219RRR\",\n  evorc_3 =\t\t\"1000021bRRR\",\n  evnand_3 =\t\t\"1000021eRRR\",\n  evsrwu_3 =\t\t\"10000220RRR\",\n  evsrws_3 =\t\t\"10000221RRR\",\n  evsrwiu_3 =\t\t\"10000222RRA\",\n  evsrwis_3 =\t\t\"10000223RRA\",\n  evslw_3 =\t\t\"10000224RRR\",\n  evslwi_3 =\t\t\"10000226RRA\",\n  evrlw_3 =\t\t\"10000228RRR\",\n  evsplati_2 =\t\t\"10000229RS\",\n  evrlwi_3 =\t\t\"1000022aRRA\",\n  evsplatfi_2 =\t\t\"1000022bRS\",\n  evmergehi_3 =\t\t\"1000022cRRR\",\n  evmergelo_3 =\t\t\"1000022dRRR\",\n  evcmpgtu_3 =\t\t\"10000230XRR\",\n  evcmpgtu_2 =\t\t\"10000230-RR\",\n  evcmpgts_3 =\t\t\"10000231XRR\",\n  evcmpgts_2 =\t\t\"10000231-RR\",\n  evcmpltu_3 =\t\t\"10000232XRR\",\n  evcmpltu_2 =\t\t\"10000232-RR\",\n  evcmplts_3 =\t\t\"10000233XRR\",\n  evcmplts_2 =\t\t\"10000233-RR\",\n  evcmpeq_3 =\t\t\"10000234XRR\",\n  evcmpeq_2 =\t\t\"10000234-RR\",\n  evsel_4 =\t\t\"10000278RRRW\",\n  evsel_3 =\t\t\"10000278RRR\",\n  evfsadd_3 =\t\t\"10000280RRR\",\n  evfssub_3 =\t\t\"10000281RRR\",\n  evfsabs_2 =\t\t\"10000284RR\",\n  evfsnabs_2 =\t\t\"10000285RR\",\n  evfsneg_2 =\t\t\"10000286RR\",\n  evfsmul_3 =\t\t\"10000288RRR\",\n  evfsdiv_3 =\t\t\"10000289RRR\",\n  evfscmpgt_3 =\t\t\"1000028cXRR\",\n  evfscmpgt_2 =\t\t\"1000028c-RR\",\n  evfscmplt_3 =\t\t\"1000028dXRR\",\n  evfscmplt_2 =\t\t\"1000028d-RR\",\n  evfscmpeq_3 =\t\t\"1000028eXRR\",\n  evfscmpeq_2 =\t\t\"1000028e-RR\",\n  evfscfui_2 =\t\t\"10000290R-R\",\n  evfscfsi_2 =\t\t\"10000291R-R\",\n  evfscfuf_2 =\t\t\"10000292R-R\",\n  evfscfsf_2 =\t\t\"10000293R-R\",\n  evfsctui_2 =\t\t\"10000294R-R\",\n  evfsctsi_2 =\t\t\"10000295R-R\",\n  evfsctuf_2 =\t\t\"10000296R-R\",\n  evfsctsf_2 =\t\t\"10000297R-R\",\n  evfsctuiz_2 =\t\t\"10000298R-R\",\n  evfsctsiz_2 =\t\t\"1000029aR-R\",\n  evfststgt_3 =\t\t\"1000029cXRR\",\n  evfststgt_2 =\t\t\"1000029c-RR\",\n  evfststlt_3 =\t\t\"1000029dXRR\",\n  evfststlt_2 =\t\t\"1000029d-RR\",\n  evfststeq_3 =\t\t\"1000029eXRR\",\n  evfststeq_2 =\t\t\"1000029e-RR\",\n  efsadd_3 =\t\t\"100002c0RRR\",\n  efssub_3 =\t\t\"100002c1RRR\",\n  efsabs_2 =\t\t\"100002c4RR\",\n  efsnabs_2 =\t\t\"100002c5RR\",\n  efsneg_2 =\t\t\"100002c6RR\",\n  efsmul_3 =\t\t\"100002c8RRR\",\n  efsdiv_3 =\t\t\"100002c9RRR\",\n  efscmpgt_3 =\t\t\"100002ccXRR\",\n  efscmpgt_2 =\t\t\"100002cc-RR\",\n  efscmplt_3 =\t\t\"100002cdXRR\",\n  efscmplt_2 =\t\t\"100002cd-RR\",\n  efscmpeq_3 =\t\t\"100002ceXRR\",\n  efscmpeq_2 =\t\t\"100002ce-RR\",\n  efscfd_2 =\t\t\"100002cfR-R\",\n  efscfui_2 =\t\t\"100002d0R-R\",\n  efscfsi_2 =\t\t\"100002d1R-R\",\n  efscfuf_2 =\t\t\"100002d2R-R\",\n  efscfsf_2 =\t\t\"100002d3R-R\",\n  efsctui_2 =\t\t\"100002d4R-R\",\n  efsctsi_2 =\t\t\"100002d5R-R\",\n  efsctuf_2 =\t\t\"100002d6R-R\",\n  efsctsf_2 =\t\t\"100002d7R-R\",\n  efsctuiz_2 =\t\t\"100002d8R-R\",\n  efsctsiz_2 =\t\t\"100002daR-R\",\n  efststgt_3 =\t\t\"100002dcXRR\",\n  efststgt_2 =\t\t\"100002dc-RR\",\n  efststlt_3 =\t\t\"100002ddXRR\",\n  efststlt_2 =\t\t\"100002dd-RR\",\n  efststeq_3 =\t\t\"100002deXRR\",\n  efststeq_2 =\t\t\"100002de-RR\",\n  efdadd_3 =\t\t\"100002e0RRR\",\n  efdsub_3 =\t\t\"100002e1RRR\",\n  efdcfuid_2 =\t\t\"100002e2R-R\",\n  efdcfsid_2 =\t\t\"100002e3R-R\",\n  efdabs_2 =\t\t\"100002e4RR\",\n  efdnabs_2 =\t\t\"100002e5RR\",\n  efdneg_2 =\t\t\"100002e6RR\",\n  efdmul_3 =\t\t\"100002e8RRR\",\n  efddiv_3 =\t\t\"100002e9RRR\",\n  efdctuidz_2 =\t\t\"100002eaR-R\",\n  efdctsidz_2 =\t\t\"100002ebR-R\",\n  efdcmpgt_3 =\t\t\"100002ecXRR\",\n  efdcmpgt_2 =\t\t\"100002ec-RR\",\n  efdcmplt_3 =\t\t\"100002edXRR\",\n  efdcmplt_2 =\t\t\"100002ed-RR\",\n  efdcmpeq_3 =\t\t\"100002eeXRR\",\n  efdcmpeq_2 =\t\t\"100002ee-RR\",\n  efdcfs_2 =\t\t\"100002efR-R\",\n  efdcfui_2 =\t\t\"100002f0R-R\",\n  efdcfsi_2 =\t\t\"100002f1R-R\",\n  efdcfuf_2 =\t\t\"100002f2R-R\",\n  efdcfsf_2 =\t\t\"100002f3R-R\",\n  efdctui_2 =\t\t\"100002f4R-R\",\n  efdctsi_2 =\t\t\"100002f5R-R\",\n  efdctuf_2 =\t\t\"100002f6R-R\",\n  efdctsf_2 =\t\t\"100002f7R-R\",\n  efdctuiz_2 =\t\t\"100002f8R-R\",\n  efdctsiz_2 =\t\t\"100002faR-R\",\n  efdtstgt_3 =\t\t\"100002fcXRR\",\n  efdtstgt_2 =\t\t\"100002fc-RR\",\n  efdtstlt_3 =\t\t\"100002fdXRR\",\n  efdtstlt_2 =\t\t\"100002fd-RR\",\n  efdtsteq_3 =\t\t\"100002feXRR\",\n  efdtsteq_2 =\t\t\"100002fe-RR\",\n  evlddx_3 =\t\t\"10000300RR0R\",\n  evldd_2 =\t\t\"10000301R8\",\n  evldwx_3 =\t\t\"10000302RR0R\",\n  evldw_2 =\t\t\"10000303R8\",\n  evldhx_3 =\t\t\"10000304RR0R\",\n  evldh_2 =\t\t\"10000305R8\",\n  evlwhex_3 =\t\t\"10000310RR0R\",\n  evlwhe_2 =\t\t\"10000311R4\",\n  evlwhoux_3 =\t\t\"10000314RR0R\",\n  evlwhou_2 =\t\t\"10000315R4\",\n  evlwhosx_3 =\t\t\"10000316RR0R\",\n  evlwhos_2 =\t\t\"10000317R4\",\n  evstddx_3 =\t\t\"10000320RR0R\",\n  evstdd_2 =\t\t\"10000321R8\",\n  evstdwx_3 =\t\t\"10000322RR0R\",\n  evstdw_2 =\t\t\"10000323R8\",\n  evstdhx_3 =\t\t\"10000324RR0R\",\n  evstdh_2 =\t\t\"10000325R8\",\n  evstwhex_3 =\t\t\"10000330RR0R\",\n  evstwhe_2 =\t\t\"10000331R4\",\n  evstwhox_3 =\t\t\"10000334RR0R\",\n  evstwho_2 =\t\t\"10000335R4\",\n  evstwwex_3 =\t\t\"10000338RR0R\",\n  evstwwe_2 =\t\t\"10000339R4\",\n  evstwwox_3 =\t\t\"1000033cRR0R\",\n  evstwwo_2 =\t\t\"1000033dR4\",\n  evmhessf_3 =\t\t\"10000403RRR\",\n  evmhossf_3 =\t\t\"10000407RRR\",\n  evmheumi_3 =\t\t\"10000408RRR\",\n  evmhesmi_3 =\t\t\"10000409RRR\",\n  evmhesmf_3 =\t\t\"1000040bRRR\",\n  evmhoumi_3 =\t\t\"1000040cRRR\",\n  evmhosmi_3 =\t\t\"1000040dRRR\",\n  evmhosmf_3 =\t\t\"1000040fRRR\",\n  evmhessfa_3 =\t\t\"10000423RRR\",\n  evmhossfa_3 =\t\t\"10000427RRR\",\n  evmheumia_3 =\t\t\"10000428RRR\",\n  evmhesmia_3 =\t\t\"10000429RRR\",\n  evmhesmfa_3 =\t\t\"1000042bRRR\",\n  evmhoumia_3 =\t\t\"1000042cRRR\",\n  evmhosmia_3 =\t\t\"1000042dRRR\",\n  evmhosmfa_3 =\t\t\"1000042fRRR\",\n  evmwhssf_3 =\t\t\"10000447RRR\",\n  evmwlumi_3 =\t\t\"10000448RRR\",\n  evmwhumi_3 =\t\t\"1000044cRRR\",\n  evmwhsmi_3 =\t\t\"1000044dRRR\",\n  evmwhsmf_3 =\t\t\"1000044fRRR\",\n  evmwssf_3 =\t\t\"10000453RRR\",\n  evmwumi_3 =\t\t\"10000458RRR\",\n  evmwsmi_3 =\t\t\"10000459RRR\",\n  evmwsmf_3 =\t\t\"1000045bRRR\",\n  evmwhssfa_3 =\t\t\"10000467RRR\",\n  evmwlumia_3 =\t\t\"10000468RRR\",\n  evmwhumia_3 =\t\t\"1000046cRRR\",\n  evmwhsmia_3 =\t\t\"1000046dRRR\",\n  evmwhsmfa_3 =\t\t\"1000046fRRR\",\n  evmwssfa_3 =\t\t\"10000473RRR\",\n  evmwumia_3 =\t\t\"10000478RRR\",\n  evmwsmia_3 =\t\t\"10000479RRR\",\n  evmwsmfa_3 =\t\t\"1000047bRRR\",\n  evmra_2 =\t\t\"100004c4RR\",\n  evdivws_3 =\t\t\"100004c6RRR\",\n  evdivwu_3 =\t\t\"100004c7RRR\",\n  evmwssfaa_3 =\t\t\"10000553RRR\",\n  evmwumiaa_3 =\t\t\"10000558RRR\",\n  evmwsmiaa_3 =\t\t\"10000559RRR\",\n  evmwsmfaa_3 =\t\t\"1000055bRRR\",\n  evmwssfan_3 =\t\t\"100005d3RRR\",\n  evmwumian_3 =\t\t\"100005d8RRR\",\n  evmwsmian_3 =\t\t\"100005d9RRR\",\n  evmwsmfan_3 =\t\t\"100005dbRRR\",\n  evmergehilo_3 =\t\"1000022eRRR\",\n  evmergelohi_3 =\t\"1000022fRRR\",\n  evlhhesplatx_3 =\t\"10000308RR0R\",\n  evlhhesplat_2 =\t\"10000309R2\",\n  evlhhousplatx_3 =\t\"1000030cRR0R\",\n  evlhhousplat_2 =\t\"1000030dR2\",\n  evlhhossplatx_3 =\t\"1000030eRR0R\",\n  evlhhossplat_2 =\t\"1000030fR2\",\n  evlwwsplatx_3 =\t\"10000318RR0R\",\n  evlwwsplat_2 =\t\"10000319R4\",\n  evlwhsplatx_3 =\t\"1000031cRR0R\",\n  evlwhsplat_2 =\t\"1000031dR4\",\n  evaddusiaaw_2 =\t\"100004c0RR\",\n  evaddssiaaw_2 =\t\"100004c1RR\",\n  evsubfusiaaw_2 =\t\"100004c2RR\",\n  evsubfssiaaw_2 =\t\"100004c3RR\",\n  evaddumiaaw_2 =\t\"100004c8RR\",\n  evaddsmiaaw_2 =\t\"100004c9RR\",\n  evsubfumiaaw_2 =\t\"100004caRR\",\n  evsubfsmiaaw_2 =\t\"100004cbRR\",\n  evmheusiaaw_3 =\t\"10000500RRR\",\n  evmhessiaaw_3 =\t\"10000501RRR\",\n  evmhessfaaw_3 =\t\"10000503RRR\",\n  evmhousiaaw_3 =\t\"10000504RRR\",\n  evmhossiaaw_3 =\t\"10000505RRR\",\n  evmhossfaaw_3 =\t\"10000507RRR\",\n  evmheumiaaw_3 =\t\"10000508RRR\",\n  evmhesmiaaw_3 =\t\"10000509RRR\",\n  evmhesmfaaw_3 =\t\"1000050bRRR\",\n  evmhoumiaaw_3 =\t\"1000050cRRR\",\n  evmhosmiaaw_3 =\t\"1000050dRRR\",\n  evmhosmfaaw_3 =\t\"1000050fRRR\",\n  evmhegumiaa_3 =\t\"10000528RRR\",\n  evmhegsmiaa_3 =\t\"10000529RRR\",\n  evmhegsmfaa_3 =\t\"1000052bRRR\",\n  evmhogumiaa_3 =\t\"1000052cRRR\",\n  evmhogsmiaa_3 =\t\"1000052dRRR\",\n  evmhogsmfaa_3 =\t\"1000052fRRR\",\n  evmwlusiaaw_3 =\t\"10000540RRR\",\n  evmwlssiaaw_3 =\t\"10000541RRR\",\n  evmwlumiaaw_3 =\t\"10000548RRR\",\n  evmwlsmiaaw_3 =\t\"10000549RRR\",\n  evmheusianw_3 =\t\"10000580RRR\",\n  evmhessianw_3 =\t\"10000581RRR\",\n  evmhessfanw_3 =\t\"10000583RRR\",\n  evmhousianw_3 =\t\"10000584RRR\",\n  evmhossianw_3 =\t\"10000585RRR\",\n  evmhossfanw_3 =\t\"10000587RRR\",\n  evmheumianw_3 =\t\"10000588RRR\",\n  evmhesmianw_3 =\t\"10000589RRR\",\n  evmhesmfanw_3 =\t\"1000058bRRR\",\n  evmhoumianw_3 =\t\"1000058cRRR\",\n  evmhosmianw_3 =\t\"1000058dRRR\",\n  evmhosmfanw_3 =\t\"1000058fRRR\",\n  evmhegumian_3 =\t\"100005a8RRR\",\n  evmhegsmian_3 =\t\"100005a9RRR\",\n  evmhegsmfan_3 =\t\"100005abRRR\",\n  evmhogumian_3 =\t\"100005acRRR\",\n  evmhogsmian_3 =\t\"100005adRRR\",\n  evmhogsmfan_3 =\t\"100005afRRR\",\n  evmwlusianw_3 =\t\"100005c0RRR\",\n  evmwlssianw_3 =\t\"100005c1RRR\",\n  evmwlumianw_3 =\t\"100005c8RRR\",\n  evmwlsmianw_3 =\t\"100005c9RRR\",\n\n  -- NYI: Book E instructions.\n}\n\n-- Add mnemonics for \".\" variants.\ndo\n  local t = {}\n  for k,v in pairs(map_op) do\n    if type(v) == \"string\" and sub(v, -1) == \".\" then\n      local v2 = sub(v, 1, 7)..char(byte(v, 8)+1)..sub(v, 9, -2)\n      t[sub(k, 1, -3)..\".\"..sub(k, -2)] = v2\n    end\n  end\n  for k,v in pairs(t) do\n    map_op[k] = v\n  end\nend\n\n-- Add more branch mnemonics.\nfor cond,c in pairs(map_cond) do\n  local b1 = \"b\"..cond\n  local c1 = shl(band(c, 3), 16) + (c < 4 and 0x01000000 or 0)\n  -- bX[l]\n  map_op[b1..\"_1\"] = tohex(0x40800000 + c1)..\"K\"\n  map_op[b1..\"y_1\"] = tohex(0x40a00000 + c1)..\"K\"\n  map_op[b1..\"l_1\"] = tohex(0x40800001 + c1)..\"K\"\n  map_op[b1..\"_2\"] = tohex(0x40800000 + c1)..\"-XK\"\n  map_op[b1..\"y_2\"] = tohex(0x40a00000 + c1)..\"-XK\"\n  map_op[b1..\"l_2\"] = tohex(0x40800001 + c1)..\"-XK\"\n  -- bXlr[l]\n  map_op[b1..\"lr_0\"] = tohex(0x4c800020 + c1)\n  map_op[b1..\"lrl_0\"] = tohex(0x4c800021 + c1)\n  map_op[b1..\"ctr_0\"] = tohex(0x4c800420 + c1)\n  map_op[b1..\"ctrl_0\"] = tohex(0x4c800421 + c1)\n  -- bXctr[l]\n  map_op[b1..\"lr_1\"] = tohex(0x4c800020 + c1)..\"-X\"\n  map_op[b1..\"lrl_1\"] = tohex(0x4c800021 + c1)..\"-X\"\n  map_op[b1..\"ctr_1\"] = tohex(0x4c800420 + c1)..\"-X\"\n  map_op[b1..\"ctrl_1\"] = tohex(0x4c800421 + c1)..\"-X\"\nend\n\n------------------------------------------------------------------------------\n\nlocal function parse_gpr(expr)\n  local tname, ovreg = match(expr, \"^([%w_]+):(r[1-3]?[0-9])$\")\n  local tp = map_type[tname or expr]\n  if tp then\n    local reg = ovreg or tp.reg\n    if not reg then\n      werror(\"type `\"..(tname or expr)..\"' needs a register override\")\n    end\n    expr = reg\n  end\n  local r = match(expr, \"^r([1-3]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 31 then return r, tp end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_fpr(expr)\n  local r = match(expr, \"^f([1-3]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 31 then return r end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_vr(expr)\n  local r = match(expr, \"^v([1-3]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 31 then return r end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_vs(expr)\n  local r = match(expr, \"^vs([1-6]?[0-9])$\")\n  if r then\n    r = tonumber(r)\n    if r <= 63 then return r end\n  end\n  werror(\"bad register name `\"..expr..\"'\")\nend\n\nlocal function parse_cr(expr)\n  local r = match(expr, \"^cr([0-7])$\")\n  if r then return tonumber(r) end\n  werror(\"bad condition register name `\"..expr..\"'\")\nend\n\nlocal function parse_cond(expr)\n  local r, cond = match(expr, \"^4%*cr([0-7])%+(%w%w)$\")\n  if r then\n    r = tonumber(r)\n    local c = map_cond[cond]\n    if c and c < 4 then return r*4+c end\n  end\n  werror(\"bad condition bit name `\"..expr..\"'\")\nend\n\nlocal parse_ctx = {}\n\nlocal loadenv = setfenv and function(s)\n  local code = loadstring(s, \"\")\n  if code then setfenv(code, parse_ctx) end\n  return code\nend or function(s)\n  return load(s, \"\", nil, parse_ctx)\nend\n\n-- Try to parse simple arithmetic, too, since some basic ops are aliases.\nlocal function parse_number(n)\n  local x = tonumber(n)\n  if x then return x end\n  local code = loadenv(\"return \"..n)\n  if code then\n    local ok, y = pcall(code)\n    if ok then return y end\n  end\n  return nil\nend\n\nlocal function parse_imm(imm, bits, shift, scale, signed)\n  local n = parse_number(imm)\n  if n then\n    local m = sar(n, scale)\n    if shl(m, scale) == n then\n      if signed then\n\tlocal s = sar(m, bits-1)\n\tif s == 0 then return shl(m, shift)\n\telseif s == -1 then return shl(m + shl(1, bits), shift) end\n      else\n\tif sar(m, bits) == 0 then return shl(m, shift) end\n      end\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  elseif match(imm, \"^[rfv]([1-3]?[0-9])$\") or\n\t match(imm, \"^vs([1-6]?[0-9])$\") or\n\t match(imm, \"^([%w_]+):(r[1-3]?[0-9])$\") then\n    werror(\"expected immediate operand, got register\")\n  else\n    waction(\"IMM\", (signed and 32768 or 0)+scale*1024+bits*32+shift, imm)\n    return 0\n  end\nend\n\nlocal function parse_shiftmask(imm, isshift)\n  local n = parse_number(imm)\n  if n then\n    if shr(n, 6) == 0 then\n      local lsb = band(n, 31)\n      local msb = n - lsb\n      return isshift and (shl(lsb, 11)+shr(msb, 4)) or (shl(lsb, 6)+msb)\n    end\n    werror(\"out of range immediate `\"..imm..\"'\")\n  elseif match(imm, \"^r([1-3]?[0-9])$\") or\n\t match(imm, \"^([%w_]+):(r[1-3]?[0-9])$\") then\n    werror(\"expected immediate operand, got register\")\n  else\n    waction(\"IMMSH\", isshift and 1 or 0, imm)\n    return 0;\n  end\nend\n\nlocal function parse_disp(disp)\n  local imm, reg = match(disp, \"^(.*)%(([%w_:]+)%)$\")\n  if imm then\n    local r = parse_gpr(reg)\n    if r == 0 then werror(\"cannot use r0 in displacement\") end\n    return shl(r, 16) + parse_imm(imm, 16, 0, 0, true)\n  end\n  local reg, tailr = match(disp, \"^([%w_:]+)%s*(.*)$\")\n  if reg and tailr ~= \"\" then\n    local r, tp = parse_gpr(reg)\n    if r == 0 then werror(\"cannot use r0 in displacement\") end\n    if tp then\n      waction(\"IMM\", 32768+16*32, format(tp.ctypefmt, tailr))\n      return shl(r, 16)\n    end\n  end\n  werror(\"bad displacement `\"..disp..\"'\")\nend\n\nlocal function parse_u5disp(disp, scale)\n  local imm, reg = match(disp, \"^(.*)%(([%w_:]+)%)$\")\n  if imm then\n    local r = parse_gpr(reg)\n    if r == 0 then werror(\"cannot use r0 in displacement\") end\n    return shl(r, 16) + parse_imm(imm, 5, 11, scale, false)\n  end\n  local reg, tailr = match(disp, \"^([%w_:]+)%s*(.*)$\")\n  if reg and tailr ~= \"\" then\n    local r, tp = parse_gpr(reg)\n    if r == 0 then werror(\"cannot use r0 in displacement\") end\n    if tp then\n      waction(\"IMM\", scale*1024+5*32+11, format(tp.ctypefmt, tailr))\n      return shl(r, 16)\n    end\n  end\n  werror(\"bad displacement `\"..disp..\"'\")\nend\n\nlocal function parse_label(label, def)\n  local prefix = sub(label, 1, 2)\n  -- =>label (pc label reference)\n  if prefix == \"=>\" then\n    return \"PC\", 0, sub(label, 3)\n  end\n  -- ->name (global label reference)\n  if prefix == \"->\" then\n    return \"LG\", map_global[sub(label, 3)]\n  end\n  if def then\n    -- [1-9] (local label definition)\n    if match(label, \"^[1-9]$\") then\n      return \"LG\", 10+tonumber(label)\n    end\n  else\n    -- [<>][1-9] (local label reference)\n    local dir, lnum = match(label, \"^([<>])([1-9])$\")\n    if dir then -- Fwd: 1-9, Bkwd: 11-19.\n      return \"LG\", lnum + (dir == \">\" and 0 or 10)\n    end\n    -- extern label (extern label reference)\n    local extname = match(label, \"^extern%s+(%S+)$\")\n    if extname then\n      return \"EXT\", map_extern[extname]\n    end\n  end\n  werror(\"bad label `\"..label..\"'\")\nend\n\n------------------------------------------------------------------------------\n\n-- Handle opcodes defined with template strings.\nop_template = function(params, template, nparams)\n  if not params then return sub(template, 9) end\n  local op = tonumber(sub(template, 1, 8), 16)\n  local n, rs = 1, 26\n\n  -- Limit number of section buffer positions used by a single dasm_put().\n  -- A single opcode needs a maximum of 3 positions (rlwinm).\n  if secpos+3 > maxsecpos then wflush() end\n  local pos = wpos()\n\n  -- Process each character.\n  for p in gmatch(sub(template, 9), \".\") do\n    if p == \"R\" then\n      rs = rs - 5; op = op + shl(parse_gpr(params[n]), rs); n = n + 1\n    elseif p == \"F\" then\n      rs = rs - 5; op = op + shl(parse_fpr(params[n]), rs); n = n + 1\n    elseif p == \"V\" then\n      rs = rs - 5; op = op + shl(parse_vr(params[n]), rs); n = n + 1\n    elseif p == \"Q\" then\n      local vs = parse_vs(params[n]); n = n + 1; rs = rs - 5\n      local sh = rs == 6 and 2 or 3 + band(shr(rs, 1), 3)\n      op = op + shl(band(vs, 31), rs) + shr(band(vs, 32), sh)\n    elseif p == \"q\" then\n      local vs = parse_vs(params[n]); n = n + 1\n      op = op + shl(band(vs, 31), 21) + shr(band(vs, 32), 5)\n    elseif p == \"A\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, false); n = n + 1\n    elseif p == \"S\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 5, rs, 0, true); n = n + 1\n    elseif p == \"I\" then\n      op = op + parse_imm(params[n], 16, 0, 0, true); n = n + 1\n    elseif p == \"U\" then\n      op = op + parse_imm(params[n], 16, 0, 0, false); n = n + 1\n    elseif p == \"D\" then\n      op = op + parse_disp(params[n]); n = n + 1\n    elseif p == \"2\" then\n      op = op + parse_u5disp(params[n], 1); n = n + 1\n    elseif p == \"4\" then\n      op = op + parse_u5disp(params[n], 2); n = n + 1\n    elseif p == \"8\" then\n      op = op + parse_u5disp(params[n], 3); n = n + 1\n    elseif p == \"C\" then\n      rs = rs - 5; op = op + shl(parse_cond(params[n]), rs); n = n + 1\n    elseif p == \"X\" then\n      rs = rs - 5; op = op + shl(parse_cr(params[n]), rs+2); n = n + 1\n    elseif p == \"1\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 1, rs, 0, false); n = n + 1\n    elseif p == \"g\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 2, rs, 0, false); n = n + 1\n    elseif p == \"3\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 3, rs, 0, false); n = n + 1\n    elseif p == \"P\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 4, rs, 0, false); n = n + 1\n    elseif p == \"p\" then\n      op = op + parse_imm(params[n], 4, rs, 0, false); n = n + 1\n    elseif p == \"6\" then\n      rs = rs - 6; op = op + parse_imm(params[n], 6, rs, 0, false); n = n + 1\n    elseif p == \"Y\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 1, rs+4, 0, false); n = n + 1\n    elseif p == \"y\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 1, rs+3, 0, false); n = n + 1\n    elseif p == \"Z\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 2, rs+3, 0, false); n = n + 1\n    elseif p == \"z\" then\n      rs = rs - 5; op = op + parse_imm(params[n], 2, rs+2, 0, false); n = n + 1\n    elseif p == \"W\" then\n      op = op + parse_cr(params[n]); n = n + 1\n    elseif p == \"G\" then\n      op = op + parse_imm(params[n], 8, 12, 0, false); n = n + 1\n    elseif p == \"H\" then\n      op = op + parse_shiftmask(params[n], true); n = n + 1\n    elseif p == \"M\" then\n      op = op + parse_shiftmask(params[n], false); n = n + 1\n    elseif p == \"J\" or p == \"K\" then\n      local mode, m, s = parse_label(params[n], false)\n      if p == \"K\" then m = m + 2048 end\n      waction(\"REL_\"..mode, m, s, 1)\n      n = n + 1\n    elseif p == \"0\" then\n      if band(shr(op, rs), 31) == 0 then werror(\"cannot use r0\") end\n    elseif p == \"=\" or p == \"%\" then\n      local t = band(shr(op, p == \"%\" and rs+5 or rs), 31)\n      rs = rs - 5\n      op = op + shl(t, rs)\n    elseif p == \"~\" then\n      local mm = shl(31, rs)\n      local lo = band(op, mm)\n      local hi = band(op, shl(mm, 5))\n      op = op - lo - hi + shl(lo, 5) + shr(hi, 5)\n    elseif p == \":\" then\n      if band(shr(op, rs), 1) ~= 0 then werror(\"register pair expected\") end\n    elseif p == \"-\" then\n      rs = rs - 5\n    elseif p == \".\" then\n      -- Ignored.\n    else\n      assert(false)\n    end\n  end\n  wputpos(pos, op)\nend\n\nmap_op[\".template__\"] = op_template\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode to mark the position where the action list is to be emitted.\nmap_op[\".actionlist_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeactions(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the global enum is to be emitted.\nmap_op[\".globals_1\"] = function(params)\n  if not params then return \"prefix\" end\n  local prefix = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobals(out, prefix) end)\nend\n\n-- Pseudo-opcode to mark the position where the global names are to be emitted.\nmap_op[\".globalnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobalnames(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the extern names are to be emitted.\nmap_op[\".externnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeexternnames(out, name) end)\nend\n\n------------------------------------------------------------------------------\n\n-- Label pseudo-opcode (converted from trailing colon form).\nmap_op[\".label_1\"] = function(params)\n  if not params then return \"[1-9] | ->global | =>pcexpr\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local mode, n, s = parse_label(params[1], true)\n  if mode == \"EXT\" then werror(\"bad label definition\") end\n  waction(\"LABEL_\"..mode, n, s, 1)\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcodes for data storage.\nmap_op[\".long_*\"] = function(params)\n  if not params then return \"imm...\" end\n  for _,p in ipairs(params) do\n    local n = tonumber(p)\n    if not n then werror(\"bad immediate `\"..p..\"'\") end\n    if n < 0 then n = n + 2^32 end\n    wputw(n)\n    if secpos+2 > maxsecpos then wflush() end\n  end\nend\n\n-- Alignment pseudo-opcode.\nmap_op[\".align_1\"] = function(params)\n  if not params then return \"numpow2\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local align = tonumber(params[1])\n  if align then\n    local x = align\n    -- Must be a power of 2 in the range (2 ... 256).\n    for i=1,8 do\n      x = x / 2\n      if x == 1 then\n\twaction(\"ALIGN\", align-1, nil, 1) -- Action byte is 2**n-1.\n\treturn\n      end\n    end\n  end\n  werror(\"bad alignment\")\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode for (primitive) type definitions (map to C types).\nmap_op[\".type_3\"] = function(params, nparams)\n  if not params then\n    return nparams == 2 and \"name, ctype\" or \"name, ctype, reg\"\n  end\n  local name, ctype, reg = params[1], params[2], params[3]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    werror(\"bad type name `\"..name..\"'\")\n  end\n  local tp = map_type[name]\n  if tp then\n    werror(\"duplicate type `\"..name..\"'\")\n  end\n  -- Add #type to defines. A bit unclean to put it in map_archdef.\n  map_archdef[\"#\"..name] = \"sizeof(\"..ctype..\")\"\n  -- Add new type and emit shortcut define.\n  local num = ctypenum + 1\n  map_type[name] = {\n    ctype = ctype,\n    ctypefmt = format(\"Dt%X(%%s)\", num),\n    reg = reg,\n  }\n  wline(format(\"#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)\", num, ctype))\n  ctypenum = num\nend\nmap_op[\".type_2\"] = map_op[\".type_3\"]\n\n-- Dump type definitions.\nlocal function dumptypes(out, lvl)\n  local t = {}\n  for name in pairs(map_type) do t[#t+1] = name end\n  sort(t)\n  out:write(\"Type definitions:\\n\")\n  for _,name in ipairs(t) do\n    local tp = map_type[name]\n    local reg = tp.reg or \"\"\n    out:write(format(\"  %-20s %-20s %s\\n\", name, tp.ctype, reg))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Set the current section.\nfunction _M.section(num)\n  waction(\"SECTION\", num)\n  wflush(true) -- SECTION is a terminal action.\nend\n\n------------------------------------------------------------------------------\n\n-- Dump architecture description.\nfunction _M.dumparch(out)\n  out:write(format(\"DynASM %s version %s, released %s\\n\\n\",\n    _info.arch, _info.version, _info.release))\n  dumpactions(out)\nend\n\n-- Dump all user defined elements.\nfunction _M.dumpdef(out, lvl)\n  dumptypes(out, lvl)\n  dumpglobals(out, lvl)\n  dumpexterns(out, lvl)\nend\n\n------------------------------------------------------------------------------\n\n-- Pass callbacks from/to the DynASM core.\nfunction _M.passcb(wl, we, wf, ww)\n  wline, werror, wfatal, wwarn = wl, we, wf, ww\n  return wflush\nend\n\n-- Setup the arch-specific module.\nfunction _M.setup(arch, opt)\n  g_arch, g_opt = arch, opt\nend\n\n-- Merge the core maps and the arch-specific maps.\nfunction _M.mergemaps(map_coreop, map_def)\n  setmetatable(map_op, { __index = map_coreop })\n  setmetatable(map_def, { __index = map_archdef })\n  return map_op, map_def\nend\n\nreturn _M\n\n------------------------------------------------------------------------------\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_proto.h",
    "content": "/*\n** DynASM encoding engine prototypes.\n** Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n** Released under the MIT license. See dynasm.lua for full copyright notice.\n*/\n\n#ifndef _DASM_PROTO_H\n#define _DASM_PROTO_H\n\n#include <stddef.h>\n#include <stdarg.h>\n\n#define DASM_IDENT\t\"DynASM 1.5.0\"\n#define DASM_VERSION\t10500\t/* 1.5.0 */\n\n#ifndef Dst_DECL\n#define Dst_DECL\tdasm_State **Dst\n#endif\n\n#ifndef Dst_REF\n#define Dst_REF\t\t(*Dst)\n#endif\n\n#ifndef DASM_FDEF\n#define DASM_FDEF\textern\n#endif\n\n#ifndef DASM_M_GROW\n#define DASM_M_GROW(ctx, t, p, sz, need) \\\n  do { \\\n    size_t _sz = (sz), _need = (need); \\\n    if (_sz < _need) { \\\n      if (_sz < 16) _sz = 16; \\\n      while (_sz < _need) _sz += _sz; \\\n      (p) = (t *)realloc((p), _sz); \\\n      if ((p) == NULL) exit(1); \\\n      (sz) = _sz; \\\n    } \\\n  } while(0)\n#endif\n\n#ifndef DASM_M_FREE\n#define DASM_M_FREE(ctx, p, sz)\tfree(p)\n#endif\n\n/* Internal DynASM encoder state. */\ntypedef struct dasm_State dasm_State;\n\n\n/* Initialize and free DynASM state. */\nDASM_FDEF void dasm_init(Dst_DECL, int maxsection);\nDASM_FDEF void dasm_free(Dst_DECL);\n\n/* Setup global array. Must be called before dasm_setup(). */\nDASM_FDEF void dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl);\n\n/* Grow PC label array. Can be called after dasm_setup(), too. */\nDASM_FDEF void dasm_growpc(Dst_DECL, unsigned int maxpc);\n\n/* Setup encoder. */\nDASM_FDEF void dasm_setup(Dst_DECL, const void *actionlist);\n\n/* Feed encoder with actions. Calls are generated by pre-processor. */\nDASM_FDEF void dasm_put(Dst_DECL, int start, ...);\n\n/* Link sections and return the resulting size. */\nDASM_FDEF int dasm_link(Dst_DECL, size_t *szp);\n\n/* Encode sections into buffer. */\nDASM_FDEF int dasm_encode(Dst_DECL, void *buffer);\n\n/* Get PC label offset. */\nDASM_FDEF int dasm_getpclabel(Dst_DECL, unsigned int pc);\n\n#ifdef DASM_CHECKS\n/* Optional sanity checker to call between isolated encoding steps. */\nDASM_FDEF int dasm_checkstep(Dst_DECL, int secmatch);\n#else\n#define dasm_checkstep(a, b)\t0\n#endif\n\n\n#endif /* _DASM_PROTO_H */\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_x64.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM x64 module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n------------------------------------------------------------------------------\n-- This module just sets 64 bit mode for the combined x86/x64 module.\n-- All the interesting stuff is there.\n------------------------------------------------------------------------------\n\nx64 = true -- Using a global is an ugly, but effective solution.\nreturn require(\"dasm_x86\")\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_x86.h",
    "content": "/*\n** DynASM x86 encoding engine.\n** Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n** Released under the MIT license. See dynasm.lua for full copyright notice.\n*/\n\n#include <stddef.h>\n#include <stdarg.h>\n#include <string.h>\n#include <stdlib.h>\n\n#define DASM_ARCH\t\t\"x86\"\n\n#ifndef DASM_EXTERN\n#define DASM_EXTERN(a,b,c,d)\t0\n#endif\n\n/* Action definitions. DASM_STOP must be 255. */\nenum {\n  DASM_DISP = 233,\n  DASM_IMM_S, DASM_IMM_B, DASM_IMM_W, DASM_IMM_D, DASM_IMM_WB, DASM_IMM_DB,\n  DASM_VREG, DASM_SPACE, DASM_SETLABEL, DASM_REL_A, DASM_REL_LG, DASM_REL_PC,\n  DASM_IMM_LG, DASM_IMM_PC, DASM_LABEL_LG, DASM_LABEL_PC, DASM_ALIGN,\n  DASM_EXTERN, DASM_ESC, DASM_MARK, DASM_SECTION, DASM_STOP\n};\n\n/* Maximum number of section buffer positions for a single dasm_put() call. */\n#define DASM_MAXSECPOS\t\t25\n\n/* DynASM encoder status codes. Action list offset or number are or'ed in. */\n#define DASM_S_OK\t\t0x00000000\n#define DASM_S_NOMEM\t\t0x01000000\n#define DASM_S_PHASE\t\t0x02000000\n#define DASM_S_MATCH_SEC\t0x03000000\n#define DASM_S_RANGE_I\t\t0x11000000\n#define DASM_S_RANGE_SEC\t0x12000000\n#define DASM_S_RANGE_LG\t\t0x13000000\n#define DASM_S_RANGE_PC\t\t0x14000000\n#define DASM_S_RANGE_VREG\t0x15000000\n#define DASM_S_UNDEF_L\t\t0x21000000\n#define DASM_S_UNDEF_PC\t\t0x22000000\n\n/* Macros to convert positions (8 bit section + 24 bit index). */\n#define DASM_POS2IDX(pos)\t((pos)&0x00ffffff)\n#define DASM_POS2BIAS(pos)\t((pos)&0xff000000)\n#define DASM_SEC2POS(sec)\t((sec)<<24)\n#define DASM_POS2SEC(pos)\t((pos)>>24)\n#define DASM_POS2PTR(D, pos)\t(D->sections[DASM_POS2SEC(pos)].rbuf + (pos))\n\n/* Action list type. */\ntypedef const unsigned char *dasm_ActList;\n\n/* Per-section structure. */\ntypedef struct dasm_Section {\n  int *rbuf;\t\t/* Biased buffer pointer (negative section bias). */\n  int *buf;\t\t/* True buffer pointer. */\n  size_t bsize;\t\t/* Buffer size in bytes. */\n  int pos;\t\t/* Biased buffer position. */\n  int epos;\t\t/* End of biased buffer position - max single put. */\n  int ofs;\t\t/* Byte offset into section. */\n} dasm_Section;\n\n/* Core structure holding the DynASM encoding state. */\nstruct dasm_State {\n  size_t psize;\t\t\t/* Allocated size of this structure. */\n  dasm_ActList actionlist;\t/* Current actionlist pointer. */\n  int *lglabels;\t\t/* Local/global chain/pos ptrs. */\n  size_t lgsize;\n  int *pclabels;\t\t/* PC label chains/pos ptrs. */\n  size_t pcsize;\n  void **globals;\t\t/* Array of globals (bias -10). */\n  dasm_Section *section;\t/* Pointer to active section. */\n  size_t codesize;\t\t/* Total size of all code sections. */\n  int maxsection;\t\t/* 0 <= sectionidx < maxsection. */\n  int status;\t\t\t/* Status code. */\n  dasm_Section sections[1];\t/* All sections. Alloc-extended. */\n};\n\n/* The size of the core structure depends on the max. number of sections. */\n#define DASM_PSZ(ms)\t(sizeof(dasm_State)+(ms-1)*sizeof(dasm_Section))\n\n\n/* Initialize DynASM state. */\nvoid dasm_init(Dst_DECL, int maxsection)\n{\n  dasm_State *D;\n  size_t psz = 0;\n  int i;\n  Dst_REF = NULL;\n  DASM_M_GROW(Dst, struct dasm_State, Dst_REF, psz, DASM_PSZ(maxsection));\n  D = Dst_REF;\n  D->psize = psz;\n  D->lglabels = NULL;\n  D->lgsize = 0;\n  D->pclabels = NULL;\n  D->pcsize = 0;\n  D->globals = NULL;\n  D->maxsection = maxsection;\n  for (i = 0; i < maxsection; i++) {\n    D->sections[i].buf = NULL;  /* Need this for pass3. */\n    D->sections[i].rbuf = D->sections[i].buf - DASM_SEC2POS(i);\n    D->sections[i].bsize = 0;\n    D->sections[i].epos = 0;  /* Wrong, but is recalculated after resize. */\n  }\n}\n\n/* Free DynASM state. */\nvoid dasm_free(Dst_DECL)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  for (i = 0; i < D->maxsection; i++)\n    if (D->sections[i].buf)\n      DASM_M_FREE(Dst, D->sections[i].buf, D->sections[i].bsize);\n  if (D->pclabels) DASM_M_FREE(Dst, D->pclabels, D->pcsize);\n  if (D->lglabels) DASM_M_FREE(Dst, D->lglabels, D->lgsize);\n  DASM_M_FREE(Dst, D, D->psize);\n}\n\n/* Setup global label array. Must be called before dasm_setup(). */\nvoid dasm_setupglobal(Dst_DECL, void **gl, unsigned int maxgl)\n{\n  dasm_State *D = Dst_REF;\n  D->globals = gl - 10;  /* Negative bias to compensate for locals. */\n  DASM_M_GROW(Dst, int, D->lglabels, D->lgsize, (10+maxgl)*sizeof(int));\n}\n\n/* Grow PC label array. Can be called after dasm_setup(), too. */\nvoid dasm_growpc(Dst_DECL, unsigned int maxpc)\n{\n  dasm_State *D = Dst_REF;\n  size_t osz = D->pcsize;\n  DASM_M_GROW(Dst, int, D->pclabels, D->pcsize, maxpc*sizeof(int));\n  memset((void *)(((unsigned char *)D->pclabels)+osz), 0, D->pcsize-osz);\n}\n\n/* Setup encoder. */\nvoid dasm_setup(Dst_DECL, const void *actionlist)\n{\n  dasm_State *D = Dst_REF;\n  int i;\n  D->actionlist = (dasm_ActList)actionlist;\n  D->status = DASM_S_OK;\n  D->section = &D->sections[0];\n  memset((void *)D->lglabels, 0, D->lgsize);\n  if (D->pclabels) memset((void *)D->pclabels, 0, D->pcsize);\n  for (i = 0; i < D->maxsection; i++) {\n    D->sections[i].pos = DASM_SEC2POS(i);\n    D->sections[i].ofs = 0;\n  }\n}\n\n\n#ifdef DASM_CHECKS\n#define CK(x, st) \\\n  do { if (!(x)) { \\\n    D->status = DASM_S_##st|(int)(p-D->actionlist-1); return; } } while (0)\n#define CKPL(kind, st) \\\n  do { if ((size_t)((char *)pl-(char *)D->kind##labels) >= D->kind##size) { \\\n    D->status=DASM_S_RANGE_##st|(int)(p-D->actionlist-1); return; } } while (0)\n#else\n#define CK(x, st)\t((void)0)\n#define CKPL(kind, st)\t((void)0)\n#endif\n\n/* Pass 1: Store actions and args, link branches/labels, estimate offsets. */\nvoid dasm_put(Dst_DECL, int start, ...)\n{\n  va_list ap;\n  dasm_State *D = Dst_REF;\n  dasm_ActList p = D->actionlist + start;\n  dasm_Section *sec = D->section;\n  int pos = sec->pos, ofs = sec->ofs, mrm = -1;\n  int *b;\n\n  if (pos >= sec->epos) {\n    DASM_M_GROW(Dst, int, sec->buf, sec->bsize,\n      sec->bsize + 2*DASM_MAXSECPOS*sizeof(int));\n    sec->rbuf = sec->buf - DASM_POS2BIAS(pos);\n    sec->epos = (int)sec->bsize/sizeof(int) - DASM_MAXSECPOS+DASM_POS2BIAS(pos);\n  }\n\n  b = sec->rbuf;\n  b[pos++] = start;\n\n  va_start(ap, start);\n  while (1) {\n    int action = *p++;\n    if (action < DASM_DISP) {\n      ofs++;\n    } else if (action <= DASM_REL_A) {\n      int n = va_arg(ap, int);\n      b[pos++] = n;\n      switch (action) {\n      case DASM_DISP:\n\tif (n == 0) { if (mrm < 0) mrm = p[-2]; if ((mrm&7) != 5) break; }\n\t/* fallthrough */\n      case DASM_IMM_DB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */\n      case DASM_REL_A: /* Assumes ptrdiff_t is int. !x64 */\n      case DASM_IMM_D: ofs += 4; break;\n      case DASM_IMM_S: CK(((n+128)&-256) == 0, RANGE_I); goto ob;\n      case DASM_IMM_B: CK((n&-256) == 0, RANGE_I); ob: ofs++; break;\n      case DASM_IMM_WB: if (((n+128)&-256) == 0) goto ob; /* fallthrough */\n      case DASM_IMM_W: CK((n&-65536) == 0, RANGE_I); ofs += 2; break;\n      case DASM_SPACE: p++; ofs += n; break;\n      case DASM_SETLABEL: b[pos-2] = -0x40000000; break;  /* Neg. label ofs. */\n      case DASM_VREG: CK((n&-16) == 0 && (n != 4 || (*p>>5) != 2), RANGE_VREG);\n\tif (*p < 0x40 && p[1] == DASM_DISP) mrm = n;\n\tif (*p < 0x20 && (n&7) == 4) ofs++;\n\tswitch ((*p++ >> 3) & 3) {\n\tcase 3: n |= b[pos-3]; /* fallthrough */\n\tcase 2: n |= b[pos-2]; /* fallthrough */\n\tcase 1: if (n <= 7) { b[pos-1] |= 0x10; ofs--; }\n\t}\n\tcontinue;\n      }\n      mrm = -1;\n    } else {\n      int *pl, n;\n      switch (action) {\n      case DASM_REL_LG:\n      case DASM_IMM_LG:\n\tn = *p++; pl = D->lglabels + n;\n\t/* Bkwd rel or global. */\n\tif (n <= 246) { CK(n>=10||*pl<0, RANGE_LG); CKPL(lg, LG); goto putrel; }\n\tpl -= 246; n = *pl;\n\tif (n < 0) n = 0;  /* Start new chain for fwd rel if label exists. */\n\tgoto linkrel;\n      case DASM_REL_PC:\n      case DASM_IMM_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);\n      putrel:\n\tn = *pl;\n\tif (n < 0) {  /* Label exists. Get label pos and store it. */\n\t  b[pos] = -n;\n\t} else {\n      linkrel:\n\t  b[pos] = n;  /* Else link to rel chain, anchored at label. */\n\t  *pl = pos;\n\t}\n\tpos++;\n\tofs += 4;  /* Maximum offset needed. */\n\tif (action == DASM_REL_LG || action == DASM_REL_PC) {\n\t  b[pos++] = ofs;  /* Store pass1 offset estimate. */\n\t} else if (sizeof(ptrdiff_t) == 8) {\n\t  ofs += 4;\n\t}\n\tbreak;\n      case DASM_LABEL_LG: pl = D->lglabels + *p++; CKPL(lg, LG); goto putlabel;\n      case DASM_LABEL_PC: pl = D->pclabels + va_arg(ap, int); CKPL(pc, PC);\n      putlabel:\n\tn = *pl;  /* n > 0: Collapse rel chain and replace with label pos. */\n\twhile (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = pos; }\n\t*pl = -pos;  /* Label exists now. */\n\tb[pos++] = ofs;  /* Store pass1 offset estimate. */\n\tbreak;\n      case DASM_ALIGN:\n\tofs += *p++;  /* Maximum alignment needed (arg is 2**n-1). */\n\tb[pos++] = ofs;  /* Store pass1 offset estimate. */\n\tbreak;\n      case DASM_EXTERN: p += 2; ofs += 4; break;\n      case DASM_ESC: p++; ofs++; break;\n      case DASM_MARK: mrm = p[-2]; break;\n      case DASM_SECTION:\n\tn = *p; CK(n < D->maxsection, RANGE_SEC); D->section = &D->sections[n];\n      case DASM_STOP: goto stop;\n      }\n    }\n  }\nstop:\n  va_end(ap);\n  sec->pos = pos;\n  sec->ofs = ofs;\n}\n#undef CK\n\n/* Pass 2: Link sections, shrink branches/aligns, fix label offsets. */\nint dasm_link(Dst_DECL, size_t *szp)\n{\n  dasm_State *D = Dst_REF;\n  int secnum;\n  int ofs = 0;\n\n#ifdef DASM_CHECKS\n  *szp = 0;\n  if (D->status != DASM_S_OK) return D->status;\n  {\n    int pc;\n    for (pc = 0; pc*sizeof(int) < D->pcsize; pc++)\n      if (D->pclabels[pc] > 0) return DASM_S_UNDEF_PC|pc;\n  }\n#endif\n\n  { /* Handle globals not defined in this translation unit. */\n    int idx;\n    for (idx = 10; idx*sizeof(int) < D->lgsize; idx++) {\n      int n = D->lglabels[idx];\n      /* Undefined label: Collapse rel chain and replace with marker (< 0). */\n      while (n > 0) { int *pb = DASM_POS2PTR(D, n); n = *pb; *pb = -idx; }\n    }\n  }\n\n  /* Combine all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->rbuf;\n    int pos = DASM_SEC2POS(secnum);\n    int lastpos = sec->pos;\n\n    while (pos != lastpos) {\n      dasm_ActList p = D->actionlist + b[pos++];\n      int op = 0;\n      while (1) {\n\tint action = *p++;\n\tswitch (action) {\n\tcase DASM_REL_LG: p++;\n\t  /* fallthrough */\n\tcase DASM_REL_PC: {\n\t  int shrink = op == 0xe9 ? 3 : ((op&0xf0) == 0x80 ? 4 : 0);\n\t  if (shrink) {  /* Shrinkable branch opcode? */\n\t    int lofs, lpos = b[pos];\n\t    if (lpos < 0) goto noshrink;  /* Ext global? */\n\t    lofs = *DASM_POS2PTR(D, lpos);\n\t    if (lpos > pos) {  /* Fwd label: add cumulative section offsets. */\n\t      int i;\n\t      for (i = secnum; i < DASM_POS2SEC(lpos); i++)\n\t\tlofs += D->sections[i].ofs;\n\t    } else {\n\t      lofs -= ofs;  /* Bkwd label: unfix offset. */\n\t    }\n\t    lofs -= b[pos+1];  /* Short branch ok? */\n\t    if (lofs >= -128-shrink && lofs <= 127) ofs -= shrink;  /* Yes. */\n\t    else { noshrink: shrink = 0; }  /* No, cannot shrink op. */\n\t  }\n\t  b[pos+1] = shrink;\n\t  pos += 2;\n\t  break;\n\t}\n\t  /* fallthrough */\n\tcase DASM_SPACE: case DASM_IMM_LG: case DASM_VREG: p++;\n\t  /* fallthrough */\n\tcase DASM_DISP: case DASM_IMM_S: case DASM_IMM_B: case DASM_IMM_W:\n\tcase DASM_IMM_D: case DASM_IMM_WB: case DASM_IMM_DB:\n\tcase DASM_SETLABEL: case DASM_REL_A: case DASM_IMM_PC: pos++; break;\n\tcase DASM_LABEL_LG: p++;\n\t  /* fallthrough */\n\tcase DASM_LABEL_PC: b[pos++] += ofs; break; /* Fix label offset. */\n\tcase DASM_ALIGN: ofs -= (b[pos++]+ofs)&*p++; break; /* Adjust ofs. */\n\tcase DASM_EXTERN: p += 2; break;\n\tcase DASM_ESC: op = *p++; break;\n\tcase DASM_MARK: break;\n\tcase DASM_SECTION: case DASM_STOP: goto stop;\n\tdefault: op = action; break;\n\t}\n      }\n      stop: (void)0;\n    }\n    ofs += sec->ofs;  /* Next section starts right after current section. */\n  }\n\n  D->codesize = ofs;  /* Total size of all code sections */\n  *szp = ofs;\n  return DASM_S_OK;\n}\n\n#define dasmb(x)\t*cp++ = (unsigned char)(x)\n#ifndef DASM_ALIGNED_WRITES\n#define dasmw(x) \\\n  do { *((unsigned short *)cp) = (unsigned short)(x); cp+=2; } while (0)\n#define dasmd(x) \\\n  do { *((unsigned int *)cp) = (unsigned int)(x); cp+=4; } while (0)\n#define dasmq(x) \\\n  do { *((unsigned long long *)cp) = (unsigned long long)(x); cp+=8; } while (0)\n#else\n#define dasmw(x)\tdo { dasmb(x); dasmb((x)>>8); } while (0)\n#define dasmd(x)\tdo { dasmw(x); dasmw((x)>>16); } while (0)\n#define dasmq(x)\tdo { dasmd(x); dasmd((x)>>32); } while (0)\n#endif\nstatic unsigned char *dasma_(unsigned char *cp, ptrdiff_t x)\n{\n  if (sizeof(ptrdiff_t) == 8)\n    dasmq((unsigned long long)x);\n  else\n    dasmd((unsigned int)x);\n  return cp;\n}\n#define dasma(x)\t(cp = dasma_(cp, (x)))\n\n/* Pass 3: Encode sections. */\nint dasm_encode(Dst_DECL, void *buffer)\n{\n  dasm_State *D = Dst_REF;\n  unsigned char *base = (unsigned char *)buffer;\n  unsigned char *cp = base;\n  int secnum;\n\n  /* Encode all code sections. No support for data sections (yet). */\n  for (secnum = 0; secnum < D->maxsection; secnum++) {\n    dasm_Section *sec = D->sections + secnum;\n    int *b = sec->buf;\n    int *endb = sec->rbuf + sec->pos;\n\n    while (b != endb) {\n      dasm_ActList p = D->actionlist + *b++;\n      unsigned char *mark = NULL;\n      while (1) {\n\tint action = *p++;\n\tint n = (action >= DASM_DISP && action <= DASM_ALIGN) ? *b++ : 0;\n\tswitch (action) {\n\tcase DASM_DISP: if (!mark) mark = cp; {\n\t  unsigned char *mm = mark;\n\t  if (*p != DASM_IMM_DB && *p != DASM_IMM_WB) mark = NULL;\n\t  if (n == 0) { int mrm = mm[-1]&7; if (mrm == 4) mrm = mm[0]&7;\n\t    if (mrm != 5) { mm[-1] -= 0x80; break; } }\n\t  if (((n+128) & -256) != 0) goto wd; else mm[-1] -= 0x40;\n\t}\n\t  /* fallthrough */\n\tcase DASM_IMM_S: case DASM_IMM_B: wb: dasmb(n); break;\n\tcase DASM_IMM_DB: if (((n+128)&-256) == 0) {\n\t    db: if (!mark) mark = cp; mark[-2] += 2; mark = NULL; goto wb;\n\t  } else mark = NULL;\n\t  /* fallthrough */\n\tcase DASM_IMM_D: wd: dasmd(n); break;\n\tcase DASM_IMM_WB: if (((n+128)&-256) == 0) goto db; else mark = NULL;\n\t  /* fallthrough */\n\tcase DASM_IMM_W: dasmw(n); break;\n\tcase DASM_VREG: {\n\t  int t = *p++;\n\t  unsigned char *ex = cp - (t&7);\n\t  if ((n & 8) && t < 0xa0) {\n\t    if (*ex & 0x80) ex[1] ^= 0x20 << (t>>6); else *ex ^= 1 << (t>>6);\n\t    n &= 7;\n\t  } else if (n & 0x10) {\n\t    if (*ex & 0x80) {\n\t      *ex = 0xc5; ex[1] = (ex[1] & 0x80) | ex[2]; ex += 2;\n\t    }\n\t    while (++ex < cp) ex[-1] = *ex;\n\t    if (mark) mark--;\n\t    cp--;\n\t    n &= 7;\n\t  }\n\t  if (t >= 0xc0) n <<= 4;\n\t  else if (t >= 0x40) n <<= 3;\n\t  else if (n == 4 && t < 0x20) { cp[-1] ^= n; *cp++ = 0x20; }\n\t  cp[-1] ^= n;\n\t  break;\n\t}\n\tcase DASM_REL_LG: p++; if (n >= 0) goto rel_pc;\n\t  b++; n = (int)(ptrdiff_t)D->globals[-n];\n\t  /* fallthrough */\n\tcase DASM_REL_A: rel_a:\n\t  n -= (unsigned int)(ptrdiff_t)(cp+4); goto wd; /* !x64 */\n\tcase DASM_REL_PC: rel_pc: {\n\t  int shrink = *b++;\n\t  int *pb = DASM_POS2PTR(D, n); if (*pb < 0) { n = pb[1]; goto rel_a; }\n\t  n = *pb - ((int)(cp-base) + 4-shrink);\n\t  if (shrink == 0) goto wd;\n\t  if (shrink == 4) { cp--; cp[-1] = *cp-0x10; } else cp[-1] = 0xeb;\n\t  goto wb;\n\t}\n\tcase DASM_IMM_LG:\n\t  p++;\n\t  if (n < 0) { dasma((ptrdiff_t)D->globals[-n]); break; }\n\t  /* fallthrough */\n\tcase DASM_IMM_PC: {\n\t  int *pb = DASM_POS2PTR(D, n);\n\t  dasma(*pb < 0 ? (ptrdiff_t)pb[1] : (*pb + (ptrdiff_t)base));\n\t  break;\n\t}\n\tcase DASM_LABEL_LG: {\n\t  int idx = *p++;\n\t  if (idx >= 10)\n\t    D->globals[idx] = (void *)(base + (*p == DASM_SETLABEL ? *b : n));\n\t  break;\n\t}\n\tcase DASM_LABEL_PC: case DASM_SETLABEL: break;\n\tcase DASM_SPACE: { int fill = *p++; while (n--) *cp++ = fill; break; }\n\tcase DASM_ALIGN:\n\t  n = *p++;\n\t  while (((cp-base) & n)) *cp++ = 0x90; /* nop */\n\t  break;\n\tcase DASM_EXTERN: n = DASM_EXTERN(Dst, cp, p[1], *p); p += 2; goto wd;\n\tcase DASM_MARK: mark = cp; break;\n\tcase DASM_ESC: action = *p++;\n\t  /* fallthrough */\n\tdefault: *cp++ = action; break;\n\tcase DASM_SECTION: case DASM_STOP: goto stop;\n\t}\n      }\n      stop: (void)0;\n    }\n  }\n\n  if (base + D->codesize != cp)  /* Check for phase errors. */\n    return DASM_S_PHASE;\n  return DASM_S_OK;\n}\n\n/* Get PC label offset. */\nint dasm_getpclabel(Dst_DECL, unsigned int pc)\n{\n  dasm_State *D = Dst_REF;\n  if (pc*sizeof(int) < D->pcsize) {\n    int pos = D->pclabels[pc];\n    if (pos < 0) return *DASM_POS2PTR(D, -pos);\n    if (pos > 0) return -1;  /* Undefined. */\n  }\n  return -2;  /* Unused or out of range. */\n}\n\n#ifdef DASM_CHECKS\n/* Optional sanity checker to call between isolated encoding steps. */\nint dasm_checkstep(Dst_DECL, int secmatch)\n{\n  dasm_State *D = Dst_REF;\n  if (D->status == DASM_S_OK) {\n    int i;\n    for (i = 1; i <= 9; i++) {\n      if (D->lglabels[i] > 0) { D->status = DASM_S_UNDEF_L|i; break; }\n      D->lglabels[i] = 0;\n    }\n  }\n  if (D->status == DASM_S_OK && secmatch >= 0 &&\n      D->section != &D->sections[secmatch])\n    D->status = DASM_S_MATCH_SEC|(int)(D->section-D->sections);\n  return D->status;\n}\n#endif\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dasm_x86.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM x86/x64 module.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See dynasm.lua for full copyright notice.\n------------------------------------------------------------------------------\n\nlocal x64 = x64\n\n-- Module information:\nlocal _info = {\n  arch =\tx64 and \"x64\" or \"x86\",\n  description =\t\"DynASM x86/x64 module\",\n  version =\t\"1.5.0\",\n  vernum =\t 10500,\n  release =\t\"2021-05-02\",\n  author =\t\"Mike Pall\",\n  license =\t\"MIT\",\n}\n\n-- Exported glue functions for the arch-specific module.\nlocal _M = { _info = _info }\n\n-- Cache library functions.\nlocal type, tonumber, pairs, ipairs = type, tonumber, pairs, ipairs\nlocal assert, unpack, setmetatable = assert, unpack or table.unpack, setmetatable\nlocal _s = string\nlocal sub, format, byte, char = _s.sub, _s.format, _s.byte, _s.char\nlocal find, match, gmatch, gsub = _s.find, _s.match, _s.gmatch, _s.gsub\nlocal concat, sort, remove = table.concat, table.sort, table.remove\nlocal bit = bit or require(\"bit\")\nlocal band, bxor, shl, shr = bit.band, bit.bxor, bit.lshift, bit.rshift\n\n-- Inherited tables and callbacks.\nlocal g_opt, g_arch\nlocal wline, werror, wfatal, wwarn\n\n-- Action name list.\n-- CHECK: Keep this in sync with the C code!\nlocal action_names = {\n  -- int arg, 1 buffer pos:\n  \"DISP\",  \"IMM_S\", \"IMM_B\", \"IMM_W\", \"IMM_D\",  \"IMM_WB\", \"IMM_DB\",\n  -- action arg (1 byte), int arg, 1 buffer pos (reg/num):\n  \"VREG\", \"SPACE\",\n  -- ptrdiff_t arg, 1 buffer pos (address): !x64\n  \"SETLABEL\", \"REL_A\",\n  -- action arg (1 byte) or int arg, 2 buffer pos (link, offset):\n  \"REL_LG\", \"REL_PC\",\n  -- action arg (1 byte) or int arg, 1 buffer pos (link):\n  \"IMM_LG\", \"IMM_PC\",\n  -- action arg (1 byte) or int arg, 1 buffer pos (offset):\n  \"LABEL_LG\", \"LABEL_PC\",\n  -- action arg (1 byte), 1 buffer pos (offset):\n  \"ALIGN\",\n  -- action args (2 bytes), no buffer pos.\n  \"EXTERN\",\n  -- action arg (1 byte), no buffer pos.\n  \"ESC\",\n  -- no action arg, no buffer pos.\n  \"MARK\",\n  -- action arg (1 byte), no buffer pos, terminal action:\n  \"SECTION\",\n  -- no args, no buffer pos, terminal action:\n  \"STOP\"\n}\n\n-- Maximum number of section buffer positions for dasm_put().\n-- CHECK: Keep this in sync with the C code!\nlocal maxsecpos = 25 -- Keep this low, to avoid excessively long C lines.\n\n-- Action name -> action number (dynamically generated below).\nlocal map_action = {}\n-- First action number. Everything below does not need to be escaped.\nlocal actfirst = 256-#action_names\n\n-- Action list buffer and string (only used to remove dupes).\nlocal actlist = {}\nlocal actstr = \"\"\n\n-- Argument list for next dasm_put(). Start with offset 0 into action list.\nlocal actargs = { 0 }\n\n-- Current number of section buffer positions for dasm_put().\nlocal secpos = 1\n\n-- VREG kind encodings, pre-shifted by 5 bits.\nlocal map_vreg = {\n  [\"modrm.rm.m\"] = 0x00,\n  [\"modrm.rm.r\"] = 0x20,\n  [\"opcode\"] =     0x20,\n  [\"sib.base\"] =   0x20,\n  [\"sib.index\"] =  0x40,\n  [\"modrm.reg\"] =  0x80,\n  [\"vex.v\"] =      0xa0,\n  [\"imm.hi\"] =     0xc0,\n}\n\n-- Current number of VREG actions contributing to REX/VEX shrinkage.\nlocal vreg_shrink_count = 0\n\n------------------------------------------------------------------------------\n\n-- Compute action numbers for action names.\nfor n,name in ipairs(action_names) do\n  local num = actfirst + n - 1\n  map_action[name] = num\nend\n\n-- Dump action names and numbers.\nlocal function dumpactions(out)\n  out:write(\"DynASM encoding engine action codes:\\n\")\n  for n,name in ipairs(action_names) do\n    local num = map_action[name]\n    out:write(format(\"  %-10s %02X  %d\\n\", name, num, num))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write action list buffer as a huge static C array.\nlocal function writeactions(out, name)\n  local nn = #actlist\n  local last = actlist[nn] or 255\n  actlist[nn] = nil -- Remove last byte.\n  if nn == 0 then nn = 1 end\n  out:write(\"static const unsigned char \", name, \"[\", nn, \"] = {\\n\")\n  local s = \"  \"\n  for n,b in ipairs(actlist) do\n    s = s..b..\",\"\n    if #s >= 75 then\n      assert(out:write(s, \"\\n\"))\n      s = \"  \"\n    end\n  end\n  out:write(s, last, \"\\n};\\n\\n\") -- Add last byte back.\nend\n\n------------------------------------------------------------------------------\n\n-- Add byte to action list.\nlocal function wputxb(n)\n  assert(n >= 0 and n <= 255 and n % 1 == 0, \"byte out of range\")\n  actlist[#actlist+1] = n\nend\n\n-- Add action to list with optional arg. Advance buffer pos, too.\nlocal function waction(action, a, num)\n  wputxb(assert(map_action[action], \"bad action name `\"..action..\"'\"))\n  if a then actargs[#actargs+1] = a end\n  if a or num then secpos = secpos + (num or 1) end\nend\n\n-- Optionally add a VREG action.\nlocal function wvreg(kind, vreg, psz, sk, defer)\n  if not vreg then return end\n  waction(\"VREG\", vreg)\n  local b = assert(map_vreg[kind], \"bad vreg kind `\"..vreg..\"'\")\n  if b < (sk or 0) then\n    vreg_shrink_count = vreg_shrink_count + 1\n  end\n  if not defer then\n    b = b + vreg_shrink_count * 8\n    vreg_shrink_count = 0\n  end\n  wputxb(b + (psz or 0))\nend\n\n-- Add call to embedded DynASM C code.\nlocal function wcall(func, args)\n  wline(format(\"dasm_%s(Dst, %s);\", func, concat(args, \", \")), true)\nend\n\n-- Delete duplicate action list chunks. A tad slow, but so what.\nlocal function dedupechunk(offset)\n  local al, as = actlist, actstr\n  local chunk = char(unpack(al, offset+1, #al))\n  local orig = find(as, chunk, 1, true)\n  if orig then\n    actargs[1] = orig-1 -- Replace with original offset.\n    for i=offset+1,#al do al[i] = nil end -- Kill dupe.\n  else\n    actstr = as..chunk\n  end\nend\n\n-- Flush action list (intervening C code or buffer pos overflow).\nlocal function wflush(term)\n  local offset = actargs[1]\n  if #actlist == offset then return end -- Nothing to flush.\n  if not term then waction(\"STOP\") end -- Terminate action list.\n  dedupechunk(offset)\n  wcall(\"put\", actargs) -- Add call to dasm_put().\n  actargs = { #actlist } -- Actionlist offset is 1st arg to next dasm_put().\n  secpos = 1 -- The actionlist offset occupies a buffer position, too.\nend\n\n-- Put escaped byte.\nlocal function wputb(n)\n  if n >= actfirst then waction(\"ESC\") end -- Need to escape byte.\n  wputxb(n)\nend\n\n------------------------------------------------------------------------------\n\n-- Global label name -> global label number. With auto assignment on 1st use.\nlocal next_global = 10\nlocal map_global = setmetatable({}, { __index = function(t, name)\n  if not match(name, \"^[%a_][%w_@]*$\") then werror(\"bad global label\") end\n  local n = next_global\n  if n > 246 then werror(\"too many global labels\") end\n  next_global = n + 1\n  t[name] = n\n  return n\nend})\n\n-- Dump global labels.\nlocal function dumpglobals(out, lvl)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"Global labels:\\n\")\n  for i=10,next_global-1 do\n    out:write(format(\"  %s\\n\", t[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write global label enum.\nlocal function writeglobals(out, prefix)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"enum {\\n\")\n  for i=10,next_global-1 do\n    out:write(\"  \", prefix, gsub(t[i], \"@.*\", \"\"), \",\\n\")\n  end\n  out:write(\"  \", prefix, \"_MAX\\n};\\n\")\nend\n\n-- Write global label names.\nlocal function writeglobalnames(out, name)\n  local t = {}\n  for name, n in pairs(map_global) do t[n] = name end\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=10,next_global-1 do\n    out:write(\"  \\\"\", t[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Extern label name -> extern label number. With auto assignment on 1st use.\nlocal next_extern = -1\nlocal map_extern = setmetatable({}, { __index = function(t, name)\n  -- No restrictions on the name for now.\n  local n = next_extern\n  if n < -256 then werror(\"too many extern labels\") end\n  next_extern = n - 1\n  t[name] = n\n  return n\nend})\n\n-- Dump extern labels.\nlocal function dumpexterns(out, lvl)\n  local t = {}\n  for name, n in pairs(map_extern) do t[-n] = name end\n  out:write(\"Extern labels:\\n\")\n  for i=1,-next_extern-1 do\n    out:write(format(\"  %s\\n\", t[i]))\n  end\n  out:write(\"\\n\")\nend\n\n-- Write extern label names.\nlocal function writeexternnames(out, name)\n  local t = {}\n  for name, n in pairs(map_extern) do t[-n] = name end\n  out:write(\"static const char *const \", name, \"[] = {\\n\")\n  for i=1,-next_extern-1 do\n    out:write(\"  \\\"\", t[i], \"\\\",\\n\")\n  end\n  out:write(\"  (const char *)0\\n};\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Arch-specific maps.\nlocal map_archdef = {}\t\t-- Ext. register name -> int. name.\nlocal map_reg_rev = {}\t\t-- Int. register name -> ext. name.\nlocal map_reg_num = {}\t\t-- Int. register name -> register number.\nlocal map_reg_opsize = {}\t-- Int. register name -> operand size.\nlocal map_reg_valid_base = {}\t-- Int. register name -> valid base register?\nlocal map_reg_valid_index = {}\t-- Int. register name -> valid index register?\nlocal map_reg_needrex = {}\t-- Int. register name -> need rex vs. no rex.\nlocal reg_list = {}\t\t-- Canonical list of int. register names.\n\nlocal map_type = {}\t\t-- Type name -> { ctype, reg }\nlocal ctypenum = 0\t\t-- Type number (for _PTx macros).\n\nlocal addrsize = x64 and \"q\" or \"d\"\t-- Size for address operands.\n\n-- Helper functions to fill register maps.\nlocal function mkrmap(sz, cl, names)\n  local cname = format(\"@%s\", sz)\n  reg_list[#reg_list+1] = cname\n  map_archdef[cl] = cname\n  map_reg_rev[cname] = cl\n  map_reg_num[cname] = -1\n  map_reg_opsize[cname] = sz\n  if sz == addrsize or sz == \"d\" then\n    map_reg_valid_base[cname] = true\n    map_reg_valid_index[cname] = true\n  end\n  if names then\n    for n,name in ipairs(names) do\n      local iname = format(\"@%s%x\", sz, n-1)\n      reg_list[#reg_list+1] = iname\n      map_archdef[name] = iname\n      map_reg_rev[iname] = name\n      map_reg_num[iname] = n-1\n      map_reg_opsize[iname] = sz\n      if sz == \"b\" and n > 4 then map_reg_needrex[iname] = false end\n      if sz == addrsize or sz == \"d\" then\n\tmap_reg_valid_base[iname] = true\n\tmap_reg_valid_index[iname] = true\n      end\n    end\n  end\n  for i=0,(x64 and sz ~= \"f\") and 15 or 7 do\n    local needrex = sz == \"b\" and i > 3\n    local iname = format(\"@%s%x%s\", sz, i, needrex and \"R\" or \"\")\n    if needrex then map_reg_needrex[iname] = true end\n    local name\n    if sz == \"o\" or sz == \"y\" then name = format(\"%s%d\", cl, i)\n    elseif sz == \"f\" then name = format(\"st%d\", i)\n    else name = format(\"r%d%s\", i, sz == addrsize and \"\" or sz) end\n    map_archdef[name] = iname\n    if not map_reg_rev[iname] then\n      reg_list[#reg_list+1] = iname\n      map_reg_rev[iname] = name\n      map_reg_num[iname] = i\n      map_reg_opsize[iname] = sz\n      if sz == addrsize or sz == \"d\" then\n\tmap_reg_valid_base[iname] = true\n\tmap_reg_valid_index[iname] = true\n      end\n    end\n  end\n  reg_list[#reg_list+1] = \"\"\nend\n\n-- Integer registers (qword, dword, word and byte sized).\nif x64 then\n  mkrmap(\"q\", \"Rq\", {\"rax\", \"rcx\", \"rdx\", \"rbx\", \"rsp\", \"rbp\", \"rsi\", \"rdi\"})\nend\nmkrmap(\"d\", \"Rd\", {\"eax\", \"ecx\", \"edx\", \"ebx\", \"esp\", \"ebp\", \"esi\", \"edi\"})\nmkrmap(\"w\", \"Rw\", {\"ax\", \"cx\", \"dx\", \"bx\", \"sp\", \"bp\", \"si\", \"di\"})\nmkrmap(\"b\", \"Rb\", {\"al\", \"cl\", \"dl\", \"bl\", \"ah\", \"ch\", \"dh\", \"bh\"})\nmap_reg_valid_index[map_archdef.esp] = false\nif x64 then map_reg_valid_index[map_archdef.rsp] = false end\nif x64 then map_reg_needrex[map_archdef.Rb] = true end\nmap_archdef[\"Ra\"] = \"@\"..addrsize\n\n-- FP registers (internally tword sized, but use \"f\" as operand size).\nmkrmap(\"f\", \"Rf\")\n\n-- SSE registers (oword sized, but qword and dword accessible).\nmkrmap(\"o\", \"xmm\")\n\n-- AVX registers (yword sized, but oword, qword and dword accessible).\nmkrmap(\"y\", \"ymm\")\n\n-- Operand size prefixes to codes.\nlocal map_opsize = {\n  byte = \"b\", word = \"w\", dword = \"d\", qword = \"q\", oword = \"o\", yword = \"y\",\n  tword = \"t\", aword = addrsize,\n}\n\n-- Operand size code to number.\nlocal map_opsizenum = {\n  b = 1, w = 2, d = 4, q = 8, o = 16, y = 32, t = 10,\n}\n\n-- Operand size code to name.\nlocal map_opsizename = {\n  b = \"byte\", w = \"word\", d = \"dword\", q = \"qword\", o = \"oword\", y = \"yword\",\n  t = \"tword\", f = \"fpword\",\n}\n\n-- Valid index register scale factors.\nlocal map_xsc = {\n  [\"1\"] = 0, [\"2\"] = 1, [\"4\"] = 2, [\"8\"] = 3,\n}\n\n-- Condition codes.\nlocal map_cc = {\n  o = 0, no = 1, b = 2, nb = 3, e = 4, ne = 5, be = 6, nbe = 7,\n  s = 8, ns = 9, p = 10, np = 11, l = 12, nl = 13, le = 14, nle = 15,\n  c = 2, nae = 2, nc = 3, ae = 3, z = 4, nz = 5, na = 6, a = 7,\n  pe = 10, po = 11, nge = 12, ge = 13, ng = 14, g = 15,\n}\n\n\n-- Reverse defines for registers.\nfunction _M.revdef(s)\n  return gsub(s, \"@%w+\", map_reg_rev)\nend\n\n-- Dump register names and numbers\nlocal function dumpregs(out)\n  out:write(\"Register names, sizes and internal numbers:\\n\")\n  for _,reg in ipairs(reg_list) do\n    if reg == \"\" then\n      out:write(\"\\n\")\n    else\n      local name = map_reg_rev[reg]\n      local num = map_reg_num[reg]\n      local opsize = map_opsizename[map_reg_opsize[reg]]\n      out:write(format(\"  %-5s %-8s %s\\n\", name, opsize,\n\t\t       num < 0 and \"(variable)\" or num))\n    end\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Put action for label arg (IMM_LG, IMM_PC, REL_LG, REL_PC).\nlocal function wputlabel(aprefix, imm, num)\n  if type(imm) == \"number\" then\n    if imm < 0 then\n      waction(\"EXTERN\")\n      wputxb(aprefix == \"IMM_\" and 0 or 1)\n      imm = -imm-1\n    else\n      waction(aprefix..\"LG\", nil, num);\n    end\n    wputxb(imm)\n  else\n    waction(aprefix..\"PC\", imm, num)\n  end\nend\n\n-- Put signed byte or arg.\nlocal function wputsbarg(n)\n  if type(n) == \"number\" then\n    if n < -128 or n > 127 then\n      werror(\"signed immediate byte out of range\")\n    end\n    if n < 0 then n = n + 256 end\n    wputb(n)\n  else waction(\"IMM_S\", n) end\nend\n\n-- Put unsigned byte or arg.\nlocal function wputbarg(n)\n  if type(n) == \"number\" then\n    if n < 0 or n > 255 then\n      werror(\"unsigned immediate byte out of range\")\n    end\n    wputb(n)\n  else waction(\"IMM_B\", n) end\nend\n\n-- Put unsigned word or arg.\nlocal function wputwarg(n)\n  if type(n) == \"number\" then\n    if shr(n, 16) ~= 0 then\n      werror(\"unsigned immediate word out of range\")\n    end\n    wputb(band(n, 255)); wputb(shr(n, 8));\n  else waction(\"IMM_W\", n) end\nend\n\n-- Put signed or unsigned dword or arg.\nlocal function wputdarg(n)\n  local tn = type(n)\n  if tn == \"number\" then\n    wputb(band(n, 255))\n    wputb(band(shr(n, 8), 255))\n    wputb(band(shr(n, 16), 255))\n    wputb(shr(n, 24))\n  elseif tn == \"table\" then\n    wputlabel(\"IMM_\", n[1], 1)\n  else\n    waction(\"IMM_D\", n)\n  end\nend\n\n-- Put signed or unsigned qword or arg.\nlocal function wputqarg(n)\n  local tn = type(n)\n  if tn == \"number\" then -- This is only used for numbers from -2^31..2^32-1.\n    wputb(band(n, 255))\n    wputb(band(shr(n, 8), 255))\n    wputb(band(shr(n, 16), 255))\n    wputb(shr(n, 24))\n    local sign = n < 0 and 255 or 0\n    wputb(sign); wputb(sign); wputb(sign); wputb(sign)\n  else\n    waction(\"IMM_D\", format(\"(unsigned int)(%s)\", n))\n    waction(\"IMM_D\", format(\"(unsigned int)((unsigned long long)(%s)>>32)\", n))\n  end\nend\n\n-- Put operand-size dependent number or arg (defaults to dword).\nlocal function wputszarg(sz, n)\n  if not sz or sz == \"d\" or sz == \"q\" then wputdarg(n)\n  elseif sz == \"w\" then wputwarg(n)\n  elseif sz == \"b\" then wputbarg(n)\n  elseif sz == \"s\" then wputsbarg(n)\n  else werror(\"bad operand size\") end\nend\n\n-- Put multi-byte opcode with operand-size dependent modifications.\nlocal function wputop(sz, op, rex, vex, vregr, vregxb)\n  local psz, sk = 0, nil\n  if vex then\n    local tail\n    if vex.m == 1 and band(rex, 11) == 0 then\n      if x64 and vregxb then\n\tsk = map_vreg[\"modrm.reg\"]\n      else\n\twputb(0xc5)\n      tail = shl(bxor(band(rex, 4), 4), 5)\n      psz = 3\n      end\n    end\n    if not tail then\n      wputb(0xc4)\n      wputb(shl(bxor(band(rex, 7), 7), 5) + vex.m)\n      tail = shl(band(rex, 8), 4)\n      psz = 4\n    end\n    local reg, vreg = 0, nil\n    if vex.v then\n      reg = vex.v.reg\n      if not reg then werror(\"bad vex operand\") end\n      if reg < 0 then reg = 0; vreg = vex.v.vreg end\n    end\n    if sz == \"y\" or vex.l then tail = tail + 4 end\n    wputb(tail + shl(bxor(reg, 15), 3) + vex.p)\n    wvreg(\"vex.v\", vreg)\n    rex = 0\n    if op >= 256 then werror(\"bad vex opcode\") end\n  else\n    if rex ~= 0 then\n      if not x64 then werror(\"bad operand size\") end\n    elseif (vregr or vregxb) and x64 then\n      rex = 0x10\n      sk = map_vreg[\"vex.v\"]\n    end\n  end\n  local r\n  if sz == \"w\" then wputb(102) end\n  -- Needs >32 bit numbers, but only for crc32 eax, word [ebx]\n  if op >= 4294967296 then r = op%4294967296 wputb((op-r)/4294967296) op = r end\n  if op >= 16777216 then wputb(shr(op, 24)); op = band(op, 0xffffff) end\n  if op >= 65536 then\n    if rex ~= 0 then\n      local opc3 = band(op, 0xffff00)\n      if opc3 == 0x0f3a00 or opc3 == 0x0f3800 then\n\twputb(64 + band(rex, 15)); rex = 0; psz = 2\n      end\n    end\n    wputb(shr(op, 16)); op = band(op, 0xffff); psz = psz + 1\n  end\n  if op >= 256 then\n    local b = shr(op, 8)\n    if b == 15 and rex ~= 0 then wputb(64 + band(rex, 15)); rex = 0; psz = 2 end\n    wputb(b); op = band(op, 255); psz = psz + 1\n  end\n  if rex ~= 0 then wputb(64 + band(rex, 15)); psz = 2 end\n  if sz == \"b\" then op = op - 1 end\n  wputb(op)\n  return psz, sk\nend\n\n-- Put ModRM or SIB formatted byte.\nlocal function wputmodrm(m, s, rm, vs, vrm)\n  assert(m < 4 and s < 16 and rm < 16, \"bad modrm operands\")\n  wputb(shl(m, 6) + shl(band(s, 7), 3) + band(rm, 7))\nend\n\n-- Put ModRM/SIB plus optional displacement.\nlocal function wputmrmsib(t, imark, s, vsreg, psz, sk)\n  local vreg, vxreg\n  local reg, xreg = t.reg, t.xreg\n  if reg and reg < 0 then reg = 0; vreg = t.vreg end\n  if xreg and xreg < 0 then xreg = 0; vxreg = t.vxreg end\n  if s < 0 then s = 0 end\n\n  -- Register mode.\n  if sub(t.mode, 1, 1) == \"r\" then\n    wputmodrm(3, s, reg)\n    wvreg(\"modrm.reg\", vsreg, psz+1, sk, vreg)\n    wvreg(\"modrm.rm.r\", vreg, psz+1, sk)\n    return\n  end\n\n  local disp = t.disp\n  local tdisp = type(disp)\n  -- No base register?\n  if not reg then\n    local riprel = false\n    if xreg then\n      -- Indexed mode with index register only.\n      -- [xreg*xsc+disp] -> (0, s, esp) (xsc, xreg, ebp)\n      wputmodrm(0, s, 4)\n      if imark == \"I\" then waction(\"MARK\") end\n      wvreg(\"modrm.reg\", vsreg, psz+1, sk, vxreg)\n      wputmodrm(t.xsc, xreg, 5)\n      wvreg(\"sib.index\", vxreg, psz+2, sk)\n    else\n      -- Pure 32 bit displacement.\n      if x64 and tdisp ~= \"table\" then\n\twputmodrm(0, s, 4) -- [disp] -> (0, s, esp) (0, esp, ebp)\n\twvreg(\"modrm.reg\", vsreg, psz+1, sk)\n\tif imark == \"I\" then waction(\"MARK\") end\n\twputmodrm(0, 4, 5)\n      else\n\triprel = x64\n\twputmodrm(0, s, 5) -- [disp|rip-label] -> (0, s, ebp)\n\twvreg(\"modrm.reg\", vsreg, psz+1, sk)\n\tif imark == \"I\" then waction(\"MARK\") end\n      end\n    end\n    if riprel then -- Emit rip-relative displacement.\n      if match(\"UWSiI\", imark) then\n\twerror(\"NYI: rip-relative displacement followed by immediate\")\n      end\n      -- The previous byte in the action buffer cannot be 0xe9 or 0x80-0x8f.\n      wputlabel(\"REL_\", disp[1], 2)\n    else\n      wputdarg(disp)\n    end\n    return\n  end\n\n  local m\n  if tdisp == \"number\" then -- Check displacement size at assembly time.\n    if disp == 0 and band(reg, 7) ~= 5 then -- [ebp] -> [ebp+0] (in SIB, too)\n      if not vreg then m = 0 end -- Force DISP to allow [Rd(5)] -> [ebp+0]\n    elseif disp >= -128 and disp <= 127 then m = 1\n    else m = 2 end\n  elseif tdisp == \"table\" then\n    m = 2\n  end\n\n  -- Index register present or esp as base register: need SIB encoding.\n  if xreg or band(reg, 7) == 4 then\n    wputmodrm(m or 2, s, 4) -- ModRM.\n    if m == nil or imark == \"I\" then waction(\"MARK\") end\n    wvreg(\"modrm.reg\", vsreg, psz+1, sk, vxreg or vreg)\n    wputmodrm(t.xsc or 0, xreg or 4, reg) -- SIB.\n    wvreg(\"sib.index\", vxreg, psz+2, sk, vreg)\n    wvreg(\"sib.base\", vreg, psz+2, sk)\n  else\n    wputmodrm(m or 2, s, reg) -- ModRM.\n    if (imark == \"I\" and (m == 1 or m == 2)) or\n       (m == nil and (vsreg or vreg)) then waction(\"MARK\") end\n    wvreg(\"modrm.reg\", vsreg, psz+1, sk, vreg)\n    wvreg(\"modrm.rm.m\", vreg, psz+1, sk)\n  end\n\n  -- Put displacement.\n  if m == 1 then wputsbarg(disp)\n  elseif m == 2 then wputdarg(disp)\n  elseif m == nil then waction(\"DISP\", disp) end\nend\n\n------------------------------------------------------------------------------\n\n-- Return human-readable operand mode string.\nlocal function opmodestr(op, args)\n  local m = {}\n  for i=1,#args do\n    local a = args[i]\n    m[#m+1] = sub(a.mode, 1, 1)..(a.opsize or \"?\")\n  end\n  return op..\" \"..concat(m, \",\")\nend\n\n-- Convert number to valid integer or nil.\nlocal function toint(expr, isqword)\n  local n = tonumber(expr)\n  if n then\n    if n % 1 ~= 0 then\n      werror(\"not an integer number `\"..expr..\"'\")\n    elseif isqword then\n      if n < -2147483648 or n > 2147483647 then\n\tn = nil -- Handle it as an expression to avoid precision loss.\n      end\n    elseif n < -2147483648 or n > 4294967295 then\n      werror(\"bad integer number `\"..expr..\"'\")\n    end\n    return n\n  end\nend\n\n-- Parse immediate expression.\nlocal function immexpr(expr)\n  -- &expr (pointer)\n  if sub(expr, 1, 1) == \"&\" then\n    return \"iPJ\", format(\"(ptrdiff_t)(%s)\", sub(expr,2))\n  end\n\n  local prefix = sub(expr, 1, 2)\n  -- =>expr (pc label reference)\n  if prefix == \"=>\" then\n    return \"iJ\", sub(expr, 3)\n  end\n  -- ->name (global label reference)\n  if prefix == \"->\" then\n    return \"iJ\", map_global[sub(expr, 3)]\n  end\n\n  -- [<>][1-9] (local label reference)\n  local dir, lnum = match(expr, \"^([<>])([1-9])$\")\n  if dir then -- Fwd: 247-255, Bkwd: 1-9.\n    return \"iJ\", lnum + (dir == \">\" and 246 or 0)\n  end\n\n  local extname = match(expr, \"^extern%s+(%S+)$\")\n  if extname then\n    return \"iJ\", map_extern[extname]\n  end\n\n  -- expr (interpreted as immediate)\n  return \"iI\", expr\nend\n\n-- Parse displacement expression: +-num, +-expr, +-opsize*num\nlocal function dispexpr(expr)\n  local disp = expr == \"\" and 0 or toint(expr)\n  if disp then return disp end\n  local c, dispt = match(expr, \"^([+-])%s*(.+)$\")\n  if c == \"+\" then\n    expr = dispt\n  elseif not c then\n    werror(\"bad displacement expression `\"..expr..\"'\")\n  end\n  local opsize, tailops = match(dispt, \"^(%w+)%s*%*%s*(.+)$\")\n  local ops, imm = map_opsize[opsize], toint(tailops)\n  if ops and imm then\n    if c == \"-\" then imm = -imm end\n    return imm*map_opsizenum[ops]\n  end\n  local mode, iexpr = immexpr(dispt)\n  if mode == \"iJ\" then\n    if c == \"-\" then werror(\"cannot invert label reference\") end\n    return { iexpr }\n  end\n  return expr -- Need to return original signed expression.\nend\n\n-- Parse register or type expression.\nlocal function rtexpr(expr)\n  if not expr then return end\n  local tname, ovreg = match(expr, \"^([%w_]+):(@[%w_]+)$\")\n  local tp = map_type[tname or expr]\n  if tp then\n    local reg = ovreg or tp.reg\n    local rnum = map_reg_num[reg]\n    if not rnum then\n      werror(\"type `\"..(tname or expr)..\"' needs a register override\")\n    end\n    if not map_reg_valid_base[reg] then\n      werror(\"bad base register override `\"..(map_reg_rev[reg] or reg)..\"'\")\n    end\n    return reg, rnum, tp\n  end\n  return expr, map_reg_num[expr]\nend\n\n-- Parse operand and return { mode, opsize, reg, xreg, xsc, disp, imm }.\nlocal function parseoperand(param, isqword)\n  local t = {}\n\n  local expr = param\n  local opsize, tailops = match(param, \"^(%w+)%s*(.+)$\")\n  if opsize then\n    t.opsize = map_opsize[opsize]\n    if t.opsize then expr = tailops end\n  end\n\n  local br = match(expr, \"^%[%s*(.-)%s*%]$\")\n  repeat\n    if br then\n      t.mode = \"xm\"\n\n      -- [disp]\n      t.disp = toint(br)\n      if t.disp then\n\tt.mode = x64 and \"xm\" or \"xmO\"\n\tbreak\n      end\n\n      -- [reg...]\n      local tp\n      local reg, tailr = match(br, \"^([@%w_:]+)%s*(.*)$\")\n      reg, t.reg, tp = rtexpr(reg)\n      if not t.reg then\n\t-- [expr]\n\tt.mode = x64 and \"xm\" or \"xmO\"\n\tt.disp = dispexpr(\"+\"..br)\n\tbreak\n      end\n\n      if t.reg == -1 then\n\tt.vreg, tailr = match(tailr, \"^(%b())(.*)$\")\n\tif not t.vreg then werror(\"bad variable register expression\") end\n      end\n\n      -- [xreg*xsc] or [xreg*xsc+-disp] or [xreg*xsc+-expr]\n      local xsc, tailsc = match(tailr, \"^%*%s*([1248])%s*(.*)$\")\n      if xsc then\n\tif not map_reg_valid_index[reg] then\n\t  werror(\"bad index register `\"..map_reg_rev[reg]..\"'\")\n\tend\n\tt.xsc = map_xsc[xsc]\n\tt.xreg = t.reg\n\tt.vxreg = t.vreg\n\tt.reg = nil\n\tt.vreg = nil\n\tt.disp = dispexpr(tailsc)\n\tbreak\n      end\n      if not map_reg_valid_base[reg] then\n\twerror(\"bad base register `\"..map_reg_rev[reg]..\"'\")\n      end\n\n      -- [reg] or [reg+-disp]\n      t.disp = toint(tailr) or (tailr == \"\" and 0)\n      if t.disp then break end\n\n      -- [reg+xreg...]\n      local xreg, tailx = match(tailr, \"^%+%s*([@%w_:]+)%s*(.*)$\")\n      xreg, t.xreg, tp = rtexpr(xreg)\n      if not t.xreg then\n\t-- [reg+-expr]\n\tt.disp = dispexpr(tailr)\n\tbreak\n      end\n      if not map_reg_valid_index[xreg] then\n\twerror(\"bad index register `\"..map_reg_rev[xreg]..\"'\")\n      end\n\n      if t.xreg == -1 then\n\tt.vxreg, tailx = match(tailx, \"^(%b())(.*)$\")\n\tif not t.vxreg then werror(\"bad variable register expression\") end\n      end\n\n      -- [reg+xreg*xsc...]\n      local xsc, tailsc = match(tailx, \"^%*%s*([1248])%s*(.*)$\")\n      if xsc then\n\tt.xsc = map_xsc[xsc]\n\ttailx = tailsc\n      end\n\n      -- [...] or [...+-disp] or [...+-expr]\n      t.disp = dispexpr(tailx)\n    else\n      -- imm or opsize*imm\n      local imm = toint(expr, isqword)\n      if not imm and sub(expr, 1, 1) == \"*\" and t.opsize then\n\timm = toint(sub(expr, 2))\n\tif imm then\n\t  imm = imm * map_opsizenum[t.opsize]\n\t  t.opsize = nil\n\tend\n      end\n      if imm then\n\tif t.opsize then werror(\"bad operand size override\") end\n\tlocal m = \"i\"\n\tif imm == 1 then m = m..\"1\" end\n\tif imm >= 4294967168 and imm <= 4294967295 then imm = imm-4294967296 end\n\tif imm >= -128 and imm <= 127 then m = m..\"S\" end\n\tt.imm = imm\n\tt.mode = m\n\tbreak\n      end\n\n      local tp\n      local reg, tailr = match(expr, \"^([@%w_:]+)%s*(.*)$\")\n      reg, t.reg, tp = rtexpr(reg)\n      if t.reg then\n\tif t.reg == -1 then\n\t  t.vreg, tailr = match(tailr, \"^(%b())(.*)$\")\n\t  if not t.vreg then werror(\"bad variable register expression\") end\n\tend\n\t-- reg\n\tif tailr == \"\" then\n\t  if t.opsize then werror(\"bad operand size override\") end\n\t  t.opsize = map_reg_opsize[reg]\n\t  if t.opsize == \"f\" then\n\t    t.mode = t.reg == 0 and \"fF\" or \"f\"\n\t  else\n\t    if reg == \"@w4\" or (x64 and reg == \"@d4\") then\n\t      wwarn(\"bad idea, try again with `\"..(x64 and \"rsp'\" or \"esp'\"))\n\t    end\n\t    t.mode = t.reg == 0 and \"rmR\" or (reg == \"@b1\" and \"rmC\" or \"rm\")\n\t  end\n\t  t.needrex = map_reg_needrex[reg]\n\t  break\n\tend\n\n\t-- type[idx], type[idx].field, type->field -> [reg+offset_expr]\n\tif not tp then werror(\"bad operand `\"..param..\"'\") end\n\tt.mode = \"xm\"\n\tt.disp = format(tp.ctypefmt, tailr)\n      else\n\tt.mode, t.imm = immexpr(expr)\n\tif sub(t.mode, -1) == \"J\" then\n\t  if t.opsize and t.opsize ~= addrsize then\n\t    werror(\"bad operand size override\")\n\t  end\n\t  t.opsize = addrsize\n\tend\n      end\n    end\n  until true\n  return t\nend\n\n------------------------------------------------------------------------------\n-- x86 Template String Description\n-- ===============================\n--\n-- Each template string is a list of [match:]pattern pairs,\n-- separated by \"|\". The first match wins. No match means a\n-- bad or unsupported combination of operand modes or sizes.\n--\n-- The match part and the \":\" is omitted if the operation has\n-- no operands. Otherwise the first N characters are matched\n-- against the mode strings of each of the N operands.\n--\n-- The mode string for each operand type is (see parseoperand()):\n--   Integer register: \"rm\", +\"R\" for eax, ax, al, +\"C\" for cl\n--   FP register:      \"f\",  +\"F\" for st0\n--   Index operand:    \"xm\", +\"O\" for [disp] (pure offset)\n--   Immediate:        \"i\",  +\"S\" for signed 8 bit, +\"1\" for 1,\n--                     +\"I\" for arg, +\"P\" for pointer\n--   Any:              +\"J\" for valid jump targets\n--\n-- So a match character \"m\" (mixed) matches both an integer register\n-- and an index operand (to be encoded with the ModRM/SIB scheme).\n-- But \"r\" matches only a register and \"x\" only an index operand\n-- (e.g. for FP memory access operations).\n--\n-- The operand size match string starts right after the mode match\n-- characters and ends before the \":\". \"dwb\" or \"qdwb\" is assumed, if empty.\n-- The effective data size of the operation is matched against this list.\n--\n-- If only the regular \"b\", \"w\", \"d\", \"q\", \"t\" operand sizes are\n-- present, then all operands must be the same size. Unspecified sizes\n-- are ignored, but at least one operand must have a size or the pattern\n-- won't match (use the \"byte\", \"word\", \"dword\", \"qword\", \"tword\"\n-- operand size overrides. E.g.: mov dword [eax], 1).\n--\n-- If the list has a \"1\" or \"2\" prefix, the operand size is taken\n-- from the respective operand and any other operand sizes are ignored.\n-- If the list contains only \".\", all operand sizes are ignored.\n-- If the list has a \"/\" prefix, the concatenated (mixed) operand sizes\n-- are compared to the match.\n--\n-- E.g. \"rrdw\" matches for either two dword registers or two word\n-- registers. \"Fx2dq\" matches an st0 operand plus an index operand\n-- pointing to a dword (float) or qword (double).\n--\n-- Every character after the \":\" is part of the pattern string:\n--   Hex chars are accumulated to form the opcode (left to right).\n--   \"n\"       disables the standard opcode mods\n--             (otherwise: -1 for \"b\", o16 prefix for \"w\", rex.w for \"q\")\n--   \"X\"       Force REX.W.\n--   \"r\"/\"R\"   adds the reg. number from the 1st/2nd operand to the opcode.\n--   \"m\"/\"M\"   generates ModRM/SIB from the 1st/2nd operand.\n--             The spare 3 bits are either filled with the last hex digit or\n--             the result from a previous \"r\"/\"R\". The opcode is restored.\n--   \"u\"       Use VEX encoding, vvvv unused.\n--   \"v\"/\"V\"   Use VEX encoding, vvvv from 1st/2nd operand (the operand is\n--             removed from the list used by future characters).\n--   \"w\"       Use VEX encoding, vvvv from 3rd operand.\n--   \"L\"       Force VEX.L\n--\n-- All of the following characters force a flush of the opcode:\n--   \"o\"/\"O\"   stores a pure 32 bit disp (offset) from the 1st/2nd operand.\n--   \"s\"       stores a 4 bit immediate from the last register operand,\n--             followed by 4 zero bits.\n--   \"S\"       stores a signed 8 bit immediate from the last operand.\n--   \"U\"       stores an unsigned 8 bit immediate from the last operand.\n--   \"W\"       stores an unsigned 16 bit immediate from the last operand.\n--   \"i\"       stores an operand sized immediate from the last operand.\n--   \"I\"       dito, but generates an action code to optionally modify\n--             the opcode (+2) for a signed 8 bit immediate.\n--   \"J\"       generates one of the REL action codes from the last operand.\n--\n------------------------------------------------------------------------------\n\n-- Template strings for x86 instructions. Ordered by first opcode byte.\n-- Unimplemented opcodes (deliberate omissions) are marked with *.\nlocal map_op = {\n  -- 00-05: add...\n  -- 06: *push es\n  -- 07: *pop es\n  -- 08-0D: or...\n  -- 0E: *push cs\n  -- 0F: two byte opcode prefix\n  -- 10-15: adc...\n  -- 16: *push ss\n  -- 17: *pop ss\n  -- 18-1D: sbb...\n  -- 1E: *push ds\n  -- 1F: *pop ds\n  -- 20-25: and...\n  es_0 =\t\"26\",\n  -- 27: *daa\n  -- 28-2D: sub...\n  cs_0 =\t\"2E\",\n  -- 2F: *das\n  -- 30-35: xor...\n  ss_0 =\t\"36\",\n  -- 37: *aaa\n  -- 38-3D: cmp...\n  ds_0 =\t\"3E\",\n  -- 3F: *aas\n  inc_1 =\tx64 and \"m:FF0m\" or \"rdw:40r|m:FF0m\",\n  dec_1 =\tx64 and \"m:FF1m\" or \"rdw:48r|m:FF1m\",\n  push_1 =\t(x64 and \"rq:n50r|rw:50r|mq:nFF6m|mw:FF6m\" or\n\t\t\t \"rdw:50r|mdw:FF6m\")..\"|S.:6AS|ib:n6Ai|i.:68i\",\n  pop_1 =\tx64 and \"rq:n58r|rw:58r|mq:n8F0m|mw:8F0m\" or \"rdw:58r|mdw:8F0m\",\n  -- 60: *pusha, *pushad, *pushaw\n  -- 61: *popa, *popad, *popaw\n  -- 62: *bound rdw,x\n  -- 63: x86: *arpl mw,rw\n  movsxd_2 =\tx64 and \"rm/qd:63rM\",\n  fs_0 =\t\"64\",\n  gs_0 =\t\"65\",\n  o16_0 =\t\"66\",\n  a16_0 =\tnot x64 and \"67\" or nil,\n  a32_0 =\tx64 and \"67\",\n  -- 68: push idw\n  -- 69: imul rdw,mdw,idw\n  -- 6A: push ib\n  -- 6B: imul rdw,mdw,S\n  -- 6C: *insb\n  -- 6D: *insd, *insw\n  -- 6E: *outsb\n  -- 6F: *outsd, *outsw\n  -- 70-7F: jcc lb\n  -- 80: add... mb,i\n  -- 81: add... mdw,i\n  -- 82: *undefined\n  -- 83: add... mdw,S\n  test_2 =\t\"mr:85Rm|rm:85rM|Ri:A9ri|mi:F70mi\",\n  -- 86: xchg rb,mb\n  -- 87: xchg rdw,mdw\n  -- 88: mov mb,r\n  -- 89: mov mdw,r\n  -- 8A: mov r,mb\n  -- 8B: mov r,mdw\n  -- 8C: *mov mdw,seg\n  lea_2 =\t\"rx1dq:8DrM\",\n  -- 8E: *mov seg,mdw\n  -- 8F: pop mdw\n  nop_0 =\t\"90\",\n  xchg_2 =\t\"Rrqdw:90R|rRqdw:90r|rm:87rM|mr:87Rm\",\n  cbw_0 =\t\"6698\",\n  cwde_0 =\t\"98\",\n  cdqe_0 =\t\"4898\",\n  cwd_0 =\t\"6699\",\n  cdq_0 =\t\"99\",\n  cqo_0 =\t\"4899\",\n  -- 9A: *call iw:idw\n  wait_0 =\t\"9B\",\n  fwait_0 =\t\"9B\",\n  pushf_0 =\t\"9C\",\n  pushfd_0 =\tnot x64 and \"9C\",\n  pushfq_0 =\tx64 and \"9C\",\n  popf_0 =\t\"9D\",\n  popfd_0 =\tnot x64 and \"9D\",\n  popfq_0 =\tx64 and \"9D\",\n  sahf_0 =\t\"9E\",\n  lahf_0 =\t\"9F\",\n  mov_2 =\t\"OR:A3o|RO:A1O|mr:89Rm|rm:8BrM|rib:nB0ri|ridw:B8ri|mi:C70mi\",\n  movsb_0 =\t\"A4\",\n  movsw_0 =\t\"66A5\",\n  movsd_0 =\t\"A5\",\n  cmpsb_0 =\t\"A6\",\n  cmpsw_0 =\t\"66A7\",\n  cmpsd_0 =\t\"A7\",\n  -- A8: test Rb,i\n  -- A9: test Rdw,i\n  stosb_0 =\t\"AA\",\n  stosw_0 =\t\"66AB\",\n  stosd_0 =\t\"AB\",\n  lodsb_0 =\t\"AC\",\n  lodsw_0 =\t\"66AD\",\n  lodsd_0 =\t\"AD\",\n  scasb_0 =\t\"AE\",\n  scasw_0 =\t\"66AF\",\n  scasd_0 =\t\"AF\",\n  -- B0-B7: mov rb,i\n  -- B8-BF: mov rdw,i\n  -- C0: rol... mb,i\n  -- C1: rol... mdw,i\n  ret_1 =\t\"i.:nC2W\",\n  ret_0 =\t\"C3\",\n  -- C4: *les rdw,mq\n  -- C5: *lds rdw,mq\n  -- C6: mov mb,i\n  -- C7: mov mdw,i\n  -- C8: *enter iw,ib\n  leave_0 =\t\"C9\",\n  -- CA: *retf iw\n  -- CB: *retf\n  int3_0 =\t\"CC\",\n  int_1 =\t\"i.:nCDU\",\n  into_0 =\t\"CE\",\n  -- CF: *iret\n  -- D0: rol... mb,1\n  -- D1: rol... mdw,1\n  -- D2: rol... mb,cl\n  -- D3: rol... mb,cl\n  -- D4: *aam ib\n  -- D5: *aad ib\n  -- D6: *salc\n  -- D7: *xlat\n  -- D8-DF: floating point ops\n  -- E0: *loopne\n  -- E1: *loope\n  -- E2: *loop\n  -- E3: *jcxz, *jecxz\n  -- E4: *in Rb,ib\n  -- E5: *in Rdw,ib\n  -- E6: *out ib,Rb\n  -- E7: *out ib,Rdw\n  call_1 =\tx64 and \"mq:nFF2m|J.:E8nJ\" or \"md:FF2m|J.:E8J\",\n  jmp_1 =\tx64 and \"mq:nFF4m|J.:E9nJ\" or \"md:FF4m|J.:E9J\", -- short: EB\n  -- EA: *jmp iw:idw\n  -- EB: jmp ib\n  -- EC: *in Rb,dx\n  -- ED: *in Rdw,dx\n  -- EE: *out dx,Rb\n  -- EF: *out dx,Rdw\n  lock_0 =\t\"F0\",\n  int1_0 =\t\"F1\",\n  repne_0 =\t\"F2\",\n  repnz_0 =\t\"F2\",\n  rep_0 =\t\"F3\",\n  repe_0 =\t\"F3\",\n  repz_0 =\t\"F3\",\n  -- F4: *hlt\n  cmc_0 =\t\"F5\",\n  -- F6: test... mb,i; div... mb\n  -- F7: test... mdw,i; div... mdw\n  clc_0 =\t\"F8\",\n  stc_0 =\t\"F9\",\n  -- FA: *cli\n  cld_0 =\t\"FC\",\n  std_0 =\t\"FD\",\n  -- FE: inc... mb\n  -- FF: inc... mdw\n\n  -- misc ops\n  not_1 =\t\"m:F72m\",\n  neg_1 =\t\"m:F73m\",\n  mul_1 =\t\"m:F74m\",\n  imul_1 =\t\"m:F75m\",\n  div_1 =\t\"m:F76m\",\n  idiv_1 =\t\"m:F77m\",\n\n  imul_2 =\t\"rmqdw:0FAFrM|rIqdw:69rmI|rSqdw:6BrmS|riqdw:69rmi\",\n  imul_3 =\t\"rmIqdw:69rMI|rmSqdw:6BrMS|rmiqdw:69rMi\",\n\n  movzx_2 =\t\"rm/db:0FB6rM|rm/qb:|rm/wb:0FB6rM|rm/dw:0FB7rM|rm/qw:\",\n  movsx_2 =\t\"rm/db:0FBErM|rm/qb:|rm/wb:0FBErM|rm/dw:0FBFrM|rm/qw:\",\n\n  bswap_1 =\t\"rqd:0FC8r\",\n  bsf_2 =\t\"rmqdw:0FBCrM\",\n  bsr_2 =\t\"rmqdw:0FBDrM\",\n  bt_2 =\t\"mrqdw:0FA3Rm|miqdw:0FBA4mU\",\n  btc_2 =\t\"mrqdw:0FBBRm|miqdw:0FBA7mU\",\n  btr_2 =\t\"mrqdw:0FB3Rm|miqdw:0FBA6mU\",\n  bts_2 =\t\"mrqdw:0FABRm|miqdw:0FBA5mU\",\n\n  shld_3 =\t\"mriqdw:0FA4RmU|mrC/qq:0FA5Rm|mrC/dd:|mrC/ww:\",\n  shrd_3 =\t\"mriqdw:0FACRmU|mrC/qq:0FADRm|mrC/dd:|mrC/ww:\",\n\n  rdtsc_0 =\t\"0F31\", -- P1+\n  rdpmc_0 =\t\"0F33\", -- P6+\n  cpuid_0 =\t\"0FA2\", -- P1+\n\n  -- floating point ops\n  fst_1 =\t\"ff:DDD0r|xd:D92m|xq:nDD2m\",\n  fstp_1 =\t\"ff:DDD8r|xd:D93m|xq:nDD3m|xt:DB7m\",\n  fld_1 =\t\"ff:D9C0r|xd:D90m|xq:nDD0m|xt:DB5m\",\n\n  fpop_0 =\t\"DDD8\", -- Alias for fstp st0.\n\n  fist_1 =\t\"xw:nDF2m|xd:DB2m\",\n  fistp_1 =\t\"xw:nDF3m|xd:DB3m|xq:nDF7m\",\n  fild_1 =\t\"xw:nDF0m|xd:DB0m|xq:nDF5m\",\n\n  fxch_0 =\t\"D9C9\",\n  fxch_1 =\t\"ff:D9C8r\",\n  fxch_2 =\t\"fFf:D9C8r|Fff:D9C8R\",\n\n  fucom_1 =\t\"ff:DDE0r\",\n  fucom_2 =\t\"Fff:DDE0R\",\n  fucomp_1 =\t\"ff:DDE8r\",\n  fucomp_2 =\t\"Fff:DDE8R\",\n  fucomi_1 =\t\"ff:DBE8r\", -- P6+\n  fucomi_2 =\t\"Fff:DBE8R\", -- P6+\n  fucomip_1 =\t\"ff:DFE8r\", -- P6+\n  fucomip_2 =\t\"Fff:DFE8R\", -- P6+\n  fcomi_1 =\t\"ff:DBF0r\", -- P6+\n  fcomi_2 =\t\"Fff:DBF0R\", -- P6+\n  fcomip_1 =\t\"ff:DFF0r\", -- P6+\n  fcomip_2 =\t\"Fff:DFF0R\", -- P6+\n  fucompp_0 =\t\"DAE9\",\n  fcompp_0 =\t\"DED9\",\n\n  fldenv_1 =\t\"x.:D94m\",\n  fnstenv_1 =\t\"x.:D96m\",\n  fstenv_1 =\t\"x.:9BD96m\",\n  fldcw_1 =\t\"xw:nD95m\",\n  fstcw_1 =\t\"xw:n9BD97m\",\n  fnstcw_1 =\t\"xw:nD97m\",\n  fstsw_1 =\t\"Rw:n9BDFE0|xw:n9BDD7m\",\n  fnstsw_1 =\t\"Rw:nDFE0|xw:nDD7m\",\n  fclex_0 =\t\"9BDBE2\",\n  fnclex_0 =\t\"DBE2\",\n\n  fnop_0 =\t\"D9D0\",\n  -- D9D1-D9DF: unassigned\n\n  fchs_0 =\t\"D9E0\",\n  fabs_0 =\t\"D9E1\",\n  -- D9E2: unassigned\n  -- D9E3: unassigned\n  ftst_0 =\t\"D9E4\",\n  fxam_0 =\t\"D9E5\",\n  -- D9E6: unassigned\n  -- D9E7: unassigned\n  fld1_0 =\t\"D9E8\",\n  fldl2t_0 =\t\"D9E9\",\n  fldl2e_0 =\t\"D9EA\",\n  fldpi_0 =\t\"D9EB\",\n  fldlg2_0 =\t\"D9EC\",\n  fldln2_0 =\t\"D9ED\",\n  fldz_0 =\t\"D9EE\",\n  -- D9EF: unassigned\n\n  f2xm1_0 =\t\"D9F0\",\n  fyl2x_0 =\t\"D9F1\",\n  fptan_0 =\t\"D9F2\",\n  fpatan_0 =\t\"D9F3\",\n  fxtract_0 =\t\"D9F4\",\n  fprem1_0 =\t\"D9F5\",\n  fdecstp_0 =\t\"D9F6\",\n  fincstp_0 =\t\"D9F7\",\n  fprem_0 =\t\"D9F8\",\n  fyl2xp1_0 =\t\"D9F9\",\n  fsqrt_0 =\t\"D9FA\",\n  fsincos_0 =\t\"D9FB\",\n  frndint_0 =\t\"D9FC\",\n  fscale_0 =\t\"D9FD\",\n  fsin_0 =\t\"D9FE\",\n  fcos_0 =\t\"D9FF\",\n\n  -- SSE, SSE2\n  andnpd_2 =\t\"rmo:660F55rM\",\n  andnps_2 =\t\"rmo:0F55rM\",\n  andpd_2 =\t\"rmo:660F54rM\",\n  andps_2 =\t\"rmo:0F54rM\",\n  clflush_1 =\t\"x.:0FAE7m\",\n  cmppd_3 =\t\"rmio:660FC2rMU\",\n  cmpps_3 =\t\"rmio:0FC2rMU\",\n  cmpsd_3 =\t\"rrio:F20FC2rMU|rxi/oq:\",\n  cmpss_3 =\t\"rrio:F30FC2rMU|rxi/od:\",\n  comisd_2 =\t\"rro:660F2FrM|rx/oq:\",\n  comiss_2 =\t\"rro:0F2FrM|rx/od:\",\n  cvtdq2pd_2 =\t\"rro:F30FE6rM|rx/oq:\",\n  cvtdq2ps_2 =\t\"rmo:0F5BrM\",\n  cvtpd2dq_2 =\t\"rmo:F20FE6rM\",\n  cvtpd2ps_2 =\t\"rmo:660F5ArM\",\n  cvtpi2pd_2 =\t\"rx/oq:660F2ArM\",\n  cvtpi2ps_2 =\t\"rx/oq:0F2ArM\",\n  cvtps2dq_2 =\t\"rmo:660F5BrM\",\n  cvtps2pd_2 =\t\"rro:0F5ArM|rx/oq:\",\n  cvtsd2si_2 =\t\"rr/do:F20F2DrM|rr/qo:|rx/dq:|rxq:\",\n  cvtsd2ss_2 =\t\"rro:F20F5ArM|rx/oq:\",\n  cvtsi2sd_2 =\t\"rm/od:F20F2ArM|rm/oq:F20F2ArXM\",\n  cvtsi2ss_2 =\t\"rm/od:F30F2ArM|rm/oq:F30F2ArXM\",\n  cvtss2sd_2 =\t\"rro:F30F5ArM|rx/od:\",\n  cvtss2si_2 =\t\"rr/do:F30F2DrM|rr/qo:|rxd:|rx/qd:\",\n  cvttpd2dq_2 =\t\"rmo:660FE6rM\",\n  cvttps2dq_2 =\t\"rmo:F30F5BrM\",\n  cvttsd2si_2 =\t\"rr/do:F20F2CrM|rr/qo:|rx/dq:|rxq:\",\n  cvttss2si_2 =\t\"rr/do:F30F2CrM|rr/qo:|rxd:|rx/qd:\",\n  fxsave_1 =\t\"x.:0FAE0m\",\n  fxrstor_1 =\t\"x.:0FAE1m\",\n  ldmxcsr_1 =\t\"xd:0FAE2m\",\n  lfence_0 =\t\"0FAEE8\",\n  maskmovdqu_2 = \"rro:660FF7rM\",\n  mfence_0 =\t\"0FAEF0\",\n  movapd_2 =\t\"rmo:660F28rM|mro:660F29Rm\",\n  movaps_2 =\t\"rmo:0F28rM|mro:0F29Rm\",\n  movd_2 =\t\"rm/od:660F6ErM|rm/oq:660F6ErXM|mr/do:660F7ERm|mr/qo:\",\n  movdqa_2 =\t\"rmo:660F6FrM|mro:660F7FRm\",\n  movdqu_2 =\t\"rmo:F30F6FrM|mro:F30F7FRm\",\n  movhlps_2 =\t\"rro:0F12rM\",\n  movhpd_2 =\t\"rx/oq:660F16rM|xr/qo:n660F17Rm\",\n  movhps_2 =\t\"rx/oq:0F16rM|xr/qo:n0F17Rm\",\n  movlhps_2 =\t\"rro:0F16rM\",\n  movlpd_2 =\t\"rx/oq:660F12rM|xr/qo:n660F13Rm\",\n  movlps_2 =\t\"rx/oq:0F12rM|xr/qo:n0F13Rm\",\n  movmskpd_2 =\t\"rr/do:660F50rM\",\n  movmskps_2 =\t\"rr/do:0F50rM\",\n  movntdq_2 =\t\"xro:660FE7Rm\",\n  movnti_2 =\t\"xrqd:0FC3Rm\",\n  movntpd_2 =\t\"xro:660F2BRm\",\n  movntps_2 =\t\"xro:0F2BRm\",\n  movq_2 =\t\"rro:F30F7ErM|rx/oq:|xr/qo:n660FD6Rm\",\n  movsd_2 =\t\"rro:F20F10rM|rx/oq:|xr/qo:nF20F11Rm\",\n  movss_2 =\t\"rro:F30F10rM|rx/od:|xr/do:F30F11Rm\",\n  movupd_2 =\t\"rmo:660F10rM|mro:660F11Rm\",\n  movups_2 =\t\"rmo:0F10rM|mro:0F11Rm\",\n  orpd_2 =\t\"rmo:660F56rM\",\n  orps_2 =\t\"rmo:0F56rM\",\n  pause_0 =\t\"F390\",\n  pextrw_3 =\t\"rri/do:660FC5rMU|xri/wo:660F3A15nRmU\", -- Mem op: SSE4.1 only.\n  pinsrw_3 =\t\"rri/od:660FC4rMU|rxi/ow:\",\n  pmovmskb_2 =\t\"rr/do:660FD7rM\",\n  prefetchnta_1 = \"xb:n0F180m\",\n  prefetcht0_1 = \"xb:n0F181m\",\n  prefetcht1_1 = \"xb:n0F182m\",\n  prefetcht2_1 = \"xb:n0F183m\",\n  pshufd_3 =\t\"rmio:660F70rMU\",\n  pshufhw_3 =\t\"rmio:F30F70rMU\",\n  pshuflw_3 =\t\"rmio:F20F70rMU\",\n  pslld_2 =\t\"rmo:660FF2rM|rio:660F726mU\",\n  pslldq_2 =\t\"rio:660F737mU\",\n  psllq_2 =\t\"rmo:660FF3rM|rio:660F736mU\",\n  psllw_2 =\t\"rmo:660FF1rM|rio:660F716mU\",\n  psrad_2 =\t\"rmo:660FE2rM|rio:660F724mU\",\n  psraw_2 =\t\"rmo:660FE1rM|rio:660F714mU\",\n  psrld_2 =\t\"rmo:660FD2rM|rio:660F722mU\",\n  psrldq_2 =\t\"rio:660F733mU\",\n  psrlq_2 =\t\"rmo:660FD3rM|rio:660F732mU\",\n  psrlw_2 =\t\"rmo:660FD1rM|rio:660F712mU\",\n  rcpps_2 =\t\"rmo:0F53rM\",\n  rcpss_2 =\t\"rro:F30F53rM|rx/od:\",\n  rsqrtps_2 =\t\"rmo:0F52rM\",\n  rsqrtss_2 =\t\"rmo:F30F52rM\",\n  sfence_0 =\t\"0FAEF8\",\n  shufpd_3 =\t\"rmio:660FC6rMU\",\n  shufps_3 =\t\"rmio:0FC6rMU\",\n  stmxcsr_1 =   \"xd:0FAE3m\",\n  ucomisd_2 =\t\"rro:660F2ErM|rx/oq:\",\n  ucomiss_2 =\t\"rro:0F2ErM|rx/od:\",\n  unpckhpd_2 =\t\"rmo:660F15rM\",\n  unpckhps_2 =\t\"rmo:0F15rM\",\n  unpcklpd_2 =\t\"rmo:660F14rM\",\n  unpcklps_2 =\t\"rmo:0F14rM\",\n  xorpd_2 =\t\"rmo:660F57rM\",\n  xorps_2 =\t\"rmo:0F57rM\",\n\n  -- SSE3 ops\n  fisttp_1 =\t\"xw:nDF1m|xd:DB1m|xq:nDD1m\",\n  addsubpd_2 =\t\"rmo:660FD0rM\",\n  addsubps_2 =\t\"rmo:F20FD0rM\",\n  haddpd_2 =\t\"rmo:660F7CrM\",\n  haddps_2 =\t\"rmo:F20F7CrM\",\n  hsubpd_2 =\t\"rmo:660F7DrM\",\n  hsubps_2 =\t\"rmo:F20F7DrM\",\n  lddqu_2 =\t\"rxo:F20FF0rM\",\n  movddup_2 =\t\"rmo:F20F12rM\",\n  movshdup_2 =\t\"rmo:F30F16rM\",\n  movsldup_2 =\t\"rmo:F30F12rM\",\n\n  -- SSSE3 ops\n  pabsb_2 =\t\"rmo:660F381CrM\",\n  pabsd_2 =\t\"rmo:660F381ErM\",\n  pabsw_2 =\t\"rmo:660F381DrM\",\n  palignr_3 =\t\"rmio:660F3A0FrMU\",\n  phaddd_2 =\t\"rmo:660F3802rM\",\n  phaddsw_2 =\t\"rmo:660F3803rM\",\n  phaddw_2 =\t\"rmo:660F3801rM\",\n  phsubd_2 =\t\"rmo:660F3806rM\",\n  phsubsw_2 =\t\"rmo:660F3807rM\",\n  phsubw_2 =\t\"rmo:660F3805rM\",\n  pmaddubsw_2 =\t\"rmo:660F3804rM\",\n  pmulhrsw_2 =\t\"rmo:660F380BrM\",\n  pshufb_2 =\t\"rmo:660F3800rM\",\n  psignb_2 =\t\"rmo:660F3808rM\",\n  psignd_2 =\t\"rmo:660F380ArM\",\n  psignw_2 =\t\"rmo:660F3809rM\",\n\n  -- SSE4.1 ops\n  blendpd_3 =\t\"rmio:660F3A0DrMU\",\n  blendps_3 =\t\"rmio:660F3A0CrMU\",\n  blendvpd_3 =\t\"rmRo:660F3815rM\",\n  blendvps_3 =\t\"rmRo:660F3814rM\",\n  dppd_3 =\t\"rmio:660F3A41rMU\",\n  dpps_3 =\t\"rmio:660F3A40rMU\",\n  extractps_3 =\t\"mri/do:660F3A17RmU|rri/qo:660F3A17RXmU\",\n  insertps_3 =\t\"rrio:660F3A41rMU|rxi/od:\",\n  movntdqa_2 =\t\"rxo:660F382ArM\",\n  mpsadbw_3 =\t\"rmio:660F3A42rMU\",\n  packusdw_2 =\t\"rmo:660F382BrM\",\n  pblendvb_3 =\t\"rmRo:660F3810rM\",\n  pblendw_3 =\t\"rmio:660F3A0ErMU\",\n  pcmpeqq_2 =\t\"rmo:660F3829rM\",\n  pextrb_3 =\t\"rri/do:660F3A14nRmU|rri/qo:|xri/bo:\",\n  pextrd_3 =\t\"mri/do:660F3A16RmU\",\n  pextrq_3 =\t\"mri/qo:660F3A16RmU\",\n  -- pextrw is SSE2, mem operand is SSE4.1 only\n  phminposuw_2 = \"rmo:660F3841rM\",\n  pinsrb_3 =\t\"rri/od:660F3A20nrMU|rxi/ob:\",\n  pinsrd_3 =\t\"rmi/od:660F3A22rMU\",\n  pinsrq_3 =\t\"rmi/oq:660F3A22rXMU\",\n  pmaxsb_2 =\t\"rmo:660F383CrM\",\n  pmaxsd_2 =\t\"rmo:660F383DrM\",\n  pmaxud_2 =\t\"rmo:660F383FrM\",\n  pmaxuw_2 =\t\"rmo:660F383ErM\",\n  pminsb_2 =\t\"rmo:660F3838rM\",\n  pminsd_2 =\t\"rmo:660F3839rM\",\n  pminud_2 =\t\"rmo:660F383BrM\",\n  pminuw_2 =\t\"rmo:660F383ArM\",\n  pmovsxbd_2 =\t\"rro:660F3821rM|rx/od:\",\n  pmovsxbq_2 =\t\"rro:660F3822rM|rx/ow:\",\n  pmovsxbw_2 =\t\"rro:660F3820rM|rx/oq:\",\n  pmovsxdq_2 =\t\"rro:660F3825rM|rx/oq:\",\n  pmovsxwd_2 =\t\"rro:660F3823rM|rx/oq:\",\n  pmovsxwq_2 =\t\"rro:660F3824rM|rx/od:\",\n  pmovzxbd_2 =\t\"rro:660F3831rM|rx/od:\",\n  pmovzxbq_2 =\t\"rro:660F3832rM|rx/ow:\",\n  pmovzxbw_2 =\t\"rro:660F3830rM|rx/oq:\",\n  pmovzxdq_2 =\t\"rro:660F3835rM|rx/oq:\",\n  pmovzxwd_2 =\t\"rro:660F3833rM|rx/oq:\",\n  pmovzxwq_2 =\t\"rro:660F3834rM|rx/od:\",\n  pmuldq_2 =\t\"rmo:660F3828rM\",\n  pmulld_2 =\t\"rmo:660F3840rM\",\n  ptest_2 =\t\"rmo:660F3817rM\",\n  roundpd_3 =\t\"rmio:660F3A09rMU\",\n  roundps_3 =\t\"rmio:660F3A08rMU\",\n  roundsd_3 =\t\"rrio:660F3A0BrMU|rxi/oq:\",\n  roundss_3 =\t\"rrio:660F3A0ArMU|rxi/od:\",\n\n  -- SSE4.2 ops\n  crc32_2 =\t\"rmqd:F20F38F1rM|rm/dw:66F20F38F1rM|rm/db:F20F38F0rM|rm/qb:\",\n  pcmpestri_3 =\t\"rmio:660F3A61rMU\",\n  pcmpestrm_3 =\t\"rmio:660F3A60rMU\",\n  pcmpgtq_2 =\t\"rmo:660F3837rM\",\n  pcmpistri_3 =\t\"rmio:660F3A63rMU\",\n  pcmpistrm_3 =\t\"rmio:660F3A62rMU\",\n  popcnt_2 =\t\"rmqdw:F30FB8rM\",\n\n  -- SSE4a\n  extrq_2 =\t\"rro:660F79rM\",\n  extrq_3 =\t\"riio:660F780mUU\",\n  insertq_2 =\t\"rro:F20F79rM\",\n  insertq_4 =\t\"rriio:F20F78rMUU\",\n  lzcnt_2 =\t\"rmqdw:F30FBDrM\",\n  movntsd_2 =\t\"xr/qo:nF20F2BRm\",\n  movntss_2 =\t\"xr/do:F30F2BRm\",\n  -- popcnt is also in SSE4.2\n\n  -- AES-NI\n  aesdec_2 =\t\"rmo:660F38DErM\",\n  aesdeclast_2 = \"rmo:660F38DFrM\",\n  aesenc_2 =\t\"rmo:660F38DCrM\",\n  aesenclast_2 = \"rmo:660F38DDrM\",\n  aesimc_2 =\t\"rmo:660F38DBrM\",\n  aeskeygenassist_3 = \"rmio:660F3ADFrMU\",\n  pclmulqdq_3 =\t\"rmio:660F3A44rMU\",\n\n   -- AVX FP ops\n  vaddsubpd_3 =\t\"rrmoy:660FVD0rM\",\n  vaddsubps_3 =\t\"rrmoy:F20FVD0rM\",\n  vandpd_3 =\t\"rrmoy:660FV54rM\",\n  vandps_3 =\t\"rrmoy:0FV54rM\",\n  vandnpd_3 =\t\"rrmoy:660FV55rM\",\n  vandnps_3 =\t\"rrmoy:0FV55rM\",\n  vblendpd_4 =\t\"rrmioy:660F3AV0DrMU\",\n  vblendps_4 =\t\"rrmioy:660F3AV0CrMU\",\n  vblendvpd_4 =\t\"rrmroy:660F3AV4BrMs\",\n  vblendvps_4 =\t\"rrmroy:660F3AV4ArMs\",\n  vbroadcastf128_2 = \"rx/yo:660F38u1ArM\",\n  vcmppd_4 =\t\"rrmioy:660FVC2rMU\",\n  vcmpps_4 =\t\"rrmioy:0FVC2rMU\",\n  vcmpsd_4 =\t\"rrrio:F20FVC2rMU|rrxi/ooq:\",\n  vcmpss_4 =\t\"rrrio:F30FVC2rMU|rrxi/ood:\",\n  vcomisd_2 =\t\"rro:660Fu2FrM|rx/oq:\",\n  vcomiss_2 =\t\"rro:0Fu2FrM|rx/od:\",\n  vcvtdq2pd_2 =\t\"rro:F30FuE6rM|rx/oq:|rm/yo:\",\n  vcvtdq2ps_2 =\t\"rmoy:0Fu5BrM\",\n  vcvtpd2dq_2 =\t\"rmoy:F20FuE6rM\",\n  vcvtpd2ps_2 =\t\"rmoy:660Fu5ArM\",\n  vcvtps2dq_2 =\t\"rmoy:660Fu5BrM\",\n  vcvtps2pd_2 =\t\"rro:0Fu5ArM|rx/oq:|rm/yo:\",\n  vcvtsd2si_2 =\t\"rr/do:F20Fu2DrM|rx/dq:|rr/qo:|rxq:\",\n  vcvtsd2ss_3 =\t\"rrro:F20FV5ArM|rrx/ooq:\",\n  vcvtsi2sd_3 =\t\"rrm/ood:F20FV2ArM|rrm/ooq:F20FVX2ArM\",\n  vcvtsi2ss_3 =\t\"rrm/ood:F30FV2ArM|rrm/ooq:F30FVX2ArM\",\n  vcvtss2sd_3 =\t\"rrro:F30FV5ArM|rrx/ood:\",\n  vcvtss2si_2 =\t\"rr/do:F30Fu2DrM|rxd:|rr/qo:|rx/qd:\",\n  vcvttpd2dq_2 = \"rmo:660FuE6rM|rm/oy:660FuLE6rM\",\n  vcvttps2dq_2 = \"rmoy:F30Fu5BrM\",\n  vcvttsd2si_2 = \"rr/do:F20Fu2CrM|rx/dq:|rr/qo:|rxq:\",\n  vcvttss2si_2 = \"rr/do:F30Fu2CrM|rxd:|rr/qo:|rx/qd:\",\n  vdppd_4 =\t\"rrmio:660F3AV41rMU\",\n  vdpps_4 =\t\"rrmioy:660F3AV40rMU\",\n  vextractf128_3 = \"mri/oy:660F3AuL19RmU\",\n  vextractps_3 = \"mri/do:660F3Au17RmU\",\n  vhaddpd_3 =\t\"rrmoy:660FV7CrM\",\n  vhaddps_3 =\t\"rrmoy:F20FV7CrM\",\n  vhsubpd_3 =\t\"rrmoy:660FV7DrM\",\n  vhsubps_3 =\t\"rrmoy:F20FV7DrM\",\n  vinsertf128_4 = \"rrmi/yyo:660F3AV18rMU\",\n  vinsertps_4 =\t\"rrrio:660F3AV21rMU|rrxi/ood:\",\n  vldmxcsr_1 =\t\"xd:0FuAE2m\",\n  vmaskmovps_3 = \"rrxoy:660F38V2CrM|xrroy:660F38V2ERm\",\n  vmaskmovpd_3 = \"rrxoy:660F38V2DrM|xrroy:660F38V2FRm\",\n  vmovapd_2 =\t\"rmoy:660Fu28rM|mroy:660Fu29Rm\",\n  vmovaps_2 =\t\"rmoy:0Fu28rM|mroy:0Fu29Rm\",\n  vmovd_2 =\t\"rm/od:660Fu6ErM|rm/oq:660FuX6ErM|mr/do:660Fu7ERm|mr/qo:\",\n  vmovq_2 =\t\"rro:F30Fu7ErM|rx/oq:|xr/qo:660FuD6Rm\",\n  vmovddup_2 =\t\"rmy:F20Fu12rM|rro:|rx/oq:\",\n  vmovhlps_3 =\t\"rrro:0FV12rM\",\n  vmovhpd_2 =\t\"xr/qo:660Fu17Rm\",\n  vmovhpd_3 =\t\"rrx/ooq:660FV16rM\",\n  vmovhps_2 =\t\"xr/qo:0Fu17Rm\",\n  vmovhps_3 =\t\"rrx/ooq:0FV16rM\",\n  vmovlhps_3 =\t\"rrro:0FV16rM\",\n  vmovlpd_2 =\t\"xr/qo:660Fu13Rm\",\n  vmovlpd_3 =\t\"rrx/ooq:660FV12rM\",\n  vmovlps_2 =\t\"xr/qo:0Fu13Rm\",\n  vmovlps_3 =\t\"rrx/ooq:0FV12rM\",\n  vmovmskpd_2 =\t\"rr/do:660Fu50rM|rr/dy:660FuL50rM\",\n  vmovmskps_2 =\t\"rr/do:0Fu50rM|rr/dy:0FuL50rM\",\n  vmovntpd_2 =\t\"xroy:660Fu2BRm\",\n  vmovntps_2 =\t\"xroy:0Fu2BRm\",\n  vmovsd_2 =\t\"rx/oq:F20Fu10rM|xr/qo:F20Fu11Rm\",\n  vmovsd_3 =\t\"rrro:F20FV10rM\",\n  vmovshdup_2 =\t\"rmoy:F30Fu16rM\",\n  vmovsldup_2 =\t\"rmoy:F30Fu12rM\",\n  vmovss_2 =\t\"rx/od:F30Fu10rM|xr/do:F30Fu11Rm\",\n  vmovss_3 =\t\"rrro:F30FV10rM\",\n  vmovupd_2 =\t\"rmoy:660Fu10rM|mroy:660Fu11Rm\",\n  vmovups_2 =\t\"rmoy:0Fu10rM|mroy:0Fu11Rm\",\n  vorpd_3 =\t\"rrmoy:660FV56rM\",\n  vorps_3 =\t\"rrmoy:0FV56rM\",\n  vpermilpd_3 =\t\"rrmoy:660F38V0DrM|rmioy:660F3Au05rMU\",\n  vpermilps_3 =\t\"rrmoy:660F38V0CrM|rmioy:660F3Au04rMU\",\n  vperm2f128_4 = \"rrmiy:660F3AV06rMU\",\n  vptestpd_2 =\t\"rmoy:660F38u0FrM\",\n  vptestps_2 =\t\"rmoy:660F38u0ErM\",\n  vrcpps_2 =\t\"rmoy:0Fu53rM\",\n  vrcpss_3 =\t\"rrro:F30FV53rM|rrx/ood:\",\n  vrsqrtps_2 =\t\"rmoy:0Fu52rM\",\n  vrsqrtss_3 =\t\"rrro:F30FV52rM|rrx/ood:\",\n  vroundpd_3 =\t\"rmioy:660F3Au09rMU\",\n  vroundps_3 =\t\"rmioy:660F3Au08rMU\",\n  vroundsd_4 =\t\"rrrio:660F3AV0BrMU|rrxi/ooq:\",\n  vroundss_4 =\t\"rrrio:660F3AV0ArMU|rrxi/ood:\",\n  vshufpd_4 =\t\"rrmioy:660FVC6rMU\",\n  vshufps_4 =\t\"rrmioy:0FVC6rMU\",\n  vsqrtps_2 =\t\"rmoy:0Fu51rM\",\n  vsqrtss_2 =\t\"rro:F30Fu51rM|rx/od:\",\n  vsqrtpd_2 =\t\"rmoy:660Fu51rM\",\n  vsqrtsd_2 =\t\"rro:F20Fu51rM|rx/oq:\",\n  vstmxcsr_1 =\t\"xd:0FuAE3m\",\n  vucomisd_2 =\t\"rro:660Fu2ErM|rx/oq:\",\n  vucomiss_2 =\t\"rro:0Fu2ErM|rx/od:\",\n  vunpckhpd_3 =\t\"rrmoy:660FV15rM\",\n  vunpckhps_3 =\t\"rrmoy:0FV15rM\",\n  vunpcklpd_3 =\t\"rrmoy:660FV14rM\",\n  vunpcklps_3 =\t\"rrmoy:0FV14rM\",\n  vxorpd_3 =\t\"rrmoy:660FV57rM\",\n  vxorps_3 =\t\"rrmoy:0FV57rM\",\n  vzeroall_0 =\t\"0FuL77\",\n  vzeroupper_0 = \"0Fu77\",\n\n  -- AVX2 FP ops\n  vbroadcastss_2 = \"rx/od:660F38u18rM|rx/yd:|rro:|rr/yo:\",\n  vbroadcastsd_2 = \"rx/yq:660F38u19rM|rr/yo:\",\n  -- *vgather* (!vsib)\n  vpermpd_3 =\t\"rmiy:660F3AuX01rMU\",\n  vpermps_3 =\t\"rrmy:660F38V16rM\",\n\n  -- AVX, AVX2 integer ops\n  -- In general, xmm requires AVX, ymm requires AVX2.\n  vaesdec_3 =  \"rrmo:660F38VDErM\",\n  vaesdeclast_3 = \"rrmo:660F38VDFrM\",\n  vaesenc_3 =  \"rrmo:660F38VDCrM\",\n  vaesenclast_3 = \"rrmo:660F38VDDrM\",\n  vaesimc_2 =  \"rmo:660F38uDBrM\",\n  vaeskeygenassist_3 = \"rmio:660F3AuDFrMU\",\n  vlddqu_2 =\t\"rxoy:F20FuF0rM\",\n  vmaskmovdqu_2 = \"rro:660FuF7rM\",\n  vmovdqa_2 =\t\"rmoy:660Fu6FrM|mroy:660Fu7FRm\",\n  vmovdqu_2 =\t\"rmoy:F30Fu6FrM|mroy:F30Fu7FRm\",\n  vmovntdq_2 =\t\"xroy:660FuE7Rm\",\n  vmovntdqa_2 =\t\"rxoy:660F38u2ArM\",\n  vmpsadbw_4 =\t\"rrmioy:660F3AV42rMU\",\n  vpabsb_2 =\t\"rmoy:660F38u1CrM\",\n  vpabsd_2 =\t\"rmoy:660F38u1ErM\",\n  vpabsw_2 =\t\"rmoy:660F38u1DrM\",\n  vpackusdw_3 =\t\"rrmoy:660F38V2BrM\",\n  vpalignr_4 =\t\"rrmioy:660F3AV0FrMU\",\n  vpblendvb_4 =\t\"rrmroy:660F3AV4CrMs\",\n  vpblendw_4 =\t\"rrmioy:660F3AV0ErMU\",\n  vpclmulqdq_4 = \"rrmio:660F3AV44rMU\",\n  vpcmpeqq_3 =\t\"rrmoy:660F38V29rM\",\n  vpcmpestri_3 = \"rmio:660F3Au61rMU\",\n  vpcmpestrm_3 = \"rmio:660F3Au60rMU\",\n  vpcmpgtq_3 =\t\"rrmoy:660F38V37rM\",\n  vpcmpistri_3 = \"rmio:660F3Au63rMU\",\n  vpcmpistrm_3 = \"rmio:660F3Au62rMU\",\n  vpextrb_3 =\t\"rri/do:660F3Au14nRmU|rri/qo:|xri/bo:\",\n  vpextrw_3 =\t\"rri/do:660FuC5rMU|xri/wo:660F3Au15nRmU\",\n  vpextrd_3 =\t\"mri/do:660F3Au16RmU\",\n  vpextrq_3 =\t\"mri/qo:660F3Au16RmU\",\n  vphaddw_3 =\t\"rrmoy:660F38V01rM\",\n  vphaddd_3 =\t\"rrmoy:660F38V02rM\",\n  vphaddsw_3 =\t\"rrmoy:660F38V03rM\",\n  vphminposuw_2 = \"rmo:660F38u41rM\",\n  vphsubw_3 =\t\"rrmoy:660F38V05rM\",\n  vphsubd_3 =\t\"rrmoy:660F38V06rM\",\n  vphsubsw_3 =\t\"rrmoy:660F38V07rM\",\n  vpinsrb_4 =\t\"rrri/ood:660F3AV20rMU|rrxi/oob:\",\n  vpinsrw_4 =\t\"rrri/ood:660FVC4rMU|rrxi/oow:\",\n  vpinsrd_4 =\t\"rrmi/ood:660F3AV22rMU\",\n  vpinsrq_4 =\t\"rrmi/ooq:660F3AVX22rMU\",\n  vpmaddubsw_3 = \"rrmoy:660F38V04rM\",\n  vpmaxsb_3 =\t\"rrmoy:660F38V3CrM\",\n  vpmaxsd_3 =\t\"rrmoy:660F38V3DrM\",\n  vpmaxuw_3 =\t\"rrmoy:660F38V3ErM\",\n  vpmaxud_3 =\t\"rrmoy:660F38V3FrM\",\n  vpminsb_3 =\t\"rrmoy:660F38V38rM\",\n  vpminsd_3 =\t\"rrmoy:660F38V39rM\",\n  vpminuw_3 =\t\"rrmoy:660F38V3ArM\",\n  vpminud_3 =\t\"rrmoy:660F38V3BrM\",\n  vpmovmskb_2 =\t\"rr/do:660FuD7rM|rr/dy:660FuLD7rM\",\n  vpmovsxbw_2 =\t\"rroy:660F38u20rM|rx/oq:|rx/yo:\",\n  vpmovsxbd_2 =\t\"rroy:660F38u21rM|rx/od:|rx/yq:\",\n  vpmovsxbq_2 =\t\"rroy:660F38u22rM|rx/ow:|rx/yd:\",\n  vpmovsxwd_2 =\t\"rroy:660F38u23rM|rx/oq:|rx/yo:\",\n  vpmovsxwq_2 =\t\"rroy:660F38u24rM|rx/od:|rx/yq:\",\n  vpmovsxdq_2 =\t\"rroy:660F38u25rM|rx/oq:|rx/yo:\",\n  vpmovzxbw_2 =\t\"rroy:660F38u30rM|rx/oq:|rx/yo:\",\n  vpmovzxbd_2 =\t\"rroy:660F38u31rM|rx/od:|rx/yq:\",\n  vpmovzxbq_2 =\t\"rroy:660F38u32rM|rx/ow:|rx/yd:\",\n  vpmovzxwd_2 =\t\"rroy:660F38u33rM|rx/oq:|rx/yo:\",\n  vpmovzxwq_2 =\t\"rroy:660F38u34rM|rx/od:|rx/yq:\",\n  vpmovzxdq_2 =\t\"rroy:660F38u35rM|rx/oq:|rx/yo:\",\n  vpmuldq_3 =\t\"rrmoy:660F38V28rM\",\n  vpmulhrsw_3 =\t\"rrmoy:660F38V0BrM\",\n  vpmulld_3 =\t\"rrmoy:660F38V40rM\",\n  vpshufb_3 =\t\"rrmoy:660F38V00rM\",\n  vpshufd_3 =\t\"rmioy:660Fu70rMU\",\n  vpshufhw_3 =\t\"rmioy:F30Fu70rMU\",\n  vpshuflw_3 =\t\"rmioy:F20Fu70rMU\",\n  vpsignb_3 =\t\"rrmoy:660F38V08rM\",\n  vpsignw_3 =\t\"rrmoy:660F38V09rM\",\n  vpsignd_3 =\t\"rrmoy:660F38V0ArM\",\n  vpslldq_3 =\t\"rrioy:660Fv737mU\",\n  vpsllw_3 =\t\"rrmoy:660FVF1rM|rrioy:660Fv716mU\",\n  vpslld_3 =\t\"rrmoy:660FVF2rM|rrioy:660Fv726mU\",\n  vpsllq_3 =\t\"rrmoy:660FVF3rM|rrioy:660Fv736mU\",\n  vpsraw_3 =\t\"rrmoy:660FVE1rM|rrioy:660Fv714mU\",\n  vpsrad_3 =\t\"rrmoy:660FVE2rM|rrioy:660Fv724mU\",\n  vpsrldq_3 =\t\"rrioy:660Fv733mU\",\n  vpsrlw_3 =\t\"rrmoy:660FVD1rM|rrioy:660Fv712mU\",\n  vpsrld_3 =\t\"rrmoy:660FVD2rM|rrioy:660Fv722mU\",\n  vpsrlq_3 =\t\"rrmoy:660FVD3rM|rrioy:660Fv732mU\",\n  vptest_2 =\t\"rmoy:660F38u17rM\",\n\n  -- AVX2 integer ops\n  vbroadcasti128_2 = \"rx/yo:660F38u5ArM\",\n  vinserti128_4 = \"rrmi/yyo:660F3AV38rMU\",\n  vextracti128_3 = \"mri/oy:660F3AuL39RmU\",\n  vpblendd_4 =\t\"rrmioy:660F3AV02rMU\",\n  vpbroadcastb_2 = \"rro:660F38u78rM|rx/ob:|rr/yo:|rx/yb:\",\n  vpbroadcastw_2 = \"rro:660F38u79rM|rx/ow:|rr/yo:|rx/yw:\",\n  vpbroadcastd_2 = \"rro:660F38u58rM|rx/od:|rr/yo:|rx/yd:\",\n  vpbroadcastq_2 = \"rro:660F38u59rM|rx/oq:|rr/yo:|rx/yq:\",\n  vpermd_3 =\t\"rrmy:660F38V36rM\",\n  vpermq_3 =\t\"rmiy:660F3AuX00rMU\",\n  -- *vpgather* (!vsib)\n  vperm2i128_4 = \"rrmiy:660F3AV46rMU\",\n  vpmaskmovd_3 = \"rrxoy:660F38V8CrM|xrroy:660F38V8ERm\",\n  vpmaskmovq_3 = \"rrxoy:660F38VX8CrM|xrroy:660F38VX8ERm\",\n  vpsllvd_3 =\t\"rrmoy:660F38V47rM\",\n  vpsllvq_3 =\t\"rrmoy:660F38VX47rM\",\n  vpsravd_3 =\t\"rrmoy:660F38V46rM\",\n  vpsrlvd_3 =\t\"rrmoy:660F38V45rM\",\n  vpsrlvq_3 =\t\"rrmoy:660F38VX45rM\",\n\n  -- Intel ADX\n  adcx_2 =\t\"rmqd:660F38F6rM\",\n  adox_2 =\t\"rmqd:F30F38F6rM\",\n\n  -- BMI1\n  andn_3 =\t\"rrmqd:0F38VF2rM\",\n  bextr_3 =\t\"rmrqd:0F38wF7rM\",\n  blsi_2 =\t\"rmqd:0F38vF33m\",\n  blsmsk_2 =\t\"rmqd:0F38vF32m\",\n  blsr_2 =\t\"rmqd:0F38vF31m\",\n  tzcnt_2 =\t\"rmqdw:F30FBCrM\",\n\n  -- BMI2\n  bzhi_3 =\t\"rmrqd:0F38wF5rM\",\n  mulx_3 =\t\"rrmqd:F20F38VF6rM\",\n  pdep_3 =\t\"rrmqd:F20F38VF5rM\",\n  pext_3 =\t\"rrmqd:F30F38VF5rM\",\n  rorx_3 =\t\"rmSqd:F20F3AuF0rMS\",\n  sarx_3 =\t\"rmrqd:F30F38wF7rM\",\n  shrx_3 =\t\"rmrqd:F20F38wF7rM\",\n  shlx_3 =\t\"rmrqd:660F38wF7rM\",\n\n  -- FMA3\n  vfmaddsub132pd_3 = \"rrmoy:660F38VX96rM\",\n  vfmaddsub132ps_3 = \"rrmoy:660F38V96rM\",\n  vfmaddsub213pd_3 = \"rrmoy:660F38VXA6rM\",\n  vfmaddsub213ps_3 = \"rrmoy:660F38VA6rM\",\n  vfmaddsub231pd_3 = \"rrmoy:660F38VXB6rM\",\n  vfmaddsub231ps_3 = \"rrmoy:660F38VB6rM\",\n\n  vfmsubadd132pd_3 = \"rrmoy:660F38VX97rM\",\n  vfmsubadd132ps_3 = \"rrmoy:660F38V97rM\",\n  vfmsubadd213pd_3 = \"rrmoy:660F38VXA7rM\",\n  vfmsubadd213ps_3 = \"rrmoy:660F38VA7rM\",\n  vfmsubadd231pd_3 = \"rrmoy:660F38VXB7rM\",\n  vfmsubadd231ps_3 = \"rrmoy:660F38VB7rM\",\n\n  vfmadd132pd_3 = \"rrmoy:660F38VX98rM\",\n  vfmadd132ps_3 = \"rrmoy:660F38V98rM\",\n  vfmadd132sd_3 = \"rrro:660F38VX99rM|rrx/ooq:\",\n  vfmadd132ss_3 = \"rrro:660F38V99rM|rrx/ood:\",\n  vfmadd213pd_3 = \"rrmoy:660F38VXA8rM\",\n  vfmadd213ps_3 = \"rrmoy:660F38VA8rM\",\n  vfmadd213sd_3 = \"rrro:660F38VXA9rM|rrx/ooq:\",\n  vfmadd213ss_3 = \"rrro:660F38VA9rM|rrx/ood:\",\n  vfmadd231pd_3 = \"rrmoy:660F38VXB8rM\",\n  vfmadd231ps_3 = \"rrmoy:660F38VB8rM\",\n  vfmadd231sd_3 = \"rrro:660F38VXB9rM|rrx/ooq:\",\n  vfmadd231ss_3 = \"rrro:660F38VB9rM|rrx/ood:\",\n\n  vfmsub132pd_3 = \"rrmoy:660F38VX9ArM\",\n  vfmsub132ps_3 = \"rrmoy:660F38V9ArM\",\n  vfmsub132sd_3 = \"rrro:660F38VX9BrM|rrx/ooq:\",\n  vfmsub132ss_3 = \"rrro:660F38V9BrM|rrx/ood:\",\n  vfmsub213pd_3 = \"rrmoy:660F38VXAArM\",\n  vfmsub213ps_3 = \"rrmoy:660F38VAArM\",\n  vfmsub213sd_3 = \"rrro:660F38VXABrM|rrx/ooq:\",\n  vfmsub213ss_3 = \"rrro:660F38VABrM|rrx/ood:\",\n  vfmsub231pd_3 = \"rrmoy:660F38VXBArM\",\n  vfmsub231ps_3 = \"rrmoy:660F38VBArM\",\n  vfmsub231sd_3 = \"rrro:660F38VXBBrM|rrx/ooq:\",\n  vfmsub231ss_3 = \"rrro:660F38VBBrM|rrx/ood:\",\n\n  vfnmadd132pd_3 = \"rrmoy:660F38VX9CrM\",\n  vfnmadd132ps_3 = \"rrmoy:660F38V9CrM\",\n  vfnmadd132sd_3 = \"rrro:660F38VX9DrM|rrx/ooq:\",\n  vfnmadd132ss_3 = \"rrro:660F38V9DrM|rrx/ood:\",\n  vfnmadd213pd_3 = \"rrmoy:660F38VXACrM\",\n  vfnmadd213ps_3 = \"rrmoy:660F38VACrM\",\n  vfnmadd213sd_3 = \"rrro:660F38VXADrM|rrx/ooq:\",\n  vfnmadd213ss_3 = \"rrro:660F38VADrM|rrx/ood:\",\n  vfnmadd231pd_3 = \"rrmoy:660F38VXBCrM\",\n  vfnmadd231ps_3 = \"rrmoy:660F38VBCrM\",\n  vfnmadd231sd_3 = \"rrro:660F38VXBDrM|rrx/ooq:\",\n  vfnmadd231ss_3 = \"rrro:660F38VBDrM|rrx/ood:\",\n\n  vfnmsub132pd_3 = \"rrmoy:660F38VX9ErM\",\n  vfnmsub132ps_3 = \"rrmoy:660F38V9ErM\",\n  vfnmsub132sd_3 = \"rrro:660F38VX9FrM|rrx/ooq:\",\n  vfnmsub132ss_3 = \"rrro:660F38V9FrM|rrx/ood:\",\n  vfnmsub213pd_3 = \"rrmoy:660F38VXAErM\",\n  vfnmsub213ps_3 = \"rrmoy:660F38VAErM\",\n  vfnmsub213sd_3 = \"rrro:660F38VXAFrM|rrx/ooq:\",\n  vfnmsub213ss_3 = \"rrro:660F38VAFrM|rrx/ood:\",\n  vfnmsub231pd_3 = \"rrmoy:660F38VXBErM\",\n  vfnmsub231ps_3 = \"rrmoy:660F38VBErM\",\n  vfnmsub231sd_3 = \"rrro:660F38VXBFrM|rrx/ooq:\",\n  vfnmsub231ss_3 = \"rrro:660F38VBFrM|rrx/ood:\",\n}\n\n------------------------------------------------------------------------------\n\n-- Arithmetic ops.\nfor name,n in pairs{ add = 0, [\"or\"] = 1, adc = 2, sbb = 3,\n\t\t     [\"and\"] = 4, sub = 5, xor = 6, cmp = 7 } do\n  local n8 = shl(n, 3)\n  map_op[name..\"_2\"] = format(\n    \"mr:%02XRm|rm:%02XrM|mI1qdw:81%XmI|mS1qdw:83%XmS|Ri1qdwb:%02Xri|mi1qdwb:81%Xmi\",\n    1+n8, 3+n8, n, n, 5+n8, n)\nend\n\n-- Shift ops.\nfor name,n in pairs{ rol = 0, ror = 1, rcl = 2, rcr = 3,\n\t\t     shl = 4, shr = 5,          sar = 7, sal = 4 } do\n  map_op[name..\"_2\"] = format(\"m1:D1%Xm|mC1qdwb:D3%Xm|mi:C1%XmU\", n, n, n)\nend\n\n-- Conditional ops.\nfor cc,n in pairs(map_cc) do\n  map_op[\"j\"..cc..\"_1\"] = format(\"J.:n0F8%XJ\", n) -- short: 7%X\n  map_op[\"set\"..cc..\"_1\"] = format(\"mb:n0F9%X2m\", n)\n  map_op[\"cmov\"..cc..\"_2\"] = format(\"rmqdw:0F4%XrM\", n) -- P6+\nend\n\n-- FP arithmetic ops.\nfor name,n in pairs{ add = 0, mul = 1, com = 2, comp = 3,\n\t\t     sub = 4, subr = 5, div = 6, divr = 7 } do\n  local nc = 0xc0 + shl(n, 3)\n  local nr = nc + (n < 4 and 0 or (n % 2 == 0 and 8 or -8))\n  local fn = \"f\"..name\n  map_op[fn..\"_1\"] = format(\"ff:D8%02Xr|xd:D8%Xm|xq:nDC%Xm\", nc, n, n)\n  if n == 2 or n == 3 then\n    map_op[fn..\"_2\"] = format(\"Fff:D8%02XR|Fx2d:D8%XM|Fx2q:nDC%XM\", nc, n, n)\n  else\n    map_op[fn..\"_2\"] = format(\"Fff:D8%02XR|fFf:DC%02Xr|Fx2d:D8%XM|Fx2q:nDC%XM\", nc, nr, n, n)\n    map_op[fn..\"p_1\"] = format(\"ff:DE%02Xr\", nr)\n    map_op[fn..\"p_2\"] = format(\"fFf:DE%02Xr\", nr)\n  end\n  map_op[\"fi\"..name..\"_1\"] = format(\"xd:DA%Xm|xw:nDE%Xm\", n, n)\nend\n\n-- FP conditional moves.\nfor cc,n in pairs{ b=0, e=1, be=2, u=3, nb=4, ne=5, nbe=6, nu=7 } do\n  local nc = 0xdac0 + shl(band(n, 3), 3) + shl(band(n, 4), 6)\n  map_op[\"fcmov\"..cc..\"_1\"] = format(\"ff:%04Xr\", nc) -- P6+\n  map_op[\"fcmov\"..cc..\"_2\"] = format(\"Fff:%04XR\", nc) -- P6+\nend\n\n-- SSE / AVX FP arithmetic ops.\nfor name,n in pairs{ sqrt = 1, add = 8, mul = 9,\n\t\t     sub = 12, min = 13, div = 14, max = 15 } do\n  map_op[name..\"ps_2\"] = format(\"rmo:0F5%XrM\", n)\n  map_op[name..\"ss_2\"] = format(\"rro:F30F5%XrM|rx/od:\", n)\n  map_op[name..\"pd_2\"] = format(\"rmo:660F5%XrM\", n)\n  map_op[name..\"sd_2\"] = format(\"rro:F20F5%XrM|rx/oq:\", n)\n  if n ~= 1 then\n    map_op[\"v\"..name..\"ps_3\"] = format(\"rrmoy:0FV5%XrM\", n)\n    map_op[\"v\"..name..\"ss_3\"] = format(\"rrro:F30FV5%XrM|rrx/ood:\", n)\n    map_op[\"v\"..name..\"pd_3\"] = format(\"rrmoy:660FV5%XrM\", n)\n    map_op[\"v\"..name..\"sd_3\"] = format(\"rrro:F20FV5%XrM|rrx/ooq:\", n)\n  end\nend\n\n-- SSE2 / AVX / AVX2 integer arithmetic ops (66 0F leaf).\nfor name,n in pairs{\n  paddb = 0xFC, paddw = 0xFD, paddd = 0xFE, paddq = 0xD4,\n  paddsb = 0xEC, paddsw = 0xED, packssdw = 0x6B,\n  packsswb = 0x63, packuswb = 0x67, paddusb = 0xDC,\n  paddusw = 0xDD, pand = 0xDB, pandn = 0xDF, pavgb = 0xE0,\n  pavgw = 0xE3, pcmpeqb = 0x74, pcmpeqd = 0x76,\n  pcmpeqw = 0x75, pcmpgtb = 0x64, pcmpgtd = 0x66,\n  pcmpgtw = 0x65, pmaddwd = 0xF5, pmaxsw = 0xEE,\n  pmaxub = 0xDE, pminsw = 0xEA, pminub = 0xDA,\n  pmulhuw = 0xE4, pmulhw = 0xE5, pmullw = 0xD5,\n  pmuludq = 0xF4, por = 0xEB, psadbw = 0xF6, psubb = 0xF8,\n  psubw = 0xF9, psubd = 0xFA, psubq = 0xFB, psubsb = 0xE8,\n  psubsw = 0xE9, psubusb = 0xD8, psubusw = 0xD9,\n  punpckhbw = 0x68, punpckhwd = 0x69, punpckhdq = 0x6A,\n  punpckhqdq = 0x6D, punpcklbw = 0x60, punpcklwd = 0x61,\n  punpckldq = 0x62, punpcklqdq = 0x6C, pxor = 0xEF\n} do\n  map_op[name..\"_2\"] = format(\"rmo:660F%02XrM\", n)\n  map_op[\"v\"..name..\"_3\"] = format(\"rrmoy:660FV%02XrM\", n)\nend\n\n------------------------------------------------------------------------------\n\nlocal map_vexarg = { u = false, v = 1, V = 2, w = 3 }\n\n-- Process pattern string.\nlocal function dopattern(pat, args, sz, op, needrex)\n  local digit, addin, vex\n  local opcode = 0\n  local szov = sz\n  local narg = 1\n  local rex = 0\n\n  -- Limit number of section buffer positions used by a single dasm_put().\n  -- A single opcode needs a maximum of 6 positions.\n  if secpos+6 > maxsecpos then wflush() end\n\n  -- Process each character.\n  for c in gmatch(pat..\"|\", \".\") do\n    if match(c, \"%x\") then\t-- Hex digit.\n      digit = byte(c) - 48\n      if digit > 48 then digit = digit - 39\n      elseif digit > 16 then digit = digit - 7 end\n      opcode = opcode*16 + digit\n      addin = nil\n    elseif c == \"n\" then\t-- Disable operand size mods for opcode.\n      szov = nil\n    elseif c == \"X\" then\t-- Force REX.W.\n      rex = 8\n    elseif c == \"L\" then\t-- Force VEX.L.\n      vex.l = true\n    elseif c == \"r\" then\t-- Merge 1st operand regno. into opcode.\n      addin = args[1]; opcode = opcode + (addin.reg % 8)\n      if narg < 2 then narg = 2 end\n    elseif c == \"R\" then\t-- Merge 2nd operand regno. into opcode.\n      addin = args[2]; opcode = opcode + (addin.reg % 8)\n      narg = 3\n    elseif c == \"m\" or c == \"M\" then\t-- Encode ModRM/SIB.\n      local s\n      if addin then\n\ts = addin.reg\n\topcode = opcode - band(s, 7)\t-- Undo regno opcode merge.\n      else\n\ts = band(opcode, 15)\t-- Undo last digit.\n\topcode = shr(opcode, 4)\n      end\n      local nn = c == \"m\" and 1 or 2\n      local t = args[nn]\n      if narg <= nn then narg = nn + 1 end\n      if szov == \"q\" and rex == 0 then rex = rex + 8 end\n      if t.reg and t.reg > 7 then rex = rex + 1 end\n      if t.xreg and t.xreg > 7 then rex = rex + 2 end\n      if s > 7 then rex = rex + 4 end\n      if needrex then rex = rex + 16 end\n      local psz, sk = wputop(szov, opcode, rex, vex, s < 0, t.vreg or t.vxreg)\n      opcode = nil\n      local imark = sub(pat, -1) -- Force a mark (ugly).\n      -- Put ModRM/SIB with regno/last digit as spare.\n      wputmrmsib(t, imark, s, addin and addin.vreg, psz, sk)\n      addin = nil\n    elseif map_vexarg[c] ~= nil then -- Encode using VEX prefix\n      local b = band(opcode, 255); opcode = shr(opcode, 8)\n      local m = 1\n      if b == 0x38 then m = 2\n      elseif b == 0x3a then m = 3 end\n      if m ~= 1 then b = band(opcode, 255); opcode = shr(opcode, 8) end\n      if b ~= 0x0f then\n\twerror(\"expected `0F', `0F38', or `0F3A' to precede `\"..c..\n\t  \"' in pattern `\"..pat..\"' for `\"..op..\"'\")\n      end\n      local v = map_vexarg[c]\n      if v then v = remove(args, v) end\n      b = band(opcode, 255)\n      local p = 0\n      if b == 0x66 then p = 1\n      elseif b == 0xf3 then p = 2\n      elseif b == 0xf2 then p = 3 end\n      if p ~= 0 then opcode = shr(opcode, 8) end\n      if opcode ~= 0 then wputop(nil, opcode, 0); opcode = 0 end\n      vex = { m = m, p = p, v = v }\n    else\n      if opcode then -- Flush opcode.\n\tif szov == \"q\" and rex == 0 then rex = rex + 8 end\n\tif needrex then rex = rex + 16 end\n\tif addin and addin.reg == -1 then\n\t  local psz, sk = wputop(szov, opcode - 7, rex, vex, true)\n\t  wvreg(\"opcode\", addin.vreg, psz, sk)\n\telse\n\t  if addin and addin.reg > 7 then rex = rex + 1 end\n\t  wputop(szov, opcode, rex, vex)\n\tend\n\topcode = nil\n      end\n      if c == \"|\" then break end\n      if c == \"o\" then -- Offset (pure 32 bit displacement).\n\twputdarg(args[1].disp); if narg < 2 then narg = 2 end\n      elseif c == \"O\" then\n\twputdarg(args[2].disp); narg = 3\n      else\n\t-- Anything else is an immediate operand.\n\tlocal a = args[narg]\n\tnarg = narg + 1\n\tlocal mode, imm = a.mode, a.imm\n\tif mode == \"iJ\" and not match(x64 and \"J\" or \"iIJ\", c) then\n\t  werror(\"bad operand size for label\")\n\tend\n\tif c == \"S\" then\n\t  wputsbarg(imm)\n\telseif c == \"U\" then\n\t  wputbarg(imm)\n\telseif c == \"W\" then\n\t  wputwarg(imm)\n\telseif c == \"i\" or c == \"I\" then\n\t  if mode == \"iJ\" then\n\t    wputlabel(\"IMM_\", imm, 1)\n\t  elseif mode == \"iI\" and c == \"I\" then\n\t    waction(sz == \"w\" and \"IMM_WB\" or \"IMM_DB\", imm)\n\t  else\n\t    wputszarg(sz, imm)\n\t  end\n\telseif c == \"J\" then\n\t  if mode == \"iPJ\" then\n\t    waction(\"REL_A\", imm) -- !x64 (secpos)\n\t  else\n\t    wputlabel(\"REL_\", imm, 2)\n\t  end\n\telseif c == \"s\" then\n\t  local reg = a.reg\n\t  if reg < 0 then\n\t    wputb(0)\n\t    wvreg(\"imm.hi\", a.vreg)\n\t  else\n\t    wputb(shl(reg, 4))\n\t  end\n\telse\n\t  werror(\"bad char `\"..c..\"' in pattern `\"..pat..\"' for `\"..op..\"'\")\n\tend\n      end\n    end\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Mapping of operand modes to short names. Suppress output with '#'.\nlocal map_modename = {\n  r = \"reg\", R = \"eax\", C = \"cl\", x = \"mem\", m = \"mrm\", i = \"imm\",\n  f = \"stx\", F = \"st0\", J = \"lbl\", [\"1\"] = \"1\",\n  I = \"#\", S = \"#\", O = \"#\",\n}\n\n-- Return a table/string showing all possible operand modes.\nlocal function templatehelp(template, nparams)\n  if nparams == 0 then return \"\" end\n  local t = {}\n  for tm in gmatch(template, \"[^%|]+\") do\n    local s = map_modename[sub(tm, 1, 1)]\n    s = s..gsub(sub(tm, 2, nparams), \".\", function(c)\n      return \", \"..map_modename[c]\n    end)\n    if not match(s, \"#\") then t[#t+1] = s end\n  end\n  return t\nend\n\n-- Match operand modes against mode match part of template.\nlocal function matchtm(tm, args)\n  for i=1,#args do\n    if not match(args[i].mode, sub(tm, i, i)) then return end\n  end\n  return true\nend\n\n-- Handle opcodes defined with template strings.\nmap_op[\".template__\"] = function(params, template, nparams)\n  if not params then return templatehelp(template, nparams) end\n  local args = {}\n\n  -- Zero-operand opcodes have no match part.\n  if #params == 0 then\n    dopattern(template, args, \"d\", params.op, nil)\n    return\n  end\n\n  -- Determine common operand size (coerce undefined size) or flag as mixed.\n  local sz, szmix, needrex\n  for i,p in ipairs(params) do\n    args[i] = parseoperand(p)\n    local nsz = args[i].opsize\n    if nsz then\n      if sz and sz ~= nsz then szmix = true else sz = nsz end\n    end\n    local nrex = args[i].needrex\n    if nrex ~= nil then\n      if needrex == nil then\n\tneedrex = nrex\n      elseif needrex ~= nrex then\n\twerror(\"bad mix of byte-addressable registers\")\n      end\n    end\n  end\n\n  -- Try all match:pattern pairs (separated by '|').\n  local gotmatch, lastpat\n  for tm in gmatch(template, \"[^%|]+\") do\n    -- Split off size match (starts after mode match) and pattern string.\n    local szm, pat = match(tm, \"^(.-):(.*)$\", #args+1)\n    if pat == \"\" then pat = lastpat else lastpat = pat end\n    if matchtm(tm, args) then\n      local prefix = sub(szm, 1, 1)\n      if prefix == \"/\" then -- Exactly match leading operand sizes.\n\tfor i = #szm,1,-1 do\n\t  if i == 1 then\n\t    dopattern(pat, args, sz, params.op, needrex) -- Process pattern.\n\t    return\n\t  elseif args[i-1].opsize ~= sub(szm, i, i) then\n\t    break\n\t  end\n\tend\n      else -- Match common operand size.\n\tlocal szp = sz\n\tif szm == \"\" then szm = x64 and \"qdwb\" or \"dwb\" end -- Default sizes.\n\tif prefix == \"1\" then szp = args[1].opsize; szmix = nil\n\telseif prefix == \"2\" then szp = args[2].opsize; szmix = nil end\n\tif not szmix and (prefix == \".\" or match(szm, szp or \"#\")) then\n\t  dopattern(pat, args, szp, params.op, needrex) -- Process pattern.\n\t  return\n\tend\n      end\n      gotmatch = true\n    end\n  end\n\n  local msg = \"bad operand mode\"\n  if gotmatch then\n    if szmix then\n      msg = \"mixed operand size\"\n    else\n      msg = sz and \"bad operand size\" or \"missing operand size\"\n    end\n  end\n\n  werror(msg..\" in `\"..opmodestr(params.op, args)..\"'\")\nend\n\n------------------------------------------------------------------------------\n\n-- x64-specific opcode for 64 bit immediates and displacements.\nif x64 then\n  function map_op.mov64_2(params)\n    if not params then return { \"reg, imm\", \"reg, [disp]\", \"[disp], reg\" } end\n    if secpos+2 > maxsecpos then wflush() end\n    local opcode, op64, sz, rex, vreg\n    local op64 = match(params[1], \"^%[%s*(.-)%s*%]$\")\n    if op64 then\n      local a = parseoperand(params[2])\n      if a.mode ~= \"rmR\" then werror(\"bad operand mode\") end\n      sz = a.opsize\n      rex = sz == \"q\" and 8 or 0\n      opcode = 0xa3\n    else\n      op64 = match(params[2], \"^%[%s*(.-)%s*%]$\")\n      local a = parseoperand(params[1])\n      if op64 then\n\tif a.mode ~= \"rmR\" then werror(\"bad operand mode\") end\n\tsz = a.opsize\n\trex = sz == \"q\" and 8 or 0\n\topcode = 0xa1\n      else\n\tif sub(a.mode, 1, 1) ~= \"r\" or a.opsize ~= \"q\" then\n\t  werror(\"bad operand mode\")\n\tend\n\top64 = params[2]\n\tif a.reg == -1 then\n\t  vreg = a.vreg\n\t  opcode = 0xb8\n\telse\n\t  opcode = 0xb8 + band(a.reg, 7)\n\tend\n\trex = a.reg > 7 and 9 or 8\n      end\n    end\n    local psz, sk = wputop(sz, opcode, rex, nil, vreg)\n    wvreg(\"opcode\", vreg, psz, sk)\n    waction(\"IMM_D\", format(\"(unsigned int)(%s)\", op64))\n    waction(\"IMM_D\", format(\"(unsigned int)((%s)>>32)\", op64))\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcodes for data storage.\nlocal function op_data(params)\n  if not params then return \"imm...\" end\n  local sz = sub(params.op, 2, 2)\n  if sz == \"l\" then sz = \"d\" elseif sz == \"a\" then sz = addrsize end\n  for _,p in ipairs(params) do\n    local a = parseoperand(p, sz == \"q\")\n    if sub(a.mode, 1, 1) ~= \"i\" or (a.opsize and a.opsize ~= sz) then\n      werror(\"bad mode or size in `\"..p..\"'\")\n    end\n    if a.mode == \"iJ\" then\n      wputlabel(\"IMM_\", a.imm, 1)\n    elseif sz == \"q\" then\n      wputqarg(a.imm)\n    else\n      wputszarg(sz, a.imm)\n    end\n    if secpos+2 > maxsecpos then wflush() end\n  end\nend\n\nmap_op[\".byte_*\"] = op_data\nmap_op[\".sbyte_*\"] = op_data\nmap_op[\".word_*\"] = op_data\nmap_op[\".dword_*\"] = op_data\nmap_op[\".qword_*\"] = op_data\nmap_op[\".aword_*\"] = op_data\nmap_op[\".long_*\"] = op_data\nmap_op[\".quad_*\"] = op_data\nmap_op[\".addr_*\"] = op_data\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode to mark the position where the action list is to be emitted.\nmap_op[\".actionlist_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeactions(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the global enum is to be emitted.\nmap_op[\".globals_1\"] = function(params)\n  if not params then return \"prefix\" end\n  local prefix = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobals(out, prefix) end)\nend\n\n-- Pseudo-opcode to mark the position where the global names are to be emitted.\nmap_op[\".globalnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeglobalnames(out, name) end)\nend\n\n-- Pseudo-opcode to mark the position where the extern names are to be emitted.\nmap_op[\".externnames_1\"] = function(params)\n  if not params then return \"cvar\" end\n  local name = params[1] -- No syntax check. You get to keep the pieces.\n  wline(function(out) writeexternnames(out, name) end)\nend\n\n------------------------------------------------------------------------------\n\n-- Label pseudo-opcode (converted from trailing colon form).\nmap_op[\".label_2\"] = function(params)\n  if not params then return \"[1-9] | ->global | =>pcexpr  [, addr]\" end\n  if secpos+2 > maxsecpos then wflush() end\n  local a = parseoperand(params[1])\n  local mode, imm = a.mode, a.imm\n  if type(imm) == \"number\" and (mode == \"iJ\" or (imm >= 1 and imm <= 9)) then\n    -- Local label (1: ... 9:) or global label (->global:).\n    waction(\"LABEL_LG\", nil, 1)\n    wputxb(imm)\n  elseif mode == \"iJ\" then\n    -- PC label (=>pcexpr:).\n    waction(\"LABEL_PC\", imm)\n  else\n    werror(\"bad label definition\")\n  end\n  -- SETLABEL must immediately follow LABEL_LG/LABEL_PC.\n  local addr = params[2]\n  if addr then\n    local a = parseoperand(addr)\n    if a.mode == \"iPJ\" then\n      waction(\"SETLABEL\", a.imm)\n    else\n      werror(\"bad label assignment\")\n    end\n  end\nend\nmap_op[\".label_1\"] = map_op[\".label_2\"]\n\n------------------------------------------------------------------------------\n\n-- Alignment pseudo-opcode.\nmap_op[\".align_1\"] = function(params)\n  if not params then return \"numpow2\" end\n  if secpos+1 > maxsecpos then wflush() end\n  local align = tonumber(params[1]) or map_opsizenum[map_opsize[params[1]]]\n  if align then\n    local x = align\n    -- Must be a power of 2 in the range (2 ... 256).\n    for i=1,8 do\n      x = x / 2\n      if x == 1 then\n\twaction(\"ALIGN\", nil, 1)\n\twputxb(align-1) -- Action byte is 2**n-1.\n\treturn\n      end\n    end\n  end\n  werror(\"bad alignment\")\nend\n\n-- Spacing pseudo-opcode.\nmap_op[\".space_2\"] = function(params)\n  if not params then return \"num [, filler]\" end\n  if secpos+1 > maxsecpos then wflush() end\n  waction(\"SPACE\", params[1])\n  local fill = params[2]\n  if fill then\n    fill = tonumber(fill)\n    if not fill or fill < 0 or fill > 255 then werror(\"bad filler\") end\n  end\n  wputxb(fill or 0)\nend\nmap_op[\".space_1\"] = map_op[\".space_2\"]\n\n------------------------------------------------------------------------------\n\n-- Pseudo-opcode for (primitive) type definitions (map to C types).\nmap_op[\".type_3\"] = function(params, nparams)\n  if not params then\n    return nparams == 2 and \"name, ctype\" or \"name, ctype, reg\"\n  end\n  local name, ctype, reg = params[1], params[2], params[3]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    werror(\"bad type name `\"..name..\"'\")\n  end\n  local tp = map_type[name]\n  if tp then\n    werror(\"duplicate type `\"..name..\"'\")\n  end\n  if reg and not map_reg_valid_base[reg] then\n    werror(\"bad base register `\"..(map_reg_rev[reg] or reg)..\"'\")\n  end\n  -- Add #type to defines. A bit unclean to put it in map_archdef.\n  map_archdef[\"#\"..name] = \"sizeof(\"..ctype..\")\"\n  -- Add new type and emit shortcut define.\n  local num = ctypenum + 1\n  map_type[name] = {\n    ctype = ctype,\n    ctypefmt = format(\"Dt%X(%%s)\", num),\n    reg = reg,\n  }\n  wline(format(\"#define Dt%X(_V) (int)(ptrdiff_t)&(((%s *)0)_V)\", num, ctype))\n  ctypenum = num\nend\nmap_op[\".type_2\"] = map_op[\".type_3\"]\n\n-- Dump type definitions.\nlocal function dumptypes(out, lvl)\n  local t = {}\n  for name in pairs(map_type) do t[#t+1] = name end\n  sort(t)\n  out:write(\"Type definitions:\\n\")\n  for _,name in ipairs(t) do\n    local tp = map_type[name]\n    local reg = tp.reg and map_reg_rev[tp.reg] or \"\"\n    out:write(format(\"  %-20s %-20s %s\\n\", name, tp.ctype, reg))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Set the current section.\nfunction _M.section(num)\n  waction(\"SECTION\")\n  wputxb(num)\n  wflush(true) -- SECTION is a terminal action.\nend\n\n------------------------------------------------------------------------------\n\n-- Dump architecture description.\nfunction _M.dumparch(out)\n  out:write(format(\"DynASM %s version %s, released %s\\n\\n\",\n    _info.arch, _info.version, _info.release))\n  dumpregs(out)\n  dumpactions(out)\nend\n\n-- Dump all user defined elements.\nfunction _M.dumpdef(out, lvl)\n  dumptypes(out, lvl)\n  dumpglobals(out, lvl)\n  dumpexterns(out, lvl)\nend\n\n------------------------------------------------------------------------------\n\n-- Pass callbacks from/to the DynASM core.\nfunction _M.passcb(wl, we, wf, ww)\n  wline, werror, wfatal, wwarn = wl, we, wf, ww\n  return wflush\nend\n\n-- Setup the arch-specific module.\nfunction _M.setup(arch, opt)\n  g_arch, g_opt = arch, opt\nend\n\n-- Merge the core maps and the arch-specific maps.\nfunction _M.mergemaps(map_coreop, map_def)\n  setmetatable(map_op, { __index = map_coreop })\n  setmetatable(map_def, { __index = map_archdef })\n  return map_op, map_def\nend\n\nreturn _M\n\n------------------------------------------------------------------------------\n\n"
  },
  {
    "path": "third_party/luajit/luajit/dynasm/dynasm.lua",
    "content": "------------------------------------------------------------------------------\n-- DynASM. A dynamic assembler for code generation engines.\n-- Originally designed and implemented for LuaJIT.\n--\n-- Copyright (C) 2005-2022 Mike Pall. All rights reserved.\n-- See below for full copyright notice.\n------------------------------------------------------------------------------\n\n-- Application information.\nlocal _info = {\n  name =\t\"DynASM\",\n  description =\t\"A dynamic assembler for code generation engines\",\n  version =\t\"1.5.0\",\n  vernum =\t 10500,\n  release =\t\"2021-05-02\",\n  author =\t\"Mike Pall\",\n  url =\t\t\"https://luajit.org/dynasm.html\",\n  license =\t\"MIT\",\n  copyright =\t[[\nCopyright (C) 2005-2022 Mike Pall. All rights reserved.\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.\nIN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY\nCLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,\nTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE\nSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n\n[ MIT license: https://www.opensource.org/licenses/mit-license.php ]\n]],\n}\n\n-- Cache library functions.\nlocal type, pairs, ipairs = type, pairs, ipairs\nlocal pcall, error, assert = pcall, error, assert\nlocal _s = string\nlocal sub, match, gmatch, gsub = _s.sub, _s.match, _s.gmatch, _s.gsub\nlocal format, rep, upper = _s.format, _s.rep, _s.upper\nlocal _t = table\nlocal insert, remove, concat, sort = _t.insert, _t.remove, _t.concat, _t.sort\nlocal exit = os.exit\nlocal io = io\nlocal stdin, stdout, stderr = io.stdin, io.stdout, io.stderr\n\n------------------------------------------------------------------------------\n\n-- Program options.\nlocal g_opt = {}\n\n-- Global state for current file.\nlocal g_fname, g_curline, g_indent, g_lineno, g_synclineno, g_arch\nlocal g_errcount = 0\n\n-- Write buffer for output file.\nlocal g_wbuffer, g_capbuffer\n\n------------------------------------------------------------------------------\n\n-- Write an output line (or callback function) to the buffer.\nlocal function wline(line, needindent)\n  local buf = g_capbuffer or g_wbuffer\n  buf[#buf+1] = needindent and g_indent..line or line\n  g_synclineno = g_synclineno + 1\nend\n\n-- Write assembler line as a comment, if requestd.\nlocal function wcomment(aline)\n  if g_opt.comment then\n    wline(g_opt.comment..aline..g_opt.endcomment, true)\n  end\nend\n\n-- Resync CPP line numbers.\nlocal function wsync()\n  if g_synclineno ~= g_lineno and g_opt.cpp then\n    wline(\"#line \"..g_lineno..' \"'..g_fname..'\"')\n    g_synclineno = g_lineno\n  end\nend\n\n-- Dummy action flush function. Replaced with arch-specific function later.\nlocal function wflush(term)\nend\n\n-- Dump all buffered output lines.\nlocal function wdumplines(out, buf)\n  for _,line in ipairs(buf) do\n    if type(line) == \"string\" then\n      assert(out:write(line, \"\\n\"))\n    else\n      -- Special callback to dynamically insert lines after end of processing.\n      line(out)\n    end\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Emit an error. Processing continues with next statement.\nlocal function werror(msg)\n  error(format(\"%s:%s: error: %s:\\n%s\", g_fname, g_lineno, msg, g_curline), 0)\nend\n\n-- Emit a fatal error. Processing stops.\nlocal function wfatal(msg)\n  g_errcount = \"fatal\"\n  werror(msg)\nend\n\n-- Print a warning. Processing continues.\nlocal function wwarn(msg)\n  stderr:write(format(\"%s:%s: warning: %s:\\n%s\\n\",\n    g_fname, g_lineno, msg, g_curline))\nend\n\n-- Print caught error message. But suppress excessive errors.\nlocal function wprinterr(...)\n  if type(g_errcount) == \"number\" then\n    -- Regular error.\n    g_errcount = g_errcount + 1\n    if g_errcount < 21 then -- Seems to be a reasonable limit.\n      stderr:write(...)\n    elseif g_errcount == 21 then\n      stderr:write(g_fname,\n\t\":*: warning: too many errors (suppressed further messages).\\n\")\n    end\n  else\n    -- Fatal error.\n    stderr:write(...)\n    return true -- Stop processing.\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Map holding all option handlers.\nlocal opt_map = {}\nlocal opt_current\n\n-- Print error and exit with error status.\nlocal function opterror(...)\n  stderr:write(\"dynasm.lua: ERROR: \", ...)\n  stderr:write(\"\\n\")\n  exit(1)\nend\n\n-- Get option parameter.\nlocal function optparam(args)\n  local argn = args.argn\n  local p = args[argn]\n  if not p then\n    opterror(\"missing parameter for option `\", opt_current, \"'.\")\n  end\n  args.argn = argn + 1\n  return p\nend\n\n------------------------------------------------------------------------------\n\n-- Core pseudo-opcodes.\nlocal map_coreop = {}\n-- Dummy opcode map. Replaced by arch-specific map.\nlocal map_op = {}\n\n-- Forward declarations.\nlocal dostmt\nlocal readfile\n\n------------------------------------------------------------------------------\n\n-- Map for defines (initially empty, chains to arch-specific map).\nlocal map_def = {}\n\n-- Pseudo-opcode to define a substitution.\nmap_coreop[\".define_2\"] = function(params, nparams)\n  if not params then return nparams == 1 and \"name\" or \"name, subst\" end\n  local name, def = params[1], params[2] or \"1\"\n  if not match(name, \"^[%a_][%w_]*$\") then werror(\"bad or duplicate define\") end\n  map_def[name] = def\nend\nmap_coreop[\".define_1\"] = map_coreop[\".define_2\"]\n\n-- Define a substitution on the command line.\nfunction opt_map.D(args)\n  local namesubst = optparam(args)\n  local name, subst = match(namesubst, \"^([%a_][%w_]*)=(.*)$\")\n  if name then\n    map_def[name] = subst\n  elseif match(namesubst, \"^[%a_][%w_]*$\") then\n    map_def[namesubst] = \"1\"\n  else\n    opterror(\"bad define\")\n  end\nend\n\n-- Undefine a substitution on the command line.\nfunction opt_map.U(args)\n  local name = optparam(args)\n  if match(name, \"^[%a_][%w_]*$\") then\n    map_def[name] = nil\n  else\n    opterror(\"bad define\")\n  end\nend\n\n-- Helper for definesubst.\nlocal gotsubst\n\nlocal function definesubst_one(word)\n  local subst = map_def[word]\n  if subst then gotsubst = word; return subst else return word end\nend\n\n-- Iteratively substitute defines.\nlocal function definesubst(stmt)\n  -- Limit number of iterations.\n  for i=1,100 do\n    gotsubst = false\n    stmt = gsub(stmt, \"#?[%w_]+\", definesubst_one)\n    if not gotsubst then break end\n  end\n  if gotsubst then wfatal(\"recursive define involving `\"..gotsubst..\"'\") end\n  return stmt\nend\n\n-- Dump all defines.\nlocal function dumpdefines(out, lvl)\n  local t = {}\n  for name in pairs(map_def) do\n    t[#t+1] = name\n  end\n  sort(t)\n  out:write(\"Defines:\\n\")\n  for _,name in ipairs(t) do\n    local subst = map_def[name]\n    if g_arch then subst = g_arch.revdef(subst) end\n    out:write(format(\"  %-20s %s\\n\", name, subst))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Support variables for conditional assembly.\nlocal condlevel = 0\nlocal condstack = {}\n\n-- Evaluate condition with a Lua expression. Substitutions already performed.\nlocal function cond_eval(cond)\n  local func, err\n  if setfenv then\n    func, err = loadstring(\"return \"..cond, \"=expr\")\n  else\n    -- No globals. All unknown identifiers evaluate to nil.\n    func, err = load(\"return \"..cond, \"=expr\", \"t\", {})\n  end\n  if func then\n    if setfenv then\n      setfenv(func, {}) -- No globals. All unknown identifiers evaluate to nil.\n    end\n    local ok, res = pcall(func)\n    if ok then\n      if res == 0 then return false end -- Oh well.\n      return not not res\n    end\n    err = res\n  end\n  wfatal(\"bad condition: \"..err)\nend\n\n-- Skip statements until next conditional pseudo-opcode at the same level.\nlocal function stmtskip()\n  local dostmt_save = dostmt\n  local lvl = 0\n  dostmt = function(stmt)\n    local op = match(stmt, \"^%s*(%S+)\")\n    if op == \".if\" then\n      lvl = lvl + 1\n    elseif lvl ~= 0 then\n      if op == \".endif\" then lvl = lvl - 1 end\n    elseif op == \".elif\" or op == \".else\" or op == \".endif\" then\n      dostmt = dostmt_save\n      dostmt(stmt)\n    end\n  end\nend\n\n-- Pseudo-opcodes for conditional assembly.\nmap_coreop[\".if_1\"] = function(params)\n  if not params then return \"condition\" end\n  local lvl = condlevel + 1\n  local res = cond_eval(params[1])\n  condlevel = lvl\n  condstack[lvl] = res\n  if not res then stmtskip() end\nend\n\nmap_coreop[\".elif_1\"] = function(params)\n  if not params then return \"condition\" end\n  if condlevel == 0 then wfatal(\".elif without .if\") end\n  local lvl = condlevel\n  local res = condstack[lvl]\n  if res then\n    if res == \"else\" then wfatal(\".elif after .else\") end\n  else\n    res = cond_eval(params[1])\n    if res then\n      condstack[lvl] = res\n      return\n    end\n  end\n  stmtskip()\nend\n\nmap_coreop[\".else_0\"] = function(params)\n  if condlevel == 0 then wfatal(\".else without .if\") end\n  local lvl = condlevel\n  local res = condstack[lvl]\n  condstack[lvl] = \"else\"\n  if res then\n    if res == \"else\" then wfatal(\".else after .else\") end\n    stmtskip()\n  end\nend\n\nmap_coreop[\".endif_0\"] = function(params)\n  local lvl = condlevel\n  if lvl == 0 then wfatal(\".endif without .if\") end\n  condlevel = lvl - 1\nend\n\n-- Check for unfinished conditionals.\nlocal function checkconds()\n  if g_errcount ~= \"fatal\" and condlevel ~= 0 then\n    wprinterr(g_fname, \":*: error: unbalanced conditional\\n\")\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Search for a file in the given path and open it for reading.\nlocal function pathopen(path, name)\n  local dirsep = package and match(package.path, \"\\\\\") and \"\\\\\" or \"/\"\n  for _,p in ipairs(path) do\n    local fullname = p == \"\" and name or p..dirsep..name\n    local fin = io.open(fullname, \"r\")\n    if fin then\n      g_fname = fullname\n      return fin\n    end\n  end\nend\n\n-- Include a file.\nmap_coreop[\".include_1\"] = function(params)\n  if not params then return \"filename\" end\n  local name = params[1]\n  -- Save state. Ugly, I know. but upvalues are fast.\n  local gf, gl, gcl, gi = g_fname, g_lineno, g_curline, g_indent\n  -- Read the included file.\n  local fatal = readfile(pathopen(g_opt.include, name) or\n\t\t\t wfatal(\"include file `\"..name..\"' not found\"))\n  -- Restore state.\n  g_synclineno = -1\n  g_fname, g_lineno, g_curline, g_indent = gf, gl, gcl, gi\n  if fatal then wfatal(\"in include file\") end\nend\n\n-- Make .include and conditionals initially available, too.\nmap_op[\".include_1\"] = map_coreop[\".include_1\"]\nmap_op[\".if_1\"] = map_coreop[\".if_1\"]\nmap_op[\".elif_1\"] = map_coreop[\".elif_1\"]\nmap_op[\".else_0\"] = map_coreop[\".else_0\"]\nmap_op[\".endif_0\"] = map_coreop[\".endif_0\"]\n\n------------------------------------------------------------------------------\n\n-- Support variables for macros.\nlocal mac_capture, mac_lineno, mac_name\nlocal mac_active = {}\nlocal mac_list = {}\n\n-- Pseudo-opcode to define a macro.\nmap_coreop[\".macro_*\"] = function(mparams)\n  if not mparams then return \"name [, params...]\" end\n  -- Split off and validate macro name.\n  local name = remove(mparams, 1)\n  if not name then werror(\"missing macro name\") end\n  if not (match(name, \"^[%a_][%w_%.]*$\") or match(name, \"^%.[%w_%.]*$\")) then\n    wfatal(\"bad macro name `\"..name..\"'\")\n  end\n  -- Validate macro parameter names.\n  local mdup = {}\n  for _,mp in ipairs(mparams) do\n    if not match(mp, \"^[%a_][%w_]*$\") then\n      wfatal(\"bad macro parameter name `\"..mp..\"'\")\n    end\n    if mdup[mp] then wfatal(\"duplicate macro parameter name `\"..mp..\"'\") end\n    mdup[mp] = true\n  end\n  -- Check for duplicate or recursive macro definitions.\n  local opname = name..\"_\"..#mparams\n  if map_op[opname] or map_op[name..\"_*\"] then\n    wfatal(\"duplicate macro `\"..name..\"' (\"..#mparams..\" parameters)\")\n  end\n  if mac_capture then wfatal(\"recursive macro definition\") end\n\n  -- Enable statement capture.\n  local lines = {}\n  mac_lineno = g_lineno\n  mac_name = name\n  mac_capture = function(stmt) -- Statement capture function.\n    -- Stop macro definition with .endmacro pseudo-opcode.\n    if not match(stmt, \"^%s*.endmacro%s*$\") then\n      lines[#lines+1] = stmt\n      return\n    end\n    mac_capture = nil\n    mac_lineno = nil\n    mac_name = nil\n    mac_list[#mac_list+1] = opname\n    -- Add macro-op definition.\n    map_op[opname] = function(params)\n      if not params then return mparams, lines end\n      -- Protect against recursive macro invocation.\n      if mac_active[opname] then wfatal(\"recursive macro invocation\") end\n      mac_active[opname] = true\n      -- Setup substitution map.\n      local subst = {}\n      for i,mp in ipairs(mparams) do subst[mp] = params[i] end\n      local mcom\n      if g_opt.maccomment and g_opt.comment then\n\tmcom = \" MACRO \"..name..\" (\"..#mparams..\")\"\n\twcomment(\"{\"..mcom)\n      end\n      -- Loop through all captured statements\n      for _,stmt in ipairs(lines) do\n\t-- Substitute macro parameters.\n\tlocal st = gsub(stmt, \"[%w_]+\", subst)\n\tst = definesubst(st)\n\tst = gsub(st, \"%s*%.%.%s*\", \"\") -- Token paste a..b.\n\tif mcom and sub(st, 1, 1) ~= \"|\" then wcomment(st) end\n\t-- Emit statement. Use a protected call for better diagnostics.\n\tlocal ok, err = pcall(dostmt, st)\n\tif not ok then\n\t  -- Add the captured statement to the error.\n\t  wprinterr(err, \"\\n\", g_indent, \"|  \", stmt,\n\t\t    \"\\t[MACRO \", name, \" (\", #mparams, \")]\\n\")\n\tend\n      end\n      if mcom then wcomment(\"}\"..mcom) end\n      mac_active[opname] = nil\n    end\n  end\nend\n\n-- An .endmacro pseudo-opcode outside of a macro definition is an error.\nmap_coreop[\".endmacro_0\"] = function(params)\n  wfatal(\".endmacro without .macro\")\nend\n\n-- Dump all macros and their contents (with -PP only).\nlocal function dumpmacros(out, lvl)\n  sort(mac_list)\n  out:write(\"Macros:\\n\")\n  for _,opname in ipairs(mac_list) do\n    local name = sub(opname, 1, -3)\n    local params, lines = map_op[opname]()\n    out:write(format(\"  %-20s %s\\n\", name, concat(params, \", \")))\n    if lvl > 1 then\n      for _,line in ipairs(lines) do\n\tout:write(\"  |\", line, \"\\n\")\n      end\n      out:write(\"\\n\")\n    end\n  end\n  out:write(\"\\n\")\nend\n\n-- Check for unfinished macro definitions.\nlocal function checkmacros()\n  if mac_capture then\n    wprinterr(g_fname, \":\", mac_lineno,\n\t      \": error: unfinished .macro `\", mac_name ,\"'\\n\")\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Support variables for captures.\nlocal cap_lineno, cap_name\nlocal cap_buffers = {}\nlocal cap_used = {}\n\n-- Start a capture.\nmap_coreop[\".capture_1\"] = function(params)\n  if not params then return \"name\" end\n  wflush()\n  local name = params[1]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    wfatal(\"bad capture name `\"..name..\"'\")\n  end\n  if cap_name then\n    wfatal(\"already capturing to `\"..cap_name..\"' since line \"..cap_lineno)\n  end\n  cap_name = name\n  cap_lineno = g_lineno\n  -- Create or continue a capture buffer and start the output line capture.\n  local buf = cap_buffers[name]\n  if not buf then buf = {}; cap_buffers[name] = buf end\n  g_capbuffer = buf\n  g_synclineno = 0\nend\n\n-- Stop a capture.\nmap_coreop[\".endcapture_0\"] = function(params)\n  wflush()\n  if not cap_name then wfatal(\".endcapture without a valid .capture\") end\n  cap_name = nil\n  cap_lineno = nil\n  g_capbuffer = nil\n  g_synclineno = 0\nend\n\n-- Dump a capture buffer.\nmap_coreop[\".dumpcapture_1\"] = function(params)\n  if not params then return \"name\" end\n  wflush()\n  local name = params[1]\n  if not match(name, \"^[%a_][%w_]*$\") then\n    wfatal(\"bad capture name `\"..name..\"'\")\n  end\n  cap_used[name] = true\n  wline(function(out)\n    local buf = cap_buffers[name]\n    if buf then wdumplines(out, buf) end\n  end)\n  g_synclineno = 0\nend\n\n-- Dump all captures and their buffers (with -PP only).\nlocal function dumpcaptures(out, lvl)\n  out:write(\"Captures:\\n\")\n  for name,buf in pairs(cap_buffers) do\n    out:write(format(\"  %-20s %4s)\\n\", name, \"(\"..#buf))\n    if lvl > 1 then\n      local bar = rep(\"=\", 76)\n      out:write(\"  \", bar, \"\\n\")\n      for _,line in ipairs(buf) do\n\tout:write(\"  \", line, \"\\n\")\n      end\n      out:write(\"  \", bar, \"\\n\\n\")\n    end\n  end\n  out:write(\"\\n\")\nend\n\n-- Check for unfinished or unused captures.\nlocal function checkcaptures()\n  if cap_name then\n    wprinterr(g_fname, \":\", cap_lineno,\n\t      \": error: unfinished .capture `\", cap_name,\"'\\n\")\n    return\n  end\n  for name in pairs(cap_buffers) do\n    if not cap_used[name] then\n      wprinterr(g_fname, \":*: error: missing .dumpcapture \", name ,\"\\n\")\n    end\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Sections names.\nlocal map_sections = {}\n\n-- Pseudo-opcode to define code sections.\n-- TODO: Data sections, BSS sections. Needs extra C code and API.\nmap_coreop[\".section_*\"] = function(params)\n  if not params then return \"name...\" end\n  if #map_sections > 0 then werror(\"duplicate section definition\") end\n  wflush()\n  for sn,name in ipairs(params) do\n    local opname = \".\"..name..\"_0\"\n    if not match(name, \"^[%a][%w_]*$\") or\n       map_op[opname] or map_op[\".\"..name..\"_*\"] then\n      werror(\"bad section name `\"..name..\"'\")\n    end\n    map_sections[#map_sections+1] = name\n    wline(format(\"#define DASM_SECTION_%s\\t%d\", upper(name), sn-1))\n    map_op[opname] = function(params) g_arch.section(sn-1) end\n  end\n  wline(format(\"#define DASM_MAXSECTION\\t\\t%d\", #map_sections))\nend\n\n-- Dump all sections.\nlocal function dumpsections(out, lvl)\n  out:write(\"Sections:\\n\")\n  for _,name in ipairs(map_sections) do\n    out:write(format(\"  %s\\n\", name))\n  end\n  out:write(\"\\n\")\nend\n\n------------------------------------------------------------------------------\n\n-- Replacement for customized Lua, which lacks the package library.\nlocal prefix = \"\"\nif not require then\n  function require(name)\n    local fp = assert(io.open(prefix..name..\".lua\"))\n    local s = fp:read(\"*a\")\n    assert(fp:close())\n    return assert(loadstring(s, \"@\"..name..\".lua\"))()\n  end\nend\n\n-- Load architecture-specific module.\nlocal function loadarch(arch)\n  if not match(arch, \"^[%w_]+$\") then return \"bad arch name\" end\n  _G._map_def = map_def\n  local ok, m_arch = pcall(require, \"dasm_\"..arch)\n  if not ok then return \"cannot load module: \"..m_arch end\n  g_arch = m_arch\n  wflush = m_arch.passcb(wline, werror, wfatal, wwarn)\n  m_arch.setup(arch, g_opt)\n  map_op, map_def = m_arch.mergemaps(map_coreop, map_def)\nend\n\n-- Dump architecture description.\nfunction opt_map.dumparch(args)\n  local name = optparam(args)\n  if not g_arch then\n    local err = loadarch(name)\n    if err then opterror(err) end\n  end\n\n  local t = {}\n  for name in pairs(map_coreop) do t[#t+1] = name end\n  for name in pairs(map_op) do t[#t+1] = name end\n  sort(t)\n\n  local out = stdout\n  local _arch = g_arch._info\n  out:write(format(\"%s version %s, released %s, %s\\n\",\n    _info.name, _info.version, _info.release, _info.url))\n  g_arch.dumparch(out)\n\n  local pseudo = true\n  out:write(\"Pseudo-Opcodes:\\n\")\n  for _,sname in ipairs(t) do\n    local name, nparam = match(sname, \"^(.+)_([0-9%*])$\")\n    if name then\n      if pseudo and sub(name, 1, 1) ~= \".\" then\n\tout:write(\"\\nOpcodes:\\n\")\n\tpseudo = false\n      end\n      local f = map_op[sname]\n      local s\n      if nparam ~= \"*\" then nparam = nparam + 0 end\n      if nparam == 0 then\n\ts = \"\"\n      elseif type(f) == \"string\" then\n\ts = map_op[\".template__\"](nil, f, nparam)\n      else\n\ts = f(nil, nparam)\n      end\n      if type(s) == \"table\" then\n\tfor _,s2 in ipairs(s) do\n\t  out:write(format(\"  %-12s %s\\n\", name, s2))\n\tend\n      else\n\tout:write(format(\"  %-12s %s\\n\", name, s))\n      end\n    end\n  end\n  out:write(\"\\n\")\n  exit(0)\nend\n\n-- Pseudo-opcode to set the architecture.\n-- Only initially available (map_op is replaced when called).\nmap_op[\".arch_1\"] = function(params)\n  if not params then return \"name\" end\n  local err = loadarch(params[1])\n  if err then wfatal(err) end\n  wline(format(\"#if DASM_VERSION != %d\", _info.vernum))\n  wline('#error \"Version mismatch between DynASM and included encoding engine\"')\n  wline(\"#endif\")\nend\n\n-- Dummy .arch pseudo-opcode to improve the error report.\nmap_coreop[\".arch_1\"] = function(params)\n  if not params then return \"name\" end\n  wfatal(\"duplicate .arch statement\")\nend\n\n------------------------------------------------------------------------------\n\n-- Dummy pseudo-opcode. Don't confuse '.nop' with 'nop'.\nmap_coreop[\".nop_*\"] = function(params)\n  if not params then return \"[ignored...]\" end\nend\n\n-- Pseudo-opcodes to raise errors.\nmap_coreop[\".error_1\"] = function(params)\n  if not params then return \"message\" end\n  werror(params[1])\nend\n\nmap_coreop[\".fatal_1\"] = function(params)\n  if not params then return \"message\" end\n  wfatal(params[1])\nend\n\n-- Dump all user defined elements.\nlocal function dumpdef(out)\n  local lvl = g_opt.dumpdef\n  if lvl == 0 then return end\n  dumpsections(out, lvl)\n  dumpdefines(out, lvl)\n  if g_arch then g_arch.dumpdef(out, lvl) end\n  dumpmacros(out, lvl)\n  dumpcaptures(out, lvl)\nend\n\n------------------------------------------------------------------------------\n\n-- Helper for splitstmt.\nlocal splitlvl\n\nlocal function splitstmt_one(c)\n  if c == \"(\" then\n    splitlvl = \")\"..splitlvl\n  elseif c == \"[\" then\n    splitlvl = \"]\"..splitlvl\n  elseif c == \"{\" then\n    splitlvl = \"}\"..splitlvl\n  elseif c == \")\" or c == \"]\" or c == \"}\" then\n    if sub(splitlvl, 1, 1) ~= c then werror(\"unbalanced (), [] or {}\") end\n    splitlvl = sub(splitlvl, 2)\n  elseif splitlvl == \"\" then\n    return \" \\0 \"\n  end\n  return c\nend\n\n-- Split statement into (pseudo-)opcode and params.\nlocal function splitstmt(stmt)\n  -- Convert label with trailing-colon into .label statement.\n  local label = match(stmt, \"^%s*(.+):%s*$\")\n  if label then return \".label\", {label} end\n\n  -- Split at commas and equal signs, but obey parentheses and brackets.\n  splitlvl = \"\"\n  stmt = gsub(stmt, \"[,%(%)%[%]{}]\", splitstmt_one)\n  if splitlvl ~= \"\" then werror(\"unbalanced () or []\") end\n\n  -- Split off opcode.\n  local op, other = match(stmt, \"^%s*([^%s%z]+)%s*(.*)$\")\n  if not op then werror(\"bad statement syntax\") end\n\n  -- Split parameters.\n  local params = {}\n  for p in gmatch(other, \"%s*(%Z+)%z?\") do\n    params[#params+1] = gsub(p, \"%s+$\", \"\")\n  end\n  if #params > 16 then werror(\"too many parameters\") end\n\n  params.op = op\n  return op, params\nend\n\n-- Process a single statement.\ndostmt = function(stmt)\n  -- Ignore empty statements.\n  if match(stmt, \"^%s*$\") then return end\n\n  -- Capture macro defs before substitution.\n  if mac_capture then return mac_capture(stmt) end\n  stmt = definesubst(stmt)\n\n  -- Emit C code without parsing the line.\n  if sub(stmt, 1, 1) == \"|\" then\n    local tail = sub(stmt, 2)\n    wflush()\n    if sub(tail, 1, 2) == \"//\" then wcomment(tail) else wline(tail, true) end\n    return\n  end\n\n  -- Split into (pseudo-)opcode and params.\n  local op, params = splitstmt(stmt)\n\n  -- Get opcode handler (matching # of parameters or generic handler).\n  local f = map_op[op..\"_\"..#params] or map_op[op..\"_*\"]\n  if not f then\n    if not g_arch then wfatal(\"first statement must be .arch\") end\n    -- Improve error report.\n    for i=0,9 do\n      if map_op[op..\"_\"..i] then\n\twerror(\"wrong number of parameters for `\"..op..\"'\")\n      end\n    end\n    werror(\"unknown statement `\"..op..\"'\")\n  end\n\n  -- Call opcode handler or special handler for template strings.\n  if type(f) == \"string\" then\n    map_op[\".template__\"](params, f)\n  else\n    f(params)\n  end\nend\n\n-- Process a single line.\nlocal function doline(line)\n  if g_opt.flushline then wflush() end\n\n  -- Assembler line?\n  local indent, aline = match(line, \"^(%s*)%|(.*)$\")\n  if not aline then\n    -- No, plain C code line, need to flush first.\n    wflush()\n    wsync()\n    wline(line, false)\n    return\n  end\n\n  g_indent = indent -- Remember current line indentation.\n\n  -- Emit C code (even from macros). Avoids echo and line parsing.\n  if sub(aline, 1, 1) == \"|\" then\n    if not mac_capture then\n      wsync()\n    elseif g_opt.comment then\n      wsync()\n      wcomment(aline)\n    end\n    dostmt(aline)\n    return\n  end\n\n  -- Echo assembler line as a comment.\n  if g_opt.comment then\n    wsync()\n    wcomment(aline)\n  end\n\n  -- Strip assembler comments.\n  aline = gsub(aline, \"//.*$\", \"\")\n\n  -- Split line into statements at semicolons.\n  if match(aline, \";\") then\n    for stmt in gmatch(aline, \"[^;]+\") do dostmt(stmt) end\n  else\n    dostmt(aline)\n  end\nend\n\n------------------------------------------------------------------------------\n\n-- Write DynASM header.\nlocal function dasmhead(out)\n  out:write(format([[\n/*\n** This file has been pre-processed with DynASM.\n** %s\n** DynASM version %s, DynASM %s version %s\n** DO NOT EDIT! The original file is in \"%s\".\n*/\n\n]], _info.url,\n    _info.version, g_arch._info.arch, g_arch._info.version,\n    g_fname))\nend\n\n-- Read input file.\nreadfile = function(fin)\n  g_indent = \"\"\n  g_lineno = 0\n  g_synclineno = -1\n\n  -- Process all lines.\n  for line in fin:lines() do\n    g_lineno = g_lineno + 1\n    g_curline = line\n    local ok, err = pcall(doline, line)\n    if not ok and wprinterr(err, \"\\n\") then return true end\n  end\n  wflush()\n\n  -- Close input file.\n  assert(fin == stdin or fin:close())\nend\n\n-- Write output file.\nlocal function writefile(outfile)\n  local fout\n\n  -- Open output file.\n  if outfile == nil or outfile == \"-\" then\n    fout = stdout\n  else\n    fout = assert(io.open(outfile, \"w\"))\n  end\n\n  -- Write all buffered lines\n  wdumplines(fout, g_wbuffer)\n\n  -- Close output file.\n  assert(fout == stdout or fout:close())\n\n  -- Optionally dump definitions.\n  dumpdef(fout == stdout and stderr or stdout)\nend\n\n-- Translate an input file to an output file.\nlocal function translate(infile, outfile)\n  g_wbuffer = {}\n  g_indent = \"\"\n  g_lineno = 0\n  g_synclineno = -1\n\n  -- Put header.\n  wline(dasmhead)\n\n  -- Read input file.\n  local fin\n  if infile == \"-\" then\n    g_fname = \"(stdin)\"\n    fin = stdin\n  else\n    g_fname = infile\n    fin = assert(io.open(infile, \"r\"))\n  end\n  readfile(fin)\n\n  -- Check for errors.\n  if not g_arch then\n    wprinterr(g_fname, \":*: error: missing .arch directive\\n\")\n  end\n  checkconds()\n  checkmacros()\n  checkcaptures()\n\n  if g_errcount ~= 0 then\n    stderr:write(g_fname, \":*: info: \", g_errcount, \" error\",\n      (type(g_errcount) == \"number\" and g_errcount > 1) and \"s\" or \"\",\n      \" in input file -- no output file generated.\\n\")\n    dumpdef(stderr)\n    exit(1)\n  end\n\n  -- Write output file.\n  writefile(outfile)\nend\n\n------------------------------------------------------------------------------\n\n-- Print help text.\nfunction opt_map.help()\n  stdout:write(\"DynASM -- \", _info.description, \".\\n\")\n  stdout:write(\"DynASM \", _info.version, \" \", _info.release, \"  \", _info.url, \"\\n\")\n  stdout:write[[\n\nUsage: dynasm [OPTION]... INFILE.dasc|-\n\n  -h, --help           Display this help text.\n  -V, --version        Display version and copyright information.\n\n  -o, --outfile FILE   Output file name (default is stdout).\n  -I, --include DIR    Add directory to the include search path.\n\n  -c, --ccomment       Use /* */ comments for assembler lines.\n  -C, --cppcomment     Use // comments for assembler lines (default).\n  -N, --nocomment      Suppress assembler lines in output.\n  -M, --maccomment     Show macro expansions as comments (default off).\n\n  -L, --nolineno       Suppress CPP line number information in output.\n  -F, --flushline      Flush action list for every line.\n\n  -D NAME[=SUBST]      Define a substitution.\n  -U NAME              Undefine a substitution.\n\n  -P, --dumpdef        Dump defines, macros, etc. Repeat for more output.\n  -A, --dumparch ARCH  Load architecture ARCH and dump description.\n]]\n  exit(0)\nend\n\n-- Print version information.\nfunction opt_map.version()\n  stdout:write(format(\"%s version %s, released %s\\n%s\\n\\n%s\",\n    _info.name, _info.version, _info.release, _info.url, _info.copyright))\n  exit(0)\nend\n\n-- Misc. options.\nfunction opt_map.outfile(args) g_opt.outfile = optparam(args) end\nfunction opt_map.include(args) insert(g_opt.include, 1, optparam(args)) end\nfunction opt_map.ccomment() g_opt.comment = \"/*|\"; g_opt.endcomment = \" */\" end\nfunction opt_map.cppcomment() g_opt.comment = \"//|\"; g_opt.endcomment = \"\" end\nfunction opt_map.nocomment() g_opt.comment = false end\nfunction opt_map.maccomment() g_opt.maccomment = true end\nfunction opt_map.nolineno() g_opt.cpp = false end\nfunction opt_map.flushline() g_opt.flushline = true end\nfunction opt_map.dumpdef() g_opt.dumpdef = g_opt.dumpdef + 1 end\n\n------------------------------------------------------------------------------\n\n-- Short aliases for long options.\nlocal opt_alias = {\n  h = \"help\", [\"?\"] = \"help\", V = \"version\",\n  o = \"outfile\", I = \"include\",\n  c = \"ccomment\", C = \"cppcomment\", N = \"nocomment\", M = \"maccomment\",\n  L = \"nolineno\", F = \"flushline\",\n  P = \"dumpdef\", A = \"dumparch\",\n}\n\n-- Parse single option.\nlocal function parseopt(opt, args)\n  opt_current = #opt == 1 and \"-\"..opt or \"--\"..opt\n  local f = opt_map[opt] or opt_map[opt_alias[opt]]\n  if not f then\n    opterror(\"unrecognized option `\", opt_current, \"'. Try `--help'.\\n\")\n  end\n  f(args)\nend\n\n-- Parse arguments.\nlocal function parseargs(args)\n  -- Default options.\n  g_opt.comment = \"//|\"\n  g_opt.endcomment = \"\"\n  g_opt.cpp = true\n  g_opt.dumpdef = 0\n  g_opt.include = { \"\" }\n\n  -- Process all option arguments.\n  args.argn = 1\n  repeat\n    local a = args[args.argn]\n    if not a then break end\n    local lopt, opt = match(a, \"^%-(%-?)(.+)\")\n    if not opt then break end\n    args.argn = args.argn + 1\n    if lopt == \"\" then\n      -- Loop through short options.\n      for o in gmatch(opt, \".\") do parseopt(o, args) end\n    else\n      -- Long option.\n      parseopt(opt, args)\n    end\n  until false\n\n  -- Check for proper number of arguments.\n  local nargs = #args - args.argn + 1\n  if nargs ~= 1 then\n    if nargs == 0 then\n      if g_opt.dumpdef > 0 then return dumpdef(stdout) end\n    end\n    opt_map.help()\n  end\n\n  -- Translate a single input file to a single output file\n  -- TODO: Handle multiple files?\n  translate(args[args.argn], g_opt.outfile)\nend\n\n------------------------------------------------------------------------------\n\n-- Add the directory dynasm.lua resides in to the Lua module search path.\nlocal arg = arg\nif arg and arg[0] then\n  prefix = match(arg[0], \"^(.*[/\\\\])\")\n  if package and prefix then package.path = prefix..\"?.lua;\"..package.path end\nend\n\n-- Start DynASM.\nparseargs{...}\n\n------------------------------------------------------------------------------\n\n"
  },
  {
    "path": "third_party/luajit/luajit/etc/luajit.1",
    "content": ".TH luajit 1 \"\" \"\" \"LuaJIT documentation\"\n.SH NAME\nluajit \\- Just-In-Time Compiler for the Lua Language\n\\fB\n.SH SYNOPSIS\n.B luajit\n[\\fIoptions\\fR]... [\\fIscript\\fR [\\fIargs\\fR]...]\n.SH \"WEB SITE\"\n.IR https://luajit.org\n.SH DESCRIPTION\n.PP\nThis is the command-line program to run Lua programs with \\fBLuaJIT\\fR.\n.PP\n\\fBLuaJIT\\fR is a just-in-time (JIT) compiler for the Lua language.\nThe virtual machine (VM) is based on a fast interpreter combined with\na trace compiler. It can significantly improve the performance of Lua programs.\n.PP\n\\fBLuaJIT\\fR is API\\- and ABI-compatible with the VM of the standard\nLua\\ 5.1 interpreter. When embedding the VM into an application,\nthe built library can be used as a drop-in replacement.\n.SH OPTIONS\n.TP\n.BI \"\\-e \" chunk\nRun the given chunk of Lua code.\n.TP\n.BI \"\\-l \" library\nLoad the named library, just like \\fBrequire(\"\\fR\\fIlibrary\\fR\\fB\")\\fR.\n.TP\n.BI \"\\-b \" ...\nSave or list bytecode. Run without arguments to get help on options.\n.TP\n.BI \"\\-j \" command\nPerform LuaJIT control command (optional space after \\fB\\-j\\fR).\n.TP\n.BI \"\\-O\" [opt]\nControl LuaJIT optimizations.\n.TP\n.B \"\\-i\"\nRun in interactive mode.\n.TP\n.B \"\\-v\"\nShow \\fBLuaJIT\\fR version.\n.TP\n.B \"\\-E\"\nIgnore environment variables.\n.TP\n.B \"\\-\\-\"\nStop processing options.\n.TP\n.B \"\\-\"\nRead script from stdin instead.\n.PP\nAfter all options are processed, the given \\fIscript\\fR is run.\nThe arguments are passed in the global \\fIarg\\fR table.\n.PP\nInteractive mode is only entered, if no \\fIscript\\fR and no \\fB\\-e\\fR\noption is given. Interactive mode can be left with EOF (\\fICtrl\\-Z\\fB).\n.SH EXAMPLES\n.TP\nluajit hello.lua world\n\nPrints \"Hello world\", assuming \\fIhello.lua\\fR contains:\n.br\n  print(\"Hello\", arg[1])\n.TP\nluajit \\-e \"local x=0; for i=1,1e9 do x=x+i end; print(x)\"\n\nCalculates the sum of the numbers from 1 to 1000000000.\n.br\nAnd finishes in a reasonable amount of time, too.\n.TP\nluajit \\-jv \\-e \"for i=1,10 do for j=1,10 do for k=1,100 do end end end\"\n\nRuns some nested loops and shows the resulting traces.\n.SH COPYRIGHT\n.PP\n\\fBLuaJIT\\fR is Copyright \\(co 2005-2022 Mike Pall.\n.br\n\\fBLuaJIT\\fR is open source software, released under the MIT license.\n.SH SEE ALSO\n.PP\nMore details in the provided HTML docs or at:\n.IR https://luajit.org\n.br\nMore about the Lua language can be found at:\n.IR https://lua.org/docs.html\n.PP\nlua(1)\n"
  },
  {
    "path": "third_party/luajit/luajit/etc/luajit.pc",
    "content": "# Package information for LuaJIT to be used by pkg-config.\nmajver=2\nminver=1\nrelver=0\nversion=${majver}.${minver}.${relver}-beta3\nabiver=5.1\n\nprefix=/usr/local\nmultilib=lib\nexec_prefix=${prefix}\nlibdir=${exec_prefix}/${multilib}\nlibname=luajit-${abiver}\nincludedir=${prefix}/include/luajit-${majver}.${minver}\n\nINSTALL_LMOD=${prefix}/share/lua/${abiver}\nINSTALL_CMOD=${prefix}/${multilib}/lua/${abiver}\n\nName: LuaJIT\nDescription: Just-in-time compiler for Lua\nURL: https://luajit.org\nVersion: ${version}\nRequires:\nLibs: -L${libdir} -l${libname}\nLibs.private: -Wl,-E -lm -ldl\nCflags: -I${includedir}\n"
  }
]