最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Linux?libdrm中drm_syncobj的實現(xiàn)原理

 更新時間:2025年09月19日 09:41:51   作者:DeeplyMind  
本文分析libdrm中drm_syncobj的API實現(xiàn),涵蓋創(chuàng)建銷毀、跨進(jìn)程同步、信號重置及時間線操作,支持多階段異步任務(wù)同步,適用于DMA與GPU渲染等復(fù)雜場景,提升同步靈活性與效率

1. 前言

在博文:Linux drm_syncobj 機制原理與應(yīng)用中介紹了內(nèi)核drm_syncobj機制的相關(guān)原理,本篇是用戶態(tài)libdrm中的syncobj的API實現(xiàn)分析。

syncobj 的設(shè)計初衷是為用戶空間提供一種高效、靈活的 GPU 任務(wù)同步原語。

它具備如下特點:

  • 對象化管理:同步狀態(tài)以對象(syncobj)形式存在,用戶空間可通過句柄引用和操作。
  • 多次信號/等待:支持多次信號和等待,適合異步和多階段任務(wù)。
  • 跨進(jìn)程同步:支持同步對象的導(dǎo)入/導(dǎo)出,實現(xiàn)進(jìn)程間同步。
  • timeline 擴展:部分驅(qū)動支持 timeline syncobj,可表示多個時間點的同步狀態(tài)。

傳統(tǒng) fence 僅能表示單次同步事件,且生命周期受限。而 syncobj 支持多次信號/等待,且可導(dǎo)入/導(dǎo)出,適合復(fù)雜的同步場景。timeline syncobj 更是將同步擴展到多時間點,極大提升了靈活性。

2. syncobj 相關(guān) IOCTLs概覽與典型流程

syncobj 的所有操作都通過 ioctl 與內(nèi)核 DRM 驅(qū)動交互。

和內(nèi)核實現(xiàn)一文中的維度劃分保持一致,把ioctl劃分如下。

維度IOCTL 名稱功能描述
創(chuàng)建與銷毀DRM_IOCTL_SYNCOBJ_CREATE創(chuàng)建同步對象,分配資源并返回句柄
DRM_IOCTL_SYNCOBJ_DESTROY銷毀同步對象,釋放資源
導(dǎo)入與導(dǎo)出DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD將同步對象句柄導(dǎo)出為文件描述符,實現(xiàn)跨進(jìn)程同步
DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE從文件描述符導(dǎo)入同步對象句柄,實現(xiàn)跨進(jìn)程同步
信號與重置DRM_IOCTL_SYNCOBJ_SIGNAL將同步對象設(shè)為已完成(signaled)狀態(tài)
DRM_IOCTL_SYNCOBJ_RESET將同步對象設(shè)為未完成(unsignaled)狀態(tài)
時間線操作DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL對 timeline syncobj 的指定時間點進(jìn)行信號
DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT等待 timeline syncobj 的指定時間點完成
DRM_IOCTL_SYNCOBJ_TIMELINE_QUERY查詢 timeline syncobj 當(dāng)前時間點狀態(tài)
等待與事件通知DRM_IOCTL_SYNCOBJ_WAIT等待同步對象變?yōu)橐淹瓿蔂顟B(tài),支持阻塞/非阻塞及超時
DRM_IOCTL_SYNCOBJ_QUERY查詢同步對象的當(dāng)前狀態(tài)

典型流程:

  • 創(chuàng)建 syncobj:通過 drmSyncobjCreate 創(chuàng)建同步對象,獲得句柄。將該句柄隨任務(wù)傳遞給內(nèi)核驅(qū)動。
  • 導(dǎo)入/導(dǎo)出:如需跨進(jìn)程同步,通過 drmSyncobjHandleToFd 和 drmSyncobjFdToHandle 實現(xiàn)句柄與 fd 的轉(zhuǎn)換。
  • 信號/重置:根據(jù)任務(wù)完成情況,調(diào)用 drmSyncobjSignal 或 drmSyncobjReset 設(shè)置同步對象狀態(tài)。
  • timeline 操作:如需多時間點同步,使用 timeline 相關(guān) API 進(jìn)行信號、等待和查詢。
  • 等待/通知:通過 drmSyncobjWait 或 drmSyncobjTimelineWait 等待任務(wù)完成(任務(wù)完成后,會signal該任務(wù)關(guān)聯(lián)的步驟1的同步對象),驅(qū)動后續(xù)處理。
  • 銷毀:任務(wù)完成后,調(diào)用 drmSyncobjDestroy 釋放資源。

3. 創(chuàng)建與銷毀

3.1 創(chuàng)建同步對象

3.1.1 DRM_IOCTL_SYNCOBJ_CREATE

該 ioctl 用于在內(nèi)核中分配一個同步對象,并返回其句柄。

用戶空間通過 libdrm 的 drmSyncobjCreate API 調(diào)用。

  • 支持普通 syncobj 和 timeline syncobj 創(chuàng)建
  • 句柄在用戶空間唯一標(biāo)識同步對象
  • 可指定初始狀態(tài)(已信號/未信號)
drm_public int drmSyncobjCreate(int fd, uint32_t flags, uint32_t *handle)
{
    struct drm_syncobj_create args;
    int ret;

    memclear(args);
    args.flags = flags;
    args.handle = 0;
    ret = drmIoctl(fd, DRM_IOCTL_SYNCOBJ_CREATE, &args);
    if (ret)
        return ret;
    *handle = args.handle;
    return 0;
}
  • fd:打開的DRM 設(shè)備文件描述符
  • flags:可選標(biāo)志,如 DRM_SYNCOBJ_CREATE_SIGNALED(初始為已信號狀態(tài))、DRM_SYNCOBJ_CREATE_TIMELINE(創(chuàng)建 timeline syncobj)
  • handle:返回的同步對象句柄

3.2 銷毀同步對象

3.2.1 DRM_IOCTL_SYNCOBJ_DESTROY

該 ioctl 用于釋放同步對象資源。libdrm 封裝為 drmSyncobjDestroy。

drm_public int drmSyncobjDestroy(int fd, uint32_t handle)
{
    struct drm_syncobj_destroy args;

    memclear(args);
    args.handle = handle;
    return drmIoctl(fd, DRM_IOCTL_SYNCOBJ_DESTROY, &args);
}
  • fd:DRM 設(shè)備文件描述符
  • handle:要銷毀的同步對象句柄

后續(xù)的API我不再給出具體實現(xiàn),感興趣的朋友請查看源碼。

4. 導(dǎo)入與導(dǎo)出

4.1 導(dǎo)出同步對象到文件描述符

4.1.1 DRM_IOCTL_SYNCOBJ_HANDLE_TO_FD

該 ioctl 用于將 syncobj 句柄導(dǎo)出為文件描述符,實現(xiàn)跨進(jìn)程同步。

libdrm 封裝為 drmSyncobjHandleToFd。

int drmSyncobjHandleToFd(int fd, uint32_t handle, int *out_fd);

4.2 從文件描述符導(dǎo)入同步對象

4.2.1 DRM_IOCTL_SYNCOBJ_FD_TO_HANDLE

該 ioctl 用于將文件描述符導(dǎo)入為 syncobj 句柄。

libdrm 封裝為 drmSyncobjFdToHandle。

drmSyncobjFdToHandle(fd, syncobj_fd, &imported_handle);

5. 信號與重置

5.1 信號同步對象

5.1.1 DRM_IOCTL_SYNCOBJ_SIGNAL

該 ioctl 用于將同步對象設(shè)為已完成(signaled)狀態(tài)。

libdrm 封裝為 drmSyncobjSignal。

int drmSyncobjSignal(int fd, const uint32_t *handles, uint32_t count);

5.2 重置同步對象

5.2.1 DRM_IOCTL_SYNCOBJ_RESET

該 ioctl 用于將同步對象設(shè)為未完成(unsignaled)狀態(tài)。

libdrm 封裝為 drmSyncobjReset

int drmSyncobjReset(int fd, const uint32_t *handles, uint32_t count);

6. 時間線操作

這個高級用法,我還沒有在項目中用到過,有用例的朋友歡迎分享。

6.1 timeline syncobj 簡介

timeline syncobj 是對傳統(tǒng)同步對象的擴展,允許一個 syncobj 維護(hù)多個時間點(value),每個 value 都可單獨信號和等待。

適用于多幀渲染、批量任務(wù)調(diào)度等復(fù)雜場景。

6.2 timeline 信號

6.2.1 DRM_IOCTL_SYNCOBJ_TIMELINE_SIGNAL

該 ioctl 用于對 timeline syncobj 的指定時間點進(jìn)行信號。

libdrm 封裝為 drmSyncobjTimelineSignal

int drmSyncobjTimelineSignal(int fd, const uint32_t *handles,
                       const uint64_t *points, uint32_t count);
  • fd:DRM 設(shè)備文件描述符
  • handles:syncobj 句柄數(shù)組
  • points:對應(yīng)時間點數(shù)組
  • count:數(shù)量

6.3 timeline 等待

6.3.1 DRM_IOCTL_SYNCOBJ_TIMELINE_WAIT

該 ioctl 用于等待 timeline syncobj 的指定時間點完成。

libdrm 封裝為 drmSyncobjTimelineWait。

int drmSyncobjTimelineWait(int fd, const uint32_t *handles,
                           const uint64_t *points, uint32_t count,
                           uint64_t timeout_nsec, uint32_t flags,
                           uint32_t *first_signaled);
  • fd:DRM 設(shè)備文件描述符
  • handles:syncobj 句柄數(shù)組
  • points:對應(yīng)時間點數(shù)組
  • count:數(shù)量
  • timeout_nsec:超時時間(納秒)
  • flags:等待標(biāo)志
  • first_signaled:返回第一個完成的 syncobj 索引

等待與事件通知

7.1 普通等待

7.1.1 DRM_IOCTL_SYNCOBJ_WAIT

該 ioctl 用于等待普通 syncobj 變?yōu)橐淹瓿蔂顟B(tài)。

libdrm 封裝為 drmSyncobjWait。

  • 支持阻塞和非阻塞等待
  • 可批量等待多個同步對象
int drmSyncobjWait(int fd, const uint32_t *handles, 
                uint32_t count, uint64_t timeout_nsec,
                uint32_t flags, uint32_t *first_signaled);
  • fd:DRM 設(shè)備文件描述符
  • handles:syncobj 句柄數(shù)組
  • count:數(shù)量
  • timeout_nsec:超時時間
  • flags:等待標(biāo)志(如阻塞/非阻塞)
  • first_signaled:返回第一個完成的 syncobj 索引

8. 應(yīng)用示例

應(yīng)用場景:要使用DMA引擎給一個大buffer填充數(shù)據(jù),即buffer填充任務(wù);然后把該buffer交給GPU的渲染任務(wù),渲染任務(wù)要等待填充任務(wù)完成后在進(jìn)行。

填充任務(wù)的執(zhí)行是一個DMA引擎設(shè)備;渲染任務(wù)的執(zhí)行是一個GPU設(shè)備。CPU負(fù)責(zé)給這兩個設(shè)備發(fā)送任務(wù)和數(shù)據(jù)。涉及到跨設(shè)備、跨驅(qū)動的異步操作的同步問題。

該場景的實現(xiàn)代碼如下。

  • 用戶態(tài):
uint32_t dma_syncobj;

//創(chuàng)建drm_syncobj對象,獲取句柄
drmSyncobjCreate(fd, flags, &dma_syncobj);
//將句柄隨transfer任務(wù)傳遞給內(nèi)核
dma_transfer(bo, size, data, dma_syncobj);

//其他準(zhǔn)備工作
.....

//等待transfer的任務(wù)完成,即dma_syncobj同步對象被signal
drmSyncobjWait(fd, &dma_syncobj, 1, ...);

submit_render_jobs(fd, jobs);
  • 內(nèi)核驅(qū)動:
do_dma_transfer(bo, size, data, dma_syncobj)
{
    //使用dma引擎?zhèn)鬏敂?shù)據(jù)到bo
    dma_transfer(bo, size, data);

    //signal dma_syncobj同步對象
    drm_syncobj_replace_fence(syn_obj, signaled_fence);
}

9. 總結(jié)

drm_syncobj 作為 libdrm 用戶空間的同步對象抽象,通過一系列 DRM_IOCTL_SYNCOBJ_* ioctl,為開發(fā)者提供了高效、靈活的 GPU 任務(wù)同步機制。其支持創(chuàng)建與銷毀、導(dǎo)入與導(dǎo)出、信號與重置、時間線操作、等待與事件通知等多種操作,適用于多隊列渲染、跨進(jìn)程同步、異步任務(wù)調(diào)度等多種應(yīng)用場景。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • linux Vim基本操作方法

    linux Vim基本操作方法

    Ubuntu的Vi也不好用,搞了個Vim用來學(xué)習(xí)了,簡單記錄下它的基本操作。還有一本相關(guān)的電子書可下載。
    2013-11-11
  • Linux如何使用HTTP進(jìn)行遠(yuǎn)程系統(tǒng)監(jiān)控

    Linux如何使用HTTP進(jìn)行遠(yuǎn)程系統(tǒng)監(jiān)控

    這篇文章主要介紹了Linux如何使用HTTP進(jìn)行遠(yuǎn)程系統(tǒng)監(jiān)控問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-11-11
  • Linux內(nèi)核啟動流程詳解(基于 5.15.119 源碼)

    Linux內(nèi)核啟動流程詳解(基于 5.15.119 源碼)

    文章詳細(xì)介紹了基于Linux 5.15.119源碼的x86_64架構(gòu)內(nèi)核啟動流程,從GRUB加載bzImage到壓縮內(nèi)核解壓、初始化硬件、切換到保護(hù)模式、64位解壓入口,直至啟動第一個用戶進(jìn)程/sbin/init的全過程,需要的朋友可以參考下
    2026-05-05
  • 詳解從Linux源碼看Socket(TCP)的bind

    詳解從Linux源碼看Socket(TCP)的bind

    本文從Linux源碼的角度看Server端的Socket在進(jìn)行bind的時候到底做了哪些事情(基于Linux 3.10內(nèi)核)
    2021-06-06
  • 嵌入式Linux重啟QT應(yīng)用程序的簡單辦法(基于QT4.8 qws)

    嵌入式Linux重啟QT應(yīng)用程序的簡單辦法(基于QT4.8 qws)

    今天小編就為大家分享一篇關(guān)于嵌入式Linux重啟QT應(yīng)用程序的簡單辦法(基于QT4.8 qws),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2018-12-12
  • linux記錄用戶登錄日志與命令執(zhí)行日志方式

    linux記錄用戶登錄日志與命令執(zhí)行日志方式

    文章介紹了在/etc/profile文件末尾增加代碼并執(zhí)行source使其生效后,不同用戶會在/var/log/history目錄下以用戶名為目錄名的子目錄中,進(jìn)入對應(yīng)目錄后有以用戶登錄時間及IP為名字的文件,文件內(nèi)容為用戶執(zhí)行命令的日志信息
    2024-12-12
  • 在Linux中如何一次重命名多個文件詳解

    在Linux中如何一次重命名多個文件詳解

    這篇文章主要給大家介紹了關(guān)于在Linux中如何一次重命名多個文件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-11-11
  • centOS7安裝jdk1.8的方法

    centOS7安裝jdk1.8的方法

    這篇文章主要介紹了centOS7安裝jdk1.8的方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-07-07
  • Linux系統(tǒng)下利用C程序輸出某進(jìn)程的內(nèi)存占用信息

    Linux系統(tǒng)下利用C程序輸出某進(jìn)程的內(nèi)存占用信息

    這篇文章主要給大家介紹了關(guān)于在Linux系統(tǒng)下利用C程序輸出某進(jìn)程的內(nèi)存占用信息的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友下面來一起看看吧。
    2017-12-12
  • Linux中的安全配置技巧分享

    Linux中的安全配置技巧分享

    這篇文章主要介紹了Linux中的安全配置技巧,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-02-02

最新評論

商南县| 鄂伦春自治旗| 永兴县| 景东| 红桥区| 布拖县| 白河县| 长沙市| 洪湖市| 临颍县| 崇信县| 沙雅县| 通州市| 绥德县| 新乐市| 延安市| 田林县| 斗六市| 射洪县| 共和县| 家居| 古丈县| 云林县| 梨树县| 上犹县| 京山县| 晋城| 繁昌县| 老河口市| 青海省| 巴林左旗| 建宁县| 泗阳县| 泾川县| 勐海县| 岐山县| 富蕴县| 姚安县| 海林市| 文安县| 通化县|