Utils_FenceWatcher - SweerItTer/utilsCore GitHub Wiki

FenceWatcher API 文档

概述

FenceWatcher 是 utilsCore Utils 模块的核心类,提供 Fence 同步对象监控功能,使用单例模式。

职责

  • 监控 Fence 同步对象
  • 异步通知 Fence 完成
  • 超时检测
  • 线程安全操作

适用场景

  • GPU 同步
  • DRM 显示同步
  • RGA 处理同步
  • 硬件加速同步

依赖关系

  • 依赖: Linux epoll, eventfd
  • 被依赖: DrmLayer, RGA 等模块

类分析

FenceWatcher 类

职责与用途

FenceWatcher 是 Fence 监控的封装类,提供:

  • 单例模式
  • Fence 监控
  • 异步回调通知
  • 超时检测

设计模式

  • 单例模式: 全局唯一实例
  • 观察者模式: 回调通知 Fence 状态
  • RAII: 自动管理资源

公共 API 方法

instance() - 获取单例

static FenceWatcher& instance();

参数说明: 无

返回值: FenceWatcher 单例引用

所有权归属:

  • 只读访问,不转移所有权

注意事项:

  1. 全局唯一实例
  2. 第一次调用时初始化
  3. 线程安全

使用例程:

auto& watcher = FenceWatcher::instance();

watchFence() - 监控 Fence

void watchFence(int fence_fd, std::function<void()> callback, int timeout_ms = 1000);

参数说明:

  • fence_fd (输入): Fence 文件描述符
  • callback (输入): 回调函数(无参数)
  • timeout_ms (输入): 超时时间(毫秒),默认 1000ms

返回值: 无

所有权归属:

  • fence_fd 由 FenceWatcher 管理(自动关闭)
  • callback 由调用者提供

注意事项:

  1. fence_fd < 0 时会立即调用 callback
  2. callback 会在 Fence 触发或超时后调用
  3. FenceWatcher 会自动关闭 fence_fd
  4. 默认超时为 1000ms
  5. 线程安全

使用例程:

auto& watcher = FenceWatcher::instance();

// 监控 Fence
watcher.watchFence(fence_fd, []() {
    printf("Fence signaled or timeout\n");
}, 1000);  // 1 秒超时

shutdown() - 关闭监控

void shutdown();

参数说明: 无

返回值: 无

所有权归属:

  • 无所有权转移

注意事项:

  1. 停止监控线程
  2. 唤醒 epoll_wait
  3. 等待线程退出
  4. 可以安全重复调用

使用例程:

auto& watcher = FenceWatcher::instance();

// 关闭监控
watcher.shutdown();

内部实现

数据成员

class FenceWatcher {
private:
    int epoll_fd_ = -1;                          // epoll 文件描述符
    int event_fd_ = -1;                          // eventfd 用于唤醒
    std::unordered_map<int, FenceData> fd_callbacks_;  // fence_fd -> 回调映射
    std::mutex map_mutex_;                       // 保护 fd_callbacks_
    std::thread loop_thread_;                    // 事件循环线程
    std::atomic<bool> running_;                  // 运行标志
};

struct FenceData {
    std::function<void()> callback;              // 回调函数
    std::chrono::steady_clock::time_point expire_time;  // 过期时间
};

事件循环

void eventLoop() {
    const int MAX_EVENTS = 16;
    struct epoll_event events[MAX_EVENTS];

    while (running_) {
        int n = epoll_wait(epoll_fd_, events, MAX_EVENTS, 50);
        auto now = std::chrono::steady_clock::now();

        // 处理就绪事件
        for (int i = 0; i < n; ++i) {
            int fd = events[i].data.fd;
            if (fd == event_fd_) {
                // shutdown 唤醒
                uint64_t dummy;
                read(event_fd_, &dummy, sizeof(dummy));
                continue;
            }
            triggerCallback(fd);
        }

        // 超时检查
        std::vector<int> expired;
        {
            std::lock_guard<std::mutex> lock(map_mutex_);
            for (auto& kv : fd_callbacks_) {
                int fd = kv.first;
                FenceData& data = kv.second;
                if (now >= data.expire_time) {
                    expired.push_back(fd);
                }
            }
        }

        for (size_t i = 0; i < expired.size(); ++i) {
            triggerCallback(expired[i]);
        }
    }

    // 退出前清理剩余 fence
    std::lock_guard<std::mutex> lock(map_mutex_);
    for (auto& kv : fd_callbacks_) {
        close(kv.first);
    }
    fd_callbacks_.clear();
}

线程安全说明

同步机制

  • 监控操作: 使用 std::mutex 保护 fd_callbacks_
  • 原子操作: std::atomic<bool> 保护运行标志
  • epoll: 使用 epoll 实现事件驱动

线程安全建议

  • 可以并发调用 watchFence()
  • 可以并发调用 shutdown()
  • 回调在事件循环线程中调用

典型使用场景

场景 1: 基本监控

auto& watcher = FenceWatcher::instance();

// 监控 Fence
watcher.watchFence(fence_fd, []() {
    printf("Fence signaled or timeout\n");
});

场景 2: DRM 显示同步

auto& watcher = FenceWatcher::instance();

// 提交 DRM 带有 Fence
int fence_fd;
compositor->commit(fence_fd);

// 监控 Fence
watcher.watchFence(fence_fd, [layer]() {
    printf("Display completed\n");
    layer->onFenceSignaled();
});

场景 3: RGA 处理同步

auto& watcher = FenceWatcher::instance();

// 提交 RGA 处理
int fence_fd;
rga_process_with_fence(input_fd, output_fd, &fence_fd);

// 监控 Fence
watcher.watchFence(fence_fd, []() {
    printf("RGA processing completed\n");
});

场景 4: Lambda 捕获

auto& watcher = FenceWatcher::instance();

// 使用 lambda 捕获上下文
FramePtr frame = ...;
watcher.watchFence(fence_fd, [frame]() {
    printf("Frame %lu completed\n", frame->meta.timestamp_ns);
});

场景 5: 应用退出

// 应用退出前关闭监控
auto& watcher = FenceWatcher::instance();
watcher.shutdown();

注意事项

  1. 单例模式: 使用 instance() 获取实例
  2. fd 管理: FenceWatcher 会自动关闭 fence_fd
  3. 回调类型: 回调函数无参数,无法区分是触发还是超时
  4. 默认超时: 默认超时为 1000ms
  5. 线程安全: 所有操作都是线程安全的
  6. shutdown: 应用退出前应调用 shutdown()
  7. epoll: 使用 epoll 实现事件驱动
  8. Linux 专用: 仅支持 Linux 系统

相关文档


参考资料

⚠️ **GitHub.com Fallback** ⚠️