Merged
docs/design/event: 参照task模块重构图表风格和内容结构 #2798
ykl999Add on Jun 13
docs/design/event: 参照task模块重构图表风格和内容结构 #2798
Merged
Total: 1 files changed+203-145
| @@ -28,19 +28,24 @@ | |||
| 28 | } | 28 | } |
| 29 | ``` | 29 | ``` |
| 30 | 30 | ||
| 31 | -- **场景三**:阻塞等待事件 | 31 | +- **场景三**:阻塞等待事件(Host 端阻塞直到 Event 完成,适用于需要同步等待计算结果再继续处理的场景) |
| 32 | ```cpp | 32 | ```cpp |
| 33 | - aclrtSynchronizeEvent(event); // 阻塞等待事件完成 | 33 | + aclrtCreateEventExWithFlag(&event, ACL_EVENT_SYNC); // 创建同步事件 |
| 34 | + aclrtRecordEvent(event, stream); // 在 Stream 上 Record 事件 | ||
| 35 | + // ... Stream 上下发计算任务 ... | ||
| 36 | + aclrtSynchronizeEvent(event); // 阻塞等待事件完成,确保该 Event 之前的所有 Stream 任务已执行完毕 | ||
| 37 | + aclrtDestroyEvent(event); // 销毁事件 | ||
| 34 | ``` | 38 | ``` |
| 35 | 39 | ||
| 36 | - **场景四**:IPC 进程间同步 | 40 | - **场景四**:IPC 进程间同步 |
| 37 | ```cpp | 41 | ```cpp |
| 38 | - // 进程 A:创建 IPC Event 并导出 handle | 42 | + // 进程 A:创建 IPC Event,Record 并导出 handle |
| 39 | aclrtCreateEventWithFlag(&event, ACL_EVENT_IPC); | 43 | aclrtCreateEventWithFlag(&event, ACL_EVENT_IPC); |
| 44 | + aclrtRecordEvent(event, streamA); // 进程 A 在 stream 上 Record 事件 | ||
| 40 | aclrtIpcGetEventHandle(event, &ipcHandle); | 45 | aclrtIpcGetEventHandle(event, &ipcHandle); |
| 41 | // 将 ipcHandle 传递给进程 B(如通过共享内存或 socket) | 46 | // 将 ipcHandle 传递给进程 B(如通过共享内存或 socket) |
| 42 | 47 | ||
| 43 | - // 进程 B:打开 IPC Event | 48 | + // 进程 B:打开 IPC Event 并等待 |
| 44 | aclrtIpcOpenEventHandle(ipcHandle, &remoteEvent); | 49 | aclrtIpcOpenEventHandle(ipcHandle, &remoteEvent); |
| 45 | aclrtStreamWaitEvent(stream, remoteEvent); | 50 | aclrtStreamWaitEvent(stream, remoteEvent); |
| 46 | ``` | 51 | ``` |
| @@ -105,88 +110,74 @@ Event Flag 通过 `aclrtCreateEventWithFlag` 传入,决定 Event 的创建分 | |||
| 105 | 110 | ||
| 106 | ## 3. 架构总览 | 111 | ## 3. 架构总览 |
| 107 | 112 | ||
| 108 | -### 3.1 整体设计思路 | 113 | +**整体设计思路** |
| 114 | +**Event 管理整体分为两部分:** | ||
| 115 | +- **Record/Wait 处理路径**:DavidEvent 的 Record/Wait 入口由 `event_c.cc` 中 `EvtRecord`/`EvtWait` 函数承接,IpcEvent 的 Record/Wait 由 `IpcEventRecordStarsV2`/`IpcEventWaitStarsV2` 承接。不同 Event 类型和 Flag 组合走不同处理分支。 | ||
| 116 | +- **任务下发流程**:配合 API 接口通过 Stream 任务申请、SQE 组装、任务下发等流程完成运行时调度。 | ||
| 109 | 117 | ||
| 110 | -Event 模块采用继承分支设计:Event 基类提供状态管理和同步框架,Stars 架构下由 DavidEvent 子类承载(CntNotifyId 模式 + 两态状态机),IPC 场景下由 IpcEvent 子类承载(P2P 共享内存 + MemWriteValue/MemWaitValue SQE)。DavidEvent 的 Record/Wait 入口由 `event_c.cc` 中 `EvtRecord`/`EvtWait` 函数承接,IpcEvent 的 Record/Wait 由 `IpcEventRecordStarsV2`/`IpcEventWaitStarsV2` 承接。 | 118 | +### 3.1 Event Record/Wait 处理路径架构 |
| 111 | - | ||
| 112 | -### 3.2 架构分层图 | ||
| 113 | 119 | ||
| 114 | ```mermaid | 120 | ```mermaid |
| 115 | -graph TB | ||
| 116 | - subgraph API["接口层"] | ||
| 117 | - aclrtCreateEvent["aclrtCreateEventExWithFlag"] | ||
| 118 | - aclrtRecordEvent["aclrtRecordEvent"] | ||
| 119 | - aclrtStreamWaitEvent["aclrtStreamWaitEvent"] | ||
| 120 | - aclrtIpcGetEventHandle["aclrtIpcGetEventHandle"] | ||
| 121 | - end | ||
| 122 | 121 | ||
| 123 | - subgraph EventBase["Event 基类层"] | 122 | +flowchart TD |
| 124 | - Event["Event<br/>状态管理 + taskId 映射<br/>+ Synchronize"] | 123 | + classDef entryStyle fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1 |
| 125 | - end | 124 | + classDef branchStyle fill:#FFF8E1,stroke:#F57F17,stroke-width:2px,color:#F57F17 |
| 125 | + classDef davidStyle fill:#E8F5E9,stroke:#2E7D32,stroke-width:2px,color:#1B5E20 | ||
| 126 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C | ||
| 126 | 127 | ||
| 127 | - subgraph EventSub["Event 派生层"] | 128 | + A["aclrtRecordEvent / aclrtStreamWaitEvent"]:::entryStyle --> B{"Event 类型"}:::branchStyle |
| 128 | - EventSubClass["Event 子类<br/>CntNotifyId 模式<br/>两态状态机"] | 129 | + B -->|DavidEvent<br/>普通同步/计时| C["EvtRecord / EvtWait<br/>event_c.cc"]:::davidStyle |
| 129 | - IpcEvent["IpcEvent<br/>P2P 共享内存同步"] | 130 | + B -->|IpcEvent<br/>IPC 进程间同步| D["IpcEventRecordStarsV2 / IpcEventWaitStarsV2"]:::ipcStyle |
| 130 | - end | ||
| 131 | 131 | ||
| 132 | - subgraph Entry["Record/Wait 入口层"] | 132 | + C --> C1["AllocEventIdResource<br/>CntNotifyId 分配"]:::davidStyle |
| 133 | - EvtRecord["EvtRecord<br/>Record 入口"] | 133 | + C --> C2["DavidEventRecordTaskInit<br/>DavidEventWaitTaskInit"]:::davidStyle |
| 134 | - EvtWait["EvtWait<br/>Wait 入口"] | 134 | + D --> D1["GetIpcRecordIndex<br/>CAS 锁分配空闲索引"]:::ipcStyle |
| 135 | - IpcRecord["IpcEventRecordStarsV2"] | 135 | + D --> D2["MemWriteValueTaskInit<br/>MemWaitValueTaskInit"]:::ipcStyle |
| 136 | - IpcWait["IpcEventWaitStarsV2"] | ||
| 137 | - end | ||
| 138 | 136 | ||
| 139 | - subgraph Task["任务层"] | ||
| 140 | - RecordTask["EventRecordTask"] | ||
| 141 | - WaitTask["EventWaitTask"] | ||
| 142 | - MemWriteValue["MemWriteValue<br/>IPC Record"] | ||
| 143 | - MemWaitValue["MemWaitValue<br/>IPC Wait"] | ||
| 144 | - end | ||
| 145 | - | ||
| 146 | - subgraph StreamLayer["流层"] | ||
| 147 | - StreamNode["Stream<br/>任务队列管理"] | ||
| 148 | - end | ||
| 149 | - | ||
| 150 | - aclrtCreateEvent --> Event | ||
| 151 | - aclrtRecordEvent --> EvtRecord --> EventSubClass | ||
| 152 | - aclrtStreamWaitEvent --> EvtWait --> EventSubClass | ||
| 153 | - aclrtIpcGetEventHandle --> IpcEvent --> IpcRecord --> MemWriteValue | ||
| 154 | - IpcEvent --> IpcWait --> MemWaitValue | ||
| 155 | - Event --> EventSubClass | ||
| 156 | - Event --> IpcEvent | ||
| 157 | - EventSubClass --> StreamNode | ||
| 158 | - RecordTask --> StreamNode | ||
| 159 | - WaitTask --> StreamNode | ||
| 160 | - MemWriteValue --> StreamNode | ||
| 161 | - MemWaitValue --> StreamNode | ||
| 162 | ``` | 137 | ``` |
| 163 | 138 | ||
| 164 | -### 3.3 核心模块交互图 | 139 | +### 3.2 Event 下发流程交互图 |
| 165 | 140 | ||
| 166 | ```mermaid | 141 | ```mermaid |
| 142 | + | ||
| 167 | sequenceDiagram | 143 | sequenceDiagram |
| 168 | - participant App as 应用程序 | 144 | + autonumber |
| 169 | - participant API as aclrt API | 145 | + participant App as 用户API |
| 170 | - participant EvtEntry as EvtRecord/EvtWait | ||
| 171 | - participant EventSub as Event 子类 | ||
| 172 | participant Stream as Stream | 146 | participant Stream as Stream |
| 147 | + participant EventSub as Event子类 | ||
| 148 | + participant Driver as HAL驱动 | ||
| 173 | participant HW as 硬件 | 149 | participant HW as 硬件 |
| 174 | 150 | ||
| 175 | - App->>API: aclrtRecordEvent(event, stream) | 151 | + rect rgba(245, 237, 244, 0.62) |
| 176 | - API->>EvtEntry: EvtRecord(event, stream) | 152 | + alt Record 下发 |
| 177 | - EvtEntry->>Stream: CheckTaskCanSend + StreamLock | 153 | + App->>Stream: aclrtRecordEvent(event, stream) |
| 178 | - EvtEntry->>EventSub: AllocEventIdResource(CntNotifyId) | 154 | + Stream->>Stream: StreamLock() <br/> 允许单流多线程下发任务 |
| 179 | - EvtEntry->>Stream: AllocTaskInfo + EventRecordTaskInit | 155 | + Stream->>EventSub: AllocEventIdResource(CntNotifyId) <br/> 或 GetIpcRecordIndex(CAS锁) |
| 180 | - EvtEntry->>HW: SendTask | 156 | + Stream->>Stream: AllocTaskInfo + EventRecordTaskInit |
| 181 | - EvtEntry->>Stream: StreamUnLock + SubmitTaskPostProc | 157 | + Stream->>Stream: 组装 SQE |
| 158 | + Stream->>Driver: halSqTaskSend(devId, &sendInfo) | ||
| 159 | + Driver->>HW: SQE 写入执行地址 | ||
| 160 | + Stream->>Stream: StreamUnLock() | ||
| 161 | + Stream->>Stream: SubmitTaskPostProc — 触发回收或唤醒回收线程 | ||
| 162 | + end | ||
| 163 | + end | ||
| 164 | + | ||
| 165 | + rect rgba(227, 242, 253, 0.62) | ||
| 166 | + alt WaitSendCheck 快路径 | ||
| 167 | + App->>Stream: aclrtStreamWaitEvent(stream, event) | ||
| 168 | + Stream->>EventSub: WaitSendCheck() | ||
| 169 | + EventSub-->>Stream: EVT_RECORDED,直接返回 <br/>不下硬件任务 | ||
| 170 | + else Wait 下发慢路径 | ||
| 171 | + App->>Stream: aclrtStreamWaitEvent(stream, event) | ||
| 172 | + Stream->>Stream: StreamLock() | ||
| 173 | + Stream->>Stream: AllocTaskInfo + EventWaitTaskInit | ||
| 174 | + Stream->>Driver: halSqTaskSend(devId, &sendInfo) | ||
| 175 | + Driver->>HW: SQE 写入执行地址 | ||
| 176 | + Stream->>Stream: StreamUnLock() | ||
| 177 | + Stream->>Stream: SubmitTaskPostProc | ||
| 178 | + end | ||
| 179 | + end | ||
| 182 | 180 | ||
| 183 | - App->>API: aclrtStreamWaitEvent(stream, event) | ||
| 184 | - API->>EvtEntry: EvtWait(event, stream) | ||
| 185 | - EvtEntry->>EventSub: WaitSendCheck | ||
| 186 | - EventSub-->>EvtEntry: 已完成,无需下任务 | ||
| 187 | - EvtEntry->>Stream: AllocTaskInfo + EventWaitTaskInit | ||
| 188 | - EvtEntry->>HW: SendTask | ||
| 189 | - EvtEntry->>Stream: StreamUnLock + SubmitTaskPostProc | ||
| 190 | ``` | 181 | ``` |
| 191 | 182 | ||
| 192 | ## 4. 详细设计 | 183 | ## 4. 详细设计 |
| @@ -194,19 +185,27 @@ sequenceDiagram | |||
| 194 | ### 4.1 DavidEvent Record 流程 | 185 | ### 4.1 DavidEvent Record 流程 |
| 195 | 186 | ||
| 196 | ```mermaid | 187 | ```mermaid |
| 188 | + | ||
| 197 | flowchart TD | 189 | flowchart TD |
| 198 | - A[aclrtRecordEvent] --> B[EvtRecord] | 190 | + classDef userStyle fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1 |
| 199 | - B --> C[CheckTaskCanSend<br/>检查流上下文状态] | 191 | + classDef lockStyle fill:#FFF3E0,stroke:#FF9800,stroke-width:2px,color:#E65100 |
| 200 | - C --> D[StreamLock + AllocTaskInfo<br/>分配任务和位置] | 192 | + classDef allocStyle fill:#E8F5E9,stroke:#4CAF50,stroke-width:2px,color:#1B5E20 |
| 201 | - D --> E{isNewMode 或<br/>RT_EVENT_DEFAULT?} | 193 | + classDef decisionStyle fill:#FFF8E1,stroke:#F57F17,stroke-width:2px,color:#F57F17 |
| 202 | - E -->|是| F[AllocEventIdResource<br/>CntNotifyId 分配] | 194 | + classDef successStyle fill:#E0F7FA,stroke:#00838F,stroke-width:2px,color:#004D40 |
| 203 | - E -->|否| G[使用已有 eventId] | 195 | + |
| 204 | - F --> H[DavidEventRecordTaskInit<br/>初始化 Record SQE] | 196 | + A["aclrtRecordEvent"]:::userStyle --> B["EvtRecord"]:::userStyle |
| 197 | + B --> C["CheckTaskCanSend<br/>检查流上下文状态"]:::allocStyle | ||
| 198 | + C --> D["StreamLock + AllocTaskInfo<br/>分配任务和位置"]:::lockStyle | ||
| 199 | + D --> E{"isNewMode 或<br/>RT_EVENT_DEFAULT?"}:::decisionStyle | ||
| 200 | + E -->|是| F["AllocEventIdResource<br/>CntNotifyId 分配"]:::allocStyle | ||
| 201 | + E -->|否| G["使用已有 eventId"]:::allocStyle | ||
| 202 | + F --> H["DavidEventRecordTaskInit<br/>初始化 Record SQE"]:::successStyle | ||
| 205 | G --> H | 203 | G --> H |
| 206 | - H --> I[DavidSendTask<br/>提交到硬件] | 204 | + H --> I["DavidSendTask<br/>提交到硬件"]:::successStyle |
| 207 | - I --> J[StreamUnLock] | 205 | + I --> J["StreamUnLock"]:::lockStyle |
| 208 | - J --> K[SubmitTaskPostProc<br/>回收后处理] | 206 | + J --> K["SubmitTaskPostProc<br/>回收后处理"]:::successStyle |
| 209 | - K --> L[UpdateLatestRecord<br/>status → EVT_NOT_RECORDED] | 207 | + K --> L["UpdateLatestRecord<br/>status → EVT_NOT_RECORDED"]:::successStyle |
| 208 | + | ||
| 210 | ``` | 209 | ``` |
| 211 | 210 | ||
| 212 | **流程步骤说明**: | 211 | **流程步骤说明**: |
| @@ -219,18 +218,27 @@ flowchart TD | |||
| 219 | ### 4.2 DavidEvent Wait 流程 | 218 | ### 4.2 DavidEvent Wait 流程 |
| 220 | 219 | ||
| 221 | ```mermaid | 220 | ```mermaid |
| 221 | + | ||
| 222 | flowchart TD | 222 | flowchart TD |
| 223 | - A[aclrtStreamWaitEvent] --> B[EvtWait] | 223 | + classDef userStyle fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1 |
| 224 | - B --> C[WaitSendCheck<br/>检查是否需要下硬件任务] | 224 | + classDef lockStyle fill:#FFF3E0,stroke:#FF9800,stroke-width:2px,color:#E65100 |
| 225 | - C --> D{status == EVT_RECORDED<br/>且无 Reset?} | 225 | + classDef allocStyle fill:#E8F5E9,stroke:#4CAF50,stroke-width:2px,color:#1B5E20 |
| 226 | - D -->|是| E[直接返回成功<br/>不下硬件任务] | 226 | + classDef decisionStyle fill:#FFF8E1,stroke:#F57F17,stroke-width:2px,color:#F57F17 |
| 227 | - D -->|否| F{未 Record 且<br/>非 EXTERNAL/DDSYNC_NS?} | 227 | + classDef errorStyle fill:#FFEBEE,stroke:#D32F2F,stroke-width:2px,color:#B71C1C |
| 228 | - F -->|是| G[返回错误<br/>不能 Wait 未 Record 的 Event] | 228 | + classDef successStyle fill:#E0F7FA,stroke:#00838F,stroke-width:2px,color:#004D40 |
| 229 | - F -->|否| H[CheckTaskCanSend] | 229 | + |
| 230 | - H --> I[StreamLock + AllocTaskInfo] | 230 | + A["aclrtStreamWaitEvent"]:::userStyle --> B["EvtWait"]:::userStyle |
| 231 | - I --> J[DavidEventWaitTaskInit<br/>初始化 Wait SQE] | 231 | + B --> C["WaitSendCheck<br/>检查是否需要下硬件任务"]:::allocStyle |
| 232 | - J --> K[DavidSendTask<br/>提交到硬件] | 232 | + C --> D{"status == EVT_RECORDED<br/>且无 Reset?"}:::decisionStyle |
| 233 | - K --> L[StreamUnLock + SubmitTaskPostProc] | 233 | + D -->|是| E["直接返回成功<br/>不下硬件任务"]:::successStyle |
| 234 | + D -->|否| F{"未 Record 且<br/>非 EXTERNAL/DDSYNC_NS?"}:::decisionStyle | ||
| 235 | + F -->|是| G["返回错误<br/>不能 Wait 未 Record 的 Event"]:::errorStyle | ||
| 236 | + F -->|否| H["CheckTaskCanSend"]:::allocStyle | ||
| 237 | + H --> I["StreamLock + AllocTaskInfo"]:::lockStyle | ||
| 238 | + I --> J["DavidEventWaitTaskInit<br/>初始化 Wait SQE"]:::successStyle | ||
| 239 | + J --> K["DavidSendTask<br/>提交到硬件"]:::successStyle | ||
| 240 | + K --> L["StreamUnLock + SubmitTaskPostProc"]:::lockStyle | ||
| 241 | + | ||
| 234 | ``` | 242 | ``` |
| 235 | 243 | ||
| 236 | **流程步骤说明**: | 244 | **流程步骤说明**: |
| @@ -242,15 +250,22 @@ flowchart TD | |||
| 242 | ### 4.3 IPC Event Record 流程(StarsV2) | 250 | ### 4.3 IPC Event Record 流程(StarsV2) |
| 243 | 251 | ||
| 244 | ```mermaid | 252 | ```mermaid |
| 253 | + | ||
| 245 | flowchart TD | 254 | flowchart TD |
| 246 | - A[IPC Record] --> B[IpcEventRecordStarsV2] | 255 | + classDef userStyle fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1 |
| 247 | - B --> C[CheckTaskCanSend] | 256 | + classDef lockStyle fill:#FFF3E0,stroke:#FF9800,stroke-width:2px,color:#E65100 |
| 248 | - C --> D[StreamLock + AllocTaskInfo] | 257 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C |
| 249 | - D --> E[GetIpcRecordIndex<br/>CAS 锁分配空闲索引] | 258 | + classDef successStyle fill:#E0F7FA,stroke:#00838F,stroke-width:2px,color:#004D40 |
| 250 | - E --> F[MemWriteValueTaskInit<br/>写入地址 = currentDeviceMem_ + curIndex<br/>写入值 = 1] | 259 | + |
| 251 | - F --> G[DavidSendTask<br/>提交硬件写入] | 260 | + A["IPC Record"]:::userStyle --> B["IpcEventRecordStarsV2"]:::ipcStyle |
| 252 | - G --> H[StreamUnLock + SubmitTaskPostProc] | 261 | + B --> C["CheckTaskCanSend"]:::ipcStyle |
| 253 | - H --> I[eventStatus → INIT] | 262 | + C --> D["StreamLock + AllocTaskInfo"]:::lockStyle |
| 263 | + D --> E["GetIpcRecordIndex<br/>CAS 锁分配空闲索引"]:::ipcStyle | ||
| 264 | + E --> F["MemWriteValueTaskInit<br/>写入地址 = currentDeviceMem_ + curIndex<br/>写入值 = 1"]:::ipcStyle | ||
| 265 | + F --> G["DavidSendTask<br/>提交硬件写入"]:::successStyle | ||
| 266 | + G --> H["StreamUnLock + SubmitTaskPostProc"]:::lockStyle | ||
| 267 | + H --> I["eventStatus → INIT"]:::successStyle | ||
| 268 | + | ||
| 254 | ``` | 269 | ``` |
| 255 | 270 | ||
| 256 | **流程步骤说明**: | 271 | **流程步骤说明**: |
| @@ -262,17 +277,25 @@ flowchart TD | |||
| 262 | ### 4.4 IPC Event Wait 流程(StarsV2) | 277 | ### 4.4 IPC Event Wait 流程(StarsV2) |
| 263 | 278 | ||
| 264 | ```mermaid | 279 | ```mermaid |
| 280 | + | ||
| 265 | flowchart TD | 281 | flowchart TD |
| 266 | - A[IPC Wait] --> B[IpcEventWaitStarsV2] | 282 | + classDef userStyle fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1 |
| 267 | - B --> C[IpcVaLock<br/>检查 currentIndex 的 deviceMemRef] | 283 | + classDef lockStyle fill:#FFF3E0,stroke:#FF9800,stroke-width:2px,color:#E65100 |
| 268 | - C --> D{deviceMemRef == 0?} | 284 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C |
| 269 | - D -->|是| E[已完成或未记录<br/>直接返回成功] | 285 | + classDef decisionStyle fill:#FFF8E1,stroke:#F57F17,stroke-width:2px,color:#F57F17 |
| 270 | - D -->|否| F[deviceMemRef++<br/>IpcEventCountAdd] | 286 | + classDef successStyle fill:#E0F7FA,stroke:#00838F,stroke-width:2px,color:#004D40 |
| 271 | - F --> G[IpcVaUnLock] | 287 | + |
| 272 | - G --> H[StreamLock + AllocTaskInfo] | 288 | + A["IPC Wait"]:::userStyle --> B["IpcEventWaitStarsV2"]:::ipcStyle |
| 273 | - H --> I[MemWaitValueTaskInit<br/>等待地址 = currentDeviceMem_ + curIndex<br/>等待值 ≠ 0] | 289 | + B --> C["IpcVaLock<br/>检查 currentIndex 的 deviceMemRef"]:::lockStyle |
| 274 | - I --> J[DavidSendTask<br/>提交硬件等待] | 290 | + C --> D{"deviceMemRef == 0?"}:::decisionStyle |
| 275 | - J --> K[StreamUnLock + SubmitTaskPostProc] | 291 | + D -->|是| E["已完成或未记录<br/>直接返回成功"]:::successStyle |
| 292 | + D -->|否| F["deviceMemRef++<br/>IpcEventCountAdd"]:::ipcStyle | ||
| 293 | + F --> G["IpcVaUnLock"]:::lockStyle | ||
| 294 | + G --> H["StreamLock + AllocTaskInfo"]:::lockStyle | ||
| 295 | + H --> I["MemWaitValueTaskInit<br/>等待地址 = currentDeviceMem_ + curIndex<br/>等待值 ≠ 0"]:::ipcStyle | ||
| 296 | + I --> J["DavidSendTask<br/>提交硬件等待"]:::successStyle | ||
| 297 | + J --> K["StreamUnLock + SubmitTaskPostProc"]:::lockStyle | ||
| 298 | + | ||
| 276 | ``` | 299 | ``` |
| 277 | 300 | ||
| 278 | **流程步骤说明**: | 301 | **流程步骤说明**: |
| @@ -318,36 +341,46 @@ CntNotifyId 由 DavidStream 管理: | |||
| 318 | **Setup 流程(创建端)**: | 341 | **Setup 流程(创建端)**: |
| 319 | 342 | ||
| 320 | ```mermaid | 343 | ```mermaid |
| 344 | + | ||
| 321 | flowchart TD | 345 | flowchart TD |
| 322 | - A[IpcEvent::Setup] --> B[GetAllocationGranularity] | 346 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C |
| 323 | - B --> C[IpcVaAndPaOperation<br/>P2P 内存映射] | 347 | + classDef memStyle fill:#E0F7FA,stroke:#00838F,stroke-width:2px,color:#004D40 |
| 324 | - C --> C1[ReserveMemAddress] | 348 | + |
| 325 | - C1 --> C2[MallocPhysical] | 349 | + A["IpcEvent::Setup"]:::ipcStyle --> B["GetAllocationGranularity"]:::ipcStyle |
| 326 | - C2 --> C3[MapMem] | 350 | + B --> C["IpcVaAndPaOperation<br/>P2P 内存映射"]:::ipcStyle |
| 327 | - C3 --> C4[ExportToShareableHandle<br/>导出共享 handle] | 351 | + C --> C1["ReserveMemAddress"]:::memStyle |
| 328 | - C4 --> C5[MemSetAccess<br/>设置 P2P 访问权限] | 352 | + C1 --> C2["MallocPhysical"]:::memStyle |
| 329 | - B --> D[IpcHandleAllocAndExport<br/>IPC Handle 映射] | 353 | + C2 --> C3["MapMem"]:::memStyle |
| 330 | - D --> D1[ReserveMemAddress] | 354 | + C3 --> C4["ExportToShareableHandle<br/>导出共享 handle"]:::memStyle |
| 331 | - D1 --> D2[MallocPhysical] | 355 | + C4 --> C5["MemSetAccess<br/>设置 P2P 访问权限"]:::memStyle |
| 332 | - D2 --> D3[MapMem] | 356 | + B --> D["IpcHandleAllocAndExport<br/>IPC Handle 映射"]:::ipcStyle |
| 333 | - D3 --> D4[ExportToShareableHandle<br/>导出 IPC handle 给远端] | 357 | + D --> D1["ReserveMemAddress"]:::memStyle |
| 334 | - D4 --> D5[IpcVaLockInit<br/>初始化 CAS 锁] | 358 | + D1 --> D2["MallocPhysical"]:::memStyle |
| 359 | + D2 --> D3["MapMem"]:::memStyle | ||
| 360 | + D3 --> D4["ExportToShareableHandle<br/>导出 IPC handle 给远端"]:::memStyle | ||
| 361 | + D4 --> D5["IpcVaLockInit<br/>初始化 CAS 锁"]:::memStyle | ||
| 362 | + | ||
| 335 | ``` | 363 | ``` |
| 336 | 364 | ||
| 337 | **Open 流程(远端进程)**: | 365 | **Open 流程(远端进程)**: |
| 338 | 366 | ||
| 339 | ```mermaid | 367 | ```mermaid |
| 368 | + | ||
| 340 | flowchart TD | 369 | flowchart TD |
| 341 | - A[aclrtIpcOpenEventHandle] --> B[IpcOpenEventHandle] | 370 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C |
| 342 | - B --> C[IpcHandleAllocAndImport<br/>导入 IPC Handle] | 371 | + classDef memStyle fill:#E0F7FA,stroke:#00838F,stroke-width:2px,color:#004D40 |
| 343 | - C --> C1[ReserveMemAddress] | 372 | + |
| 344 | - C1 --> C2[ImportFromShareableHandle<br/>从 handle 导入物理内存] | 373 | + A["aclrtIpcOpenEventHandle"]:::ipcStyle --> B["IpcOpenEventHandle"]:::ipcStyle |
| 345 | - C2 --> C3[MapMem] | 374 | + B --> C["IpcHandleAllocAndImport<br/>导入 IPC Handle"]:::ipcStyle |
| 346 | - B --> D[EnableP2PForIpc<br/>建立 P2P 通道] | 375 | + C --> C1["ReserveMemAddress"]:::memStyle |
| 347 | - D --> E[IpcMemHandleImport<br/>Host 端导入] | 376 | + C1 --> C2["ImportFromShareableHandle<br/>从 handle 导入物理内存"]:::memStyle |
| 348 | - E --> E1[ReserveMemAddress + Import + Map] | 377 | + C2 --> C3["MapMem"]:::memStyle |
| 349 | - B --> F[IpcMemHandleImport<br/>Device 端导入] | 378 | + B --> D["EnableP2PForIpc<br/>建立 P2P 通道"]:::ipcStyle |
| 350 | - F --> F1[ReserveMemAddress + Import + Map] | 379 | + D --> E["IpcMemHandleImport<br/>Host 端导入"]:::ipcStyle |
| 380 | + E --> E1["ReserveMemAddress + Import + Map"]:::memStyle | ||
| 381 | + B --> F["IpcMemHandleImport<br/>Device 端导入"]:::ipcStyle | ||
| 382 | + F --> F1["ReserveMemAddress + Import + Map"]:::memStyle | ||
| 383 | + | ||
| 351 | ``` | 384 | ``` |
| 352 | 385 | ||
| 353 | - **创建端**:分配 P2P 共享内存 + IPC Handle,导出两个 shareable handle(deviceMemHandle + ipcHandle) | 386 | - **创建端**:分配 P2P 共享内存 + IPC Handle,导出两个 shareable handle(deviceMemHandle + ipcHandle) |
| @@ -368,9 +401,17 @@ flowchart TD | |||
| 368 | 401 | ||
| 369 | ### 4.7 核心数据结构 | 402 | ### 4.7 核心数据结构 |
| 370 | 403 | ||
| 404 | +#### 4.7.1 Event 继承体系类图 | ||
| 405 | + | ||
| 371 | ```mermaid | 406 | ```mermaid |
| 407 | + | ||
| 372 | classDiagram | 408 | classDiagram |
| 373 | - class Event { | 409 | + classDef baseStyle fill:#E3F2FD,stroke:#1565C0,stroke-width:2px,color:#0D47A1 |
| 410 | + classDef eventStyle fill:#E8F5E9,stroke:#2E7D32,stroke-width:2px,color:#1B5E20 | ||
| 411 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C | ||
| 412 | + classDef streamStyle fill:#FFF3E0,stroke:#FF9800,stroke-width:2px,color:#E65100 | ||
| 413 | + | ||
| 414 | + class Event:::baseStyle { | ||
| 374 | <<base>> | 415 | <<base>> |
| 375 | -Device* device_ | 416 | -Device* device_ |
| 376 | -int32_t eventId_ | 417 | -int32_t eventId_ |
| @@ -386,7 +427,7 @@ classDiagram | |||
| 386 | +Query() rtError_t | 427 | +Query() rtError_t |
| 387 | } | 428 | } |
| 388 | 429 | ||
| 389 | - class DavidEvent { | 430 | + class DavidEvent:::eventStyle { |
| 390 | -bool isCntNotify_ | 431 | -bool isCntNotify_ |
| 391 | -uint32_t cntValue_ | 432 | -uint32_t cntValue_ |
| 392 | -DavidEventState_t status_ | 433 | -DavidEventState_t status_ |
| @@ -399,7 +440,7 @@ classDiagram | |||
| 399 | +ClearRecordStatus() rtError_t | 440 | +ClearRecordStatus() rtError_t |
| 400 | } | 441 | } |
| 401 | 442 | ||
| 402 | - class IpcEvent { | 443 | + class IpcEvent:::ipcStyle { |
| 403 | -IpcHandleVa* ipcHandleVa_ | 444 | -IpcHandleVa* ipcHandleVa_ |
| 404 | -void* currentDeviceMem_ | 445 | -void* currentDeviceMem_ |
| 405 | -void* currentHostMem_ | 446 | -void* currentHostMem_ |
| @@ -415,14 +456,7 @@ classDiagram | |||
| 415 | +IpcEventWaitStarsV2(stm) rtError_t | 456 | +IpcEventWaitStarsV2(stm) rtError_t |
| 416 | } | 457 | } |
| 417 | 458 | ||
| 418 | - class IpcHandleVa { | 459 | + class DavidStream:::streamStyle { |
| 419 | - +uint64_t volatile lockStatus | ||
| 420 | - +void* deviceMemHandle | ||
| 421 | - +uint64_t deviceMemRef[IPC_EVENT_P2P_SIZE] | ||
| 422 | - +uint16_t currentIndex | ||
| 423 | - } | ||
| 424 | - | ||
| 425 | - class DavidStream { | ||
| 426 | -uint32_t cntNotifyId_ | 460 | -uint32_t cntNotifyId_ |
| 427 | -mutex cntNotifyInfoLock_ | 461 | -mutex cntNotifyInfoLock_ |
| 428 | +ApplyCntNotifyId(newEventId) rtError_t | 462 | +ApplyCntNotifyId(newEventId) rtError_t |
| @@ -432,8 +466,32 @@ classDiagram | |||
| 432 | 466 | ||
| 433 | Event <|-- DavidEvent | 467 | Event <|-- DavidEvent |
| 434 | Event <|-- IpcEvent | 468 | Event <|-- IpcEvent |
| 435 | - IpcEvent *-- IpcHandleVa | ||
| 436 | DavidEvent --> DavidStream | 469 | DavidEvent --> DavidStream |
| 470 | + | ||
| 471 | +``` | ||
| 472 | + | ||
| 473 | +#### 4.7.2 IpcHandleVa 数据结构类图 | ||
| 474 | + | ||
| 475 | +```mermaid | ||
| 476 | + | ||
| 477 | +classDiagram | ||
| 478 | + classDef ipcStyle fill:#F3E5F5,stroke:#7B1FA2,stroke-width:2px,color:#4A148C | ||
| 479 | + classDef dataStyle fill:#E0F2F1,stroke:#00695C,stroke-width:2px,color:#004D40 | ||
| 480 | + | ||
| 481 | + class IpcEvent:::ipcStyle { | ||
| 482 | + -IpcHandleVa* ipcHandleVa_ | ||
| 483 | + -void* currentDeviceMem_ | ||
| 484 | + } | ||
| 485 | + | ||
| 486 | + class IpcHandleVa:::dataStyle { | ||
| 487 | + +uint64_t volatile lockStatus | ||
| 488 | + +void* deviceMemHandle | ||
| 489 | + +uint64_t deviceMemRef[IPC_EVENT_P2P_SIZE] | ||
| 490 | + +uint16_t currentIndex | ||
| 491 | + } | ||
| 492 | + | ||
| 493 | + IpcEvent *-- IpcHandleVa | ||
| 494 | + | ||
| 437 | ``` | 495 | ``` |
| 438 | 496 | ||
| 439 | ## 5. 关键文件索引 | 497 | ## 5. 关键文件索引 |