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