积分145 / 贡献0

提问0答案被采纳0文章11

[经验分享] OpenHarmony蓝牙STACK模块单线程实现方法

深开鸿_石悌君 显示全部楼层 发表于 2024-11-29 18:00:00

前言

蓝牙系统服务层的架构如下图

arch.png

蓝牙系统服务组件的核心是STACK模块,STACK模块为了简化处理设计成了一个单线程模块;但系统服务层组件使用IPC和Framework交互,标准设备上蓝牙系统服务层有16条线程用于接收IPC消息,本文解析蓝牙实现从多线程到单线程的实现思路。

解决思路

蓝牙通过消息队列实现从IPC多线程到单线程的处理,原理简图如下

queue.png

具体实现以开启蓝牙发现流程为例说明;以下是该流程调用栈

#03 pc 0007b489 /system/lib/libbtstack.z.so(GapRunTaskBlockProcess+100)
#04 pc 000785cb /system/lib/libbtstack.z.so(GAPIF_Inquiry+78)
#05 pc 001999db /system/lib/libbtservice.z.so(OHOS::bluetooth::ClassicAdapter::StartBtDiscovery()+118)
#06 pc 0005fe0f /system/lib/libbluetooth_server.z.so(OHOS::Bluetooth::BluetoothHostServer::StartBtDiscovery()+194)
#07 pc 00092719 /system/lib/libbluetooth_server.z.so(OHOS::Bluetooth::BluetoothHostStub::StartBtDiscoveryInner(OHOS::MessageParcel&, OHOS::MessageParcel&)+12)
#08 pc 00095257 /system/lib/libbluetooth_server.z.so(OHOS::Bluetooth::BluetoothHostStub::OnRemoteRequest(unsigned int, OHOS::MessageParcel&, OHOS::MessageParcel&, OHOS::MessageOption&)+362)

从调用栈可以看到#08是IPC处理函数,#07开始进入业务处理流程,以调用GapRunTaskBlockProcess结束;GapRunTaskBlockProcess函数将任务信息加入到PROCESSING_QUEUE_ID_GAP队列

int GapRunTaskBlockProcess(void (*func)(void *), void *ctx)
{
    GapRunTaskBlockInfo *info = MEM_MALLOC.alloc(sizeof(GapRunTaskBlockInfo));
    if (info == NULL) {
        return BT_NO_MEMORY;
    }

    info->event = EventCreate(true);
    info->ctx = ctx;
    info->func = func;

    int ret = BTM_RunTaskInProcessingQueue(PROCESSING_QUEUE_ID_GAP, GapBlockInTaskProcess, info);
    if (ret == BT_SUCCESS) {
        ret = EventWait(info->event, WAIT_TIME);
        ...
    }
}

Stack模块包含由链表组成的多个任务队列,Stack线程初始化时创建队列头部;stack线程通过epoll监控多个队列;队列中有消息就触发读取处理

void BtmInitThread()
{
   g_processingThread = ThreadCreate("Stack");
   g_processingQueueList = ListCreate(FreeProcessingQueue);
   g_processingQueueLock = MutexCreate();
}

GapRunTaskBlockProcess函数通过EventWait等待队列处理结果,会阻塞调用线程;该函数还有一个异步版本GapRunTaskUnBlockProcess,如果不需要得到函数执行结果,调用异步函数原则上效率更高。调用两个函数还需要注意,GapRunTaskBlockProcess由调用方释放ctx,GapRunTaskUnBlockProcess调用方不需要释放ctx

©著作权归作者所有,转载或内容合作请联系作者

您尚未登录,无法参与评论,登录后可以:
参与开源共建问题交流
认同或收藏高质量问答
获取积分成为开源共建先驱

Copyright   ©2023  OpenHarmony开发者论坛  京ICP备2020036654号-3 |技术支持 Discuz!

返回顶部