Some tasks to be finished

本文列出了一组Windows编程的学习和实践任务,包括阅读《Programming Windows》理解消息路由和窗口绘制,深入研究MFC框架,实现托盘程序,开发Tetris和Mine等游戏,遵循编码规范,掌握并实现撤销/重做设计模式,学习COM组件对象模型,以及实现类似WMP的绘图功能。
部署运行你感兴趣的模型镜像
Task listing:
    1. Read 《Programming Windows》(manage message routing and windows painting)
    2. Read 《Dissect MFC》(understand the framework completely)
    3. Implement a Windows Tray
    4. Tetris(Game)
    5. Mine(Game)
    6. Coding obey the Coding Spec
    7. Understand Redo/Undo design pattern and implement it with source code
    8. COM
    9. Implement painting function like WMP

您可能感兴趣的与本文相关的镜像

Llama Factory

Llama Factory

模型微调
LLama-Factory

LLaMA Factory 是一个简单易用且高效的大型语言模型(Large Language Model)训练与微调平台。通过 LLaMA Factory,可以在无需编写任何代码的前提下,在本地完成上百种预训练模型的微调

pub fn run_gpu_device(opts: Options) -> anyhow::Result<()> { let Options { x_display, params: mut gpu_parameters, resource_bridge, socket, wayland_sock, } = opts; let channels: BTreeMap<_, _> = wayland_sock.into_iter().collect(); let resource_bridge_listeners = resource_bridge .into_iter() .map(|p| { UnixSeqpacketListener::bind(&p) .map(UnlinkUnixSeqpacketListener) .with_context(|| format!("failed to bind socket at path {}", p)) }) .collect::<anyhow::Result<Vec<_>>>()?; if gpu_parameters.display_params.is_empty() { gpu_parameters .display_params .push(GpuDisplayParameters::default()); } let ex = Executor::new().context("failed to create executor")?; // We don't know the order in which other devices are going to connect to the resource bridges // so start listening for all of them on separate threads. Any devices that connect after the // gpu device starts its queues will not have its resource bridges processed. In practice this // should be fine since the devices that use the resource bridge always try to connect to the // gpu device before handling messages from the VM. let resource_bridges = Arc::new(Mutex::new(Vec::with_capacity( resource_bridge_listeners.len(), ))); for listener in resource_bridge_listeners { let resource_bridges = Arc::clone(&resource_bridges); ex.spawn_blocking(move || match listener.accept() { Ok(stream) => resource_bridges .lock() .push(Tube::new_from_unix_seqpacket(stream).unwrap()), Err(e) => { let path = listener .path() .unwrap_or_else(|_| PathBuf::from("{unknown}")); error!( "Failed to accept resource bridge connection for socket {}: {}", path.display(), e ); } }) .detach(); } // TODO(b/232344535): Read side of the tube is ignored currently. // Complete the implementation by polling `exit_evt_rdtube` and // kill the sibling VM. let (exit_evt_wrtube, _) = Tube::directional_pair().context("failed to create vm event tube")?; let (gpu_control_tube, _) = Tube::pair().context("failed to create gpu control tube")?; let mut display_backends = vec![ virtio::DisplayBackend::X(x_display), virtio::DisplayBackend::Stub, ]; if let Some(p) = channels.get("") { display_backends.insert(0, virtio::DisplayBackend::Wayland(Some(p.to_owned()))); } // These are only used when there is an input device. let event_devices = Vec::new(); let base_features = virtio::base_features(ProtectionType::Unprotected); let listener = VhostUserListener::new_socket(&socket, None)?; let gpu = Rc::new(RefCell::new(Gpu::new( exit_evt_wrtube, gpu_control_tube, Vec::new(), // resource_bridges, handled separately by us display_backends, &gpu_parameters, /* rutabaga_server_descriptor */ None, event_devices, base_features, &channels, /* gpu_cgroup_path */ None, ))); let backend = GpuBackend { ex: ex.clone(), gpu, resource_bridges, state: None, fence_state: Default::default(), queue_workers: Default::default(), platform_workers: Default::default(), shmem_mapper: Arc::new(Mutex::new(None)), }; // Run until the backend is finished. let _ = ex.run_until(listener.run_backend(backend, &ex))?; // Process any tasks from the backend's destructor. Ok(ex.run_until(async {})?) }
07-25
这段 Rust 代码定义了一个名为 `run_gpu_device` 的函数,用于启动一个 GPU 设备的 vhost-user 服务端。它主要负责: - 接受来自 QEMU 的 vhost-user 协议连接; - 设置 GPU 显示后端(如 X11、Wayland); - 启动异步事件循环; - 处理资源桥接(resource bridge)连接; - 初始化 GPU 设备并绑定到 vhost-user 协议处理逻辑。 --- ## 代码详解 ### 函数签名 ```rust pub fn run_gpu_device(opts: Options) -> anyhow::Result<()> ``` - `opts: Options`:包含 GPU 设备的配置参数,如 socket 路径、Wayland socket、X11 显示等。 - 返回值:`anyhow::Result<()>`,表示可能失败的运行结果。 --- ### 解构 `Options` ```rust let Options { x_display, params: mut gpu_parameters, resource_bridge, socket, wayland_sock, } = opts; ``` - `x_display`:X11 显示信息。 - `gpu_parameters`:GPU 设备的参数配置。 - `resource_bridge`:资源桥接 socket 路径。 - `socket`:vhost-user 主 socket 路径。 - `wayland_sock`:Wayland socket 路径。 --- ### 创建 `BTreeMap` 映射 Wayland socket ```rust let channels: BTreeMap<_, _> = wayland_sock.into_iter().collect(); ``` - 用于后续设置 Wayland 显示后端。 --- ### 绑定资源桥接监听器 ```rust let resource_bridge_listeners = resource_bridge .into_iter() .map(|p| { UnixSeqpacketListener::bind(&p) .map(UnlinkUnixSeqpacketListener) .with_context(|| format!("failed to bind socket at path {}", p)) }) .collect::<anyhow::Result<Vec<_>>>()?; ``` - 创建 Unix Seqpacket 监听器,用于 GPU 设备与其他设备之间的资源共享通信。 - 使用 `UnlinkUnixSeqpacketListener` 自动清理 socket 文件。 --- ### 设置默认的显示参数 ```rust if gpu_parameters.display_params.is_empty() { gpu_parameters .display_params .push(GpuDisplayParameters::default()); } ``` - 如果没有指定显示参数,则使用默认值。 --- ### 创建异步执行器(Executor) ```rust let ex = Executor::new().context("failed to create executor")?; ``` - `Executor` 是一个异步任务调度器,用来运行异步逻辑。 --- ### 异步接受资源桥接连接 ```rust let resource_bridges = Arc::new(Mutex::new(Vec::with_capacity(resource_bridge_listeners.len()))); for listener in resource_bridge_listeners { let resource_bridges = Arc::clone(&resource_bridges); ex.spawn_blocking(move || match listener.accept() { Ok(stream) => resource_bridges .lock() .push(Tube::new_from_unix_seqpacket(stream).unwrap()), Err(e) => { let path = listener .path() .unwrap_or_else(|_| PathBuf::from("{unknown}")); error!( "Failed to accept resource bridge connection for socket {}: {}", path.display(), e ); } }) .detach(); } ``` - 使用 `spawn_blocking` 在独立线程中监听资源桥接 socket。 - 接收到连接后,使用 `Tube` 封装 socket 流,并保存到 `resource_bridges` 中。 --- ### 创建 GPU 控制通道和退出事件通道 ```rust let (exit_evt_wrtube, _) = Tube::directional_pair()?; let (gpu_control_tube, _) = Tube::pair()?; ``` - `Tube` 是 Crosvm 中用于进程间通信的一种封装。 - `exit_evt_wrtube` 用于通知 GPU 设备退出。 - `gpu_control_tube` 用于控制 GPU 设备。 --- ### 设置显示后端 ```rust let mut display_backends = vec![ virtio::DisplayBackend::X(x_display), virtio::DisplayBackend::Stub, ]; if let Some(p) = channels.get("") { display_backends.insert(0, virtio::DisplayBackend::Wayland(Some(p.to_owned()))); } ``` - 支持 X11 和 Wayland 显示后端。 - 如果有 Wayland socket,则优先使用。 --- ### 初始化 GPU 设备 ```rust let base_features = virtio::base_features(ProtectionType::Unprotected); let listener = VhostUserListener::new_socket(&socket, None)?; let gpu = Rc::new(RefCell::new(Gpu::new( exit_evt_wrtube, gpu_control_tube, Vec::new(), // resource_bridges, handled separately by us display_backends, &gpu_parameters, None, event_devices, base_features, &channels, None, ))); ``` - `Gpu::new(...)` 创建 GPU 设备实例。 - 使用 `Rc<RefCell<Gpu>>` 实现共享可变状态。 --- ### 定义 `GpuBackend` 结构体 ```rust struct GpuBackend { ex: Executor, gpu: Rc<RefCell<Gpu>>, resource_bridges: Arc<Mutex<Vec<Tube>>>, state: Option<BackendState>, fence_state: Default::default(), queue_workers: Default::default(), platform_workers: Default::default(), shmem_mapper: Arc::new(Mutex::new(None)), } ``` - `GpuBackend` 是 `vmm_vhost::Backend` trait 的实现者,负责处理 vhost-user 协议消息。 - 包含 GPU 状态、线程池、共享内存映射器等。 --- ### 启动 vhost-user 服务端循环 ```rust let _ = ex.run_until(listener.run_backend(backend, &ex))?; ``` - 启动异步循环,监听客户端连接并处理请求。 --- ### 清理异步任务 ```rust Ok(ex.run_until(async {})?) ``` - 确保所有后台任务完成后再退出。 --- ## 总结 - `run_gpu_device` 是一个完整的 GPU vhost-user 服务端启动函数。 - 它支持 X11 和 Wayland 显示后端。 - 使用 `Tube` 实现进程间通信。 - 使用 `Executor` 运行异步任务。 - 支持多资源桥接连接。 - 是 Crosvm 中 GPU 虚拟化的核心实现之一。 --- ###
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值