Jingyuan
Jingyuan
### What problem does this PR solve? Issue Number: #2635 Problem Summary: 当brpc server 下处理的应用执行时间较短(bthread生命周期短),且使用了bthread_local变量时,由于keytable 由bthread_keytable_pool_t中的一个全局链表维护,borrow_keytable、return_keytable时内部加互斥锁,导致锁成为瓶颈。  基于此,重新设计了bthread_keytable_pool_t: 新的bthread_keytable_pool_t结构体中,使用butil::ThreadLocal* list 保存TLS的KeyTable list。同时保留原有的free_keytables,不改变reserved_thread_local_data的语义,调用bthread_keytable_pool_reserve会在全局链表中预分配keytable.原有的互斥锁改为读写锁。 * borrow_keytable时优先从本地TLS链表中查找是否有可用的KeyTable,如果没有,且free_keytables不为NULL,再去从全局链表中加写锁获取keytable;如果都没有可用table,则返回NULL。 * return_keytable时只会将keytable插入TLS的KeyTable list中,由于是TLS变量,只有当bthread_keytable_pool_destroy才会产生竞争,所以只需要加写锁。 * bthread_keytable_pool_destroy时加写锁,首先delete butil::ThreadLocal*...
目前bthread中对于bthread_local的管理是每个bthread会维护一个keytable。如果bthread_attr_t中设置有bthread_keytable_pool_t,那么bthread结束后只会return keytable而不会销毁,在第一次调用bthread_getspecific获取bthread_local变量时可以borrow_keytable;否则每当第一次访问bthread_local变量时和bthread结束时均需要构造/销毁keytable。 然而,即使是使用bthread_keytable_pool_t管理keytable,由于bthread_keytable_pool_t结构是一个用pthread_mutex_t维护的单链表格式,每次return/borrow都需要加锁。在bthread执行流程较短且需要访问bthread_local变量的场景下,锁的竞争会显著影响性能。 一个想法是将keytable嵌入task_meta一同由task_meta所属的resource_pool管理,当task_meta构造时初始化keytable指针为空,第一次需要使用keytbale时构造,并赋值给task_meta.local_storage. keytable,task_meta析构时销毁keytable。keytable只会在task_meta析构时销毁,理论上增加的内存使用量=存活的bthread个数的峰值\*bthread_key_t的个数\*平均一个value的大小。
If the kernel version does not support `io_uring_prep_poll_multishot`, are there any alternative ways to use the io_uring engine?
 在使用过程中,观察server侧的火焰图,此时brpc_worker thread的cpu基本打满。发现futex_wake、futex_wait占用的时间占比比较高,竞争锁成为了瓶颈。怀疑可能是由于调度不均衡,某些worker中的task较多,而一些worker的task较少,当这些task消费完之后每次都会调用wait,然后又快速被signal唤醒。同时也存在parking_lot中没有wait的线程但仍然在signal的场景。 这方面是否存在一些优化点,比如: 1. signal时判断是否存在wait状态的线程; 2. wait之前先尝试steal_task n 次,如果都失败再wait挂起线程;或者wait时设置timeout时间而不是每次都是永久wait,只能被signal主动唤醒。
* 项目中依赖brpc作为第三方库时出现的报错问题: brpc中的mutex.cpp覆盖了pthread_mutex_lock的实现,疑似导致tsan识别不了bthread内部实现的pthread_mutex_lock,导致出现了告警,请问有办法解决这个warning吗?一个简单的复现方式 ```cpp #include #include #include namespace my::test { class TsanCheckTest : public ::testing::Test {}; int counter; std::mutex mutex_std; pthread_mutex_t mu; const int kIncrementsPerThread = 100; void* Locker(void*) {...