Update third_party/benchmark to 1.9.5

Picks up
https://github.com/google/benchmark/commit/d8db2f90b643eb28a12976beb4d57bcfb639911d

This results in deprecation warnings with benchmark::internal::Benchmark
so go ahead and fix those.

Also add third_party/benchmark to .bazelignore. This stops
`bazel test ...` from recursing in here. It looks like we previously
suppressed copying some files, but we can avoid having to post-process
the files this way.

Change-Id: Idf20fce28153a450fe03e121d9bc0d601d43ec6c
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/88948
Auto-Submit: David Benjamin <davidben@google.com>
Reviewed-by: Lily Chen <chlily@google.com>
Commit-Queue: Lily Chen <chlily@google.com>
diff --git a/.bazelignore b/.bazelignore
index 9dad64c..56daf3d 100644
--- a/.bazelignore
+++ b/.bazelignore
@@ -1,2 +1,3 @@
+third_party/benchmark
 third_party/googletest
 util/bazel-example
diff --git a/MODULE.bazel b/MODULE.bazel
index 03d80da..181bf5e 100644
--- a/MODULE.bazel
+++ b/MODULE.bazel
@@ -36,7 +36,7 @@
 # https://github.com/bazelbuild/bazel/issues/22187 is ever fixed, we can change
 # this.
 bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
-bazel_dep(name = "google_benchmark", version = "1.9.4")
+bazel_dep(name = "google_benchmark", version = "1.9.5")
 bazel_dep(name = "platforms", version = "1.0.0")
 bazel_dep(name = "rules_cc", version = "0.2.14")
 bazel_dep(name = "rules_license", version = "1.0.0")
diff --git a/MODULE.bazel.lock b/MODULE.bazel.lock
index 2b56124..221cabc 100644
--- a/MODULE.bazel.lock
+++ b/MODULE.bazel.lock
@@ -44,8 +44,8 @@
     "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
     "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
     "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
-    "https://bcr.bazel.build/modules/google_benchmark/1.9.4/MODULE.bazel": "3bab7c17c10580f87b647478a72a05621f88abc275afb97b578c828f56e59d45",
-    "https://bcr.bazel.build/modules/google_benchmark/1.9.4/source.json": "8e0036f76a5c2aa9c16ca0da57d8065cff69edeed58f1f85584c588c0ef723a5",
+    "https://bcr.bazel.build/modules/google_benchmark/1.9.5/MODULE.bazel": "8a85cfd90b1e45e6e68f1aa2aa9efce3c04add57df732571d7fd54c07e7c5143",
+    "https://bcr.bazel.build/modules/google_benchmark/1.9.5/source.json": "0bd357fd9db30ee31d5eb4c78b1086ce3d79b4423ce76de19e8a2fa7b2fa2e10",
     "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
     "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
     "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",
diff --git a/bench/aead.cc b/bench/aead.cc
index 06068aa..269dd9c 100644
--- a/bench/aead.cc
+++ b/bench/aead.cc
@@ -118,7 +118,7 @@
 
 static const int64_t kInputSizes[] = {16, 256, 1350, 8192, 16384};
 
-void SetInputLength(benchmark::internal::Benchmark *bench) {
+void SetInputLength(benchmark::Benchmark *bench) {
   bench->ArgName("InputSize");
   auto input_sizes = bench::GetInputSizes(bench);
   if (input_sizes.empty()) {
diff --git a/bench/hash.cc b/bench/hash.cc
index c8669d7..4555c8a 100644
--- a/bench/hash.cc
+++ b/bench/hash.cc
@@ -46,7 +46,7 @@
 
 static const int64_t kInputSizes[] = {16, 256, 1350, 8192, 16384};
 
-void SetInputLength(benchmark::internal::Benchmark *bench) {
+void SetInputLength(benchmark::Benchmark *bench) {
   bench->ArgName("InputSize");
   auto input_sizes = bssl::bench::GetInputSizes(bench);
   if (input_sizes.empty()) {
diff --git a/bench/internal.h b/bench/internal.h
index 57ffd21..70e0d9e 100644
--- a/bench/internal.h
+++ b/bench/internal.h
@@ -63,7 +63,7 @@
 //
 // This function can only be used in the context of |BSSL_BENCH_LAZY_REGISTER|.
 // Otherwise, the benchmark will be aborted.
-void SetThreads(benchmark::internal::Benchmark *bench);
+void SetThreads(benchmark::Benchmark *bench);
 
 // For benchmark registration, get the input size from the runtime flag.
 // This is an interim solution, until the next `google/benchmark` release,
@@ -71,7 +71,7 @@
 //
 // This function can only be used in the context of |BSSL_BENCH_LAZY_REGISTER|.
 // Otherwise, the benchmark will be aborted.
-Span<const int64_t> GetInputSizes(benchmark::internal::Benchmark *bench);
+Span<const int64_t> GetInputSizes(benchmark::Benchmark *bench);
 
 }  // namespace bench
 
diff --git a/bench/main.cc b/bench/main.cc
index ebcb215..61e54b7 100644
--- a/bench/main.cc
+++ b/bench/main.cc
@@ -46,7 +46,7 @@
 }
 }  // namespace
 
-void SetThreads(benchmark::internal::Benchmark *bench) {
+void SetThreads(benchmark::Benchmark *bench) {
   if (!flags_parsed) {
     fprintf(stderr,
             "Benchmark %s attempts to set thread count before flag parsing is "
@@ -71,7 +71,7 @@
   return 0;
 }
 
-Span<const int64_t> GetInputSizes(benchmark::internal::Benchmark *bench) {
+Span<const int64_t> GetInputSizes(benchmark::Benchmark *bench) {
   if (!flags_parsed) {
     fprintf(stderr,
             "Benchmark %s attempts to set thread count before flag parsing is "
diff --git a/bench/rand.cc b/bench/rand.cc
index ddeabe5..222a01a 100644
--- a/bench/rand.cc
+++ b/bench/rand.cc
@@ -39,7 +39,7 @@
 
 static const int64_t kInputSizes[] = {16, 256, 1350, 8192, 16384};
 
-void SetInputLength(benchmark::internal::Benchmark *bench) {
+void SetInputLength(benchmark::Benchmark *bench) {
   bench->ArgName("InputSize");
   auto input_sizes = bssl::bench::GetInputSizes(bench);
   if (input_sizes.empty()) {
diff --git a/third_party/benchmark/.bazelversion b/third_party/benchmark/.bazelversion
new file mode 100644
index 0000000..2b0aa21
--- /dev/null
+++ b/third_party/benchmark/.bazelversion
@@ -0,0 +1 @@
+8.2.1
diff --git a/third_party/benchmark/.github/dependabot.yml b/third_party/benchmark/.github/dependabot.yml
new file mode 100644
index 0000000..3661e97
--- /dev/null
+++ b/third_party/benchmark/.github/dependabot.yml
@@ -0,0 +1,11 @@
+version: 2
+updates:
+  - package-ecosystem: github-actions
+    directory: /
+    schedule:
+      interval: daily
+
+  - package-ecosystem: pip
+    directory: /tools
+    schedule:
+      interval: daily
diff --git a/third_party/benchmark/.github/workflows/bazel.yml b/third_party/benchmark/.github/workflows/bazel.yml
index d966877..ab94f16 100644
--- a/third_party/benchmark/.github/workflows/bazel.yml
+++ b/third_party/benchmark/.github/workflows/bazel.yml
@@ -7,6 +7,9 @@
 env:
   CMAKE_GENERATOR: Ninja
 
+permissions:
+  contents: read
+
 jobs:
   build_and_test_default:
     name: bazel.${{ matrix.os }}
@@ -16,10 +19,10 @@
       matrix:
         os: [ubuntu-latest, macos-latest, windows-latest]
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
     - name: mount bazel cache
-      uses: actions/cache@v4
+      uses: actions/cache@8b402f58fbc84540c8b491a91e594a4576fec3d7 # v5.0.2
       env:
         cache-name: bazel-cache
       with:
diff --git a/third_party/benchmark/.github/workflows/build-and-test-min-cmake.yml b/third_party/benchmark/.github/workflows/build-and-test-min-cmake.yml
index 2b56e6a..c9d6e04 100644
--- a/third_party/benchmark/.github/workflows/build-and-test-min-cmake.yml
+++ b/third_party/benchmark/.github/workflows/build-and-test-min-cmake.yml
@@ -19,9 +19,9 @@
         os: [ubuntu-latest, macos-latest]
 
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
-      - uses: lukka/get-cmake@latest
+      - uses: lukka/get-cmake@9e07ecdcee1b12e5037e42f410b67f03e2f626e1 # latest
         with:
           cmakeVersion: 3.13.0
 
diff --git a/third_party/benchmark/.github/workflows/build-and-test-perfcounters.yml b/third_party/benchmark/.github/workflows/build-and-test-perfcounters.yml
index ad92602..df2ff34 100644
--- a/third_party/benchmark/.github/workflows/build-and-test-perfcounters.yml
+++ b/third_party/benchmark/.github/workflows/build-and-test-perfcounters.yml
@@ -9,6 +9,9 @@
 env:
   CMAKE_GENERATOR: Ninja
 
+permissions:
+  contents: read
+
 jobs:
   job:
     # TODO(dominic): Extend this to include compiler and set through env: CC/CXX.
@@ -20,7 +23,7 @@
         os: [ubuntu-latest]
         build_type: ['Release', 'Debug']
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
     - name: install libpfm
       run: |
diff --git a/third_party/benchmark/.github/workflows/build-and-test.yml b/third_party/benchmark/.github/workflows/build-and-test.yml
index 858ea8c..90215c5 100644
--- a/third_party/benchmark/.github/workflows/build-and-test.yml
+++ b/third_party/benchmark/.github/workflows/build-and-test.yml
@@ -30,10 +30,10 @@
         if: runner.os == 'macOS'
         run: brew install ninja
 
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
       - name: build
-        uses: threeal/cmake-action@v2.1.0
+        uses: threeal/cmake-action@725d1314ccf9ea922805d7e3f9d9bcbca892b406 # v2.1.0
         with:
           build-dir: ${{ runner.workspace }}/_build
           cxx-compiler: ${{ matrix.compiler }}
@@ -60,7 +60,7 @@
       fail-fast: false
       matrix:
         msvc:
-          - VS-16-2019
+          - VS-17-2025
           - VS-17-2022
         build_type:
           - Debug
@@ -69,17 +69,17 @@
           - shared
           - static
         include:
-          - msvc: VS-16-2019
-            os: windows-2019
-            generator: 'Visual Studio 16 2019'
+          - msvc: VS-17-2025
+            os: windows-2025
+            generator: 'Visual Studio 17 2022'
           - msvc: VS-17-2022
             os: windows-2022
             generator: 'Visual Studio 17 2022'
 
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
-      - uses: lukka/get-cmake@latest
+      - uses: lukka/get-cmake@9e07ecdcee1b12e5037e42f410b67f03e2f626e1 # latest
 
       - name: configure cmake
         run: >
@@ -117,7 +117,7 @@
 
     steps:
       - name: setup msys2
-        uses: msys2/setup-msys2@v2
+        uses: msys2/setup-msys2@4f806de0a5a7294ffabaff804b38a9b435a73bda # v2.30.0
         with:
           cache: false
           msystem: ${{ matrix.msys2.msystem }}
@@ -131,7 +131,7 @@
             cmake:p
             ninja:p
 
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
       # NOTE: we can't use cmake actions here as we need to do everything in msys2 shell.
       - name: configure cmake
diff --git a/third_party/benchmark/.github/workflows/clang-format-lint.yml b/third_party/benchmark/.github/workflows/clang-format-lint.yml
index 3956516..c9f0315 100644
--- a/third_party/benchmark/.github/workflows/clang-format-lint.yml
+++ b/third_party/benchmark/.github/workflows/clang-format-lint.yml
@@ -6,14 +6,17 @@
 env:
   CMAKE_GENERATOR: Ninja
 
+permissions:
+  contents: read
+
 jobs:
   job:
     name: check-clang-format
     runs-on: ubuntu-latest
 
     steps:
-    - uses: actions/checkout@v4
-    - uses: DoozyX/clang-format-lint-action@v0.18.2
+    - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+    - uses: DoozyX/clang-format-lint-action@bcb4eb2cb0d707ee4f3e5cc3b456eb075f12cf73 # v0.20
       with:
-        source: './include/benchmark ./src ./test'
+        source: './include/benchmark ./src ./test ./bindings'
         clangFormatVersion: 18
diff --git a/third_party/benchmark/.github/workflows/clang-tidy-lint.yml b/third_party/benchmark/.github/workflows/clang-tidy-lint.yml
index b3a8964..1c92cfc 100644
--- a/third_party/benchmark/.github/workflows/clang-tidy-lint.yml
+++ b/third_party/benchmark/.github/workflows/clang-tidy-lint.yml
@@ -7,6 +7,9 @@
 env:
   CMAKE_GENERATOR: Ninja
 
+permissions:
+  contents: read
+
 jobs:
   job:
     name: run-clang-tidy
@@ -14,7 +17,7 @@
     strategy:
       fail-fast: false
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
     - name: install clang-tidy
       run: sudo apt update && sudo apt -y install clang-tidy
diff --git a/third_party/benchmark/.github/workflows/doxygen.yml b/third_party/benchmark/.github/workflows/doxygen.yml
index bcab2c2..075a385 100644
--- a/third_party/benchmark/.github/workflows/doxygen.yml
+++ b/third_party/benchmark/.github/workflows/doxygen.yml
@@ -9,13 +9,16 @@
 env:
   CMAKE_GENERATOR: Ninja
 
+permissions:
+  contents: read
+
 jobs:
   build-and-deploy:
     name: Build HTML documentation
     runs-on: ubuntu-latest
     steps:
     - name: Fetching sources
-      uses: actions/checkout@v4
+      uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
     - name: Installing build dependencies
       run: |
diff --git a/third_party/benchmark/.github/workflows/ossf.yml b/third_party/benchmark/.github/workflows/ossf.yml
new file mode 100644
index 0000000..db742fb
--- /dev/null
+++ b/third_party/benchmark/.github/workflows/ossf.yml
@@ -0,0 +1,27 @@
+name: OSSF Scorecard Weekly
+
+on:
+  schedule:
+    - cron: '0 0 * * 0' # Runs every Sunday at midnight UTC
+  workflow_dispatch:
+
+permissions:
+  contents: read
+
+jobs:
+  ossf-scorecard:
+    # To write a badge
+    permissions:
+      id-token: write
+      
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
+
+      - name: Run analysis
+        uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
+        with:
+          publish_results: true
+          results_file: ossf_scorecard.json
+          results_format: json
diff --git a/third_party/benchmark/.github/workflows/pre-commit.yml b/third_party/benchmark/.github/workflows/pre-commit.yml
index d56dde9..f630060 100644
--- a/third_party/benchmark/.github/workflows/pre-commit.yml
+++ b/third_party/benchmark/.github/workflows/pre-commit.yml
@@ -6,36 +6,17 @@
   pull_request:
     branches: [ main ]
 
-env:
-  CMAKE_GENERATOR: Ninja
-
 jobs:
   pre-commit:
     runs-on: ubuntu-latest
-    env:
-      MYPY_CACHE_DIR: "${{ github.workspace }}/.cache/mypy"
-      RUFF_CACHE_DIR: "${{ github.workspace }}/.cache/ruff"
-      PRE_COMMIT_HOME: "${{ github.workspace }}/.cache/pre-commit"
 
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
       with:
-        fetch-depth: 0
-    - name: Set up Python
-      uses: actions/setup-python@v5
+        persist-credentials: false
+    - name: Install uv
+      uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
       with:
-        python-version: 3.11
-        cache: pip
-        cache-dependency-path: pyproject.toml
-    - name: Install dependencies
-      run: python -m pip install ".[dev]"
-    - name: Cache pre-commit tools
-      uses: actions/cache@v4
-      with:
-        path: |
-          ${{ env.MYPY_CACHE_DIR }}
-          ${{ env.RUFF_CACHE_DIR }}
-          ${{ env.PRE_COMMIT_HOME }}
-        key: ${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}-linter-cache
+        python-version: 3.12
     - name: Run pre-commit checks
-      run: pre-commit run --all-files --verbose --show-diff-on-failure
+      run: uv run --only-group=dev pre-commit run --all-files --verbose --show-diff-on-failure
diff --git a/third_party/benchmark/.github/workflows/sanitizer.yml b/third_party/benchmark/.github/workflows/sanitizer.yml
index 05c265b..6e9404f 100644
--- a/third_party/benchmark/.github/workflows/sanitizer.yml
+++ b/third_party/benchmark/.github/workflows/sanitizer.yml
@@ -19,7 +19,7 @@
         sanitizer: ['asan', 'ubsan', 'tsan', 'msan']
 
     steps:
-    - uses: actions/checkout@v4
+    - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
 
     - name: configure msan env
       if: matrix.sanitizer == 'msan'
@@ -52,7 +52,7 @@
         echo "ASAN_OPTIONS=alloc_dealloc_mismatch=0" >> $GITHUB_ENV
 
     - name: setup clang
-      uses: egor-tensin/setup-clang@v1
+      uses: egor-tensin/setup-clang@471a6f8ef1d449dba8e1a51780e7f943572a3f99 # v2.1
       with:
         version: latest
         platform: x64
diff --git a/third_party/benchmark/.github/workflows/test_bindings.yml b/third_party/benchmark/.github/workflows/test_bindings.yml
index df02c9f..191239c 100644
--- a/third_party/benchmark/.github/workflows/test_bindings.yml
+++ b/third_party/benchmark/.github/workflows/test_bindings.yml
@@ -9,6 +9,9 @@
 env:
   CMAKE_GENERATOR: Ninja
 
+permissions:
+  contents: read
+
 jobs:
   python_bindings:
     name: Test GBM Python ${{ matrix.python-version }} bindings on ${{ matrix.os }}
@@ -20,11 +23,11 @@
         python-version: [ "3.10", "3.11", "3.12", "3.13" ]
 
     steps:
-      - uses: actions/checkout@v4
+      - uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
           fetch-depth: 0
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@v5
+        uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
         with:
           python-version: ${{ matrix.python-version }}
       - name: Install GBM Python bindings on ${{ matrix.os }}
diff --git a/third_party/benchmark/.github/workflows/wheels.yml b/third_party/benchmark/.github/workflows/wheels.yml
index 4f0fa87..c0c8eab 100644
--- a/third_party/benchmark/.github/workflows/wheels.yml
+++ b/third_party/benchmark/.github/workflows/wheels.yml
@@ -15,17 +15,17 @@
     runs-on: ubuntu-latest
     steps:
       - name: Check out repo
-        uses: actions/checkout@v4
+        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
           fetch-depth: 0
       - name: Install Python 3.12
-        uses: actions/setup-python@v5
+        uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
         with:
           python-version: "3.12"
       - run: python -m pip install build
       - name: Build sdist
         run: python -m build --sdist
-      - uses: actions/upload-artifact@v4
+      - uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
         with:
           name: dist-sdist
           path: dist/*.tar.gz
@@ -35,21 +35,22 @@
     runs-on: ${{ matrix.os }}
     strategy:
       matrix:
-        os: [ubuntu-latest, ubuntu-24.04-arm, macos-13, macos-14, windows-latest]
+        os: [ubuntu-latest, ubuntu-24.04-arm, macos-15-intel, macos-latest, windows-latest]
     steps:
       - name: Check out Google Benchmark
-        uses: actions/checkout@v4
+        uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
         with:
           fetch-depth: 0
 
-      - uses: actions/setup-python@v5
+      - uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
         name: Install Python 3.12
         with:
           python-version: "3.12"
-      - run: pip install --upgrade pip uv
+      - name: Install the latest version of uv
+        uses: astral-sh/setup-uv@61cb8a9741eeb8a550a1b8544337180c0fc8476b # v7.2.0
 
       - name: Build wheels on ${{ matrix.os }} using cibuildwheel
-        uses: pypa/cibuildwheel@v2.23.2
+        uses: pypa/cibuildwheel@298ed2fb2c105540f5ed055e8a6ad78d82dd3a7e # v3.3.1
         env:
           CIBW_BUILD: "cp310-* cp311-* cp312-*"
           CIBW_BUILD_FRONTEND: "build[uv]"
@@ -60,10 +61,10 @@
           CIBW_ENVIRONMENT_LINUX: PATH=$PATH:$HOME/bin
           CIBW_TEST_COMMAND: python {project}/bindings/python/google_benchmark/example.py
           # unused by Bazel, but needed explicitly by delocate on MacOS.
-          MACOSX_DEPLOYMENT_TARGET: "10.14"
+          MACOSX_DEPLOYMENT_TARGET: ${{ matrix.os == 'macos-15-intel' && 10.14 || 11.0 }}
 
       - name: Upload Google Benchmark ${{ matrix.os }} wheels
-        uses: actions/upload-artifact@v4
+        uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
         with:
           name: dist-${{ matrix.os }}
           path: wheelhouse/*.whl
@@ -75,9 +76,9 @@
     permissions:
       id-token: write
     steps:
-      - uses: actions/download-artifact@v4
+      - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0
         with:
           path: dist
           pattern: dist-*
           merge-multiple: true
-      - uses: pypa/gh-action-pypi-publish@release/v1
+      - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # release/v1
diff --git a/third_party/benchmark/.gitignore b/third_party/benchmark/.gitignore
index 24a1fb6..8f6ce84 100644
--- a/third_party/benchmark/.gitignore
+++ b/third_party/benchmark/.gitignore
@@ -66,3 +66,4 @@
 # Python build stuff
 dist/
 *.egg-info*
+uv.lock
diff --git a/third_party/benchmark/.pre-commit-config.yaml b/third_party/benchmark/.pre-commit-config.yaml
index 49d544e..57af012 100644
--- a/third_party/benchmark/.pre-commit-config.yaml
+++ b/third_party/benchmark/.pre-commit-config.yaml
@@ -1,18 +1,18 @@
 repos:
   -   repo: https://github.com/keith/pre-commit-buildifier
-      rev: 8.0.3
+      rev: 8.2.1
       hooks:
       -   id: buildifier
       -   id: buildifier-lint
   - repo: https://github.com/pre-commit/mirrors-mypy
-    rev: v1.15.0
+    rev: v1.18.2
     hooks:
       - id: mypy
         types_or: [ python, pyi ]
         args: [ "--ignore-missing-imports", "--scripts-are-modules" ]
   - repo: https://github.com/astral-sh/ruff-pre-commit
-    rev: v0.11.8
+    rev: v0.14.0
     hooks:
-      - id: ruff
+      - id: ruff-check
         args: [ --fix, --exit-non-zero-on-fix ]
       - id: ruff-format
diff --git a/third_party/benchmark/AUTHORS b/third_party/benchmark/AUTHORS
index 2170e46..11d28f7 100644
--- a/third_party/benchmark/AUTHORS
+++ b/third_party/benchmark/AUTHORS
@@ -44,6 +44,7 @@
 Jussi Knuuttila <jussi.knuuttila@gmail.com>
 Kaito Udagawa <umireon@gmail.com>
 Kishan Kumar <kumar.kishan@outlook.com>
+Kostiantyn Lazukin <konstantin.lazukin@gmail.com>
 Lei Xu <eddyxu@gmail.com>
 Marcel Jacobse <mjacobse@uni-bremen.de>
 Matt Clarkson <mattyclarkson@gmail.com>
@@ -54,14 +55,17 @@
 Nick Hutchinson <nshutchinson@gmail.com>
 Norman Heino <norman.heino@gmail.com>
 Oleksandr Sochka <sasha.sochka@gmail.com>
+Olga Fadeeva <olga.kiselik@gmail.com>
 Ori Livneh <ori.livneh@gmail.com>
 Paul Redmond <paul.redmond@gmail.com>
+Prithvi Rao <ee22b024@smail.iitm.ac.in>
 Radoslav Yovchev <radoslav.tm@gmail.com>
 Raghu Raja <raghu@enfabrica.net>
 Rainer Orth <ro@cebitec.uni-bielefeld.de>
 Roman Lebedev <lebedev.ri@gmail.com>
 Sayan Bhattacharjee <aero.sayan@gmail.com>
 Shapr3D <google-contributors@shapr3d.com>
+Shashank Thakur <shashankt2004@gmail.com>
 Shuo Chen <chenshuo@chenshuo.com>
 Staffan Tjernstrom <staffantj@gmail.com>
 Steinar H. Gunderson <sgunderson@bigfoot.com>
diff --git a/third_party/benchmark/BUILD.bazel b/third_party/benchmark/BUILD.bazel
new file mode 100644
index 0000000..993b261
--- /dev/null
+++ b/third_party/benchmark/BUILD.bazel
@@ -0,0 +1,103 @@
+load("@rules_cc//cc:defs.bzl", "cc_library")
+
+licenses(["notice"])
+
+COPTS = [
+    "-pedantic",
+    "-pedantic-errors",
+    "-std=c++17",
+    "-Wall",
+    "-Wconversion",
+    "-Wextra",
+    "-Wshadow",
+    #    "-Wshorten-64-to-32",
+    "-Wfloat-equal",
+    "-Wformat=2",
+    "-fstrict-aliasing",
+    ## assert() are used a lot in tests upstream, which may be optimised out leading to
+    ## unused-variable warning.
+    "-Wno-unused-variable",
+    "-Werror=old-style-cast",
+]
+
+MSVC_COPTS = [
+    "/std:c++17",
+]
+
+config_setting(
+    name = "windows",
+    constraint_values = ["@platforms//os:windows"],
+    visibility = [":__subpackages__"],
+)
+
+config_setting(
+    name = "perfcounters",
+    define_values = {
+        "pfm": "1",
+    },
+    visibility = [":__subpackages__"],
+)
+
+cc_library(
+    name = "benchmark",
+    srcs = glob(
+        [
+            "src/*.cc",
+            "src/*.h",
+        ],
+        exclude = ["src/benchmark_main.cc"],
+    ),
+    hdrs = [
+        "include/benchmark/benchmark.h",
+        "include/benchmark/export.h",
+    ],
+    copts = select({
+        ":windows": MSVC_COPTS,
+        "//conditions:default": COPTS,
+    }),
+    defines = [
+        "BENCHMARK_STATIC_DEFINE",
+        "BENCHMARK_VERSION=\\\"" + (module_version() if module_version() != None else "") + "\\\"",
+    ] + select({
+        ":perfcounters": ["HAVE_LIBPFM"],
+        "//conditions:default": [],
+    }),
+    includes = ["include"],
+    linkopts = select({
+        ":windows": ["-DEFAULTLIB:shlwapi.lib"],
+        "//conditions:default": ["-pthread"],
+    }),
+    # Only static linking is allowed; no .so will be produced.
+    # Using `defines` (i.e. not `local_defines`) means that no
+    # dependent rules need to bother about defining the macro.
+    linkstatic = True,
+    local_defines = [
+        # Turn on Large-file Support
+        "_FILE_OFFSET_BITS=64",
+        "_LARGEFILE64_SOURCE",
+        "_LARGEFILE_SOURCE",
+    ],
+    visibility = ["//visibility:public"],
+    deps = select({
+        ":perfcounters": ["@libpfm"],
+        "//conditions:default": [],
+    }),
+)
+
+cc_library(
+    name = "benchmark_main",
+    srcs = ["src/benchmark_main.cc"],
+    hdrs = [
+        "include/benchmark/benchmark.h",
+        "include/benchmark/export.h",
+    ],
+    includes = ["include"],
+    visibility = ["//visibility:public"],
+    deps = [":benchmark"],
+)
+
+cc_library(
+    name = "benchmark_internal_headers",
+    hdrs = glob(["src/*.h"]),
+    visibility = ["//test:__pkg__"],
+)
diff --git a/third_party/benchmark/CMakeLists.txt b/third_party/benchmark/CMakeLists.txt
index 219b151..ada04a6 100644
--- a/third_party/benchmark/CMakeLists.txt
+++ b/third_party/benchmark/CMakeLists.txt
@@ -1,7 +1,7 @@
 # Require CMake 3.10. If available, use the policies up to CMake 3.22.
 cmake_minimum_required (VERSION 3.13...3.22)
 
-project (benchmark VERSION 1.9.4 LANGUAGES CXX)
+project (benchmark VERSION 1.9.5 LANGUAGES CXX)
 
 option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." ON)
 option(BENCHMARK_ENABLE_EXCEPTIONS "Enable the use of exceptions in the benchmark library." ON)
@@ -29,6 +29,7 @@
 option(BENCHMARK_ENABLE_INSTALL "Enable installation of benchmark. (Projects embedding benchmark may want to turn this OFF.)" ON)
 option(BENCHMARK_ENABLE_DOXYGEN "Build documentation with Doxygen." OFF)
 option(BENCHMARK_INSTALL_DOCS "Enable installation of documentation." ON)
+option(BENCHMARK_INSTALL_TOOLS "Enable installation of tools." ON)
 
 # Allow unmet dependencies to be met using CMake's ExternalProject mechanics, which
 # may require downloading the source code.
@@ -196,6 +197,7 @@
   add_cxx_compiler_flag(-Wfloat-equal)
   add_cxx_compiler_flag(-Wold-style-cast)
   add_cxx_compiler_flag(-Wconversion)
+  add_cxx_compiler_flag(-Wformat=2)
   if(BENCHMARK_ENABLE_WERROR)
       add_cxx_compiler_flag(-Werror)
   endif()
@@ -216,6 +218,9 @@
     # See #631 for rationale.
     add_cxx_compiler_flag(-wd1786)
     add_cxx_compiler_flag(-fno-finite-math-only)
+    # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially
+    # overridden (because of deprecated overload)
+    add_cxx_compiler_flag(-wd654)
   endif()
   # Disable deprecation warnings for release builds (when -Werror is enabled).
   if(BENCHMARK_ENABLE_WERROR)
@@ -230,9 +235,7 @@
       add_cxx_compiler_flag(-Wstrict-aliasing)
     endif()
   endif()
-  # ICC17u2: overloaded virtual function "benchmark::Fixture::SetUp" is only partially overridden
-  # (because of deprecated overload)
-  add_cxx_compiler_flag(-wd654)
+
   add_cxx_compiler_flag(-Wthread-safety)
   if (HAVE_CXX_FLAG_WTHREAD_SAFETY)
     cxx_feature_check(THREAD_SAFETY_ATTRIBUTES "-DINCLUDE_DIRECTORIES=${PROJECT_SOURCE_DIR}/include")
@@ -307,10 +310,17 @@
 endif(BENCHMARK_USE_LIBCXX)
 
 # C++ feature checks
-# Determine the correct regular expression engine to use
+# Determine the correct regular expression engine to use. First compatible engine found is used.
 cxx_feature_check(STD_REGEX)
-cxx_feature_check(GNU_POSIX_REGEX)
-cxx_feature_check(POSIX_REGEX)
+
+if(NOT HAVE_STD_REGEX)
+  cxx_feature_check(GNU_POSIX_REGEX)
+endif()
+
+if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX)
+  cxx_feature_check(POSIX_REGEX)
+endif()
+
 if(NOT HAVE_STD_REGEX AND NOT HAVE_GNU_POSIX_REGEX AND NOT HAVE_POSIX_REGEX)
   message(FATAL_ERROR "Failed to determine the source files for the regular expression backend")
 endif()
diff --git a/third_party/benchmark/CONTRIBUTORS b/third_party/benchmark/CONTRIBUTORS
index 54aba7b..52e49cc 100644
--- a/third_party/benchmark/CONTRIBUTORS
+++ b/third_party/benchmark/CONTRIBUTORS
@@ -67,6 +67,7 @@
 Kaito Udagawa <umireon@gmail.com>
 Kai Wolf <kai.wolf@gmail.com>
 Kishan Kumar <kumar.kishan@outlook.com>
+Kostiantyn Lazukin <konstantin.lazukin@gmail.com>
 Lei Xu <eddyxu@gmail.com>
 Marcel Jacobse <mjacobse@uni-bremen.de>
 Matt Clarkson <mattyclarkson@gmail.com>
@@ -76,10 +77,12 @@
 Nick Hutchinson <nshutchinson@gmail.com>
 Norman Heino <norman.heino@gmail.com>
 Oleksandr Sochka <sasha.sochka@gmail.com>
+Olga Fadeeva <olga.kiselik@gmail.com>
 Ori Livneh <ori.livneh@gmail.com>
 Pascal Leroy <phl@google.com>
 Paul Redmond <paul.redmond@gmail.com>
 Pierre Phaneuf <pphaneuf@google.com>
+Prithvi Rao <ee22b024@smail.iitm.ac.in>
 Radoslav Yovchev <radoslav.tm@gmail.com>
 Raghu Raja <raghu@enfabrica.net>
 Rainer Orth <ro@cebitec.uni-bielefeld.de>
@@ -88,6 +91,7 @@
 Robert Guo <robert.guo@mongodb.com>
 Roman Lebedev <lebedev.ri@gmail.com>
 Sayan Bhattacharjee <aero.sayan@gmail.com>
+Shashank Thakur <shashankt2004@gmail.com>
 Shuo Chen <chenshuo@chenshuo.com>
 Steven Wan <wan.yu@ibm.com>
 Tobias Schmidt <tobias.schmidt@in.tum.de>
diff --git a/third_party/benchmark/METADATA b/third_party/benchmark/METADATA
index b776340..4e5a41b 100644
--- a/third_party/benchmark/METADATA
+++ b/third_party/benchmark/METADATA
@@ -8,9 +8,9 @@
     type: "Git"
     value: "https://github.com/google/benchmark"
     primary_source: true
-    version: "1.9.4"
+    version: "1.9.5"
   }
-  version: "1.9.4"
-  last_upgrade_date { year: 2025 month: 10 day: 23 }
+  version: "1.9.5"
+  last_upgrade_date { year: 2026 month: 2 day: 9 }
   license_type: PERMISSIVE
 }
diff --git a/third_party/benchmark/MODULE.bazel b/third_party/benchmark/MODULE.bazel
index 7390c98..c162d05 100644
--- a/third_party/benchmark/MODULE.bazel
+++ b/third_party/benchmark/MODULE.bazel
@@ -1,6 +1,6 @@
 module(
     name = "google_benchmark",
-    version = "1.9.4",
+    version = "1.9.5",
 )
 
 bazel_dep(name = "bazel_skylib", version = "1.7.1")
@@ -38,4 +38,4 @@
 
 # -- bazel_dep definitions -- #
 
-bazel_dep(name = "nanobind_bazel", version = "2.7.0", dev_dependency = True)
+bazel_dep(name = "nanobind_bazel", version = "2.9.2", dev_dependency = True)
diff --git a/third_party/benchmark/README.md b/third_party/benchmark/README.md
index 4e73025..1d4470e 100644
--- a/third_party/benchmark/README.md
+++ b/third_party/benchmark/README.md
@@ -2,9 +2,9 @@
 
 [![build-and-test](https://github.com/google/benchmark/workflows/build-and-test/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Abuild-and-test)
 [![bazel](https://github.com/google/benchmark/actions/workflows/bazel.yml/badge.svg)](https://github.com/google/benchmark/actions/workflows/bazel.yml)
-[![pylint](https://github.com/google/benchmark/workflows/pylint/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Apylint)
 [![test-bindings](https://github.com/google/benchmark/workflows/test-bindings/badge.svg)](https://github.com/google/benchmark/actions?query=workflow%3Atest-bindings)
 [![Coverage Status](https://coveralls.io/repos/google/benchmark/badge.svg)](https://coveralls.io/r/google/benchmark)
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/google/benchmark/badge)](https://securityscorecards.dev/viewer/?uri=github.com/google/benchmark)
 
 [![Discord](https://discordapp.com/api/guilds/1125694995928719494/widget.png?style=shield)](https://discord.gg/cz7UX7wKC2)
 
diff --git a/third_party/benchmark/bindings/python/google_benchmark/BUILD b/third_party/benchmark/bindings/python/google_benchmark/BUILD
new file mode 100644
index 0000000..8938b37
--- /dev/null
+++ b/third_party/benchmark/bindings/python/google_benchmark/BUILD
@@ -0,0 +1,34 @@
+load("@nanobind_bazel//:build_defs.bzl", "nanobind_extension", "nanobind_stubgen")
+load("@rules_python//python:defs.bzl", "py_library", "py_test")
+
+py_library(
+    name = "google_benchmark",
+    srcs = ["__init__.py"],
+    visibility = ["//visibility:public"],
+    deps = [
+        ":_benchmark",
+    ],
+)
+
+nanobind_extension(
+    name = "_benchmark",
+    srcs = ["benchmark.cc"],
+    deps = ["//:benchmark"],
+)
+
+nanobind_stubgen(
+    name = "benchmark_stubgen",
+    marker_file = "bindings/python/google_benchmark/py.typed",
+    module = ":_benchmark",
+)
+
+py_test(
+    name = "example",
+    srcs = ["example.py"],
+    python_version = "PY3",
+    srcs_version = "PY3",
+    visibility = ["//visibility:public"],
+    deps = [
+        ":google_benchmark",
+    ],
+)
diff --git a/third_party/benchmark/bindings/python/google_benchmark/__init__.py b/third_party/benchmark/bindings/python/google_benchmark/__init__.py
new file mode 100644
index 0000000..331a88e
--- /dev/null
+++ b/third_party/benchmark/bindings/python/google_benchmark/__init__.py
@@ -0,0 +1,136 @@
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Python benchmarking utilities.
+
+Example usage:
+  import google_benchmark as benchmark
+
+  @benchmark.register
+  def my_benchmark(state):
+      ...  # Code executed outside `while` loop is not timed.
+
+      while state:
+        ...  # Code executed within `while` loop is timed.
+
+  if __name__ == '__main__':
+    benchmark.main()
+"""
+
+import atexit
+
+from google_benchmark import _benchmark
+from google_benchmark._benchmark import (
+    Counter as Counter,
+    State as State,
+    kMicrosecond as kMicrosecond,
+    kMillisecond as kMillisecond,
+    kNanosecond as kNanosecond,
+    kSecond as kSecond,
+    o1 as o1,
+    oAuto as oAuto,
+    oLambda as oLambda,
+    oLogN as oLogN,
+    oN as oN,
+    oNCubed as oNCubed,
+    oNLogN as oNLogN,
+    oNone as oNone,
+    oNSquared as oNSquared,
+)
+
+__version__ = "1.9.5"
+
+
+class __OptionMaker:
+    """A stateless class to collect benchmark options.
+
+    Collect all decorator calls like @option.range(start=0, limit=1<<5).
+    """
+
+    class Options:
+        """Pure data class to store options calls, along with the benchmarked
+        function."""
+
+        def __init__(self, func):
+            self.func = func
+            self.builder_calls = []
+
+    @classmethod
+    def make(cls, func_or_options):
+        """Make Options from Options or the benchmarked function."""
+        if isinstance(func_or_options, cls.Options):
+            return func_or_options
+        return cls.Options(func_or_options)
+
+    def __getattr__(self, builder_name):
+        """Append option call in the Options."""
+
+        # The function that get returned on @option.range(start=0, limit=1<<5).
+        def __builder_method(*args, **kwargs):
+            # The decorator that get called, either with the benchmared function
+            # or the previous Options
+            def __decorator(func_or_options):
+                options = self.make(func_or_options)
+                options.builder_calls.append((builder_name, args, kwargs))
+                # The decorator returns Options so it is not technically a
+                # decorator and needs a final call to @register
+                return options
+
+            return __decorator
+
+        return __builder_method
+
+
+# Alias for nicer API.
+# We have to instantiate an object, even if stateless, to be able to use
+# __getattr__ on option.range
+option = __OptionMaker()
+
+
+def register(undefined=None, *, name=None):
+    """Register function for benchmarking."""
+    if undefined is None:
+        # Decorator is called without parenthesis so we return a decorator
+        return lambda f: register(f, name=name)
+
+    # We have either the function to benchmark (simple case) or an instance of
+    # Options (@option._ case).
+    options = __OptionMaker.make(undefined)
+
+    if name is None:
+        name = options.func.__name__
+
+    # We register the benchmark and reproduce all the @option._ calls onto the
+    # benchmark builder pattern
+    benchmark = _benchmark.RegisterBenchmark(name, options.func)
+    for name, args, kwargs in options.builder_calls[::-1]:
+        getattr(benchmark, name)(*args, **kwargs)
+
+    # return the benchmarked function because the decorator does not modify it
+    return options.func
+
+
+def main(argv: list[str] | None = None) -> None:
+    import sys
+
+    _benchmark.Initialize(argv or sys.argv)
+    return _benchmark.RunSpecifiedBenchmarks()
+
+
+# FIXME: can we rerun with disabled ASLR?
+
+# Methods for use with custom main function.
+initialize = _benchmark.Initialize
+run_benchmarks = _benchmark.RunSpecifiedBenchmarks
+add_custom_context = _benchmark.AddCustomContext
+atexit.register(_benchmark.ClearRegisteredBenchmarks)
diff --git a/third_party/benchmark/bindings/python/google_benchmark/benchmark.cc b/third_party/benchmark/bindings/python/google_benchmark/benchmark.cc
new file mode 100644
index 0000000..ccd7eb5
--- /dev/null
+++ b/third_party/benchmark/bindings/python/google_benchmark/benchmark.cc
@@ -0,0 +1,189 @@
+// Benchmark for Python.
+
+#include "benchmark/benchmark.h"
+
+#include "nanobind/nanobind.h"
+#include "nanobind/operators.h"
+#include "nanobind/stl/bind_map.h"
+#include "nanobind/stl/string.h"
+#include "nanobind/stl/vector.h"
+
+NB_MAKE_OPAQUE(benchmark::UserCounters);
+
+namespace {
+namespace nb = nanobind;
+
+std::vector<std::string> Initialize(const std::vector<std::string>& argv) {
+  std::vector<char*> ptrs;
+  ptrs.reserve(argv.size());
+  for (auto& arg : argv) {
+    ptrs.push_back(const_cast<char*>(arg.c_str()));
+  }
+  if (!ptrs.empty()) {
+    // The `argv` pointers here become invalid when this function returns, but
+    // benchmark holds the pointer to `argv[0]`. We create a static copy of it
+    // so it persists, and replace the pointer below.
+    static std::string executable_name(argv[0]);
+    ptrs[0] = const_cast<char*>(executable_name.c_str());
+  }
+  int argc = static_cast<int>(argv.size());
+  benchmark::Initialize(&argc, ptrs.data());
+  std::vector<std::string> remaining_argv;
+  remaining_argv.reserve(argc);
+  for (int i = 0; i < argc; ++i) {
+    remaining_argv.emplace_back(ptrs[i]);
+  }
+  return remaining_argv;
+}
+
+benchmark::Benchmark* RegisterBenchmark(const std::string& name,
+                                        nb::callable f) {
+  return benchmark::RegisterBenchmark(
+      name, [f](benchmark::State& state) { f(&state); });
+}
+
+NB_MODULE(_benchmark, m) {
+  using benchmark::TimeUnit;
+  nb::enum_<TimeUnit>(m, "TimeUnit")
+      .value("kNanosecond", TimeUnit::kNanosecond)
+      .value("kMicrosecond", TimeUnit::kMicrosecond)
+      .value("kMillisecond", TimeUnit::kMillisecond)
+      .value("kSecond", TimeUnit::kSecond)
+      .export_values();
+
+  using benchmark::BigO;
+  nb::enum_<BigO>(m, "BigO")
+      .value("oNone", BigO::oNone)
+      .value("o1", BigO::o1)
+      .value("oN", BigO::oN)
+      .value("oNSquared", BigO::oNSquared)
+      .value("oNCubed", BigO::oNCubed)
+      .value("oLogN", BigO::oLogN)
+      .value("oNLogN", BigO::oNLogN)
+      .value("oAuto", BigO::oAuto)
+      .value("oLambda", BigO::oLambda)
+      .export_values();
+
+  using benchmark::Benchmark;
+  nb::class_<Benchmark>(m, "Benchmark")
+      // For methods returning a pointer to the current object, reference
+      // return policy is used to ask nanobind not to take ownership of the
+      // returned object and avoid calling delete on it.
+      // https://pybind11.readthedocs.io/en/stable/advanced/functions.html#return-value-policies
+      //
+      // For methods taking a const std::vector<...>&, a copy is created
+      // because a it is bound to a Python list.
+      // https://pybind11.readthedocs.io/en/stable/advanced/cast/stl.html
+      .def("unit", &Benchmark::Unit, nb::rv_policy::reference)
+      .def("arg", &Benchmark::Arg, nb::rv_policy::reference)
+      .def("args", &Benchmark::Args, nb::rv_policy::reference)
+      .def("range", &Benchmark::Range, nb::rv_policy::reference,
+           nb::arg("start"), nb::arg("limit"))
+      .def("dense_range", &Benchmark::DenseRange, nb::rv_policy::reference,
+           nb::arg("start"), nb::arg("limit"), nb::arg("step") = 1)
+      .def("ranges", &Benchmark::Ranges, nb::rv_policy::reference)
+      .def("args_product", &Benchmark::ArgsProduct, nb::rv_policy::reference)
+      .def("arg_name", &Benchmark::ArgName, nb::rv_policy::reference)
+      .def("arg_names", &Benchmark::ArgNames, nb::rv_policy::reference)
+      .def("range_pair", &Benchmark::RangePair, nb::rv_policy::reference,
+           nb::arg("lo1"), nb::arg("hi1"), nb::arg("lo2"), nb::arg("hi2"))
+      .def("range_multiplier", &Benchmark::RangeMultiplier,
+           nb::rv_policy::reference)
+      .def("min_time", &Benchmark::MinTime, nb::rv_policy::reference)
+      .def("min_warmup_time", &Benchmark::MinWarmUpTime,
+           nb::rv_policy::reference)
+      .def("iterations", &Benchmark::Iterations, nb::rv_policy::reference)
+      .def("repetitions", &Benchmark::Repetitions, nb::rv_policy::reference)
+      .def("report_aggregates_only", &Benchmark::ReportAggregatesOnly,
+           nb::rv_policy::reference, nb::arg("value") = true)
+      .def("display_aggregates_only", &Benchmark::DisplayAggregatesOnly,
+           nb::rv_policy::reference, nb::arg("value") = true)
+      .def("measure_process_cpu_time", &Benchmark::MeasureProcessCPUTime,
+           nb::rv_policy::reference)
+      .def("use_real_time", &Benchmark::UseRealTime, nb::rv_policy::reference)
+      .def("use_manual_time", &Benchmark::UseManualTime,
+           nb::rv_policy::reference)
+      .def(
+          "complexity",
+          (Benchmark * (Benchmark::*)(benchmark::BigO)) & Benchmark::Complexity,
+          nb::rv_policy::reference, nb::arg("complexity") = benchmark::oAuto);
+
+  using benchmark::Counter;
+  nb::class_<Counter> py_counter(m, "Counter");
+
+  nb::enum_<Counter::Flags>(py_counter, "Flags", nb::is_arithmetic(),
+                            nb::is_flag())
+      .value("kDefaults", Counter::Flags::kDefaults)
+      .value("kIsRate", Counter::Flags::kIsRate)
+      .value("kAvgThreads", Counter::Flags::kAvgThreads)
+      .value("kAvgThreadsRate", Counter::Flags::kAvgThreadsRate)
+      .value("kIsIterationInvariant", Counter::Flags::kIsIterationInvariant)
+      .value("kIsIterationInvariantRate",
+             Counter::Flags::kIsIterationInvariantRate)
+      .value("kAvgIterations", Counter::Flags::kAvgIterations)
+      .value("kAvgIterationsRate", Counter::Flags::kAvgIterationsRate)
+      .value("kInvert", Counter::Flags::kInvert)
+      .export_values();
+
+  nb::enum_<Counter::OneK>(py_counter, "OneK")
+      .value("kIs1000", Counter::OneK::kIs1000)
+      .value("kIs1024", Counter::OneK::kIs1024)
+      .export_values();
+
+  py_counter
+      .def(nb::init<double, Counter::Flags, Counter::OneK>(),
+           nb::arg("value") = 0., nb::arg("flags") = Counter::kDefaults,
+           nb::arg("k") = Counter::kIs1000)
+      .def("__init__",
+           ([](Counter* c, double value) { new (c) Counter(value); }))
+      .def_rw("value", &Counter::value)
+      .def_rw("flags", &Counter::flags)
+      .def_rw("oneK", &Counter::oneK)
+      .def(nb::init_implicit<double>());
+
+  nb::implicitly_convertible<nb::int_, Counter>();
+
+  nb::bind_map<benchmark::UserCounters>(m, "UserCounters");
+
+  using benchmark::State;
+  nb::class_<State>(m, "State")
+      .def("__bool__", &State::KeepRunning)
+      .def_prop_ro("keep_running", &State::KeepRunning)
+      .def("pause_timing", &State::PauseTiming)
+      .def("resume_timing", &State::ResumeTiming)
+      .def("skip_with_error", &State::SkipWithError)
+      .def_prop_ro("error_occurred", &State::error_occurred)
+      .def("set_iteration_time", &State::SetIterationTime)
+      .def_prop_rw("bytes_processed", &State::bytes_processed,
+                   &State::SetBytesProcessed)
+      .def_prop_rw("complexity_n", &State::complexity_length_n,
+                   &State::SetComplexityN)
+      .def_prop_rw("items_processed", &State::items_processed,
+                   &State::SetItemsProcessed)
+      .def("set_label", &State::SetLabel)
+      .def(
+          "range",
+          [](const State& state, std::size_t pos = 0) -> int64_t {
+            if (pos < state.range_size()) {
+              return state.range(pos);
+            }
+            throw nb::index_error("pos is out of range");
+          },
+          nb::arg("pos") = 0)
+      .def_prop_ro("iterations", &State::iterations)
+      .def_prop_ro("name", &State::name)
+      .def_rw("counters", &State::counters)
+      .def_prop_ro("thread_index", &State::thread_index)
+      .def_prop_ro("threads", &State::threads);
+
+  m.def("Initialize", Initialize);
+  m.def("RegisterBenchmark", RegisterBenchmark, nb::rv_policy::reference);
+  m.def("RunSpecifiedBenchmarks",
+        []() { benchmark::RunSpecifiedBenchmarks(); });
+  m.def("ClearRegisteredBenchmarks", benchmark::ClearRegisteredBenchmarks);
+  m.def("AddCustomContext", benchmark::AddCustomContext, nb::arg("key"),
+        nb::arg("value"),
+        "Add a key-value pair to output as part of the context stanza in the "
+        "report.");
+};
+}  // namespace
diff --git a/third_party/benchmark/bindings/python/google_benchmark/example.py b/third_party/benchmark/bindings/python/google_benchmark/example.py
new file mode 100644
index 0000000..8217b40
--- /dev/null
+++ b/third_party/benchmark/bindings/python/google_benchmark/example.py
@@ -0,0 +1,142 @@
+# Copyright 2020 Google Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""Example of Python using C++ benchmark framework.
+
+To run this example, you must first install the `google_benchmark` Python
+package.
+
+To install using `setup.py`, download and extract the `google_benchmark` source.
+In the extracted directory, execute:
+  python setup.py install
+"""
+
+import random
+import sys
+import time
+
+import google_benchmark as benchmark
+from google_benchmark import Counter
+
+
+@benchmark.register
+def empty(state):
+    while state:
+        pass
+
+
+@benchmark.register
+def sum_million(state):
+    while state:
+        sum(range(1_000_000))
+
+
+@benchmark.register
+def pause_timing(state):
+    """Pause timing every iteration."""
+    while state:
+        # Construct a list of random ints every iteration without timing it
+        state.pause_timing()
+        random_list = [random.randint(0, 100) for _ in range(100)]
+        state.resume_timing()
+        # Time the in place sorting algorithm
+        random_list.sort()
+
+
+@benchmark.register
+def skipped(state):
+    if True:  # Test some predicate here.
+        state.skip_with_error("some error")
+        return  # NOTE: You must explicitly return, or benchmark will continue.
+
+    # Benchmark code would be here.
+
+
+@benchmark.register
+@benchmark.option.use_manual_time()
+def manual_timing(state):
+    while state:
+        # Manually count Python CPU time
+        start = time.perf_counter()  # perf_counter_ns() in Python 3.7+
+        # Something to benchmark
+        time.sleep(0.01)
+        end = time.perf_counter()
+        state.set_iteration_time(end - start)
+
+
+@benchmark.register
+def custom_counters(state):
+    """Collect custom metric using benchmark.Counter."""
+    num_foo = 0.0
+    while state:
+        # Benchmark some code here
+        # Collect some custom metric named foo
+        num_foo += 0.13
+
+    # Automatic Counter from numbers.
+    state.counters["foo"] = num_foo
+    # Set a counter as a rate.
+    state.counters["foo_rate"] = Counter(num_foo, Counter.kIsRate)
+    #  Set a counter as an inverse of rate.
+    state.counters["foo_inv_rate"] = Counter(
+        num_foo, Counter.kIsRate | Counter.kInvert
+    )
+    # Set a counter as a thread-average quantity.
+    state.counters["foo_avg"] = Counter(num_foo, Counter.kAvgThreads)
+    # There's also a combined flag:
+    state.counters["foo_avg_rate"] = Counter(num_foo, Counter.kAvgThreadsRate)
+
+
+@benchmark.register
+@benchmark.option.measure_process_cpu_time()
+@benchmark.option.use_real_time()
+def with_options(state):
+    while state:
+        sum(range(1_000_000))
+
+
+@benchmark.register(name="sum_million_microseconds")
+@benchmark.option.unit(benchmark.kMicrosecond)
+def with_options2(state):
+    while state:
+        sum(range(1_000_000))
+
+
+@benchmark.register
+@benchmark.option.arg(100)
+@benchmark.option.arg(1000)
+def passing_argument(state):
+    while state:
+        sum(range(state.range(0)))
+
+
+@benchmark.register
+@benchmark.option.range(8, limit=8 << 10)
+def using_range(state):
+    while state:
+        sum(range(state.range(0)))
+
+
+@benchmark.register
+@benchmark.option.range_multiplier(2)
+@benchmark.option.range(1 << 10, 1 << 18)
+@benchmark.option.complexity(benchmark.oN)
+def computing_complexity(state):
+    while state:
+        sum(range(state.range(0)))
+    state.complexity_n = state.range(0)
+
+
+if __name__ == "__main__":
+    benchmark.add_custom_context("python", sys.version)
+    benchmark.main()
diff --git a/third_party/benchmark/cmake/CXXFeatureCheck.cmake b/third_party/benchmark/cmake/CXXFeatureCheck.cmake
index 0dfe93d..a163a6e 100644
--- a/third_party/benchmark/cmake/CXXFeatureCheck.cmake
+++ b/third_party/benchmark/cmake/CXXFeatureCheck.cmake
@@ -10,22 +10,35 @@
 #
 # include(CXXFeatureCheck)
 # cxx_feature_check(STD_REGEX)
-# Requires CMake 2.8.12+
+# Requires CMake 3.13+
 
 if(__cxx_feature_check)
   return()
 endif()
 set(__cxx_feature_check INCLUDED)
 
-option(CXXFEATURECHECK_DEBUG OFF)
+option(CXXFEATURECHECK_DEBUG OFF "Enable debug messages for CXX feature checks")
 
-function(cxx_feature_check FILE)
-  string(TOLOWER ${FILE} FILE)
-  string(TOUPPER ${FILE} VAR)
-  string(TOUPPER "HAVE_${VAR}" FEATURE)
-  if (DEFINED HAVE_${VAR})
-    set(HAVE_${VAR} 1 PARENT_SCOPE)
-    add_definitions(-DHAVE_${VAR})
+function(cxx_feature_check_print log)
+  if(CXXFEATURECHECK_DEBUG)
+    message(STATUS "${log}")
+  endif()
+endfunction()
+
+function(cxx_feature_check FEATURE)
+  string(TOLOWER ${FEATURE} FILE)
+  string(TOUPPER HAVE_${FEATURE} VAR)
+
+  # Check if the variable is already defined to a true or false for a quick return.
+  # This allows users to predefine the variable to skip the check.
+  # Or, if the variable is already defined by a previous check, we skip the costly check.
+  if (DEFINED ${VAR})
+    if (${VAR})
+      cxx_feature_check_print("Feature ${FEATURE} already enabled.")
+      add_compile_definitions(${VAR})
+    else()
+      cxx_feature_check_print("Feature ${FEATURE} already disabled.")
+    endif()
     return()
   endif()
 
@@ -35,48 +48,53 @@
     list(APPEND FEATURE_CHECK_CMAKE_FLAGS ${ARGV1})
   endif()
 
-  if (NOT DEFINED COMPILE_${FEATURE})
-    if(CMAKE_CROSSCOMPILING)
-      message(STATUS "Cross-compiling to test ${FEATURE}")
-      try_compile(COMPILE_${FEATURE}
-              ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
-              CXX_STANDARD 17
-              CXX_STANDARD_REQUIRED ON
-              CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
-              LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
-              OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
-      if(COMPILE_${FEATURE})
-        message(WARNING
-              "If you see build failures due to cross compilation, try setting HAVE_${VAR} to 0")
-        set(RUN_${FEATURE} 0 CACHE INTERNAL "")
-      else()
-        set(RUN_${FEATURE} 1 CACHE INTERNAL "")
-      endif()
-    else()
-      message(STATUS "Compiling and running to test ${FEATURE}")
-      try_run(RUN_${FEATURE} COMPILE_${FEATURE}
-              ${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
-              CXX_STANDARD 17
-              CXX_STANDARD_REQUIRED ON
-              CMAKE_FLAGS ${FEATURE_CHECK_CMAKE_FLAGS}
-              LINK_LIBRARIES ${BENCHMARK_CXX_LIBRARIES}
-              COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT_VAR)
+  if(CMAKE_CROSSCOMPILING)
+    cxx_feature_check_print("Cross-compiling to test ${FEATURE}")
+    try_compile(
+      COMPILE_STATUS
+      ${CMAKE_BINARY_DIR} 
+      ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
+      CXX_STANDARD 17
+      CXX_STANDARD_REQUIRED ON
+      CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}"
+      LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}"
+      OUTPUT_VARIABLE COMPILE_OUTPUT_VAR
+    )
+    if(COMPILE_STATUS)
+      set(RUN_STATUS 0)
+      message(WARNING
+              "If you see build failures due to cross compilation, try setting ${VAR} to 0")
     endif()
+  else()
+    cxx_feature_check_print("Compiling and running to test ${FEATURE}")
+    try_run(
+      RUN_STATUS 
+      COMPILE_STATUS
+      ${CMAKE_BINARY_DIR} 
+      ${CMAKE_CURRENT_SOURCE_DIR}/cmake/${FILE}.cpp
+      CXX_STANDARD 17
+      CXX_STANDARD_REQUIRED ON
+      CMAKE_FLAGS "${FEATURE_CHECK_CMAKE_FLAGS}"
+      LINK_LIBRARIES "${BENCHMARK_CXX_LIBRARIES}"
+      COMPILE_OUTPUT_VARIABLE COMPILE_OUTPUT
+      RUN_OUTPUT_VARIABLE RUN_OUTPUT
+    )
   endif()
 
-  if(RUN_${FEATURE} EQUAL 0)
+  if(COMPILE_STATUS AND RUN_STATUS EQUAL 0)
     message(STATUS "Performing Test ${FEATURE} -- success")
-    set(HAVE_${VAR} 1 PARENT_SCOPE)
-    add_definitions(-DHAVE_${VAR})
-  else()
-    if(NOT COMPILE_${FEATURE})
-      if(CXXFEATURECHECK_DEBUG)
-        message(STATUS "Performing Test ${FEATURE} -- failed to compile: ${COMPILE_OUTPUT_VAR}")
-      else()
-        message(STATUS "Performing Test ${FEATURE} -- failed to compile")
-      endif()
-    else()
-      message(STATUS "Performing Test ${FEATURE} -- compiled but failed to run")
-    endif()
+    set(${VAR} TRUE CACHE BOOL "" FORCE)
+    add_compile_definitions(${VAR})
+    return()
   endif()
+
+  set(${VAR} FALSE CACHE BOOL "" FORCE)
+  message(STATUS "Performing Test ${FEATURE} -- failed")
+
+  if(NOT COMPILE_STATUS)
+    cxx_feature_check_print("Compile Output: ${COMPILE_OUTPUT}")
+  else()
+    cxx_feature_check_print("Run Output: ${RUN_OUTPUT}")
+  endif()
+
 endfunction()
diff --git a/third_party/benchmark/docs/reducing_variance.md b/third_party/benchmark/docs/reducing_variance.md
index e604c66..364f4af 100644
--- a/third_party/benchmark/docs/reducing_variance.md
+++ b/third_party/benchmark/docs/reducing_variance.md
@@ -105,23 +105,28 @@
 
 1. Use the performance governor as [discussed
 above](user_guide#disabling-cpu-frequency-scaling).
-1. Disable processor boosting by:
+2. Disable processor boosting by:
    ```sh
    echo 0 | sudo tee /sys/devices/system/cpu/cpufreq/boost
    ```
    See the Linux kernel's
    [boost.txt](https://www.kernel.org/doc/Documentation/cpu-freq/boost.txt)
    for more information.
-2. Set the benchmark program's task affinity to a fixed cpu.  For example:
+3. Set the benchmark program's task affinity to a fixed cpu.  For example:
    ```sh
    taskset -c 0 ./mybenchmark
    ```
-3. Disabling Hyperthreading/SMT.  This can be done in the Bios or using the
+4. Increase the program's scheduling priority to minimize context switches using `nice` or `chrt`:
+   ```sh
+   sudo nice -n -20 ./mybenchmark
+   sudo chrt -f 80 ./mybenchmark
+   ```
+5. Disabling Hyperthreading/SMT.  This can be done in the Bios or using the
    `/sys` file system (see the LLVM project's [Benchmarking
    tips](https://llvm.org/docs/Benchmarking.html)).
-4. Close other programs that do non-trivial things based on timers, such as
+6. Close other programs that do non-trivial things based on timers, such as
    your web browser, desktop environment, etc.
-5. Reduce the working set of your benchmark to fit within the L1 cache, but
+7. Reduce the working set of your benchmark to fit within the L1 cache, but
    do be aware that this may lead you to optimize for an unrealistic
    situation.
 
diff --git a/third_party/benchmark/docs/user_guide.md b/third_party/benchmark/docs/user_guide.md
index ae8e125..997737f 100644
--- a/third_party/benchmark/docs/user_guide.md
+++ b/third_party/benchmark/docs/user_guide.md
@@ -452,7 +452,7 @@
 and a sparse range on the second.
 
 ```c++
-static void CustomArguments(benchmark::internal::Benchmark* b) {
+static void CustomArguments(benchmark::Benchmark* b) {
   for (int i = 0; i <= 10; ++i)
     for (int j = 32; j <= 1024*1024; j *= 8)
       b->Args({i, j});
@@ -749,10 +749,6 @@
 conversion to `double&`. Thus you can use all of the standard arithmetic
 assignment operators (`=,+=,-=,*=,/=`) to change the value of each counter.
 
-In multithreaded benchmarks, each counter is set on the calling thread only.
-When the benchmark finishes, the counters from each thread will be summed;
-the resulting sum is the value which will be shown for the benchmark.
-
 The `Counter` constructor accepts three parameters: the value as a `double`
 ; a bit flag which allows you to show counters as rates, and/or as per-thread
 iteration, and/or as per-thread averages, and/or iteration invariants,
@@ -797,6 +793,10 @@
 ```
 <!-- {% endraw %} -->
 
+In multithreaded benchmarks, each counter is set on the calling thread only.
+When the benchmark finishes, the counters from each thread will be summed.
+Counters that are configured with `kIsRate`, will report the average rate across all threads, while `kAvgThreadsRate` counters will report the average rate per thread.
+
 ### Counter Reporting
 
 When using the console reporter, by default, user counters are printed at
diff --git a/third_party/benchmark/include/benchmark/benchmark.h b/third_party/benchmark/include/benchmark/benchmark.h
index f455e05..f7d1341 100644
--- a/third_party/benchmark/include/benchmark/benchmark.h
+++ b/third_party/benchmark/include/benchmark/benchmark.h
@@ -103,7 +103,7 @@
 // arbitrary set of arguments to run the microbenchmark on.
 // The following example enumerates a dense range on
 // one parameter, and a sparse range on the second.
-static void CustomArguments(benchmark::internal::Benchmark* b) {
+static void CustomArguments(benchmark::Benchmark* b) {
   for (int i = 0; i <= 10; ++i)
     for (int j = 32; j <= 1024*1024; j *= 8)
       b->Args({i, j});
@@ -171,7 +171,6 @@
 #include <cassert>
 #include <cstddef>
 #include <functional>
-#include <initializer_list>
 #include <iosfwd>
 #include <limits>
 #include <map>
@@ -239,6 +238,16 @@
   _Pragma("diagnostic push") \
   _Pragma("diag_suppress deprecated_entity_with_custom_message")
 #define BENCHMARK_RESTORE_DEPRECATED_WARNING _Pragma("diagnostic pop")
+#elif defined(_MSC_VER)
+#define BENCHMARK_BUILTIN_EXPECT(x, y) x
+#define BENCHMARK_DEPRECATED_MSG(msg) __declspec(deprecated(msg))
+#define BENCHMARK_WARNING_MSG(msg)                           \
+  __pragma(message(__FILE__ "(" BENCHMARK_INTERNAL_TOSTRING( \
+      __LINE__) ") : warning note: " msg))
+#define BENCHMARK_DISABLE_DEPRECATED_WARNING \
+  __pragma(warning(push)) \
+  __pragma(warning(disable : 4996))
+#define BENCHMARK_RESTORE_DEPRECATED_WARNING __pragma(warning(pop))
 #else
 #define BENCHMARK_BUILTIN_EXPECT(x, y) x
 #define BENCHMARK_DEPRECATED_MSG(msg)
@@ -476,10 +485,11 @@
 
 // Add a key-value pair to output as part of the context stanza in the report.
 BENCHMARK_EXPORT
-void AddCustomContext(const std::string& key, const std::string& value);
+void AddCustomContext(std::string key, std::string value);
+
+class Benchmark;
 
 namespace internal {
-class Benchmark;
 class BenchmarkImp;
 class BenchmarkFamilies;
 
@@ -611,6 +621,17 @@
   _ReadWriteBarrier();
 }
 
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp& value) {
+  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
+  _ReadWriteBarrier();
+}
+
+template <class Tp>
+inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
+  internal::UseCharPointer(&reinterpret_cast<char const volatile&>(value));
+  _ReadWriteBarrier();
+}
 #else
 template <class Tp>
 inline BENCHMARK_ALWAYS_INLINE void DoNotOptimize(Tp&& value) {
@@ -956,6 +977,8 @@
   BENCHMARK_ALWAYS_INLINE
   std::string name() const { return name_; }
 
+  size_t range_size() const { return range_.size(); }
+
  private:
   // items we expect on the first cache line (ie 64 bytes of the struct)
   // When total_iterations_ is 0, KeepRunning() and friends will return false.
@@ -1102,20 +1125,15 @@
   virtual void RunThreads(const std::function<void(int)>& fn) = 0;
 };
 
-namespace internal {
-
 // Define alias of ThreadRunner factory function type
 using threadrunner_factory =
     std::function<std::unique_ptr<ThreadRunnerBase>(int)>;
 
-typedef void(Function)(State&);
-
 // ------------------------------------------------------
-// Benchmark registration object.  The BENCHMARK() macro expands
-// into an internal::Benchmark* object.  Various methods can
-// be called on this object to change the properties of the benchmark.
-// Each method returns "this" so that multiple method calls can
-// chained into one expression.
+// Benchmark registration object.  The BENCHMARK() macro expands into a
+// Benchmark* object.  Various methods can be called on this object to
+// change the properties of the benchmark.  Each method returns "this" so
+// that multiple method calls can chained into one expression.
 class BENCHMARK_EXPORT Benchmark {
  public:
   virtual ~Benchmark();
@@ -1206,7 +1224,7 @@
   // Pass this benchmark object to *func, which can customize
   // the benchmark by calling various methods like Arg, Args,
   // Threads, etc.
-  Benchmark* Apply(void (*custom_arguments)(Benchmark* benchmark));
+  Benchmark* Apply(const std::function<void(Benchmark* benchmark)>&);
 
   // Set the range multiplier for non-dense range. If not called, the range
   // multiplier kRangeMultiplier will be used.
@@ -1329,11 +1347,11 @@
   const char* GetArgName(int arg) const;
 
  private:
-  friend class BenchmarkFamilies;
-  friend class BenchmarkInstance;
+  friend class internal::BenchmarkFamilies;
+  friend class internal::BenchmarkInstance;
 
   std::string name_;
-  AggregationReportMode aggregation_report_mode_;
+  internal::AggregationReportMode aggregation_report_mode_;
   std::vector<std::string> arg_names_;      // Args for all benchmark runs
   std::vector<std::vector<int64_t>> args_;  // Args for all benchmark runs
 
@@ -1350,7 +1368,7 @@
   bool use_manual_time_;
   BigO complexity_;
   BigOFunc* complexity_lambda_;
-  std::vector<Statistics> statistics_;
+  std::vector<internal::Statistics> statistics_;
   std::vector<int> thread_counts_;
 
   callback_function setup_;
@@ -1361,17 +1379,28 @@
   BENCHMARK_DISALLOW_COPY_AND_ASSIGN(Benchmark);
 };
 
+namespace internal {
+
+// clang-format off
+typedef BENCHMARK_DEPRECATED_MSG("Use ::benchmark::Benchmark instead")
+    ::benchmark::Benchmark Benchmark;
+typedef BENCHMARK_DEPRECATED_MSG(
+    "Use ::benchmark::threadrunner_factory instead")
+    ::benchmark::threadrunner_factory threadrunner_factory;
+// clang-format on
+
+typedef void(Function)(State&);
+
 }  // namespace internal
 
 // Create and register a benchmark with the specified 'name' that invokes
 // the specified functor 'fn'.
 //
 // RETURNS: A pointer to the registered benchmark.
-internal::Benchmark* RegisterBenchmark(const std::string& name,
-                                       internal::Function* fn);
+Benchmark* RegisterBenchmark(const std::string& name, internal::Function* fn);
 
 template <class Lambda>
-internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
+Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn);
 
 // Remove all registered benchmarks. All pointers to previously registered
 // benchmarks are invalidated.
@@ -1380,7 +1409,7 @@
 namespace internal {
 // The class used to hold all Benchmarks created from static function.
 // (ie those created using the BENCHMARK(...) macros.
-class BENCHMARK_EXPORT FunctionBenchmark : public Benchmark {
+class BENCHMARK_EXPORT FunctionBenchmark : public benchmark::Benchmark {
  public:
   FunctionBenchmark(const std::string& name, Function* func)
       : Benchmark(name), func_(func) {}
@@ -1392,7 +1421,7 @@
 };
 
 template <class Lambda>
-class LambdaBenchmark : public Benchmark {
+class LambdaBenchmark : public benchmark::Benchmark {
  public:
   void Run(State& st) override { lambda_(st); }
 
@@ -1406,15 +1435,15 @@
 };
 }  // namespace internal
 
-inline internal::Benchmark* RegisterBenchmark(const std::string& name,
-                                              internal::Function* fn) {
+inline Benchmark* RegisterBenchmark(const std::string& name,
+                                    internal::Function* fn) {
   return internal::RegisterBenchmarkInternal(
       ::benchmark::internal::make_unique<internal::FunctionBenchmark>(name,
                                                                       fn));
 }
 
 template <class Lambda>
-internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
+Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn) {
   using BenchType =
       internal::LambdaBenchmark<typename std::decay<Lambda>::type>;
   return internal::RegisterBenchmarkInternal(
@@ -1423,16 +1452,16 @@
 }
 
 template <class Lambda, class... Args>
-internal::Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
-                                       Args&&... args) {
+Benchmark* RegisterBenchmark(const std::string& name, Lambda&& fn,
+                             Args&&... args) {
   return benchmark::RegisterBenchmark(
       name, [=](benchmark::State& st) { fn(st, args...); });
 }
 
 // The base class for all fixture tests.
-class Fixture : public internal::Benchmark {
+class Fixture : public Benchmark {
  public:
-  Fixture() : internal::Benchmark("") {}
+  Fixture() : Benchmark("") {}
 
   void Run(State& st) override {
     this->SetUp(st);
@@ -1455,14 +1484,29 @@
 // ------------------------------------------------------
 // Macro to register benchmarks
 
+// clang-format off
+#if defined(__clang__)
+#define BENCHMARK_DISABLE_COUNTER_WARNING                        \
+  _Pragma("GCC diagnostic push")                                 \
+  _Pragma("GCC diagnostic ignored \"-Wunknown-warning-option\"") \
+  _Pragma("GCC diagnostic ignored \"-Wc2y-extensions\"")
+#define BENCHMARK_RESTORE_COUNTER_WARNING _Pragma("GCC diagnostic pop")
+#else
+#define BENCHMARK_DISABLE_COUNTER_WARNING
+#define BENCHMARK_RESTORE_COUNTER_WARNING
+#endif
+// clang-format on
+
 // Check that __COUNTER__ is defined and that __COUNTER__ increases by 1
 // every time it is expanded. X + 1 == X + 0 is used in case X is defined to be
 // empty. If X is empty the expression becomes (+1 == +0).
+BENCHMARK_DISABLE_COUNTER_WARNING
 #if defined(__COUNTER__) && (__COUNTER__ + 1 == __COUNTER__ + 0)
 #define BENCHMARK_PRIVATE_UNIQUE_ID __COUNTER__
 #else
 #define BENCHMARK_PRIVATE_UNIQUE_ID __LINE__
 #endif
+BENCHMARK_RESTORE_COUNTER_WARNING
 
 // Helpers for generating unique variable names
 #define BENCHMARK_PRIVATE_NAME(...)                                      \
@@ -1475,17 +1519,19 @@
 #define BENCHMARK_PRIVATE_CONCAT_NAME(BaseClass, Method) \
   BaseClass##_##Method##_Benchmark
 
-#define BENCHMARK_PRIVATE_DECLARE(n)                                           \
-  /* NOLINTNEXTLINE(misc-use-anonymous-namespace) */                           \
-  static ::benchmark::internal::Benchmark const* const BENCHMARK_PRIVATE_NAME( \
-      n) BENCHMARK_UNUSED
+#define BENCHMARK_PRIVATE_DECLARE(n)                                   \
+  BENCHMARK_DISABLE_COUNTER_WARNING                                    \
+  /* NOLINTNEXTLINE(misc-use-anonymous-namespace) */                   \
+  static ::benchmark::Benchmark const* const BENCHMARK_PRIVATE_NAME(n) \
+      BENCHMARK_RESTORE_COUNTER_WARNING BENCHMARK_UNUSED
 
-#define BENCHMARK(...)                                                \
-  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =                            \
-      (::benchmark::internal::RegisterBenchmarkInternal(              \
-          ::benchmark::internal::make_unique<                         \
-              ::benchmark::internal::FunctionBenchmark>(#__VA_ARGS__, \
-                                                        __VA_ARGS__)))
+#define BENCHMARK(...)                                   \
+  BENCHMARK_PRIVATE_DECLARE(_benchmark_) =               \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #__VA_ARGS__,                              \
+              static_cast<::benchmark::internal::Function*>(__VA_ARGS__))))
 
 // Old-style macros
 #define BENCHMARK_WITH_ARG(n, a) BENCHMARK(n)->Arg((a))
@@ -1526,21 +1572,25 @@
   BENCHMARK_PRIVATE_DECLARE(n) =                         \
       (::benchmark::internal::RegisterBenchmarkInternal( \
           ::benchmark::internal::make_unique<            \
-              ::benchmark::internal::FunctionBenchmark>(#n "<" #a ">", n<a>)))
+              ::benchmark::internal::FunctionBenchmark>( \
+              #n "<" #a ">",                             \
+              static_cast<::benchmark::internal::Function*>(n<a>))))
 
-#define BENCHMARK_TEMPLATE2(n, a, b)                                          \
-  BENCHMARK_PRIVATE_DECLARE(n) =                                              \
-      (::benchmark::internal::RegisterBenchmarkInternal(                      \
-          ::benchmark::internal::make_unique<                                 \
-              ::benchmark::internal::FunctionBenchmark>(#n "<" #a "," #b ">", \
-                                                        n<a, b>)))
+#define BENCHMARK_TEMPLATE2(n, a, b)                     \
+  BENCHMARK_PRIVATE_DECLARE(n) =                         \
+      (::benchmark::internal::RegisterBenchmarkInternal( \
+          ::benchmark::internal::make_unique<            \
+              ::benchmark::internal::FunctionBenchmark>( \
+              #n "<" #a "," #b ">",                      \
+              static_cast<::benchmark::internal::Function*>(n<a, b>))))
 
 #define BENCHMARK_TEMPLATE(n, ...)                       \
   BENCHMARK_PRIVATE_DECLARE(n) =                         \
       (::benchmark::internal::RegisterBenchmarkInternal( \
           ::benchmark::internal::make_unique<            \
               ::benchmark::internal::FunctionBenchmark>( \
-              #n "<" #__VA_ARGS__ ">", n<__VA_ARGS__>)))
+              #n "<" #__VA_ARGS__ ">",                   \
+              static_cast<::benchmark::internal::Function*>(n<__VA_ARGS__>))))
 
 // This will register a benchmark for a templatized function,
 // with the additional arguments specified by `...`.
@@ -1661,9 +1711,11 @@
           ::benchmark::internal::make_unique<UniqueName>()))
 
 #define BENCHMARK_TEMPLATE_INSTANTIATE_F(BaseClass, Method, ...)    \
+  BENCHMARK_DISABLE_COUNTER_WARNING                                 \
   BENCHMARK_TEMPLATE_PRIVATE_INSTANTIATE_F(                         \
       BaseClass, Method, BENCHMARK_PRIVATE_NAME(BaseClass##Method), \
-      __VA_ARGS__)
+      __VA_ARGS__)                                                  \
+  BENCHMARK_RESTORE_COUNTER_WARNING
 
 // This macro will define and register a benchmark within a fixture class.
 #define BENCHMARK_F(BaseClass, Method)           \
@@ -1798,6 +1850,7 @@
           complexity(oNone),
           complexity_lambda(),
           complexity_n(0),
+          statistics(),
           report_big_o(false),
           report_rms(false),
           allocs_per_iter(0.0) {}
diff --git a/third_party/benchmark/pyproject.toml b/third_party/benchmark/pyproject.toml
index 4595b6d..f55daf2 100644
--- a/third_party/benchmark/pyproject.toml
+++ b/third_party/benchmark/pyproject.toml
@@ -19,15 +19,14 @@
     "Programming Language :: Python :: 3.10",
     "Programming Language :: Python :: 3.11",
     "Programming Language :: Python :: 3.12",
+    "Programming Language :: Python :: 3.13",
     "Topic :: Software Development :: Testing",
     "Topic :: System :: Benchmark",
 ]
 
 dynamic = ["readme", "version"]
 
-dependencies = ["absl-py>=0.7.1"]
-
-[project.optional-dependencies]
+[dependency-groups]
 dev = ["pre-commit>=3.3.3"]
 
 [project.urls]
diff --git a/third_party/benchmark/setup.py b/third_party/benchmark/setup.py
index 3c0269b..d7807b4 100644
--- a/third_party/benchmark/setup.py
+++ b/third_party/benchmark/setup.py
@@ -131,7 +131,12 @@
         pkgname = "google_benchmark"
         pythonroot = Path("bindings") / "python" / "google_benchmark"
         srcdir = temp_path / "bazel-bin" / pythonroot
-        libdir = Path(self.build_lib) / pkgname
+        if not self.inplace:
+            libdir = Path(self.build_lib) / pkgname
+        else:
+            build_py = self.get_finalized_command("build_py")
+            libdir = Path(build_py.get_package_dir(pkgname))
+
         for root, dirs, files in os.walk(srcdir, topdown=True):
             # exclude runfiles directories and children.
             dirs[:] = [d for d in dirs if "runfiles" not in d]
diff --git a/third_party/benchmark/src/CMakeLists.txt b/third_party/benchmark/src/CMakeLists.txt
index 9fb305a..8e5db41 100644
--- a/third_party/benchmark/src/CMakeLists.txt
+++ b/third_party/benchmark/src/CMakeLists.txt
@@ -67,7 +67,6 @@
 # We need extra libraries on Solaris
 if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS")
   target_link_libraries(benchmark PRIVATE kstat)
-  set(BENCHMARK_PRIVATE_LINK_LIBRARIES -lkstat)
 endif()
 
 if (NOT BUILD_SHARED_LIBS)
@@ -109,6 +108,20 @@
   "${version_config}" VERSION ${GENERIC_LIB_VERSION} COMPATIBILITY SameMajorVersion
 )
 
+# Derive private link libraries from target
+if(NOT BUILD_SHARED_LIBS)
+  get_target_property(LINK_LIBS benchmark LINK_LIBRARIES)
+  if(LINK_LIBS)
+    set(BENCHMARK_PRIVATE_LINK_LIBRARIES "")
+    foreach(LIB IN LISTS LINK_LIBS)
+      if(NOT TARGET "${LIB}" AND LIB MATCHES "^[a-zA-Z0-9_.-]+$")
+        list(APPEND BENCHMARK_PRIVATE_LINK_LIBRARIES "-l${LIB}")
+      endif()
+    endforeach()
+    string(JOIN " " BENCHMARK_PRIVATE_LINK_LIBRARIES ${BENCHMARK_PRIVATE_LINK_LIBRARIES})
+  endif()
+endif()
+
 configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark.pc.in" "${pkg_config}" @ONLY)
 configure_file("${PROJECT_SOURCE_DIR}/cmake/benchmark_main.pc.in" "${pkg_config_main}" @ONLY)
 
@@ -181,3 +194,11 @@
       DESTINATION ${CMAKE_INSTALL_DOCDIR})
   endif()
 endif()
+
+set(CMAKE_INSTALL_PYTOOLSDIR "${CMAKE_INSTALL_DATADIR}/googlebenchmark/tools" CACHE PATH "")
+
+if (BENCHMARK_ENABLE_INSTALL AND BENCHMARK_INSTALL_TOOLS)
+  install(
+    DIRECTORY "${PROJECT_SOURCE_DIR}/tools/"
+    DESTINATION ${CMAKE_INSTALL_PYTOOLSDIR})
+endif()
diff --git a/third_party/benchmark/src/benchmark.cc b/third_party/benchmark/src/benchmark.cc
index 8672c8a..fc36fed 100644
--- a/third_party/benchmark/src/benchmark.cc
+++ b/third_party/benchmark/src/benchmark.cc
@@ -708,11 +708,12 @@
   internal::profiler_manager = manager;
 }
 
-void AddCustomContext(const std::string& key, const std::string& value) {
+void AddCustomContext(std::string key, std::string value) {
   if (internal::global_context == nullptr) {
     internal::global_context = new std::map<std::string, std::string>();
   }
-  if (!internal::global_context->emplace(key, value).second) {
+  if (!internal::global_context->emplace(std::move(key), std::move(value))
+           .second) {
     std::cerr << "Failed to add custom context \"" << key << "\" as it already "
               << "exists with value \"" << value << "\"\n";
   }
@@ -722,6 +723,7 @@
 
 void (*HelperPrintf)();
 
+namespace {
 void PrintUsageAndExit() {
   HelperPrintf();
   std::flush(std::cout);
@@ -810,6 +812,8 @@
   }
 }
 
+}  // end namespace
+
 int InitializeStreams() {
   static std::ios_base::Init init;
   return 0;
diff --git a/third_party/benchmark/src/benchmark_api_internal.cc b/third_party/benchmark/src/benchmark_api_internal.cc
index 60609d3..f9c4990 100644
--- a/third_party/benchmark/src/benchmark_api_internal.cc
+++ b/third_party/benchmark/src/benchmark_api_internal.cc
@@ -7,7 +7,8 @@
 namespace benchmark {
 namespace internal {
 
-BenchmarkInstance::BenchmarkInstance(Benchmark* benchmark, int family_idx,
+BenchmarkInstance::BenchmarkInstance(benchmark::Benchmark* benchmark,
+                                     int family_idx,
                                      int per_family_instance_idx,
                                      const std::vector<int64_t>& args,
                                      int thread_count)
diff --git a/third_party/benchmark/src/benchmark_api_internal.h b/third_party/benchmark/src/benchmark_api_internal.h
index efa0602..5b48ea2 100644
--- a/third_party/benchmark/src/benchmark_api_internal.h
+++ b/third_party/benchmark/src/benchmark_api_internal.h
@@ -17,7 +17,7 @@
 // Information kept per benchmark we may want to run
 class BenchmarkInstance {
  public:
-  BenchmarkInstance(Benchmark* benchmark, int family_idx,
+  BenchmarkInstance(benchmark::Benchmark* benchmark, int family_idx,
                     int per_family_instance_idx,
                     const std::vector<int64_t>& args, int thread_count);
 
@@ -52,7 +52,7 @@
 
  private:
   BenchmarkName name_;
-  Benchmark& benchmark_;
+  benchmark::Benchmark& benchmark_;
   const int family_index_;
   const int per_family_instance_index_;
   AggregationReportMode aggregation_report_mode_;
diff --git a/third_party/benchmark/src/benchmark_register.cc b/third_party/benchmark/src/benchmark_register.cc
index d8cefe4..65e1afc 100644
--- a/third_party/benchmark/src/benchmark_register.cc
+++ b/third_party/benchmark/src/benchmark_register.cc
@@ -75,7 +75,7 @@
   static BenchmarkFamilies* GetInstance();
 
   // Registers a benchmark family and returns the index assigned to it.
-  size_t AddBenchmark(std::unique_ptr<Benchmark> family);
+  size_t AddBenchmark(std::unique_ptr<benchmark::Benchmark> family);
 
   // Clear all registered benchmark families.
   void ClearBenchmarks();
@@ -89,7 +89,7 @@
  private:
   BenchmarkFamilies() {}
 
-  std::vector<std::unique_ptr<Benchmark>> families_;
+  std::vector<std::unique_ptr<benchmark::Benchmark>> families_;
   Mutex mutex_;
 };
 
@@ -98,7 +98,8 @@
   return &instance;
 }
 
-size_t BenchmarkFamilies::AddBenchmark(std::unique_ptr<Benchmark> family) {
+size_t BenchmarkFamilies::AddBenchmark(
+    std::unique_ptr<benchmark::Benchmark> family) {
   MutexLock l(mutex_);
   size_t index = families_.size();
   families_.push_back(std::move(family));
@@ -135,7 +136,7 @@
   int next_family_index = 0;
 
   MutexLock l(mutex_);
-  for (std::unique_ptr<Benchmark>& family : families_) {
+  for (std::unique_ptr<benchmark::Benchmark>& family : families_) {
     int family_index = next_family_index;
     int per_family_instance_index = 0;
 
@@ -179,7 +180,7 @@
 
           ++per_family_instance_index;
 
-          // Only bump the next family index once we've estabilished that
+          // Only bump the next family index once we've established that
           // at least one instance of this family will be run.
           if (next_family_index == family_index) {
             ++next_family_index;
@@ -191,8 +192,9 @@
   return true;
 }
 
-Benchmark* RegisterBenchmarkInternal(std::unique_ptr<Benchmark> bench) {
-  Benchmark* bench_ptr = bench.get();
+benchmark::Benchmark* RegisterBenchmarkInternal(
+    std::unique_ptr<benchmark::Benchmark> bench) {
+  benchmark::Benchmark* bench_ptr = bench.get();
   BenchmarkFamilies* families = BenchmarkFamilies::GetInstance();
   families->AddBenchmark(std::move(bench));
   return bench_ptr;
@@ -206,13 +208,15 @@
   return BenchmarkFamilies::GetInstance()->FindBenchmarks(re, benchmarks, Err);
 }
 
+}  // end namespace internal
+
 //=============================================================================//
 //                               Benchmark
 //=============================================================================//
 
 Benchmark::Benchmark(const std::string& name)
     : name_(name),
-      aggregation_report_mode_(ARM_Unspecified),
+      aggregation_report_mode_(internal::ARM_Unspecified),
       time_unit_(GetDefaultTimeUnit()),
       use_default_time_unit_(true),
       range_multiplier_(kRangeMultiplier),
@@ -253,7 +257,7 @@
 Benchmark* Benchmark::Range(int64_t start, int64_t limit) {
   BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == 1);
   std::vector<int64_t> arglist;
-  AddRange(&arglist, start, limit, range_multiplier_);
+  internal::AddRange(&arglist, start, limit, range_multiplier_);
 
   for (int64_t i : arglist) {
     args_.push_back({i});
@@ -266,8 +270,8 @@
   BM_CHECK(ArgsCnt() == -1 || ArgsCnt() == static_cast<int>(ranges.size()));
   std::vector<std::vector<int64_t>> arglists(ranges.size());
   for (std::size_t i = 0; i < ranges.size(); i++) {
-    AddRange(&arglists[i], ranges[i].first, ranges[i].second,
-             range_multiplier_);
+    internal::AddRange(&arglists[i], ranges[i].first, ranges[i].second,
+                       range_multiplier_);
   }
 
   ArgsProduct(arglists);
@@ -330,7 +334,8 @@
   return this;
 }
 
-Benchmark* Benchmark::Apply(void (*custom_arguments)(Benchmark* benchmark)) {
+Benchmark* Benchmark::Apply(
+    const std::function<void(Benchmark* benchmark)>& custom_arguments) {
   custom_arguments(this);
   return this;
 }
@@ -381,8 +386,8 @@
 
 Benchmark* Benchmark::Iterations(IterationCount n) {
   BM_CHECK(n > 0);
-  BM_CHECK(IsZero(min_time_));
-  BM_CHECK(IsZero(min_warmup_time_));
+  BM_CHECK(internal::IsZero(min_time_));
+  BM_CHECK(internal::IsZero(min_warmup_time_));
   iterations_ = n;
   return this;
 }
@@ -394,21 +399,23 @@
 }
 
 Benchmark* Benchmark::ReportAggregatesOnly(bool value) {
-  aggregation_report_mode_ = value ? ARM_ReportAggregatesOnly : ARM_Default;
+  aggregation_report_mode_ =
+      value ? internal::ARM_ReportAggregatesOnly : internal::ARM_Default;
   return this;
 }
 
 Benchmark* Benchmark::DisplayAggregatesOnly(bool value) {
   // If we were called, the report mode is no longer 'unspecified', in any case.
+  using internal::AggregationReportMode;
   aggregation_report_mode_ = static_cast<AggregationReportMode>(
-      aggregation_report_mode_ | ARM_Default);
+      aggregation_report_mode_ | internal::ARM_Default);
 
   if (value) {
     aggregation_report_mode_ = static_cast<AggregationReportMode>(
-        aggregation_report_mode_ | ARM_DisplayReportAggregatesOnly);
+        aggregation_report_mode_ | internal::ARM_DisplayReportAggregatesOnly);
   } else {
     aggregation_report_mode_ = static_cast<AggregationReportMode>(
-        aggregation_report_mode_ & ~ARM_DisplayReportAggregatesOnly);
+        aggregation_report_mode_ & ~internal::ARM_DisplayReportAggregatesOnly);
   }
 
   return this;
@@ -462,7 +469,7 @@
   BM_CHECK_GT(min_threads, 0);
   BM_CHECK_GE(max_threads, min_threads);
 
-  AddRange(&thread_counts_, min_threads, max_threads, 2);
+  internal::AddRange(&thread_counts_, min_threads, max_threads, 2);
   return this;
 }
 
@@ -514,6 +521,8 @@
   return use_default_time_unit_ ? GetDefaultTimeUnit() : time_unit_;
 }
 
+namespace internal {
+
 //=============================================================================//
 //                            FunctionBenchmark
 //=============================================================================//
diff --git a/third_party/benchmark/src/benchmark_register.h b/third_party/benchmark/src/benchmark_register.h
index be50265..e0ace51 100644
--- a/third_party/benchmark/src/benchmark_register.h
+++ b/third_party/benchmark/src/benchmark_register.h
@@ -3,6 +3,7 @@
 
 #include <algorithm>
 #include <limits>
+#include <type_traits>
 #include <vector>
 
 #include "check.h"
diff --git a/third_party/benchmark/src/benchmark_runner.cc b/third_party/benchmark/src/benchmark_runner.cc
index 1f5bb6b..fb68867 100644
--- a/third_party/benchmark/src/benchmark_runner.cc
+++ b/third_party/benchmark/src/benchmark_runner.cc
@@ -123,7 +123,12 @@
               : 0;
     }
 
-    internal::Finish(&report.counters, results.iterations, seconds,
+    // The CPU time is the total time taken by all thread. If we used that as
+    // the denominator, we'd be calculating the rate per thread here. This is
+    // why we have to divide the total cpu_time by the number of threads for
+    // global counters to get a global rate.
+    const double thread_seconds = seconds / b.threads();
+    internal::Finish(&report.counters, results.iterations, thread_seconds,
                      b.threads());
   }
   return report;
@@ -191,7 +196,7 @@
   explicit ThreadRunnerDefault(int num_threads)
       : pool(static_cast<size_t>(num_threads - 1)) {}
 
-  void RunThreads(const std::function<void(int)>& fn) final {
+  void RunThreads(const std::function<void(int)>& fn) override final {
     // Run all but one thread in separate threads
     for (std::size_t ti = 0; ti < pool.size(); ++ti) {
       pool[ti] = std::thread(fn, static_cast<int>(ti + 1));
@@ -212,7 +217,8 @@
 };
 
 std::unique_ptr<ThreadRunnerBase> GetThreadRunner(
-    const threadrunner_factory& userThreadRunnerFactory, int num_threads) {
+    const benchmark::threadrunner_factory& userThreadRunnerFactory,
+    int num_threads) {
   return userThreadRunnerFactory
              ? userThreadRunnerFactory(num_threads)
              : std::make_unique<ThreadRunnerDefault>(num_threads);
@@ -400,7 +406,7 @@
 }
 
 double BenchmarkRunner::GetMinTimeToApply() const {
-  // In order to re-use functionality to run and measure benchmarks for running
+  // In order to reuse functionality to run and measure benchmarks for running
   // a warmup phase of the benchmark, we need a way of telling whether to apply
   // min_time or min_warmup_time. This function will figure out if we are in the
   // warmup phase and therefore need to apply min_warmup_time or if we already
diff --git a/third_party/benchmark/src/colorprint.h b/third_party/benchmark/src/colorprint.h
index 9f6fab9..469045c 100644
--- a/third_party/benchmark/src/colorprint.h
+++ b/third_party/benchmark/src/colorprint.h
@@ -5,6 +5,8 @@
 #include <iostream>
 #include <string>
 
+#include "internal_macros.h"
+
 namespace benchmark {
 enum LogColor {
   COLOR_DEFAULT,
@@ -17,11 +19,14 @@
   COLOR_WHITE
 };
 
+PRINTF_FORMAT_STRING_FUNC(1, 0)
 std::string FormatString(const char* msg, va_list args);
-std::string FormatString(const char* msg, ...);
+PRINTF_FORMAT_STRING_FUNC(1, 2) std::string FormatString(const char* msg, ...);
 
+PRINTF_FORMAT_STRING_FUNC(3, 0)
 void ColorPrintf(std::ostream& out, LogColor color, const char* fmt,
                  va_list args);
+PRINTF_FORMAT_STRING_FUNC(3, 4)
 void ColorPrintf(std::ostream& out, LogColor color, const char* fmt, ...);
 
 // Returns true if stdout appears to be a terminal that supports colored
diff --git a/third_party/benchmark/src/commandlineflags.cc b/third_party/benchmark/src/commandlineflags.cc
index 3ab280a..99a240c 100644
--- a/third_party/benchmark/src/commandlineflags.cc
+++ b/third_party/benchmark/src/commandlineflags.cc
@@ -179,6 +179,8 @@
   return value;
 }
 
+namespace {
+
 // Parses a string as a command line flag.  The string should have
 // the format "--flag=value".  When def_optional is true, the "=value"
 // part can be omitted.
@@ -217,6 +219,8 @@
   return flag_end + 1;
 }
 
+}  // end namespace
+
 BENCHMARK_EXPORT
 bool ParseBoolFlag(const char* str, const char* flag, bool* value) {
   // Gets the value of the flag as a string.
diff --git a/third_party/benchmark/src/complexity.cc b/third_party/benchmark/src/complexity.cc
index a474645..4c9ef6d 100644
--- a/third_party/benchmark/src/complexity.cc
+++ b/third_party/benchmark/src/complexity.cc
@@ -17,7 +17,6 @@
 
 #include "complexity.h"
 
-#include <algorithm>
 #include <cmath>
 
 #include "benchmark/benchmark.h"
@@ -25,6 +24,8 @@
 
 namespace benchmark {
 
+namespace {
+
 // Internal function to calculate the different scalability forms
 BigOFunc* FittingCurve(BigO complexity) {
   switch (complexity) {
@@ -48,6 +49,8 @@
   }
 }
 
+}  // end namespace
+
 // Function to return an string for the calculated complexity
 std::string GetBigOString(BigO complexity) {
   switch (complexity) {
@@ -68,6 +71,8 @@
   }
 }
 
+namespace {
+
 // Find the coefficient for the high-order term in the running time, by
 // minimizing the sum of squares of relative error, for the fitting curve
 // given by the lambda expression.
@@ -152,6 +157,8 @@
   return best_fit;
 }
 
+}  // end namespace
+
 std::vector<BenchmarkReporter::Run> ComputeBigO(
     const std::vector<BenchmarkReporter::Run>& reports) {
   typedef BenchmarkReporter::Run Run;
diff --git a/third_party/benchmark/src/console_reporter.cc b/third_party/benchmark/src/console_reporter.cc
index 0bb9f27..6db6788 100644
--- a/third_party/benchmark/src/console_reporter.cc
+++ b/third_party/benchmark/src/console_reporter.cc
@@ -97,6 +97,7 @@
   }
 }
 
+PRINTF_FORMAT_STRING_FUNC(3, 4)
 static void IgnoreColorPrint(std::ostream& out, LogColor /*unused*/,
                              const char* fmt, ...) {
   va_list args;
diff --git a/third_party/benchmark/src/counter.cc b/third_party/benchmark/src/counter.cc
index a76bf76..4bdd5e9 100644
--- a/third_party/benchmark/src/counter.cc
+++ b/third_party/benchmark/src/counter.cc
@@ -17,6 +17,8 @@
 namespace benchmark {
 namespace internal {
 
+namespace {
+
 double Finish(Counter const& c, IterationCount iterations, double cpu_time,
               double num_threads) {
   double v = c.value;
@@ -39,6 +41,8 @@
   return v;
 }
 
+}  // namespace
+
 void Finish(UserCounters* l, IterationCount iterations, double cpu_time,
             double num_threads) {
   for (auto& c : *l) {
diff --git a/third_party/benchmark/src/csv_reporter.cc b/third_party/benchmark/src/csv_reporter.cc
index 3ee434b..0f99804 100644
--- a/third_party/benchmark/src/csv_reporter.cc
+++ b/third_party/benchmark/src/csv_reporter.cc
@@ -12,29 +12,23 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-#include <algorithm>
-#include <cstdint>
 #include <iostream>
 #include <string>
-#include <tuple>
 #include <vector>
 
 #include "benchmark/benchmark.h"
 #include "check.h"
 #include "complexity.h"
-#include "string_util.h"
-#include "timers.h"
 
 // File format reference: http://edoceo.com/utilitas/csv-file-format.
 
 namespace benchmark {
 
 namespace {
-std::vector<std::string> elements = {
+const std::vector<const char*> elements = {
     "name",           "iterations",       "real_time",        "cpu_time",
     "time_unit",      "bytes_per_second", "items_per_second", "label",
     "error_occurred", "error_message"};
-}  // namespace
 
 std::string CsvEscape(const std::string& s) {
   std::string tmp;
@@ -51,6 +45,7 @@
   }
   return '"' + tmp + '"';
 }
+}  // namespace
 
 BENCHMARK_EXPORT
 bool CSVReporter::ReportContext(const Context& context) {
diff --git a/third_party/benchmark/src/cycleclock.h b/third_party/benchmark/src/cycleclock.h
index 3951ff3..0671a42 100644
--- a/third_party/benchmark/src/cycleclock.h
+++ b/third_party/benchmark/src/cycleclock.h
@@ -36,6 +36,9 @@
 // declarations of some other intrinsics, breaking compilation.
 // Therefore, we simply declare __rdtsc ourselves. See also
 // http://connect.microsoft.com/VisualStudio/feedback/details/262047
+//
+// Note that MSVC defines the x64 preprocessor macros when building
+// for Arm64EC, despite it using Arm64 assembly instructions.
 #if defined(COMPILER_MSVC) && !defined(_M_IX86) && !defined(_M_ARM64) && \
     !defined(_M_ARM64EC)
 extern "C" uint64_t __rdtsc();
@@ -79,7 +82,10 @@
   int64_t ret;
   __asm__ volatile("rdtsc" : "=A"(ret));
   return ret;
-#elif defined(__x86_64__) || defined(__amd64__)
+
+// Note that Clang, like MSVC, defines the x64 preprocessor macros when building
+// for Arm64EC, despite it using Arm64 assembly instructions.
+#elif (defined(__x86_64__) || defined(__amd64__)) && !defined(__arm64ec__)
   uint64_t low, high;
   __asm__ volatile("rdtsc" : "=a"(low), "=d"(high));
   return static_cast<int64_t>((high << 32) | low);
@@ -139,7 +145,7 @@
   struct timespec ts = {0, 0};
   clock_gettime(CLOCK_MONOTONIC, &ts);
   return static_cast<int64_t>(ts.tv_sec) * 1000000000 + ts.tv_nsec;
-#elif defined(__aarch64__)
+#elif defined(__aarch64__) || defined(__arm64ec__)
   // System timer of ARMv8 runs at a different frequency than the CPU's.
   // The frequency is fixed, typically in the range 1-50MHz.  It can be
   // read at CNTFRQ special register.  We assume the OS has set up
diff --git a/third_party/benchmark/src/internal_macros.h b/third_party/benchmark/src/internal_macros.h
index f4894ba..22e3e21 100644
--- a/third_party/benchmark/src/internal_macros.h
+++ b/third_party/benchmark/src/internal_macros.h
@@ -106,6 +106,16 @@
   #define BENCHMARK_MAYBE_UNUSED
 #endif
 
+#if defined(__GNUC__) || defined(__clang__)
+#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
+  __attribute__((format(printf, format_arg, first_idx)))
+#elif defined(__MINGW32__)
+#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx) \
+  __attribute__((format(__MINGW_PRINTF_FORMAT, format_arg, first_idx)))
+#else
+#define PRINTF_FORMAT_STRING_FUNC(format_arg, first_idx)
+#endif
+
 // clang-format on
 
 #endif  // BENCHMARK_INTERNAL_MACROS_H_
diff --git a/third_party/benchmark/src/json_reporter.cc b/third_party/benchmark/src/json_reporter.cc
index deff77e..2b84cd1 100644
--- a/third_party/benchmark/src/json_reporter.cc
+++ b/third_party/benchmark/src/json_reporter.cc
@@ -81,7 +81,9 @@
 
 std::string FormatKV(std::string const& key, int64_t value) {
   std::stringstream ss;
-  ss << '"' << StrEscape(key) << "\": " << value;
+  // We really want to just dump the integer as-is,
+  // without the system locale interfering.
+  ss << '"' << StrEscape(key) << "\": " << std::to_string(value);
   return ss.str();
 }
 
diff --git a/third_party/benchmark/src/perf_counters.cc b/third_party/benchmark/src/perf_counters.cc
index a2fa7fe..f47aa7b 100644
--- a/third_party/benchmark/src/perf_counters.cc
+++ b/third_party/benchmark/src/perf_counters.cc
@@ -214,7 +214,7 @@
       // This should never happen but if it does, we give up on the
       // entire batch as recovery would be a mess.
       GetErrorLogInstance() << "***WARNING*** Failed to start counters. "
-                               "Claring out all counters.\n";
+                               "Clearing out all counters.\n";
 
       // Close all performance counters
       for (int id : counter_ids) {
diff --git a/third_party/benchmark/src/re.h b/third_party/benchmark/src/re.h
index af4b8bb..1486dd8 100644
--- a/third_party/benchmark/src/re.h
+++ b/third_party/benchmark/src/re.h
@@ -15,6 +15,8 @@
 #ifndef BENCHMARK_RE_H_
 #define BENCHMARK_RE_H_
 
+#include <vector>
+
 #include "internal_macros.h"
 
 // clang-format off
diff --git a/third_party/benchmark/src/string_util.cc b/third_party/benchmark/src/string_util.cc
index 420de4c..9c5df3b 100644
--- a/third_party/benchmark/src/string_util.cc
+++ b/third_party/benchmark/src/string_util.cc
@@ -112,13 +112,14 @@
   return mantissa + ExponentToPrefix(exponent, one_k == Counter::kIs1024);
 }
 
+PRINTF_FORMAT_STRING_FUNC(1, 0)
 std::string StrFormatImp(const char* msg, va_list args) {
   // we might need a second shot at this, so pre-emptivly make a copy
   va_list args_cp;
   va_copy(args_cp, args);
 
-  // TODO(ericwf): use std::array for first attempt to avoid one memory
-  // allocation guess what the size might be
+  // Use std::array for first attempt to avoid one memory allocation guess what
+  // the size might be
   std::array<char, 256> local_buff = {};
 
   // 2015-10-08: vsnprintf is used instead of snd::vsnprintf due to a limitation
diff --git a/third_party/benchmark/src/sysinfo.cc b/third_party/benchmark/src/sysinfo.cc
index 60e9e5c..3977772 100644
--- a/third_party/benchmark/src/sysinfo.cc
+++ b/third_party/benchmark/src/sysinfo.cc
@@ -461,7 +461,7 @@
                                 DWCOUNT, NULL, 0, NULL, NULL);
   str.resize(len);
   WideCharToMultiByte(CP_UTF8, WC_ERR_INVALID_CHARS, hostname, DWCOUNT, &str[0],
-                      str.size(), NULL, NULL);
+                      static_cast<int>(str.size()), NULL, NULL);
 #endif
   return str;
 #elif defined(BENCHMARK_OS_QURT)
diff --git a/third_party/benchmark/test/BUILD b/third_party/benchmark/test/BUILD
new file mode 100644
index 0000000..9a26970
--- /dev/null
+++ b/third_party/benchmark/test/BUILD
@@ -0,0 +1,135 @@
+load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
+
+platform(
+    name = "windows",
+    constraint_values = [
+        "@platforms//os:windows",
+    ],
+)
+
+TEST_COPTS = [
+    "-pedantic",
+    "-pedantic-errors",
+    "-std=c++17",
+    "-Wall",
+    "-Wconversion",
+    "-Wextra",
+    "-Wshadow",
+    #    "-Wshorten-64-to-32",
+    "-Wfloat-equal",
+    "-fstrict-aliasing",
+    ## assert() are used a lot in tests upstream, which may be optimised out leading to
+    ## unused-variable warning.
+    "-Wno-unused-variable",
+    "-Werror=old-style-cast",
+]
+
+TEST_MSVC_OPTS = [
+    "/std:c++17",
+]
+
+# Some of the issues with DoNotOptimize only occur when optimization is enabled
+PER_SRC_COPTS = {
+    "donotoptimize_test.cc": ["-O3"],
+}
+
+TEST_ARGS = ["--benchmark_min_time=0.01s"]
+
+PER_SRC_TEST_ARGS = {
+    "user_counters_tabular_test.cc": ["--benchmark_counters_tabular=true"],
+    "repetitions_test.cc": [" --benchmark_repetitions=3"],
+    "spec_arg_test.cc": ["--benchmark_filter=BM_NotChosen"],
+    "spec_arg_verbosity_test.cc": ["--v=42"],
+    "complexity_test.cc": ["--benchmark_min_time=1000000x"],
+}
+
+cc_library(
+    name = "output_test_helper",
+    testonly = 1,
+    srcs = ["output_test_helper.cc"],
+    hdrs = ["output_test.h"],
+    copts = select({
+        "//:windows": TEST_MSVC_OPTS,
+        "//conditions:default": TEST_COPTS,
+    }),
+    deps = [
+        "//:benchmark",
+        "//:benchmark_internal_headers",
+    ],
+)
+
+# Tests that use gtest.  These rely on `gtest_main`.
+[
+    cc_test(
+        name = test_src[:-len(".cc")],
+        size = "small",
+        srcs = [test_src],
+        copts = select({
+            "//:windows": TEST_MSVC_OPTS,
+            "//conditions:default": TEST_COPTS,
+        }) + PER_SRC_COPTS.get(test_src, []),
+        deps = [
+            "//:benchmark",
+            "//:benchmark_internal_headers",
+            "@com_google_googletest//:gtest",
+            "@com_google_googletest//:gtest_main",
+        ],
+    )
+    for test_src in glob(["*_gtest.cc"])
+]
+
+# Tests that do not use gtest.  These have their own `main` defined.
+[
+    cc_test(
+        name = test_src[:-len(".cc")],
+        size = "small",
+        srcs = [test_src],
+        args = TEST_ARGS + PER_SRC_TEST_ARGS.get(test_src, []),
+        copts = select({
+            "//:windows": TEST_MSVC_OPTS,
+            "//conditions:default": TEST_COPTS,
+        }) + PER_SRC_COPTS.get(test_src, []),
+        deps = [
+            ":output_test_helper",
+            "//:benchmark",
+            "//:benchmark_internal_headers",
+        ],
+        # FIXME: Add support for assembly tests to bazel.
+        # See Issue #556
+        # https://github.com/google/benchmark/issues/556
+    )
+    for test_src in glob(
+        ["*_test.cc"],
+        exclude = [
+            "*_assembly_test.cc",
+            "cxx11_test.cc",
+            "link_main_test.cc",
+        ],
+    )
+]
+
+cc_test(
+    name = "cxx11_test",
+    size = "small",
+    srcs = ["cxx11_test.cc"],
+    copts = TEST_COPTS + ["-std=c++11"],
+    target_compatible_with = select({
+        "//:windows": ["@platforms//:incompatible"],
+        "//conditions:default": [],
+    }),
+    deps = [
+        ":output_test_helper",
+        "//:benchmark_main",
+    ],
+)
+
+cc_test(
+    name = "link_main_test",
+    size = "small",
+    srcs = ["link_main_test.cc"],
+    copts = select({
+        "//:windows": TEST_MSVC_OPTS,
+        "//conditions:default": TEST_COPTS,
+    }),
+    deps = ["//:benchmark_main"],
+)
diff --git a/third_party/benchmark/test/CMakeLists.txt b/third_party/benchmark/test/CMakeLists.txt
index b7a6ac4..8a1a1a9 100644
--- a/third_party/benchmark/test/CMakeLists.txt
+++ b/third_party/benchmark/test/CMakeLists.txt
@@ -186,6 +186,9 @@
 compile_output_test(user_counters_test)
 benchmark_add_test(NAME user_counters_test COMMAND user_counters_test --benchmark_min_time=0.01s)
 
+compile_output_test(user_counters_threads_test)
+benchmark_add_test(NAME user_counters_threads_test COMMAND user_counters_threads_test --benchmark_min_time=0.01s)
+
 compile_output_test(perf_counters_test)
 benchmark_add_test(NAME perf_counters_test COMMAND perf_counters_test --benchmark_min_time=0.01s --benchmark_perf_counters=CYCLES,INSTRUCTIONS)
 
@@ -219,6 +222,9 @@
 compile_output_test(complexity_test)
 benchmark_add_test(NAME complexity_benchmark COMMAND complexity_test --benchmark_min_time=1000000x)
 
+compile_output_test(locale_impermeability_test)
+benchmark_add_test(NAME locale_impermeability_test COMMAND locale_impermeability_test)
+
 ###############################################################################
 # GoogleTest Unit Tests
 ###############################################################################
diff --git a/third_party/benchmark/test/basic_test.cc b/third_party/benchmark/test/basic_test.cc
index b51494b..068cd98 100644
--- a/third_party/benchmark/test/basic_test.cc
+++ b/third_party/benchmark/test/basic_test.cc
@@ -3,6 +3,7 @@
 
 #define BASIC_BENCHMARK_TEST(x) BENCHMARK(x)->Arg(8)->Arg(512)->Arg(8192)
 
+namespace {
 void BM_empty(benchmark::State& state) {
   for (auto _ : state) {
     auto iterations = static_cast<double>(state.iterations()) *
@@ -174,5 +175,6 @@
                      benchmark::State::StateIterator>::value_type,
                  typename benchmark::State::StateIterator::value_type>::value,
     "");
+}  // end namespace
 
 BENCHMARK_MAIN();
diff --git a/third_party/benchmark/test/benchmark_min_time_flag_iters_test.cc b/third_party/benchmark/test/benchmark_min_time_flag_iters_test.cc
index 5e25aa9..dedcbe6 100644
--- a/third_party/benchmark/test/benchmark_min_time_flag_iters_test.cc
+++ b/third_party/benchmark/test/benchmark_min_time_flag_iters_test.cc
@@ -1,7 +1,6 @@
 #include <cassert>
 #include <cstdlib>
 #include <cstring>
-#include <iostream>
 #include <string>
 #include <vector>
 
@@ -35,12 +34,12 @@
   std::vector<benchmark::IterationCount> iter_nums_;
 };
 
-}  // end namespace
-
-static void BM_MyBench(benchmark::State& state) {
+void BM_MyBench(benchmark::State& state) {
   for (auto s : state) {
   }
 }
+}  // end namespace
+
 BENCHMARK(BM_MyBench);
 
 int main(int argc, char** argv) {
diff --git a/third_party/benchmark/test/benchmark_min_time_flag_time_test.cc b/third_party/benchmark/test/benchmark_min_time_flag_time_test.cc
index 8d221e4..bbc2cc3 100644
--- a/third_party/benchmark/test/benchmark_min_time_flag_time_test.cc
+++ b/third_party/benchmark/test/benchmark_min_time_flag_time_test.cc
@@ -60,14 +60,14 @@
   assert(!min_times.empty() && AlmostEqual(min_times[0], expected));
 }
 
-}  // end namespace
-
-static void BM_MyBench(benchmark::State& state) {
+void BM_MyBench(benchmark::State& state) {
   for (auto s : state) {
   }
 }
 BENCHMARK(BM_MyBench);
 
+}  // end namespace
+
 int main(int argc, char** argv) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
 
diff --git a/third_party/benchmark/test/benchmark_setup_teardown_cb_types_gtest.cc b/third_party/benchmark/test/benchmark_setup_teardown_cb_types_gtest.cc
index c5a1a66..2ed255d 100644
--- a/third_party/benchmark/test/benchmark_setup_teardown_cb_types_gtest.cc
+++ b/third_party/benchmark/test/benchmark_setup_teardown_cb_types_gtest.cc
@@ -1,13 +1,13 @@
 #include "benchmark/benchmark.h"
 #include "gtest/gtest.h"
 
+using benchmark::Benchmark;
 using benchmark::BenchmarkReporter;
 using benchmark::callback_function;
 using benchmark::ClearRegisteredBenchmarks;
 using benchmark::RegisterBenchmark;
 using benchmark::RunSpecifiedBenchmarks;
 using benchmark::State;
-using benchmark::internal::Benchmark;
 
 static int functor_called = 0;
 struct Functor {
diff --git a/third_party/benchmark/test/benchmark_setup_teardown_test.cc b/third_party/benchmark/test/benchmark_setup_teardown_test.cc
index 53695e9..eb45a73 100644
--- a/third_party/benchmark/test/benchmark_setup_teardown_test.cc
+++ b/third_party/benchmark/test/benchmark_setup_teardown_test.cc
@@ -2,8 +2,6 @@
 #include <cassert>
 #include <cstdlib>
 #include <cstring>
-#include <iostream>
-#include <limits>
 #include <string>
 
 #include "benchmark/benchmark.h"
@@ -48,19 +46,18 @@
 static std::atomic<int> teardown_call(0);
 static std::atomic<int> func_call(0);
 }  // namespace concurrent
-}  // namespace
 
-static void DoSetup2(const benchmark::State& state) {
+void DoSetup2(const benchmark::State& state) {
   concurrent::setup_call.fetch_add(1, std::memory_order_acquire);
   assert(state.thread_index() == 0);
 }
 
-static void DoTeardown2(const benchmark::State& state) {
+void DoTeardown2(const benchmark::State& state) {
   concurrent::teardown_call.fetch_add(1, std::memory_order_acquire);
   assert(state.thread_index() == 0);
 }
 
-static void BM_concurrent(benchmark::State& state) {
+void BM_concurrent(benchmark::State& state) {
   for (auto s : state) {
   }
   concurrent::func_call.fetch_add(1, std::memory_order_acquire);
@@ -75,12 +72,10 @@
     ->Threads(15);
 
 // Testing interaction with Fixture::Setup/Teardown
-namespace {
 namespace fixture_interaction {
 int setup = 0;
 int fixture_setup = 0;
 }  // namespace fixture_interaction
-}  // namespace
 
 #define FIXTURE_BECHMARK_NAME MyFixture
 
@@ -98,7 +93,7 @@
   }
 }
 
-static void DoSetupWithFixture(const benchmark::State& /*unused*/) {
+void DoSetupWithFixture(const benchmark::State& /*unused*/) {
   fixture_interaction::setup++;
 }
 
@@ -116,10 +111,10 @@
 int setup = 0;
 }
 
-static void DoSetupWithRepetitions(const benchmark::State& /*unused*/) {
+void DoSetupWithRepetitions(const benchmark::State& /*unused*/) {
   repetitions::setup++;
 }
-static void BM_WithRep(benchmark::State& state) {
+void BM_WithRep(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
@@ -132,6 +127,7 @@
     ->Setup(DoSetupWithRepetitions)
     ->Iterations(100)
     ->Repetitions(4);
+}  // namespace
 
 int main(int argc, char** argv) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/benchmark_test.cc b/third_party/benchmark/test/benchmark_test.cc
index 141f286..49cbfba 100644
--- a/third_party/benchmark/test/benchmark_test.cc
+++ b/third_party/benchmark/test/benchmark_test.cc
@@ -8,9 +8,7 @@
 #include <complex>
 #include <cstdlib>
 #include <iostream>
-#include <limits>
 #include <list>
-#include <map>
 #include <mutex>
 #include <optional>
 #include <set>
@@ -56,9 +54,7 @@
 std::optional<std::vector<int>> test_vector;
 // NOLINTEND(cppcoreguidelines-avoid-non-const-global-variables)
 
-}  // end namespace
-
-static void BM_Factorial(benchmark::State& state) {
+void BM_Factorial(benchmark::State& state) {
   int fac_42 = 0;
   for (auto _ : state) {
     fac_42 = Factorial(8);
@@ -71,7 +67,7 @@
 BENCHMARK(BM_Factorial);
 BENCHMARK(BM_Factorial)->UseRealTime();
 
-static void BM_CalculatePiRange(benchmark::State& state) {
+void BM_CalculatePiRange(benchmark::State& state) {
   double pi = 0.0;
   for (auto _ : state) {
     pi = CalculatePi(static_cast<int>(state.range(0)));
@@ -82,7 +78,7 @@
 }
 BENCHMARK_RANGE(BM_CalculatePiRange, 1, 1024 * 1024);
 
-static void BM_CalculatePi(benchmark::State& state) {
+void BM_CalculatePi(benchmark::State& state) {
   static const int depth = 1024;
   for (auto _ : state) {
     double pi = CalculatePi(static_cast<int>(depth));
@@ -93,7 +89,7 @@
 BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32);
 BENCHMARK(BM_CalculatePi)->ThreadPerCpu();
 
-static void BM_SetInsert(benchmark::State& state) {
+void BM_SetInsert(benchmark::State& state) {
   std::set<int64_t> data;
   for (auto _ : state) {
     state.PauseTiming();
@@ -115,7 +111,7 @@
 
 template <typename Container,
           typename ValueType = typename Container::value_type>
-static void BM_Sequential(benchmark::State& state) {
+void BM_Sequential(benchmark::State& state) {
   ValueType v = 42;
   for (auto _ : state) {
     Container c;
@@ -133,7 +129,7 @@
 // Test the variadic version of BENCHMARK_TEMPLATE in C++11 and beyond.
 BENCHMARK_TEMPLATE(BM_Sequential, std::vector<int>, int)->Arg(512);
 
-static void BM_StringCompare(benchmark::State& state) {
+void BM_StringCompare(benchmark::State& state) {
   size_t len = static_cast<size_t>(state.range(0));
   std::string s1(len, '-');
   std::string s2(len, '-');
@@ -144,7 +140,7 @@
 }
 BENCHMARK(BM_StringCompare)->Range(1, 1 << 20);
 
-static void BM_SetupTeardown(benchmark::State& state) {
+void BM_SetupTeardown(benchmark::State& state) {
   if (state.thread_index() == 0) {
     // No need to lock test_vector_mu here as this is running single-threaded.
     test_vector = std::vector<int>();
@@ -165,7 +161,7 @@
 }
 BENCHMARK(BM_SetupTeardown)->ThreadPerCpu();
 
-static void BM_LongTest(benchmark::State& state) {
+void BM_LongTest(benchmark::State& state) {
   double tracker = 0.0;
   for (auto _ : state) {
     for (int i = 0; i < state.range(0); ++i) {
@@ -175,7 +171,7 @@
 }
 BENCHMARK(BM_LongTest)->Range(1 << 16, 1 << 28);
 
-static void BM_ParallelMemset(benchmark::State& state) {
+void BM_ParallelMemset(benchmark::State& state) {
   int64_t size = state.range(0) / static_cast<int64_t>(sizeof(int));
   int thread_size = static_cast<int>(size) / state.threads();
   int from = thread_size * state.thread_index();
@@ -199,7 +195,7 @@
 }
 BENCHMARK(BM_ParallelMemset)->Arg(10 << 20)->ThreadRange(1, 4);
 
-static void BM_ManualTiming(benchmark::State& state) {
+void BM_ManualTiming(benchmark::State& state) {
   int64_t slept_for = 0;
   int64_t microseconds = state.range(0);
   std::chrono::duration<double, std::micro> sleep_duration{
@@ -263,7 +259,7 @@
 BENCHMARK_TEMPLATE1_CAPTURE(BM_template1_capture, void, foo, 24UL);
 BENCHMARK_CAPTURE(BM_template1_capture<void>, foo, 24UL);
 
-static void BM_DenseThreadRanges(benchmark::State& st) {
+void BM_DenseThreadRanges(benchmark::State& st) {
   switch (st.range(0)) {
     case 1:
       assert(st.threads() == 1 || st.threads() == 2 || st.threads() == 3);
@@ -285,7 +281,7 @@
 BENCHMARK(BM_DenseThreadRanges)->Arg(2)->DenseThreadRange(1, 4, 2);
 BENCHMARK(BM_DenseThreadRanges)->Arg(3)->DenseThreadRange(5, 14, 3);
 
-static void BM_BenchmarkName(benchmark::State& state) {
+void BM_BenchmarkName(benchmark::State& state) {
   for (auto _ : state) {
   }
 
@@ -296,15 +292,15 @@
 
 // regression test for #1446
 template <typename type>
-static void BM_templated_test(benchmark::State& state) {
+void BM_templated_test(benchmark::State& state) {
   for (auto _ : state) {
     type created_string;
     benchmark::DoNotOptimize(created_string);
   }
 }
 
-static const auto BM_templated_test_double =
-    BM_templated_test<std::complex<double>>;
+const auto BM_templated_test_double = BM_templated_test<std::complex<double>>;
 BENCHMARK(BM_templated_test_double);
+}  // end namespace
 
 BENCHMARK_MAIN();
diff --git a/third_party/benchmark/test/complexity_test.cc b/third_party/benchmark/test/complexity_test.cc
index 23c5f3e..8cf17f4 100644
--- a/third_party/benchmark/test/complexity_test.cc
+++ b/third_party/benchmark/test/complexity_test.cc
@@ -1,5 +1,4 @@
 #undef NDEBUG
-#include <algorithm>
 #include <cassert>
 #include <cmath>
 #include <cstdlib>
@@ -13,10 +12,10 @@
 #define ADD_COMPLEXITY_CASES(...) \
   const int CONCAT(dummy, __LINE__) = AddComplexityTest(__VA_ARGS__)
 
-int AddComplexityTest(const std::string &test_name,
-                      const std::string &big_o_test_name,
-                      const std::string &rms_test_name,
-                      const std::string &big_o, int family_index) {
+int AddComplexityTest(const std::string& test_name,
+                      const std::string& big_o_test_name,
+                      const std::string& rms_test_name,
+                      const std::string& big_o, int family_index) {
   SetSubstitutions({{"%name", test_name},
                     {"%bigo_name", big_o_test_name},
                     {"%rms_name", rms_test_name},
@@ -61,13 +60,11 @@
   return 0;
 }
 
-}  // end namespace
-
 // ========================================================================= //
 // --------------------------- Testing BigO O(1) --------------------------- //
 // ========================================================================= //
 
-void BM_Complexity_O1(benchmark::State &state) {
+void BM_Complexity_O1(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
     benchmark::DoNotOptimize(state.iterations());
@@ -116,7 +113,7 @@
 // --------------------------- Testing BigO O(N) --------------------------- //
 // ========================================================================= //
 
-void BM_Complexity_O_N(benchmark::State &state) {
+void BM_Complexity_O_N(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
     benchmark::DoNotOptimize(state.iterations());
@@ -173,8 +170,8 @@
 // ------------------------- Testing BigO O(NlgN) ------------------------- //
 // ========================================================================= //
 
-static const double kLog2E = 1.44269504088896340736;
-static void BM_Complexity_O_N_log_N(benchmark::State &state) {
+const double kLog2E = 1.44269504088896340736;
+void BM_Complexity_O_N_log_N(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
     benchmark::DoNotOptimize(state.iterations());
@@ -236,7 +233,7 @@
 // -------- Testing formatting of Complexity with captured args ------------ //
 // ========================================================================= //
 
-void BM_ComplexityCaptureArgs(benchmark::State &state, int n) {
+void BM_ComplexityCaptureArgs(benchmark::State& state, int n) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
     benchmark::DoNotOptimize(state.iterations());
@@ -264,12 +261,13 @@
 ADD_COMPLEXITY_CASES(complexity_capture_name, complexity_capture_name + "_BigO",
                      complexity_capture_name + "_RMS", "N",
                      /*family_index=*/9);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------------- TEST CASES END ------------------------------ //
 // ========================================================================= //
 
-int main(int argc, char *argv[]) {
+int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
   RunOutputTests(argc, argv);
 }
diff --git a/third_party/benchmark/test/diagnostics_test.cc b/third_party/benchmark/test/diagnostics_test.cc
index e930f02..e8d7d91 100644
--- a/third_party/benchmark/test/diagnostics_test.cc
+++ b/third_party/benchmark/test/diagnostics_test.cc
@@ -17,6 +17,7 @@
 #define TEST_HAS_NO_EXCEPTIONS
 #endif
 
+namespace {
 void TestHandler() {
 #ifndef TEST_HAS_NO_EXCEPTIONS
   throw std::logic_error("");
@@ -84,6 +85,7 @@
   called_once = true;
 }
 BENCHMARK(BM_diagnostic_test_keep_running);
+}  // end namespace
 
 int main(int argc, char* argv[]) {
 #ifdef NDEBUG
diff --git a/third_party/benchmark/test/display_aggregates_only_test.cc b/third_party/benchmark/test/display_aggregates_only_test.cc
index 1d3b6cd..bae9759 100644
--- a/third_party/benchmark/test/display_aggregates_only_test.cc
+++ b/third_party/benchmark/test/display_aggregates_only_test.cc
@@ -10,11 +10,13 @@
 // reporter in the presence of DisplayAggregatesOnly().
 // We do not care about console output, the normal tests check that already.
 
+namespace {
 void BM_SummaryRepeat(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->DisplayAggregatesOnly();
+}  // end namespace
 
 int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/donotoptimize_assembly_test.cc b/third_party/benchmark/test/donotoptimize_assembly_test.cc
index dc286f5..1f817e0 100644
--- a/third_party/benchmark/test/donotoptimize_assembly_test.cc
+++ b/third_party/benchmark/test/donotoptimize_assembly_test.cc
@@ -2,6 +2,7 @@
 
 #ifdef __clang__
 #pragma clang diagnostic ignored "-Wreturn-type"
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
 #endif
 BENCHMARK_DISABLE_DEPRECATED_WARNING
 
@@ -19,7 +20,7 @@
 struct NotTriviallyCopyable {
   NotTriviallyCopyable();
   explicit NotTriviallyCopyable(int x) : value(x) {}
-  NotTriviallyCopyable(NotTriviallyCopyable const &);
+  NotTriviallyCopyable(NotTriviallyCopyable const&);
   int value;
 };
 
@@ -185,7 +186,7 @@
   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z]+]])
   // CHECK: ret
   int x = 42;
-  int *const xp = &x;
+  int* const xp = &x;
   benchmark::DoNotOptimize(xp);
 }
 
@@ -196,6 +197,6 @@
   // CHECK-CLANG: movq %rax, -{{[0-9]+}}(%[[REG:[a-z+]+]])
   // CHECK: ret
   int x = 42;
-  int *xp = &x;
+  int* xp = &x;
   benchmark::DoNotOptimize(xp);
 }
diff --git a/third_party/benchmark/test/filter_test.cc b/third_party/benchmark/test/filter_test.cc
index 0a4a1df..8c150eb 100644
--- a/third_party/benchmark/test/filter_test.cc
+++ b/third_party/benchmark/test/filter_test.cc
@@ -37,37 +37,36 @@
   mutable int64_t max_family_index_;
 };
 
-}  // end namespace
-
-static void NoPrefix(benchmark::State& state) {
+void NoPrefix(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(NoPrefix);
 
-static void BM_Foo(benchmark::State& state) {
+void BM_Foo(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_Foo);
 
-static void BM_Bar(benchmark::State& state) {
+void BM_Bar(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_Bar);
 
-static void BM_FooBar(benchmark::State& state) {
+void BM_FooBar(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_FooBar);
 
-static void BM_FooBa(benchmark::State& state) {
+void BM_FooBa(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_FooBa);
+}  // end namespace
 
 int main(int argc, char** argv) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/internal_threading_test.cc b/third_party/benchmark/test/internal_threading_test.cc
index d2897e7..c57bf44 100644
--- a/third_party/benchmark/test/internal_threading_test.cc
+++ b/third_party/benchmark/test/internal_threading_test.cc
@@ -8,8 +8,9 @@
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
-static const std::chrono::duration<double, std::milli> time_frame(50);
-static const double time_frame_in_sec(
+namespace {
+const std::chrono::duration<double, std::milli> time_frame(50);
+const double time_frame_in_sec(
     std::chrono::duration_cast<std::chrono::duration<double, std::ratio<1, 1>>>(
         time_frame)
         .count());
@@ -178,6 +179,7 @@
     ->Threads(2)
     ->MeasureProcessCPUTime()
     ->UseManualTime();
+}  // end namespace
 
 // ========================================================================= //
 // ---------------------------- TEST CASES END ----------------------------- //
diff --git a/third_party/benchmark/test/link_main_test.cc b/third_party/benchmark/test/link_main_test.cc
index b0a37c0..41dbac9 100644
--- a/third_party/benchmark/test/link_main_test.cc
+++ b/third_party/benchmark/test/link_main_test.cc
@@ -1,5 +1,6 @@
 #include "benchmark/benchmark.h"
 
+namespace {
 void BM_empty(benchmark::State& state) {
   for (auto _ : state) {
     auto iterations = static_cast<double>(state.iterations()) *
@@ -8,3 +9,4 @@
   }
 }
 BENCHMARK(BM_empty);
+}  // end namespace
diff --git a/third_party/benchmark/test/locale_impermeability_test.cc b/third_party/benchmark/test/locale_impermeability_test.cc
new file mode 100644
index 0000000..e2dd6cf
--- /dev/null
+++ b/third_party/benchmark/test/locale_impermeability_test.cc
@@ -0,0 +1,47 @@
+#undef NDEBUG
+#include <cassert>
+#include <cmath>
+#include <cstdlib>
+
+#include "benchmark/benchmark.h"
+#include "output_test.h"
+
+namespace {
+void BM_ostream(benchmark::State& state) {
+#if !defined(__MINGW64__) || defined(__clang__)
+  // GCC-based versions of MINGW64 do not support locale manipulations,
+  // don't run the test under them.
+  std::locale::global(std::locale("en_US.UTF-8"));
+#endif
+  while (state.KeepRunning()) {
+    state.SetIterationTime(1e-6);
+  }
+}
+BENCHMARK(BM_ostream)->UseManualTime()->Iterations(1000000);
+
+ADD_CASES(TC_ConsoleOut, {{"^BM_ostream/iterations:1000000/manual_time"
+                           " %console_report$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_ostream/iterations:1000000/manual_time\",$"},
+           {"\"family_index\": 0,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": "
+            "\"BM_ostream/iterations:1000000/manual_time\",$",
+            MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": 1,$", MR_Next},
+           {"\"iterations\": 1000000,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\"$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_ostream/iterations:1000000/"
+                       "manual_time\",1000000,%float,%float,ns,,,,,$"}});
+}  // end namespace
+
+int main(int argc, char* argv[]) {
+  benchmark::MaybeReenterWithoutASLR(argc, argv);
+  RunOutputTests(argc, argv);
+}
diff --git a/third_party/benchmark/test/map_test.cc b/third_party/benchmark/test/map_test.cc
index 216ed03..018e12a 100644
--- a/third_party/benchmark/test/map_test.cc
+++ b/third_party/benchmark/test/map_test.cc
@@ -13,10 +13,8 @@
   return m;
 }
 
-}  // namespace
-
 // Basic version.
-static void BM_MapLookup(benchmark::State& state) {
+void BM_MapLookup(benchmark::State& state) {
   const int size = static_cast<int>(state.range(0));
   std::map<int, int> m;
   for (auto _ : state) {
@@ -31,6 +29,7 @@
   state.SetItemsProcessed(state.iterations() * size);
 }
 BENCHMARK(BM_MapLookup)->Range(1 << 3, 1 << 12);
+}  // namespace
 
 // Using fixtures.
 class MapFixture : public ::benchmark::Fixture {
diff --git a/third_party/benchmark/test/memory_manager_test.cc b/third_party/benchmark/test/memory_manager_test.cc
index f9b9021..39b3216 100644
--- a/third_party/benchmark/test/memory_manager_test.cc
+++ b/third_party/benchmark/test/memory_manager_test.cc
@@ -1,9 +1,9 @@
 #include <memory>
 
-#include "../src/check.h"
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 class TestMemoryManager : public benchmark::MemoryManager {
   void Start() override {}
   void Stop(Result& result) override {
@@ -20,6 +20,7 @@
   }
 }
 BENCHMARK(BM_empty);
+}  // end namespace
 
 ADD_CASES(TC_ConsoleOut, {{"^BM_empty %console_report$"}});
 ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_empty\",$"},
diff --git a/third_party/benchmark/test/memory_results_gtest.cc b/third_party/benchmark/test/memory_results_gtest.cc
index c40df8f..70a5a5a 100644
--- a/third_party/benchmark/test/memory_results_gtest.cc
+++ b/third_party/benchmark/test/memory_results_gtest.cc
@@ -5,13 +5,13 @@
 
 namespace {
 
+using benchmark::Benchmark;
 using benchmark::ClearRegisteredBenchmarks;
 using benchmark::ConsoleReporter;
 using benchmark::MemoryManager;
 using benchmark::RegisterBenchmark;
 using benchmark::RunSpecifiedBenchmarks;
 using benchmark::State;
-using benchmark::internal::Benchmark;
 
 constexpr int N_REPETITIONS = 100;
 constexpr int N_ITERATIONS = 1;
diff --git a/third_party/benchmark/test/multiple_ranges_test.cc b/third_party/benchmark/test/multiple_ranges_test.cc
index 5300a96..987b69c 100644
--- a/third_party/benchmark/test/multiple_ranges_test.cc
+++ b/third_party/benchmark/test/multiple_ranges_test.cc
@@ -5,6 +5,7 @@
 
 #include "benchmark/benchmark.h"
 
+namespace {
 class MultipleRangesFixture : public ::benchmark::Fixture {
  public:
   MultipleRangesFixture()
@@ -87,10 +88,11 @@
 }
 BENCHMARK(BM_CheckDefaultArgument)->Ranges({{1, 5}, {6, 10}});
 
-static void BM_MultipleRanges(benchmark::State& st) {
+void BM_MultipleRanges(benchmark::State& st) {
   for (auto _ : st) {
   }
 }
 BENCHMARK(BM_MultipleRanges)->Ranges({{5, 5}, {6, 6}});
+}  // end namespace
 
 BENCHMARK_MAIN();
diff --git a/third_party/benchmark/test/options_test.cc b/third_party/benchmark/test/options_test.cc
index a1b209f..70e3e18 100644
--- a/third_party/benchmark/test/options_test.cc
+++ b/third_party/benchmark/test/options_test.cc
@@ -8,6 +8,7 @@
 #endif
 #include <cassert>
 
+namespace {
 void BM_basic(benchmark::State& state) {
   for (auto _ : state) {
   }
@@ -50,7 +51,7 @@
 BENCHMARK(BM_basic)->DenseRange(-2, 2, 1);
 BENCHMARK(BM_basic)->Ranges({{-64, 1}, {-8, -1}});
 
-void CustomArgs(benchmark::internal::Benchmark* b) {
+void CustomArgs(benchmark::Benchmark* b) {
   for (int i = 0; i < 10; ++i) {
     b->Arg(i);
   }
@@ -73,5 +74,6 @@
   assert(state.iterations() == 42);
 }
 BENCHMARK(BM_explicit_iteration_count)->Iterations(42);
+}  // end namespace
 
 BENCHMARK_MAIN();
diff --git a/third_party/benchmark/test/output_test_helper.cc b/third_party/benchmark/test/output_test_helper.cc
index a0898be..43a1bfd 100644
--- a/third_party/benchmark/test/output_test_helper.cc
+++ b/third_party/benchmark/test/output_test_helper.cc
@@ -209,12 +209,14 @@
   std::vector<std::string> SplitCsv_(const std::string& line) const;
 };
 
+namespace {
 // store the static ResultsChecker in a function to prevent initialization
 // order problems
 ResultsChecker& GetResultsChecker() {
   static ResultsChecker rc;
   return rc;
 }
+}  // end namespace
 
 // add a results checker for a benchmark
 void ResultsChecker::Add(const std::string& entry_pattern,
@@ -489,18 +491,19 @@
   return count;
 }
 
-static char ToHex(int ch) {
+namespace {
+char ToHex(int ch) {
   return ch < 10 ? static_cast<char>('0' + ch)
                  : static_cast<char>('a' + (ch - 10));
 }
 
-static char RandomHexChar() {
+char RandomHexChar() {
   static std::mt19937 rd{std::random_device{}()};
   static std::uniform_int_distribution<int> mrand{0, 15};
   return ToHex(mrand(rd));
 }
 
-static std::string GetRandomFileName() {
+std::string GetRandomFileName() {
   std::string model = "test.%%%%%%";
   for (auto& ch : model) {
     if (ch == '%') {
@@ -510,12 +513,12 @@
   return model;
 }
 
-static bool FileExists(std::string const& name) {
+bool FileExists(std::string const& name) {
   std::ifstream in(name.c_str());
   return in.good();
 }
 
-static std::string GetTempFileName() {
+std::string GetTempFileName() {
   // This function attempts to avoid race conditions where two tests
   // create the same file at the same time. However, it still introduces races
   // similar to tmpnam.
@@ -530,6 +533,7 @@
   std::flush(std::cerr);
   std::exit(1);
 }
+}  // end namespace
 
 std::string GetFileReporterOutput(int argc, char* argv[]) {
   std::vector<char*> new_argv(argv, argv + argc);
diff --git a/third_party/benchmark/test/overload_test.cc b/third_party/benchmark/test/overload_test.cc
new file mode 100644
index 0000000..d1fee9a
--- /dev/null
+++ b/third_party/benchmark/test/overload_test.cc
@@ -0,0 +1,35 @@
+#include "benchmark/benchmark.h"
+
+namespace {
+// Simulate an overloaded function name.
+// This version does nothing and is just here to create ambiguity for
+// MyOverloadedBenchmark.
+BENCHMARK_UNUSED void MyOverloadedBenchmark() {}
+
+// This is the actual benchmark function we want to register.
+// It has the signature void(benchmark::State&) required by the library.
+void MyOverloadedBenchmark(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+}
+
+// This macro invocation should compile correctly if benchmark.h
+// contains the fix (using static_cast), but would fail to compile
+// if the benchmark name were ambiguous (e.g., when using + or no cast
+// with an overloaded function).
+BENCHMARK(MyOverloadedBenchmark);
+
+// Also test BENCHMARK_TEMPLATE with an overloaded name.
+template <int N>
+void MyTemplatedOverloadedBenchmark() {}
+
+template <int N>
+void MyTemplatedOverloadedBenchmark(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+}
+
+BENCHMARK_TEMPLATE(MyTemplatedOverloadedBenchmark, 1);
+}  // end namespace
+
+BENCHMARK_MAIN();
diff --git a/third_party/benchmark/test/perf_counters_test.cc b/third_party/benchmark/test/perf_counters_test.cc
index 8aa3a7b..a830b5e 100644
--- a/third_party/benchmark/test/perf_counters_test.cc
+++ b/third_party/benchmark/test/perf_counters_test.cc
@@ -11,8 +11,9 @@
 BM_DECLARE_string(benchmark_perf_counters);
 
 }  // namespace benchmark
+namespace {
 
-static void BM_Simple(benchmark::State& state) {
+void BM_Simple(benchmark::State& state) {
   for (auto _ : state) {
     auto iterations = double(state.iterations()) * double(state.iterations());
     benchmark::DoNotOptimize(iterations);
@@ -66,17 +67,18 @@
 double withoutPauseResumeInstrCount = 0.0;
 double withPauseResumeInstrCount = 0.0;
 
-static void SaveInstrCountWithoutResume(Results const& e) {
+void SaveInstrCountWithoutResume(Results const& e) {
   withoutPauseResumeInstrCount = e.GetAs<double>("INSTRUCTIONS");
 }
 
-static void SaveInstrCountWithResume(Results const& e) {
+void SaveInstrCountWithResume(Results const& e) {
   withPauseResumeInstrCount = e.GetAs<double>("INSTRUCTIONS");
 }
 
 CHECK_BENCHMARK_RESULTS("BM_Simple", &CheckSimple);
 CHECK_BENCHMARK_RESULTS("BM_WithoutPauseResume", &SaveInstrCountWithoutResume);
 CHECK_BENCHMARK_RESULTS("BM_WithPauseResume", &SaveInstrCountWithResume);
+}  // end namespace
 
 int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/profiler_manager_iterations_test.cc b/third_party/benchmark/test/profiler_manager_iterations_test.cc
index af1052f..c4983eb 100644
--- a/third_party/benchmark/test/profiler_manager_iterations_test.cc
+++ b/third_party/benchmark/test/profiler_manager_iterations_test.cc
@@ -25,14 +25,13 @@
   void ReportRuns(const std::vector<Run>& /* report */) override {}
 };
 
-}  // end namespace
-
-static void BM_MyBench(benchmark::State& state) {
+void BM_MyBench(benchmark::State& state) {
   for (auto s : state) {
     ++iteration_count;
   }
 }
 BENCHMARK(BM_MyBench);
+}  // end namespace
 
 int main(int argc, char** argv) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/profiler_manager_test.cc b/third_party/benchmark/test/profiler_manager_test.cc
index 75a2aaa..5c4b14d 100644
--- a/third_party/benchmark/test/profiler_manager_test.cc
+++ b/third_party/benchmark/test/profiler_manager_test.cc
@@ -6,6 +6,7 @@
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 class TestProfilerManager : public benchmark::ProfilerManager {
  public:
   void AfterSetupStart() override { ++start_called; }
@@ -38,6 +39,7 @@
                        {"\"time_unit\": \"ns\"$", MR_Next},
                        {"}", MR_Next}});
 ADD_CASES(TC_CSVOut, {{"^\"BM_empty\",%csv_report$"}});
+}  // end namespace
 
 int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/register_benchmark_test.cc b/third_party/benchmark/test/register_benchmark_test.cc
index e91ba97..3e39437 100644
--- a/third_party/benchmark/test/register_benchmark_test.cc
+++ b/third_party/benchmark/test/register_benchmark_test.cc
@@ -56,9 +56,7 @@
 #define ADD_CASES(...) \
   const int CONCAT(dummy, __LINE__) = AddCases({__VA_ARGS__})
 
-}  // end namespace
-
-using ReturnVal = benchmark::internal::Benchmark const* const;
+using ReturnVal = benchmark::Benchmark const* const;
 
 //----------------------------------------------------------------------------//
 // Test RegisterBenchmark with no additional arguments
@@ -182,6 +180,7 @@
   }
   assert(EB == ExpectedResults.end());
 }
+}  // end namespace
 
 int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/repetitions_test.cc b/third_party/benchmark/test/repetitions_test.cc
index 9a7dcc3..9116fa6 100644
--- a/third_party/benchmark/test/repetitions_test.cc
+++ b/third_party/benchmark/test/repetitions_test.cc
@@ -2,11 +2,12 @@
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 // ========================================================================= //
 // ------------------------ Testing Basic Output --------------------------- //
 // ========================================================================= //
 
-static void BM_ExplicitRepetitions(benchmark::State& state) {
+void BM_ExplicitRepetitions(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
@@ -108,7 +109,7 @@
 // ------------------------ Testing Basic Output --------------------------- //
 // ========================================================================= //
 
-static void BM_ImplicitRepetitions(benchmark::State& state) {
+void BM_ImplicitRepetitions(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
@@ -206,6 +207,7 @@
 ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_mean\",%csv_report$"}});
 ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_median\",%csv_report$"}});
 ADD_CASES(TC_CSVOut, {{"^\"BM_ImplicitRepetitions_stddev\",%csv_report$"}});
+}  // end namespace
 
 // ========================================================================= //
 // --------------------------- TEST CASES END ------------------------------ //
diff --git a/third_party/benchmark/test/report_aggregates_only_test.cc b/third_party/benchmark/test/report_aggregates_only_test.cc
index d907559..707d923 100644
--- a/third_party/benchmark/test/report_aggregates_only_test.cc
+++ b/third_party/benchmark/test/report_aggregates_only_test.cc
@@ -6,6 +6,7 @@
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 // Ok this test is super ugly. We want to check what happens with the file
 // reporter in the presence of ReportAggregatesOnly().
 // We do not care about console output, the normal tests check that already.
@@ -15,6 +16,7 @@
   }
 }
 BENCHMARK(BM_SummaryRepeat)->Repetitions(3)->ReportAggregatesOnly();
+}  // end namespace
 
 int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/reporter_output_test.cc b/third_party/benchmark/test/reporter_output_test.cc
index 58860ca..9940ab7 100644
--- a/third_party/benchmark/test/reporter_output_test.cc
+++ b/third_party/benchmark/test/reporter_output_test.cc
@@ -1,11 +1,9 @@
-
 #undef NDEBUG
-#include <numeric>
-#include <utility>
 
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 // ========================================================================= //
 // ---------------------- Testing Prologue Output -------------------------- //
 // ========================================================================= //
@@ -13,7 +11,7 @@
 ADD_CASES(TC_ConsoleOut, {{"^[-]+$", MR_Next},
                           {"^Benchmark %s Time %s CPU %s Iterations$", MR_Next},
                           {"^[-]+$", MR_Next}});
-static int AddContextCases() {
+int AddContextCases() {
   AddCases(TC_ConsoleErr,
            {
                {"^%int-%int-%intT%int:%int:%int[-+]%int:%int$", MR_Default},
@@ -1128,6 +1126,7 @@
 }
 BENCHMARK(BM_CSV_Format);
 ADD_CASES(TC_CSVOut, {{"^\"BM_CSV_Format\",,,,,,,,true,\"\"\"freedom\"\"\"$"}});
+}  // end namespace
 
 // ========================================================================= //
 // --------------------------- TEST CASES END ------------------------------ //
diff --git a/third_party/benchmark/test/skip_with_error_test.cc b/third_party/benchmark/test/skip_with_error_test.cc
index 7553eba..4258959 100644
--- a/third_party/benchmark/test/skip_with_error_test.cc
+++ b/third_party/benchmark/test/skip_with_error_test.cc
@@ -62,8 +62,6 @@
 #define CONCAT2(x, y) x##y
 #define ADD_CASES(...) const int CONCAT(dummy, __LINE__) = AddCases(__VA_ARGS__)
 
-}  // end namespace
-
 void BM_error_no_running(benchmark::State& state) {
   state.SkipWithError("error message");
 }
@@ -182,6 +180,16 @@
                                     {"/2/threads:4", false, ""},
                                     {"/2/threads:8", false, ""}});
 
+void BM_malformed(benchmark::State& /*unused*/) {
+  // NOTE: empty body wanted. No thing else.
+}
+BENCHMARK(BM_malformed);
+ADD_CASES("BM_malformed",
+          {{"", true,
+            "The benchmark didn't run, nor was it explicitly skipped. Please "
+            "call 'SkipWithXXX` in your benchmark as appropriate."}});
+}  // end namespace
+
 int main(int argc, char* argv[]) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
   benchmark::Initialize(&argc, argv);
@@ -201,12 +209,3 @@
 
   return 0;
 }
-
-void BM_malformed(benchmark::State&) {
-  // NOTE: empty body wanted. No thing else.
-}
-BENCHMARK(BM_malformed);
-ADD_CASES("BM_malformed",
-          {{"", true,
-            "The benchmark didn't run, nor was it explicitly skipped. Please "
-            "call 'SkipWithXXX` in your benchmark as appropriate."}});
diff --git a/third_party/benchmark/test/spec_arg_test.cc b/third_party/benchmark/test/spec_arg_test.cc
index cec5c32..21275ef 100644
--- a/third_party/benchmark/test/spec_arg_test.cc
+++ b/third_party/benchmark/test/spec_arg_test.cc
@@ -39,21 +39,21 @@
   std::vector<std::string> matched_functions;
 };
 
-}  // end namespace
-
-static void BM_NotChosen(benchmark::State& state) {
+void BM_NotChosen(benchmark::State& state) {
   assert(false && "SHOULD NOT BE CALLED");
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_NotChosen);
 
-static void BM_Chosen(benchmark::State& state) {
+void BM_Chosen(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_Chosen);
 
+}  // end namespace
+
 int main(int argc, char** argv) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
 
diff --git a/third_party/benchmark/test/spec_arg_verbosity_test.cc b/third_party/benchmark/test/spec_arg_verbosity_test.cc
index 43dfda9..318784c 100644
--- a/third_party/benchmark/test/spec_arg_verbosity_test.cc
+++ b/third_party/benchmark/test/spec_arg_verbosity_test.cc
@@ -4,12 +4,14 @@
 
 #include "benchmark/benchmark.h"
 
+namespace {
 // Tests that the user specified verbosity level can be get.
-static void BM_Verbosity(benchmark::State& state) {
+void BM_Verbosity(benchmark::State& state) {
   for (auto _ : state) {
   }
 }
 BENCHMARK(BM_Verbosity);
+}  // end namespace
 
 int main(int argc, char** argv) {
   benchmark::MaybeReenterWithoutASLR(argc, argv);
diff --git a/third_party/benchmark/test/state_assembly_test.cc b/third_party/benchmark/test/state_assembly_test.cc
index 7ddbb3b..e9ecfeb 100644
--- a/third_party/benchmark/test/state_assembly_test.cc
+++ b/third_party/benchmark/test/state_assembly_test.cc
@@ -2,6 +2,7 @@
 
 #ifdef __clang__
 #pragma clang diagnostic ignored "-Wreturn-type"
+#pragma clang diagnostic ignored "-Wmissing-prototypes"
 #endif
 
 // clang-format off
diff --git a/third_party/benchmark/test/time_unit_gtest.cc b/third_party/benchmark/test/time_unit_gtest.cc
index 21fd91b..0da1109 100644
--- a/third_party/benchmark/test/time_unit_gtest.cc
+++ b/third_party/benchmark/test/time_unit_gtest.cc
@@ -6,7 +6,7 @@
 
 namespace {
 
-class DummyBenchmark : public Benchmark {
+class DummyBenchmark : public benchmark::Benchmark {
  public:
   DummyBenchmark() : Benchmark("dummy") {}
   void Run(State& /*state*/) override {}
diff --git a/third_party/benchmark/test/user_counters_tabular_test.cc b/third_party/benchmark/test/user_counters_tabular_test.cc
index 0046210..7db0e20 100644
--- a/third_party/benchmark/test/user_counters_tabular_test.cc
+++ b/third_party/benchmark/test/user_counters_tabular_test.cc
@@ -4,6 +4,7 @@
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 // @todo: <jpmag> this checks the full output at once; the rule for
 // CounterSet1 was failing because it was not matching "^[-]+$".
 // @todo: <jpmag> check that the counters are vertically aligned.
@@ -417,7 +418,7 @@
 // VS2013 does not allow this function to be passed as a lambda argument
 // to CHECK_BENCHMARK_RESULTS()
 void CheckTabularRate(Results const& e) {
-  double t = e.DurationCPUTime();
+  double t = e.DurationCPUTime() / e.NumThreads();
   CHECK_FLOAT_COUNTER_VALUE(e, "Foo", EQ, 1. / t, 0.001);
   CHECK_FLOAT_COUNTER_VALUE(e, "Bar", EQ, 2. / t, 0.001);
   CHECK_FLOAT_COUNTER_VALUE(e, "Baz", EQ, 4. / t, 0.001);
@@ -555,6 +556,7 @@
   CHECK_COUNTER_VALUE(e, int, "Baz", EQ, 40);
 }
 CHECK_BENCHMARK_RESULTS("BM_CounterSet2_Tabular", &CheckSet2);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------------- TEST CASES END ------------------------------ //
diff --git a/third_party/benchmark/test/user_counters_test.cc b/third_party/benchmark/test/user_counters_test.cc
index 910f930..a8af087 100644
--- a/third_party/benchmark/test/user_counters_test.cc
+++ b/third_party/benchmark/test/user_counters_test.cc
@@ -21,7 +21,7 @@
 // ========================================================================= //
 // ------------------------- Simple Counters Output ------------------------ //
 // ========================================================================= //
-
+namespace {
 void BM_Counters_Simple(benchmark::State& state) {
   for (auto _ : state) {
   }
@@ -56,6 +56,7 @@
   CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_Simple", &CheckSimple);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------- Counters+Items+Bytes/s Output --------------------- //
@@ -63,7 +64,6 @@
 
 namespace {
 int num_calls1 = 0;
-}
 void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -112,11 +112,12 @@
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec",
                         &CheckBytesAndItemsPSec);
+}  // end namespace
 
 // ========================================================================= //
 // ------------------------- Rate Counters Output -------------------------- //
 // ========================================================================= //
-
+namespace {
 void BM_Counters_Rate(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -157,11 +158,13 @@
   CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_Rate", &CheckRate);
+}  // end namespace
 
 // ========================================================================= //
 // ----------------------- Inverted Counters Output ------------------------ //
 // ========================================================================= //
 
+namespace {
 void BM_Invert(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -199,11 +202,13 @@
   CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 0.0001, 0.0001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Invert", &CheckInvert);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------- InvertedRate Counters Output ---------------------- //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_InvertedRate(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -247,11 +252,13 @@
   CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / 8192.0, 0.001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate", &CheckInvertedRate);
+}  // end namespace
 
 // ========================================================================= //
 // ------------------------- Thread Counters Output ------------------------ //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_Threads(benchmark::State& state) {
   for (auto _ : state) {
   }
@@ -287,11 +294,13 @@
   CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads());
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads);
+}  // end namespace
 
 // ========================================================================= //
 // ---------------------- ThreadAvg Counters Output ------------------------ //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_AvgThreads(benchmark::State& state) {
   for (auto _ : state) {
   }
@@ -329,11 +338,13 @@
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int",
                         &CheckAvgThreads);
+}  // end namespace
 
 // ========================================================================= //
 // ---------------------- ThreadAvg Counters Output ------------------------ //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_AvgThreadsRate(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -370,16 +381,20 @@
 // VS2013 does not allow this function to be passed as a lambda argument
 // to CHECK_BENCHMARK_RESULTS()
 void CheckAvgThreadsRate(Results const& e) {
-  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / e.DurationCPUTime(), 0.001);
-  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / e.DurationCPUTime(), 0.001);
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int",
                         &CheckAvgThreadsRate);
+}  // end namespace
 
 // ========================================================================= //
 // ------------------- IterationInvariant Counters Output ------------------ //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_IterationInvariant(benchmark::State& state) {
   for (auto _ : state) {
   }
@@ -418,11 +433,13 @@
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant",
                         &CheckIterationInvariant);
+}  // end namespace
 
 // ========================================================================= //
 // ----------------- IterationInvariantRate Counters Output ---------------- //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -469,11 +486,13 @@
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate",
                         &CheckIsIterationInvariantRate);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------- AvgIterations Counters Output --------------------- //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_AvgIterations(benchmark::State& state) {
   for (auto _ : state) {
   }
@@ -511,11 +530,13 @@
   CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / its, 0.001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations", &CheckAvgIterations);
+}  // end namespace
 
 // ========================================================================= //
 // ------------------- AvgIterationsRate Counters Output ------------------- //
 // ========================================================================= //
 
+namespace {
 void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
   for (auto _ : state) {
     // This test requires a non-zero CPU time to avoid divide-by-zero
@@ -560,6 +581,7 @@
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate",
                         &CheckAvgIterationsRate);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------------- TEST CASES END ------------------------------ //
diff --git a/third_party/benchmark/test/user_counters_thousands_test.cc b/third_party/benchmark/test/user_counters_thousands_test.cc
index 4f341db..0ef78d3 100644
--- a/third_party/benchmark/test/user_counters_thousands_test.cc
+++ b/third_party/benchmark/test/user_counters_thousands_test.cc
@@ -4,6 +4,7 @@
 #include "benchmark/benchmark.h"
 #include "output_test.h"
 
+namespace {
 // ========================================================================= //
 // ------------------------ Thousands Customisation ------------------------ //
 // ========================================================================= //
@@ -179,6 +180,7 @@
   CHECK_FLOAT_COUNTER_VALUE(e, "t4_1048576Base1024", EQ, 1024 * 1024, 0.0001);
 }
 CHECK_BENCHMARK_RESULTS("BM_Counters_Thousands", &CheckThousands);
+}  // end namespace
 
 // ========================================================================= //
 // --------------------------- TEST CASES END ------------------------------ //
diff --git a/third_party/benchmark/test/user_counters_threads_test.cc b/third_party/benchmark/test/user_counters_threads_test.cc
new file mode 100644
index 0000000..e2e5ade
--- /dev/null
+++ b/third_party/benchmark/test/user_counters_threads_test.cc
@@ -0,0 +1,622 @@
+
+#undef NDEBUG
+
+#include "benchmark/benchmark.h"
+#include "output_test.h"
+
+// ========================================================================= //
+// ---------------------- Testing Prologue Output -------------------------- //
+// ========================================================================= //
+
+// clang-format off
+
+ADD_CASES(TC_ConsoleOut,
+          {{"^[-]+$", MR_Next},
+           {"^Benchmark %s Time %s CPU %s Iterations UserCounters...$", MR_Next},
+           {"^[-]+$", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"%csv_header,\"bar\",\"foo\""}});
+
+// clang-format on
+
+// ========================================================================= //
+// ------------------------- Simple Counters Output ------------------------ //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_Simple(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+  state.counters["foo"] = 1;
+  state.counters["bar"] = 2 * static_cast<double>(state.iterations());
+}
+BENCHMARK(BM_Counters_Simple)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Simple/threads:%int %console_report "
+                           "bar=%hrfloat foo=%hrfloat$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_Simple/threads:%int\",$"},
+           {"\"family_index\": 0,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_Simple/threads:%int\",$", MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(
+    TC_CSVOut,
+    {{"^\"BM_Counters_Simple/threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckSimple(Results const& e) {
+  double its = e.NumIterations();
+  CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1 * e.NumThreads());
+  // check that the value of bar is within 0.1% of the expected value
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_Simple/threads:%int", &CheckSimple);
+}  // end namespace
+
+// ========================================================================= //
+// --------------------- Counters+Items+Bytes/s Output --------------------- //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_WithBytesAndItemsPSec(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  state.counters["foo"] = 1;
+  state.SetBytesProcessed(364);
+  state.SetItemsProcessed(150);
+}
+BENCHMARK(BM_Counters_WithBytesAndItemsPSec)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut,
+          {{"^BM_Counters_WithBytesAndItemsPSec/threads:%int %console_report "
+            "bytes_per_second=%hrfloat/s "
+            "foo=%hrfloat items_per_second=%hrfloat/s$"}});
+ADD_CASES(
+    TC_JSONOut,
+    {{"\"name\": \"BM_Counters_WithBytesAndItemsPSec/threads:%int\",$"},
+     {"\"family_index\": 1,$", MR_Next},
+     {"\"per_family_instance_index\": 0,$", MR_Next},
+     {"\"run_name\": \"BM_Counters_WithBytesAndItemsPSec/threads:%int\",$",
+      MR_Next},
+     {"\"run_type\": \"iteration\",$", MR_Next},
+     {"\"repetitions\": 1,$", MR_Next},
+     {"\"repetition_index\": 0,$", MR_Next},
+     {"\"threads\": %int,$", MR_Next},
+     {"\"iterations\": %int,$", MR_Next},
+     {"\"real_time\": %float,$", MR_Next},
+     {"\"cpu_time\": %float,$", MR_Next},
+     {"\"time_unit\": \"ns\",$", MR_Next},
+     {"\"bytes_per_second\": %float,$", MR_Next},
+     {"\"foo\": %float,$", MR_Next},
+     {"\"items_per_second\": %float$", MR_Next},
+     {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_WithBytesAndItemsPSec/threads:%int\","
+                       "%csv_bytes_items_report,,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckBytesAndItemsPSec(Results const& e) {
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1 * e.NumThreads());
+  // check that the values are within 0.1% of the expected values
+  CHECK_FLOAT_RESULT_VALUE(e, "bytes_per_second", EQ,
+                           (364. * e.NumThreads()) / t, 0.001);
+  CHECK_FLOAT_RESULT_VALUE(e, "items_per_second", EQ,
+                           (150. * e.NumThreads()) / t, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_WithBytesAndItemsPSec/threads:%int",
+                        &CheckBytesAndItemsPSec);
+}  // end namespace
+
+// ========================================================================= //
+// ------------------------- Rate Counters Output -------------------------- //
+// ========================================================================= //
+namespace {
+void BM_Counters_Rate(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{1, bm::Counter::kIsRate};
+  state.counters["bar"] = bm::Counter{2, bm::Counter::kIsRate};
+}
+BENCHMARK(BM_Counters_Rate)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Rate/threads:%int %console_report "
+                           "bar=%hrfloat/s foo=%hrfloat/s$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_Rate/threads:%int\",$"},
+           {"\"family_index\": 2,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_Rate/threads:%int\",$", MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut,
+          {{"^\"BM_Counters_Rate/threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckRate(Results const& e) {
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  // check that the values are within 0.1% of the expected values
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, (1. * e.NumThreads()) / t, 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, (2. * e.NumThreads()) / t, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_Rate/threads:%int", &CheckRate);
+}  // end namespace
+
+// ========================================================================= //
+// ----------------------- Inverted Counters Output ------------------------ //
+// ========================================================================= //
+
+namespace {
+void BM_Invert(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{0.0001, bm::Counter::kInvert};
+  state.counters["bar"] = bm::Counter{10000, bm::Counter::kInvert};
+}
+BENCHMARK(BM_Invert)->ThreadRange(1, 8);
+ADD_CASES(
+    TC_ConsoleOut,
+    {{"^BM_Invert/threads:%int %console_report bar=%hrfloatu foo=%hrfloatk$"}});
+ADD_CASES(TC_JSONOut, {{"\"name\": \"BM_Invert/threads:%int\",$"},
+                       {"\"family_index\": 3,$", MR_Next},
+                       {"\"per_family_instance_index\": 0,$", MR_Next},
+                       {"\"run_name\": \"BM_Invert/threads:%int\",$", MR_Next},
+                       {"\"run_type\": \"iteration\",$", MR_Next},
+                       {"\"repetitions\": 1,$", MR_Next},
+                       {"\"repetition_index\": 0,$", MR_Next},
+                       {"\"threads\": %int,$", MR_Next},
+                       {"\"iterations\": %int,$", MR_Next},
+                       {"\"real_time\": %float,$", MR_Next},
+                       {"\"cpu_time\": %float,$", MR_Next},
+                       {"\"time_unit\": \"ns\",$", MR_Next},
+                       {"\"bar\": %float,$", MR_Next},
+                       {"\"foo\": %float$", MR_Next},
+                       {"}", MR_Next}});
+ADD_CASES(TC_CSVOut,
+          {{"^\"BM_Invert/threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckInvert(Results const& e) {
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / (0.0001 * e.NumThreads()),
+                            0.0001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 1. / (10000 * e.NumThreads()),
+                            0.0001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Invert/threads:%int", &CheckInvert);
+}  // end namespace
+
+// ========================================================================= //
+// --------------------- InvertedRate Counters Output ---------------------- //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_InvertedRate(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] =
+      bm::Counter{1, bm::Counter::kIsRate | bm::Counter::kInvert};
+  state.counters["bar"] =
+      bm::Counter{8192, bm::Counter::kIsRate | bm::Counter::kInvert};
+}
+BENCHMARK(BM_Counters_InvertedRate)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut,
+          {{"^BM_Counters_InvertedRate/threads:%int %console_report "
+            "bar=%hrfloats foo=%hrfloats$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_InvertedRate/threads:%int\",$"},
+           {"\"family_index\": 4,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_InvertedRate/threads:%int\",$",
+            MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_InvertedRate/"
+                       "threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckInvertedRate(Results const& e) {
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  // check that the values are within 0.1% of the expected values
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, t / (e.NumThreads()), 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, t / (8192.0 * e.NumThreads()), 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_InvertedRate/threads:%int",
+                        &CheckInvertedRate);
+}  // end namespace
+
+// ========================================================================= //
+// ------------------------- Thread Counters Output ------------------------ //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_Threads(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+  state.counters["foo"] = 1;
+  state.counters["bar"] = 2;
+}
+BENCHMARK(BM_Counters_Threads)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_Threads/threads:%int %console_report "
+                           "bar=%hrfloat foo=%hrfloat$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_Threads/threads:%int\",$"},
+           {"\"family_index\": 5,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_Threads/threads:%int\",$", MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(
+    TC_CSVOut,
+    {{"^\"BM_Counters_Threads/threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckThreads(Results const& e) {
+  CHECK_COUNTER_VALUE(e, int, "foo", EQ, e.NumThreads());
+  CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2 * e.NumThreads());
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_Threads/threads:%int", &CheckThreads);
+}  // end namespace
+
+// ========================================================================= //
+// ---------------------- ThreadAvg Counters Output ------------------------ //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_AvgThreads(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreads};
+  state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreads};
+}
+BENCHMARK(BM_Counters_AvgThreads)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreads/threads:%int "
+                           "%console_report bar=%hrfloat foo=%hrfloat$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_AvgThreads/threads:%int\",$"},
+           {"\"family_index\": 6,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_AvgThreads/threads:%int\",$", MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(
+    TC_CSVOut,
+    {{"^\"BM_Counters_AvgThreads/threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckAvgThreads(Results const& e) {
+  CHECK_COUNTER_VALUE(e, int, "foo", EQ, 1);
+  CHECK_COUNTER_VALUE(e, int, "bar", EQ, 2);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreads/threads:%int",
+                        &CheckAvgThreads);
+}  // end namespace
+
+// ========================================================================= //
+// ---------------------- ThreadAvg Counters Output ------------------------ //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_AvgThreadsRate(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgThreadsRate};
+  state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgThreadsRate};
+}
+BENCHMARK(BM_Counters_AvgThreadsRate)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_AvgThreadsRate/threads:%int "
+                           "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$"},
+           {"\"family_index\": 7,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_AvgThreadsRate/threads:%int\",$",
+            MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgThreadsRate/"
+                       "threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckAvgThreadsRate(Results const& e) {
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. / t, 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. / t, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_AvgThreadsRate/threads:%int",
+                        &CheckAvgThreadsRate);
+}  // end namespace
+
+// ========================================================================= //
+// ------------------- IterationInvariant Counters Output ------------------ //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_IterationInvariant(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{1, bm::Counter::kIsIterationInvariant};
+  state.counters["bar"] = bm::Counter{2, bm::Counter::kIsIterationInvariant};
+}
+BENCHMARK(BM_Counters_IterationInvariant)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut,
+          {{"^BM_Counters_IterationInvariant/threads:%int %console_report "
+            "bar=%hrfloat foo=%hrfloat$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_IterationInvariant/threads:%int\",$"},
+           {"\"family_index\": 8,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_IterationInvariant/threads:%int\",$",
+            MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_IterationInvariant/"
+                       "threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckIterationInvariant(Results const& e) {
+  double its = e.NumIterations();
+  // check that the values are within 0.1% of the expected value
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * e.NumThreads(), 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * its * e.NumThreads(), 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_IterationInvariant/threads:%int",
+                        &CheckIterationInvariant);
+}  // end namespace
+
+// ========================================================================= //
+// ----------------- IterationInvariantRate Counters Output ---------------- //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_kIsIterationInvariantRate(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] =
+      bm::Counter{1, bm::Counter::kIsIterationInvariantRate};
+  state.counters["bar"] =
+      bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kIsIterationInvariant};
+}
+BENCHMARK(BM_Counters_kIsIterationInvariantRate)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut,
+          {{"^BM_Counters_kIsIterationInvariantRate/threads:%int "
+            "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
+ADD_CASES(
+    TC_JSONOut,
+    {{"\"name\": \"BM_Counters_kIsIterationInvariantRate/threads:%int\",$"},
+     {"\"family_index\": 9,$", MR_Next},
+     {"\"per_family_instance_index\": 0,$", MR_Next},
+     {"\"run_name\": \"BM_Counters_kIsIterationInvariantRate/threads:%int\",$",
+      MR_Next},
+     {"\"run_type\": \"iteration\",$", MR_Next},
+     {"\"repetitions\": 1,$", MR_Next},
+     {"\"repetition_index\": 0,$", MR_Next},
+     {"\"threads\": %int,$", MR_Next},
+     {"\"iterations\": %int,$", MR_Next},
+     {"\"real_time\": %float,$", MR_Next},
+     {"\"cpu_time\": %float,$", MR_Next},
+     {"\"time_unit\": \"ns\",$", MR_Next},
+     {"\"bar\": %float,$", MR_Next},
+     {"\"foo\": %float$", MR_Next},
+     {"}", MR_Next}});
+ADD_CASES(
+    TC_CSVOut,
+    {{"^\"BM_Counters_kIsIterationInvariantRate/threads:%int\",%csv_report,"
+      "%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckIsIterationInvariantRate(Results const& e) {
+  double its = e.NumIterations();
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  // check that the values are within 0.1% of the expected values
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, its * 1. * e.NumThreads() / t, 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, its * 2. * e.NumThreads() / t, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_kIsIterationInvariantRate/threads:%int",
+                        &CheckIsIterationInvariantRate);
+}  // end namespace
+
+// ========================================================================= //
+// --------------------- AvgIterations Counters Output --------------------- //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_AvgIterations(benchmark::State& state) {
+  for (auto _ : state) {
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterations};
+  state.counters["bar"] = bm::Counter{2, bm::Counter::kAvgIterations};
+}
+BENCHMARK(BM_Counters_AvgIterations)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut,
+          {{"^BM_Counters_AvgIterations/threads:%int %console_report "
+            "bar=%hrfloat foo=%hrfloat$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_AvgIterations/threads:%int\",$"},
+           {"\"family_index\": 10,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_AvgIterations/threads:%int\",$",
+            MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut, {{"^\"BM_Counters_AvgIterations/"
+                       "threads:%int\",%csv_report,%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckAvgIterations(Results const& e) {
+  double its = e.NumIterations();
+  // check that the values are within 0.1% of the expected value
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. * e.NumThreads() / its, 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * e.NumThreads() / its, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_AvgIterations/threads:%int",
+                        &CheckAvgIterations);
+}  // end namespace
+
+// ========================================================================= //
+// ------------------- AvgIterationsRate Counters Output ------------------- //
+// ========================================================================= //
+
+namespace {
+void BM_Counters_kAvgIterationsRate(benchmark::State& state) {
+  for (auto _ : state) {
+    // This test requires a non-zero CPU time to avoid divide-by-zero
+    auto iterations = static_cast<double>(state.iterations()) *
+                      static_cast<double>(state.iterations());
+    benchmark::DoNotOptimize(iterations);
+  }
+  namespace bm = benchmark;
+  state.counters["foo"] = bm::Counter{1, bm::Counter::kAvgIterationsRate};
+  state.counters["bar"] =
+      bm::Counter{2, bm::Counter::kIsRate | bm::Counter::kAvgIterations};
+}
+BENCHMARK(BM_Counters_kAvgIterationsRate)->ThreadRange(1, 8);
+ADD_CASES(TC_ConsoleOut, {{"^BM_Counters_kAvgIterationsRate/threads:%int "
+                           "%console_report bar=%hrfloat/s foo=%hrfloat/s$"}});
+ADD_CASES(TC_JSONOut,
+          {{"\"name\": \"BM_Counters_kAvgIterationsRate/threads:%int\",$"},
+           {"\"family_index\": 11,$", MR_Next},
+           {"\"per_family_instance_index\": 0,$", MR_Next},
+           {"\"run_name\": \"BM_Counters_kAvgIterationsRate/threads:%int\",$",
+            MR_Next},
+           {"\"run_type\": \"iteration\",$", MR_Next},
+           {"\"repetitions\": 1,$", MR_Next},
+           {"\"repetition_index\": 0,$", MR_Next},
+           {"\"threads\": %int,$", MR_Next},
+           {"\"iterations\": %int,$", MR_Next},
+           {"\"real_time\": %float,$", MR_Next},
+           {"\"cpu_time\": %float,$", MR_Next},
+           {"\"time_unit\": \"ns\",$", MR_Next},
+           {"\"bar\": %float,$", MR_Next},
+           {"\"foo\": %float$", MR_Next},
+           {"}", MR_Next}});
+ADD_CASES(TC_CSVOut,
+          {{"^\"BM_Counters_kAvgIterationsRate/threads:%int\",%csv_report,"
+            "%float,%float$"}});
+// VS2013 does not allow this function to be passed as a lambda argument
+// to CHECK_BENCHMARK_RESULTS()
+void CheckAvgIterationsRate(Results const& e) {
+  double its = e.NumIterations();
+  // this (and not real time) is the time used
+  double t = e.DurationCPUTime() / e.NumThreads();
+  // check that the values are within 0.1% of the expected values
+  CHECK_FLOAT_COUNTER_VALUE(e, "foo", EQ, 1. * e.NumThreads() / its / t, 0.001);
+  CHECK_FLOAT_COUNTER_VALUE(e, "bar", EQ, 2. * e.NumThreads() / its / t, 0.001);
+}
+CHECK_BENCHMARK_RESULTS("BM_Counters_kAvgIterationsRate/threads:%int",
+                        &CheckAvgIterationsRate);
+}  // end namespace
+
+// ========================================================================= //
+// --------------------------- TEST CASES END ------------------------------ //
+// ========================================================================= //
+
+int main(int argc, char* argv[]) {
+  benchmark::MaybeReenterWithoutASLR(argc, argv);
+  RunOutputTests(argc, argv);
+}
diff --git a/third_party/benchmark/tools/BUILD.bazel b/third_party/benchmark/tools/BUILD.bazel
new file mode 100644
index 0000000..a49edb7
--- /dev/null
+++ b/third_party/benchmark/tools/BUILD.bazel
@@ -0,0 +1,21 @@
+load("@rules_python//python:defs.bzl", "py_binary", "py_library")
+load("@tools_pip_deps//:requirements.bzl", "requirement")
+
+py_library(
+    name = "gbench",
+    srcs = glob(["gbench/*.py"]),
+    deps = [
+        requirement("numpy"),
+        requirement("scipy"),
+    ],
+)
+
+py_binary(
+    name = "compare",
+    srcs = ["compare.py"],
+    imports = ["."],
+    python_version = "PY3",
+    deps = [
+        ":gbench",
+    ],
+)
diff --git a/third_party/benchmark/tools/compare.py b/third_party/benchmark/tools/compare.py
index 1dd9de2..1a65634 100755
--- a/third_party/benchmark/tools/compare.py
+++ b/third_party/benchmark/tools/compare.py
@@ -21,8 +21,8 @@
     """
     Perform checking on the user provided inputs and diagnose any abnormalities
     """
-    in1_kind, in1_err = util.classify_input_file(in1)
-    in2_kind, in2_err = util.classify_input_file(in2)
+    in1_kind, _ = util.classify_input_file(in1)
+    in2_kind, _ = util.classify_input_file(in2)
     output_file = util.find_benchmark_flag("--benchmark_out=", flags)
     output_type = util.find_benchmark_flag("--benchmark_out_format=", flags)
     if (
diff --git a/third_party/benchmark/tools/requirements.txt b/third_party/benchmark/tools/requirements.txt
index f32f35b..12d5d9c 100644
--- a/third_party/benchmark/tools/requirements.txt
+++ b/third_party/benchmark/tools/requirements.txt
@@ -1,2 +1,2 @@
-numpy == 1.25
-scipy == 1.10.0
+numpy == 2.4.1
+scipy == 1.17.0
diff --git a/third_party/benchmark/tools/strip_asm.py b/third_party/benchmark/tools/strip_asm.py
index 14d80ed..f49a8c8 100755
--- a/third_party/benchmark/tools/strip_asm.py
+++ b/third_party/benchmark/tools/strip_asm.py
@@ -141,7 +141,7 @@
     parser.add_argument(
         "out", metavar="output", type=str, nargs=1, help="The output file"
     )
-    args, unknown_args = parser.parse_known_args()
+    args, _ = parser.parse_known_args()
     input = args.input[0]
     output = args.out[0]
     if not os.path.isfile(input):
diff --git a/util/bazel-example/MODULE.bazel.lock b/util/bazel-example/MODULE.bazel.lock
index 2b56124..221cabc 100644
--- a/util/bazel-example/MODULE.bazel.lock
+++ b/util/bazel-example/MODULE.bazel.lock
@@ -44,8 +44,8 @@
     "https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
     "https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
     "https://bcr.bazel.build/modules/google_benchmark/1.8.2/MODULE.bazel": "a70cf1bba851000ba93b58ae2f6d76490a9feb74192e57ab8e8ff13c34ec50cb",
-    "https://bcr.bazel.build/modules/google_benchmark/1.9.4/MODULE.bazel": "3bab7c17c10580f87b647478a72a05621f88abc275afb97b578c828f56e59d45",
-    "https://bcr.bazel.build/modules/google_benchmark/1.9.4/source.json": "8e0036f76a5c2aa9c16ca0da57d8065cff69edeed58f1f85584c588c0ef723a5",
+    "https://bcr.bazel.build/modules/google_benchmark/1.9.5/MODULE.bazel": "8a85cfd90b1e45e6e68f1aa2aa9efce3c04add57df732571d7fd54c07e7c5143",
+    "https://bcr.bazel.build/modules/google_benchmark/1.9.5/source.json": "0bd357fd9db30ee31d5eb4c78b1086ce3d79b4423ce76de19e8a2fa7b2fa2e10",
     "https://bcr.bazel.build/modules/googletest/1.11.0/MODULE.bazel": "3a83f095183f66345ca86aa13c58b59f9f94a2f81999c093d4eeaa2d262d12f4",
     "https://bcr.bazel.build/modules/googletest/1.14.0.bcr.1/MODULE.bazel": "22c31a561553727960057361aa33bf20fb2e98584bc4fec007906e27053f80c6",
     "https://bcr.bazel.build/modules/googletest/1.14.0/MODULE.bazel": "cfbcbf3e6eac06ef9d85900f64424708cc08687d1b527f0ef65aa7517af8118f",