当前位置: 首页 > ds >正文

window 显示驱动开发-线程和同步级别为零级

在零级线程处理和同步中,WDDM 允许以可重入的方式对显示微型端口驱动程序进行零级 DxgkDdi*Xxx 调用。 也就是说,多个线程可以通过调用零级 DDI 同时进入驱动程序。

驱动程序应预期系统中的任何线程会传入,并应相应地保护该线程的数据。

尽管驱动程序中可以同时运行两个或多个线程,但不能有两个线程属于单个进程。

级别零是默认的线程和同步级别,包括以下函数:

  • DxgkDdiCheckMultiPlaneOverlaySupport3 (或 DxgkDdiCheckMultiPlaneOverlaySupport2/DxgkDdiCheckMultiPlaneOverlaySupport)
  • DxgkDdiCloseAllocation
  • DxgkDdiCollectDbgInfo。 此函数应收集各种故障的调试信息,并且可以随时在高 IRQL (调用,也就是说, DxgkDdiCollectDbgInfo 运行所在的 IRQL 通常) 未定义。 在所有情况下, DxgkDdiCollectDbgInfo 都必须验证所需调试信息和正确同步的可用性。 但是,如果 pCollectDbgInfo 参数指向的 DXGKARG_COLLECTDBGINFO 结构的 Reason 成员设置为 VIDEO_TDR_TIMEOUT_DETECTED 或 VIDEO_ENGINE_TIMEOUT_DETECTED,则驱动程序必须确保 DxgkDdiCollectDbgInfo 可分页、在 IRQL = PASSIVE_LEVEL 运行并支持零级同步。
  • DxgkDdiControlEtwLogging
  • DxgkDdiCreateAllocation
  • DxgkDdiCreateContext
  • DxgkDdiCreateDevice
  • DxgkDdiDescribeAllocation
  • DxgkDdiDestroyAllocation
  • DxgkDdiDestroyContext
  • DxgkDdiDestroyDevice
  • DxgkDdiDpcRoutine
  • DxgkDdiEnumVidPnCofuncModality
  • DxgkDdiGetScanLine
  • DxgkDdiGetStandardAllocationDriverData
  • DxgkDdiInterruptRoutine
  • DxgkDdiIsSupportedVidPn
  • DxgkDdiMiracastCreateContext
  • DxgkDdiMiracastDestroyContext
  • DxgkDdiMiracastIoControl
  • DxgkDdiMiracastQueryCaps
  • DxgkDdiOpenAllocation
  • DxgkDdiPresent
  • DxgkDdiQueryAdapterInfo
  • DxgkDdiQueryCurrentFence
  • DxgkDdiRecommendFunctionalVidPn
  • DxgkDdiRecommendVidPnTopology
  • DxgkDdiRender
  • DxgkDdiRenderKm
  • DxgkDdiResetDevice

1. 零级同步的核心特性

(1) 可重入性(Reentrancy)

  • 多个线程可同时调用零级 DDI 函数,但 同一进程的两个线程不能同时进入驱动程序(跨进程允许并发)。
  • 驱动程序必须 自行保护共享数据(如全局状态、硬件寄存器等),避免竞争条件。

(2) 默认同步级别

  • 零级是 默认级别,适用于大多数常规 DDI 调用。
  • 相比 Level 1/2/3,零级同步限制最少,但要求驱动程序 自行管理线程安全。

(3) IRQL 限制

  • 大多数零级函数可以在 任意 IRQL(中断请求级别)运行,但某些特殊情况(如 DxgkDdiCollectDbgInfo 处理超时)必须在 PASSIVE_LEVEL(低 IRQL)执行。

2. 零级包含的主要函数

以下是常见的零级 DDI 函数: 

函数描述
DxgkDdiCheckMultiPlaneOverlaySupport[2/3]检查硬件是否支持多平面覆盖(MPO)
DxgkDdiCloseAllocation关闭分配的资源(如显存)
DxgkDdiCollectDbgInfo调试信息收集(关键函数,见下文)

3. 特殊函数:DxgkDdiCollectDbgInfo

(1) 一般情况

  • 可以在 任意 IRQL 调用(包括 DISPATCH_LEVEL 或更高)。
  • 必须验证数据可用性(如内存是否可分页)。
  • 必须同步访问共享资源(如日志缓冲区)。

(2) 超时检测(TDR/Engine Timeout)
当 DXGKARG_COLLECTDBGINFO.Reason 为以下值时:

  • VIDEO_TDR_TIMEOUT_DETECTED(GPU 超时)
  • VIDEO_ENGINE_TIMEOUT_DETECTED(引擎超时)

驱动必须:

  • 在 PASSIVE_LEVEL(低 IRQL)运行(可分页代码)。
  • 支持零级同步(允许多线程进入)。
  • 避免死锁(不能持有自旋锁等不可睡眠的锁)。

4. 线程安全实现建议

由于零级允许可重入调用,驱动程序必须:

使用适当的同步机制:

  • 自旋锁(Spin Lock):适用于高 IRQL(如 DISPATCH_LEVEL)。
  • 互斥体(Mutex):适用于 PASSIVE_LEVEL(可分页代码)。
  • 原子操作(Atomic Operations):适用于简单状态更新(如引用计数)。

避免全局状态污染:

  • 使用 线程局部存储(TLS) 或 上下文结构体 隔离不同线程的数据。

5. 典型应用场景

多线程资源管理:

  • 线程A调用 DxgkDdiCloseAllocation 释放资源,同时线程B调用 DxgkDdiCheckMultiPlaneOverlaySupport3 检查 MPO 支持。

调试信息收集:

  • 系统在 GPU 超时(TDR)时调用 DxgkDdiCollectDbgInfo,同时其他线程可能仍在提交命令。

6. 总结

特性零级(Level 0)一级(Level 1)二级(Level 2)三级(Level 3)
可重入性✅ 允许(跨进程)❌ 类内禁止❌ 单线程❌ 单线程
默认级别✅ 是❌ 否❌ 否❌ 否
IRQL 限制大多数任意 IRQL通常 PASSIVE_LEVEL硬件空闲时硬件空闲时
同步要求驱动自行管理类内互斥WDDM 保证单线程WDDM 保证单线程

 零级同步适用于大多数常规操作,但驱动程序必须自行处理线程安全!

http://www.xdnf.cn/news/4361.html

相关文章:

  • Git仓库基本操作
  • Spark 的 Shuffle 机制:原理与源码详解
  • 内网im软件,支持企业云盘的协同办公软件推荐
  • 【ES】Elasticsearch字段映射冲突问题分析与解决
  • JAVA设计模式——(十二)原型模式(Prototype Pattern)
  • [ linux-系统 ] 常见指令2
  • 二、Hadoop狭义和广义的理解
  • STM32教程:串口USART通讯协议原理及分析(基于STM32F103C8T6最小系统板标准库开发)*详细教程*
  • AI Agent 入门指南:从 LLM 到智能体
  • 【能力比对】数据质量管理VS数据质量平台
  • python打卡day17
  • 并发设计模式实战系列(16):屏障(Barrier)
  • BIO(Blocking I/O)、NIO(Non-blocking I/O)和 AIO(Asynchronous I/O)
  • Super-vlan
  • 【上位机——MFC】绘图
  • 智能车载台如何成为工业4.0的智慧中枢?解码AORO V80技术革新
  • 某团小程序mtgsig,_token 生成逻辑分析
  • 音视频之H.265/HEVC编解码并处理
  • AUTOSAR图解==>AUTOSAR_SRS_EEPROMDriver
  • Kotlin-解构声明
  • Webpack 5 Module Federation 深度解析
  • 【网络编程】一、socket编程详解
  • 中达瑞和便携式高光谱相机:珠宝鉴定领域的“光谱之眼”
  • Python企业级MySQL数据库开发实战指南
  • Unity 游戏数量单位换算(K/M/B/T)
  • Transformer 与 LSTM 在时序回归中的实践与优化
  • Apache Doris 使用指南:从入门到生产实践
  • SpringCloud入门教程合集(1)-SpringCloud简介与Eureka+Feign实现服务注册中心、服务提供与服务消费
  • LightGBM算法原理及Python实现
  • AWS WebRTC如何实现拉流?内部是这样实现的