[llvm-dev] [clang-tidy][RFC] checks concurrency-async-{blocking, fs, no-new-threads}

Vasily Kulikov via llvm-dev llvm-dev at lists.llvm.org
Wed Jan 27 03:23:32 PST 2021


Hi,

With official C++20 inclusion of coroutines it gets important to 
identify synchronous code usage inside of coroutines. Volunteer 
preemption of a system thread in asynchronous code (e.g. in
coroutines/fibers/green threads) is a bug that prevents the current 
thread from executing other coroutines/etc. and negatively affects 
overall process performance.

I've tried to address it in a series of clang-tidy checks that
try to find such synchronous code based on blacklists from
POSIX/C++ std/C11/Boost/Linux syscalls. Basically, one should enable 
concurrency-*
checks for the strictest mode. It finds usages of synchronous primitives 
(e.g. std::mutex), fs access (e.g. open(3)), implicit system threads 
creation (e.g. via std::execution::par). In some cases one may want to 
relax the check, e.g.:
- if new threads creation is not an issue, I don't force coroutine-only 
code, just don't want to block coroutine threads => disable 
concurrency-async-no-new-threads
- if I have no means to delegate fs access to a thread pool and don't 
want to use aio, so I have to make synchronous fs access from coroutines 
=> disable concurrency-async-fs

Nathan James in a review (https://reviews.llvm.org/D94621#2497859) 
questions whether such check based on functions/types blacklist worth 
implementing. I think it does as every coroutine/fiber-based C++ program 
may suffer from the same problem - you may not use a lot of std stuff 
unless you're OK with ineffective code, so having such "do not use part 
of std/boost" checks is handy.

The checks:

concurrency-async-blocking: https://reviews.llvm.org/D93940
concurrency-async-fs: https://reviews.llvm.org/D94621
concurrency-async-no-new-threads: https://reviews.llvm.org/D94622

The patch series are based on a much more simple check used in 
Yandex.Taxi. I think it worth something to the community, so I've 
separated a big list of functions/types apart to address e.g. 
environments without fs threadpool, and added possibility to extend the 
types/functions lists via option.

I'd be happy to hear any comments how the checks can be improved, or 
maybe organized in some other way, or whether they confront any implicit 
clang-tidy policy.


More information about the llvm-dev mailing list