1load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") 2 3licenses(["notice"]) 4 5exports_files(["LICENSE"]) 6 7############################## pthreadpool library ############################# 8 9INTERNAL_HDRS = [ 10 "src/threadpool-atomics.h", 11 "src/threadpool-common.h", 12 "src/threadpool-object.h", 13 "src/threadpool-utils.h", 14] 15 16PORTABLE_SRCS = [ 17 "src/memory.c", 18 "src/portable-api.c", 19] 20 21ARCH_SPECIFIC_SRCS = [ 22 "src/fastpath.c", 23] 24 25PTHREADS_IMPL_SRCS = PORTABLE_SRCS + ["src/pthreads.c"] 26 27GCD_IMPL_SRCS = PORTABLE_SRCS + ["src/gcd.c"] 28 29WINDOWS_IMPL_SRCS = PORTABLE_SRCS + ["src/windows.c"] 30 31SHIM_IMPL_SRCS = ["src/shim.c"] 32 33cc_library( 34 name = "pthreadpool", 35 srcs = select({ 36 ":pthreadpool_sync_primitive_explicit_condvar": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, 37 ":pthreadpool_sync_primitive_explicit_futex": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, 38 ":pthreadpool_sync_primitive_explicit_gcd": INTERNAL_HDRS + GCD_IMPL_SRCS, 39 ":pthreadpool_sync_primitive_explicit_event": INTERNAL_HDRS + WINDOWS_IMPL_SRCS, 40 ":emscripten_with_threads": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, 41 ":emscripten": INTERNAL_HDRS + SHIM_IMPL_SRCS, 42 ":macos_x86": INTERNAL_HDRS + GCD_IMPL_SRCS, 43 ":macos_x86_64": INTERNAL_HDRS + GCD_IMPL_SRCS, 44 ":macos_arm64": INTERNAL_HDRS + GCD_IMPL_SRCS, 45 ":ios": INTERNAL_HDRS + GCD_IMPL_SRCS, 46 ":watchos": INTERNAL_HDRS + GCD_IMPL_SRCS, 47 ":tvos": INTERNAL_HDRS + GCD_IMPL_SRCS, 48 ":windows_x86_64": INTERNAL_HDRS + WINDOWS_IMPL_SRCS, 49 ":windows_arm64": INTERNAL_HDRS + WINDOWS_IMPL_SRCS, 50 "//conditions:default": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, 51 }) + select({ 52 ":linux_x86_64": ARCH_SPECIFIC_SRCS, 53 ":android_x86": ARCH_SPECIFIC_SRCS, 54 ":android_x86_64": ARCH_SPECIFIC_SRCS, 55 ":windows_x86_64": ARCH_SPECIFIC_SRCS, 56 ":windows_arm64": ARCH_SPECIFIC_SRCS, 57 ":macos_x86": ARCH_SPECIFIC_SRCS, 58 ":macos_x86_64": ARCH_SPECIFIC_SRCS, 59 ":macos_arm64": ARCH_SPECIFIC_SRCS, 60 ":ios_x86": ARCH_SPECIFIC_SRCS, 61 ":ios_x86_64": ARCH_SPECIFIC_SRCS, 62 ":watchos_x86": ARCH_SPECIFIC_SRCS, 63 ":watchos_x86_64": ARCH_SPECIFIC_SRCS, 64 ":tvos_x86_64": ARCH_SPECIFIC_SRCS, 65 "//conditions:default": [], 66 }), 67 copts = [ 68 "-std=gnu11", 69 ] + select({ 70 ":optimized_build": ["-O2"], 71 "//conditions:default": [], 72 }) + select({ 73 ":linux_arm": ["-DPTHREADPOOL_USE_CPUINFO=1"], 74 ":linux_armeabi": ["-DPTHREADPOOL_USE_CPUINFO=1"], 75 ":linux_armhf": ["-DPTHREADPOOL_USE_CPUINFO=1"], 76 ":linux_armv7a": ["-DPTHREADPOOL_USE_CPUINFO=1"], 77 ":linux_aarch64": ["-DPTHREADPOOL_USE_CPUINFO=1"], 78 ":android_armv7": ["-DPTHREADPOOL_USE_CPUINFO=1"], 79 ":android_arm64": ["-DPTHREADPOOL_USE_CPUINFO=1"], 80 "//conditions:default": ["-DPTHREADPOOL_USE_CPUINFO=0"], 81 }) + select({ 82 ":pthreadpool_sync_primitive_explicit_condvar": [ 83 "-DPTHREADPOOL_USE_CONDVAR=1", 84 "-DPTHREADPOOL_USE_FUTEX=0", 85 "-DPTHREADPOOL_USE_GCD=0", 86 "-DPTHREADPOOL_USE_EVENT=0", 87 ], 88 ":pthreadpool_sync_primitive_explicit_futex": [ 89 "-DPTHREADPOOL_USE_CONDVAR=0", 90 "-DPTHREADPOOL_USE_FUTEX=1", 91 "-DPTHREADPOOL_USE_GCD=0", 92 "-DPTHREADPOOL_USE_EVENT=0", 93 ], 94 ":pthreadpool_sync_primitive_explicit_gcd": [ 95 "-DPTHREADPOOL_USE_CONDVAR=0", 96 "-DPTHREADPOOL_USE_FUTEX=0", 97 "-DPTHREADPOOL_USE_GCD=1", 98 "-DPTHREADPOOL_USE_EVENT=0", 99 ], 100 ":pthreadpool_sync_primitive_explicit_event": [ 101 "-DPTHREADPOOL_USE_CONDVAR=0", 102 "-DPTHREADPOOL_USE_FUTEX=0", 103 "-DPTHREADPOOL_USE_GCD=0", 104 "-DPTHREADPOOL_USE_EVENT=1", 105 ], 106 "//conditions:default": [], 107 }) + select({ 108 ":linux_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 109 ":android_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], 110 ":android_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 111 ":windows_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 112 ":windows_arm64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 113 ":macos_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], 114 ":macos_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 115 ":macos_arm64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 116 ":ios_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], 117 ":ios_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 118 ":watchos_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], 119 ":watchos_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 120 ":tvos_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], 121 "//conditions:default": ["-DPTHREADPOOL_USE_FASTPATH=0"], 122 }), 123 hdrs = [ 124 "include/pthreadpool.h", 125 ], 126 defines = [ 127 "PTHREADPOOL_NO_DEPRECATED_API", 128 ], 129 includes = [ 130 "include", 131 ], 132 linkopts = select({ 133 ":emscripten_with_threads": [ 134 "-s ALLOW_BLOCKING_ON_MAIN_THREAD=1", 135 "-s PTHREAD_POOL_SIZE=8", 136 ], 137 "//conditions:default": [], 138 }), 139 strip_include_prefix = "include", 140 deps = [ 141 "@FXdiv", 142 ] + select({ 143 ":linux_arm": ["@cpuinfo"], 144 ":linux_armeabi": ["@cpuinfo"], 145 ":linux_armhf": ["@cpuinfo"], 146 ":linux_armv7a": ["@cpuinfo"], 147 ":linux_aarch64": ["@cpuinfo"], 148 ":android_armv7": ["@cpuinfo"], 149 ":android_arm64": ["@cpuinfo"], 150 "//conditions:default": [], 151 }), 152 visibility = ["//visibility:public"], 153) 154 155################################## Unit tests ################################## 156 157EMSCRIPTEN_TEST_LINKOPTS = [ 158 "-s ASSERTIONS=2", 159 "-s ERROR_ON_UNDEFINED_SYMBOLS=1", 160 "-s DEMANGLE_SUPPORT=1", 161 "-s EXIT_RUNTIME=1", 162 "-s ALLOW_MEMORY_GROWTH=0", 163 "-s TOTAL_MEMORY=67108864", # 64M 164] 165 166cc_test( 167 name = "pthreadpool_test", 168 srcs = ["test/pthreadpool.cc"], 169 linkopts = select({ 170 ":emscripten": EMSCRIPTEN_TEST_LINKOPTS, 171 "//conditions:default": [], 172 }), 173 deps = [ 174 ":pthreadpool", 175 "@com_google_googletest//:gtest_main", 176 ], 177) 178 179cc_test( 180 name = "pthreadpool_cxx_test", 181 srcs = ["test/pthreadpool-cxx.cc"], 182 linkopts = select({ 183 ":emscripten": EMSCRIPTEN_TEST_LINKOPTS, 184 "//conditions:default": [], 185 }), 186 deps = [ 187 ":pthreadpool", 188 "@com_google_googletest//:gtest_main", 189 ], 190) 191 192################################## Benchmarks ################################## 193 194EMSCRIPTEN_BENCHMARK_LINKOPTS = [ 195 "-s ASSERTIONS=1", 196 "-s ERROR_ON_UNDEFINED_SYMBOLS=1", 197 "-s EXIT_RUNTIME=1", 198 "-s ALLOW_MEMORY_GROWTH=0", 199] 200 201cc_binary( 202 name = "latency_bench", 203 srcs = ["bench/latency.cc"], 204 linkopts = select({ 205 ":emscripten": EMSCRIPTEN_BENCHMARK_LINKOPTS, 206 "//conditions:default": [], 207 }), 208 deps = [ 209 ":pthreadpool", 210 "@com_google_benchmark//:benchmark", 211 ], 212) 213 214cc_binary( 215 name = "throughput_bench", 216 srcs = ["bench/throughput.cc"], 217 linkopts = select({ 218 ":emscripten": EMSCRIPTEN_BENCHMARK_LINKOPTS, 219 "//conditions:default": [], 220 }), 221 deps = [ 222 ":pthreadpool", 223 "@com_google_benchmark//:benchmark", 224 ], 225) 226 227############################# Build configurations ############################# 228 229# Synchronize workers using pthreads condition variable. 230config_setting( 231 name = "pthreadpool_sync_primitive_explicit_condvar", 232 define_values = {"pthreadpool_sync_primitive": "condvar"}, 233) 234 235# Synchronize workers using futex. 236config_setting( 237 name = "pthreadpool_sync_primitive_explicit_futex", 238 define_values = {"pthreadpool_sync_primitive": "futex"}, 239) 240 241# Synchronize workers using Grand Central Dispatch. 242config_setting( 243 name = "pthreadpool_sync_primitive_explicit_gcd", 244 define_values = {"pthreadpool_sync_primitive": "gcd"}, 245) 246 247# Synchronize workers using WinAPI event. 248config_setting( 249 name = "pthreadpool_sync_primitive_explicit_event", 250 define_values = {"pthreadpool_sync_primitive": "event"}, 251) 252 253config_setting( 254 name = "optimized_build", 255 values = { 256 "compilation_mode": "opt", 257 }, 258) 259 260config_setting( 261 name = "linux_x86_64", 262 values = {"cpu": "k8"}, 263) 264 265config_setting( 266 name = "linux_arm", 267 values = {"cpu": "arm"}, 268) 269 270config_setting( 271 name = "linux_armeabi", 272 values = {"cpu": "armeabi"}, 273) 274 275config_setting( 276 name = "linux_armhf", 277 values = {"cpu": "armhf"}, 278) 279 280config_setting( 281 name = "linux_armv7a", 282 values = {"cpu": "armv7a"}, 283) 284 285config_setting( 286 name = "linux_aarch64", 287 values = {"cpu": "aarch64"}, 288) 289 290config_setting( 291 name = "android_x86", 292 values = { 293 "crosstool_top": "//external:android/crosstool", 294 "cpu": "x86", 295 }, 296) 297 298config_setting( 299 name = "android_x86_64", 300 values = { 301 "crosstool_top": "//external:android/crosstool", 302 "cpu": "x86_64", 303 }, 304) 305 306config_setting( 307 name = "android_armv7", 308 values = { 309 "crosstool_top": "//external:android/crosstool", 310 "cpu": "armeabi-v7a", 311 }, 312) 313 314config_setting( 315 name = "android_arm64", 316 values = { 317 "crosstool_top": "//external:android/crosstool", 318 "cpu": "arm64-v8a", 319 }, 320) 321 322# Note: we need to individually match x86 and x86-64 macOS rather than use 323# catch-all "apple_platform_type": "macos" because that option defaults to 324# "macos" even when building on Linux! 325config_setting( 326 name = "macos_x86", 327 values = { 328 "apple_platform_type": "macos", 329 "cpu": "darwin", 330 }, 331) 332 333config_setting( 334 name = "macos_x86_64", 335 values = { 336 "apple_platform_type": "macos", 337 "cpu": "darwin_x86_64", 338 }, 339) 340 341config_setting( 342 name = "macos_arm64", 343 values = { 344 "apple_platform_type": "macos", 345 "cpu": "darwin_arm64", 346 }, 347) 348 349config_setting( 350 name = "ios", 351 values = { 352 "crosstool_top": "@bazel_tools//tools/cpp:toolchain", 353 "apple_platform_type": "ios", 354 }, 355) 356 357config_setting( 358 name = "ios_x86", 359 values = { 360 "apple_platform_type": "ios", 361 "cpu": "ios_i386", 362 }, 363) 364 365config_setting( 366 name = "ios_x86_64", 367 values = { 368 "apple_platform_type": "ios", 369 "cpu": "ios_x86_64", 370 }, 371) 372 373config_setting( 374 name = "watchos", 375 values = { 376 "crosstool_top": "@bazel_tools//tools/cpp:toolchain", 377 "apple_platform_type": "watchos", 378 }, 379) 380 381config_setting( 382 name = "watchos_x86", 383 values = { 384 "apple_platform_type": "watchos", 385 "cpu": "watchos_i386", 386 }, 387) 388 389config_setting( 390 name = "watchos_x86_64", 391 values = { 392 "apple_platform_type": "watchos", 393 "cpu": "watchos_x86_64", 394 }, 395) 396 397config_setting( 398 name = "tvos", 399 values = { 400 "crosstool_top": "@bazel_tools//tools/cpp:toolchain", 401 "apple_platform_type": "tvos", 402 }, 403) 404 405config_setting( 406 name = "tvos_x86_64", 407 values = { 408 "apple_platform_type": "tvos", 409 "cpu": "tvos_x86_64", 410 }, 411) 412 413config_setting( 414 name = "windows_x86_64", 415 values = { 416 "cpu": "x64_windows", 417 }, 418) 419 420config_setting( 421 name = "windows_arm64", 422 values = { 423 "cpu": "arm64_windows", 424 }, 425) 426 427config_setting( 428 name = "emscripten", 429 values = { 430 "crosstool_top": "//toolchain:emscripten", 431 } 432) 433 434config_setting( 435 name = "emscripten_with_threads", 436 values = { 437 "crosstool_top": "//toolchain:emscripten", 438 "copt": "-pthread", 439 } 440) 441