load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library", "cc_test") licenses(["notice"]) ############################## pthreadpool library ############################# INTERNAL_HDRS = [ "src/threadpool-atomics.h", "src/threadpool-common.h", "src/threadpool-object.h", "src/threadpool-utils.h", ] PORTABLE_SRCS = [ "src/memory.c", "src/portable-api.c", ] ARCH_SPECIFIC_SRCS = [ "src/fastpath.c", ] PTHREADS_IMPL_SRCS = PORTABLE_SRCS + ["src/pthreads.c"] GCD_IMPL_SRCS = PORTABLE_SRCS + ["src/gcd.c"] WINDOWS_IMPL_SRCS = PORTABLE_SRCS + ["src/windows.c"] SHIM_IMPL_SRCS = ["src/shim.c"] cc_library( name = "pthreadpool", srcs = select({ ":pthreadpool_sync_primitive_explicit_condvar": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, ":pthreadpool_sync_primitive_explicit_futex": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, ":pthreadpool_sync_primitive_explicit_gcd": INTERNAL_HDRS + GCD_IMPL_SRCS, ":pthreadpool_sync_primitive_explicit_event": INTERNAL_HDRS + WINDOWS_IMPL_SRCS, ":emscripten_with_threads": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, ":emscripten": INTERNAL_HDRS + SHIM_IMPL_SRCS, ":macos_x86": INTERNAL_HDRS + GCD_IMPL_SRCS, ":macos_x86_64": INTERNAL_HDRS + GCD_IMPL_SRCS, ":ios": INTERNAL_HDRS + GCD_IMPL_SRCS, ":watchos": INTERNAL_HDRS + GCD_IMPL_SRCS, ":tvos": INTERNAL_HDRS + GCD_IMPL_SRCS, ":windows_x86_64": INTERNAL_HDRS + WINDOWS_IMPL_SRCS, "//conditions:default": INTERNAL_HDRS + PTHREADS_IMPL_SRCS, }) + select({ ":linux_x86_64": ARCH_SPECIFIC_SRCS, ":android_x86": ARCH_SPECIFIC_SRCS, ":android_x86_64": ARCH_SPECIFIC_SRCS, ":windows_x86_64": ARCH_SPECIFIC_SRCS, ":macos_x86": ARCH_SPECIFIC_SRCS, ":macos_x86_64": ARCH_SPECIFIC_SRCS, ":ios_x86": ARCH_SPECIFIC_SRCS, ":ios_x86_64": ARCH_SPECIFIC_SRCS, ":watchos_x86": ARCH_SPECIFIC_SRCS, ":watchos_x86_64": ARCH_SPECIFIC_SRCS, ":tvos_x86_64": ARCH_SPECIFIC_SRCS, "//conditions:default": [], }), copts = [ "-std=gnu11", ] + select({ ":optimized_build": ["-O2"], "//conditions:default": [], }) + select({ ":linux_arm": ["-DPTHREADPOOL_USE_CPUINFO=1"], ":linux_armeabi": ["-DPTHREADPOOL_USE_CPUINFO=1"], ":linux_armhf": ["-DPTHREADPOOL_USE_CPUINFO=1"], ":linux_armv7a": ["-DPTHREADPOOL_USE_CPUINFO=1"], ":linux_aarch64": ["-DPTHREADPOOL_USE_CPUINFO=1"], ":android_armv7": ["-DPTHREADPOOL_USE_CPUINFO=1"], ":android_arm64": ["-DPTHREADPOOL_USE_CPUINFO=1"], "//conditions:default": ["-DPTHREADPOOL_USE_CPUINFO=0"], }) + select({ ":pthreadpool_sync_primitive_explicit_condvar": [ "-DPTHREADPOOL_USE_CONDVAR=1", "-DPTHREADPOOL_USE_FUTEX=0", "-DPTHREADPOOL_USE_GCD=0", "-DPTHREADPOOL_USE_EVENT=0", ], ":pthreadpool_sync_primitive_explicit_futex": [ "-DPTHREADPOOL_USE_CONDVAR=0", "-DPTHREADPOOL_USE_FUTEX=1", "-DPTHREADPOOL_USE_GCD=0", "-DPTHREADPOOL_USE_EVENT=0", ], ":pthreadpool_sync_primitive_explicit_gcd": [ "-DPTHREADPOOL_USE_CONDVAR=0", "-DPTHREADPOOL_USE_FUTEX=0", "-DPTHREADPOOL_USE_GCD=1", "-DPTHREADPOOL_USE_EVENT=0", ], ":pthreadpool_sync_primitive_explicit_event": [ "-DPTHREADPOOL_USE_CONDVAR=0", "-DPTHREADPOOL_USE_FUTEX=0", "-DPTHREADPOOL_USE_GCD=0", "-DPTHREADPOOL_USE_EVENT=1", ], "//conditions:default": [], }) + select({ ":linux_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":android_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":android_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":windows_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":macos_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":macos_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":ios_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":ios_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":watchos_x86": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":watchos_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], ":tvos_x86_64": ["-DPTHREADPOOL_USE_FASTPATH=1"], "//conditions:default": ["-DPTHREADPOOL_USE_FASTPATH=0"], }), hdrs = [ "include/pthreadpool.h", ], defines = [ "PTHREADPOOL_NO_DEPRECATED_API", ], includes = [ "include", ], linkopts = select({ ":emscripten_with_threads": [ "-s ALLOW_BLOCKING_ON_MAIN_THREAD=1", "-s PTHREAD_POOL_SIZE=8", ], "//conditions:default": [], }), strip_include_prefix = "include", deps = [ "@FXdiv", ] + select({ ":linux_arm": ["@cpuinfo"], ":linux_armeabi": ["@cpuinfo"], ":linux_armhf": ["@cpuinfo"], ":linux_armv7a": ["@cpuinfo"], ":linux_aarch64": ["@cpuinfo"], ":android_armv7": ["@cpuinfo"], ":android_arm64": ["@cpuinfo"], "//conditions:default": [], }), visibility = ["//visibility:public"], ) ################################## Unit tests ################################## EMSCRIPTEN_TEST_LINKOPTS = [ "-s ASSERTIONS=2", "-s ERROR_ON_UNDEFINED_SYMBOLS=1", "-s DEMANGLE_SUPPORT=1", "-s EXIT_RUNTIME=1", "-s ALLOW_MEMORY_GROWTH=0", "-s TOTAL_MEMORY=67108864", # 64M ] cc_test( name = "pthreadpool_test", srcs = ["test/pthreadpool.cc"], linkopts = select({ ":emscripten": EMSCRIPTEN_TEST_LINKOPTS, "//conditions:default": [], }), deps = [ ":pthreadpool", "@com_google_googletest//:gtest_main", ], ) ################################## Benchmarks ################################## EMSCRIPTEN_BENCHMARK_LINKOPTS = [ "-s ASSERTIONS=1", "-s ERROR_ON_UNDEFINED_SYMBOLS=1", "-s EXIT_RUNTIME=1", "-s ALLOW_MEMORY_GROWTH=0", ] cc_binary( name = "latency_bench", srcs = ["bench/latency.cc"], linkopts = select({ ":emscripten": EMSCRIPTEN_BENCHMARK_LINKOPTS, "//conditions:default": [], }), deps = [ ":pthreadpool", "@com_google_benchmark//:benchmark", ], ) cc_binary( name = "throughput_bench", srcs = ["bench/throughput.cc"], linkopts = select({ ":emscripten": EMSCRIPTEN_BENCHMARK_LINKOPTS, "//conditions:default": [], }), deps = [ ":pthreadpool", "@com_google_benchmark//:benchmark", ], ) ############################# Build configurations ############################# # Synchronize workers using pthreads condition variable. config_setting( name = "pthreadpool_sync_primitive_explicit_condvar", define_values = {"pthreadpool_sync_primitive": "condvar"}, ) # Synchronize workers using futex. config_setting( name = "pthreadpool_sync_primitive_explicit_futex", define_values = {"pthreadpool_sync_primitive": "futex"}, ) # Synchronize workers using Grand Central Dispatch. config_setting( name = "pthreadpool_sync_primitive_explicit_gcd", define_values = {"pthreadpool_sync_primitive": "gcd"}, ) # Synchronize workers using WinAPI event. config_setting( name = "pthreadpool_sync_primitive_explicit_event", define_values = {"pthreadpool_sync_primitive": "event"}, ) config_setting( name = "optimized_build", values = { "compilation_mode": "opt", }, ) config_setting( name = "linux_x86_64", values = {"cpu": "k8"}, ) config_setting( name = "linux_arm", values = {"cpu": "arm"}, ) config_setting( name = "linux_armeabi", values = {"cpu": "armeabi"}, ) config_setting( name = "linux_armhf", values = {"cpu": "armhf"}, ) config_setting( name = "linux_armv7a", values = {"cpu": "armv7a"}, ) config_setting( name = "linux_aarch64", values = {"cpu": "aarch64"}, ) config_setting( name = "android_x86", values = { "crosstool_top": "//external:android/crosstool", "cpu": "x86", }, ) config_setting( name = "android_x86_64", values = { "crosstool_top": "//external:android/crosstool", "cpu": "x86_64", }, ) config_setting( name = "android_armv7", values = { "crosstool_top": "//external:android/crosstool", "cpu": "armeabi-v7a", }, ) config_setting( name = "android_arm64", values = { "crosstool_top": "//external:android/crosstool", "cpu": "arm64-v8a", }, ) # Note: we need to individually match x86 and x86-64 macOS rather than use # catch-all "apple_platform_type": "macos" because that option defaults to # "macos" even when building on Linux! config_setting( name = "macos_x86", values = { "apple_platform_type": "macos", "cpu": "darwin", }, ) config_setting( name = "macos_x86_64", values = { "apple_platform_type": "macos", "cpu": "darwin_x86_64", }, ) config_setting( name = "ios", values = { "crosstool_top": "@bazel_tools//tools/cpp:toolchain", "apple_platform_type": "ios", }, ) config_setting( name = "ios_x86", values = { "apple_platform_type": "ios", "cpu": "ios_i386", }, ) config_setting( name = "ios_x86_64", values = { "apple_platform_type": "ios", "cpu": "ios_x86_64", }, ) config_setting( name = "watchos", values = { "crosstool_top": "@bazel_tools//tools/cpp:toolchain", "apple_platform_type": "watchos", }, ) config_setting( name = "watchos_x86", values = { "apple_platform_type": "watchos", "cpu": "watchos_i386", }, ) config_setting( name = "watchos_x86_64", values = { "apple_platform_type": "watchos", "cpu": "watchos_x86_64", }, ) config_setting( name = "tvos", values = { "crosstool_top": "@bazel_tools//tools/cpp:toolchain", "apple_platform_type": "tvos", }, ) config_setting( name = "tvos_x86_64", values = { "apple_platform_type": "tvos", "cpu": "tvos_x86_64", }, ) config_setting( name = "windows_x86_64", values = { "cpu": "x64_windows", }, ) config_setting( name = "emscripten", values = { "crosstool_top": "//toolchain:emscripten", } ) config_setting( name = "emscripten_with_threads", values = { "crosstool_top": "//toolchain:emscripten", "copt": "-pthread", } )