• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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