-
-
Notifications
You must be signed in to change notification settings - Fork 142
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Patch refactor scm and textui #289
Patch refactor scm and textui #289
Conversation
SCM_FRAMEWORK_LIST.lock().push_back(framework.clone()); | ||
// 调用ui框架的回调函数以安装ui框架,并将其激活 | ||
framework.install()?; | ||
framework.enable()?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
为啥这里要调用enable,然后里面又调用1次
pub extern "C" fn scm_enable_double_buffer() -> i32 { | ||
let r = ture_scm_enable_double_buffer() | ||
.map_err(|e| e.to_posix_errno()) | ||
.unwrap(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里产生err的时候,直接unwrap会产生错误
*/ | ||
#[no_mangle] | ||
pub extern "C" fn scm_enable_double_buffer() -> i32 { | ||
let r = ture_scm_enable_double_buffer() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true打错字啦,类似的地方还有好几处
} | ||
/** | ||
* @brief 销毁双缓冲区 | ||
* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
类似这样的代码需要删掉
} | ||
} | ||
|
||
pub fn get_vaddr(&self) -> usize { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这种函数命名不符合规范,不需要get_
前缀。
kernel/src/libs/libUI/textui.rs
Outdated
pub extern "C" fn scm_disable_put_to_window() { | ||
// unsafe{kfree(*TEXTUI_BUF_VADDR.read() as *mut c_void)}; | ||
|
||
unsafe { ENABLE_PUT_TO_WINDOW = false }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
原子变量
kernel/src/libs/libUI/textui.rs
Outdated
* @return int | ||
*/ | ||
#[no_mangle] | ||
pub extern "C" fn rs_textui_init() -> i32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
导出到C的函数,都把他们丢到一个新的文件“c_adapter.rs"吧
kernel/src/libs/libUI/textui.rs
Outdated
|
||
drop(private_info); | ||
|
||
unsafe { TEST_IS_INIT = true }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个干啥用的
kernel/src/libs/libUI/textui.rs
Outdated
pub static CHAR_PER_LINE: RwLock<i32> = RwLock::new(0); | ||
//textui 未初始化时直接向缓冲区写,不使用虚拟行 | ||
pub static NO_INIT_OPERATIONS_LINE: RwLock<i32> = RwLock::new(0); | ||
pub static NO_INIT_OPERATIONS_INDEX: RwLock<i32> = RwLock::new(0); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个变量我看的很迷惑,这个干啥用的?是未初始化内存管理的时候,用于记录下标的吗?
还有就是,我建议把内存管理未初始化的时候,相关的textui代码独立到一个新的文件"textui_mm_no_init.rs“,这样看的清楚一点。
还有就是,不要用rwlock去保护i32,直接原子变量就行了
kernel/src/driver/video/video.rs
Outdated
@@ -0,0 +1,44 @@ | |||
// use crate::include::bindings::bindings::PAGE_PCD; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
删掉这个文件
docs/kernel/libs/libUI/scm.md
Outdated
  用于储存scm中的ui框架中的帧缓冲区中的信息,定义如下: | ||
```rust | ||
#[derive(Debug, Clone)] | ||
pub struct ScmBufferInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
具体数据结构的内容我感觉可以不用放上文档,因为很难保持同步。只要说说是哪个结构就好,我觉得。然后文档主要讲实现思路(架构上面的),不用过于细节。因为细节的去看代码就能看的明白,因此我感觉把更高一个层次的视角的框架设计,写出来会更有用,下面那个文档也是一样的。
} | ||
/// 允许往窗口打印信息 | ||
#[no_mangle] | ||
pub extern "C" fn scm_enable_put_to_window() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个函数和下面的disable都不需要extern C
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct ScmBufferInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
命名问题
这个结构体命名为ScmBuffer更合适
存在内存泄露问题
要为这个结构体实现Drop trait,在它被drop的时候释放缓冲区(如果是动态申请来的),否则将会造成内存泄露。
并且,由于在很多地方都直接clone这个结构体,然后把vaddr指向的内存当作缓冲区来使用,因此本身就存在大量的“越界访问”的隐患。上面derive的Clone需要删掉。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个结构体命名为ScmBuffer更合适
|
||
frame_buffer_info.flags = buf_type; | ||
|
||
frame_buffer_info.vaddr = VirtAddr::new(unsafe { kzalloc(video_frame_buffer_info.size as usize, 0) }); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
不要使用kzalloc申请内存,请使用allocate_frames,并且映射到指定的位置。
pub fn vaddr(&self) -> usize { | ||
self.vaddr.data() | ||
} | ||
pub fn buf_size_about_u8(&self) -> u32 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个命名很有迷惑性,而且没有注释。需要更改。下面那个buf_size_about_u32同理
} | ||
pub trait ScmUiFramework: Sync + Send + Debug { | ||
// 安装ui框架的回调函数 | ||
fn install(&self) -> Result<i32, SystemError> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这些函数全部都不需要默认实现吧,我感觉都是必须的?
|
||
let metadata = framework.metadata()?; | ||
|
||
if metadata.buf_info.vaddr.data() == 0 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
调用vaddr的is_null方法,而不是这样写
@@ -1,7 +1,14 @@ | |||
#pragma once |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个文件我感觉可以删掉了
kernel/src/libs/libUI/textui.rs
Outdated
Arc::new(SpinLock::new(TextuiWindow::new( | ||
WindowFlag::TEXTUI_IS_CHROMATIC, | ||
0, | ||
0, | ||
))), | ||
Arc::new(SpinLock::new(TextuiWindow::new( | ||
WindowFlag::TEXTUI_IS_CHROMATIC, | ||
0, | ||
0, | ||
))), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
current window为啥要和default的是不同的2个实例呀。。。
而且不应该先初始化line数量为0的window对象,然后再在外面的函数进行初始化赋值。这样不满足“资源获取即初始化”
|
||
// 遍历当前所有使用帧缓冲区的框架,更新地址 | ||
for framework in SCM_FRAMEWORK_LIST.lock().iter_mut() { | ||
framework.change(unsafe { ScmBufferInfo::from(&video_frame_buffer_info) })?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
为什么要把所有的框架的缓冲区都设置成相同的???
// 遍历当前所有使用帧缓冲区的框架,更新地址 | ||
drop(scm_list); | ||
for framework in SCM_FRAMEWORK_LIST.lock().iter_mut() { | ||
(*framework).change(buf_info.clone())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里也是,为什么要把所有框架的缓冲区设置成相同的?
pub static SCM_DOUBLE_BUFFER_ENABLED: AtomicBool = AtomicBool::new(false); | ||
|
||
bitflags! { | ||
pub struct ScmBfFlag:u8{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个命名也需要改,很有迷惑性。一般不用bf来代指buffer的,这不是常用缩写
} | ||
|
||
#[derive(Debug, Clone)] | ||
pub struct ScmBufferInfo { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个结构体命名为ScmBuffer更合适
} | ||
} | ||
|
||
#[derive(Debug, Clone)] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
由于buffer的内存安全问题,这个不应该继承clone
还有,textui.h里面有很多的无用的函数导出、无用的数据结构,这些都要删除 |
kernel/src/libs/libUI/textui.rs
Outdated
/// 将窗口的帧缓冲区内容清零 | ||
pub fn _renew_buf(&self) { | ||
// let mut addr: *mut u32 = fb as *mut u32; | ||
let mut addr: *mut u32 = self.metadata.buf_info.vaddr() as *mut u32; | ||
|
||
for _i in 0..self.metadata.buf_info.buf_size_about_u8() { | ||
unsafe { *addr = 0 }; | ||
unsafe { | ||
addr = (addr.offset(1)) as *mut u32; | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
感觉这个函数可以删掉
kernel/src/libs/libUI/textui.rs
Outdated
fn change(&self, buf: ScmBufferInfo) -> Result<i32, SystemError> { | ||
let src = self.metadata.buf_info.vaddr() as *const u8; | ||
let dst = buf.vaddr() as *mut u8; | ||
let count = self.metadata.buf_info.buf_size_about_u8() as usize; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这里有内存安全问题,没有检查src和dst是否同样大小。建议把拷贝缓冲区内容的工作,写成buffer的成员函数。
kernel/src/libs/libUI/textui.rs
Outdated
/// -失败:Err(错误码) | ||
fn metadata(&self) -> Result<ScmUiFrameworkMetadata, SystemError> { | ||
// let framework_guard = self.0.lock(); | ||
let metadata = self.metadata.clone(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个函数会把buffer的vaddr给拷贝出去,这是有问题的,可能会导致难以定位的内存越界访问
kernel/src/libs/libUI/textui.rs
Outdated
} | ||
} | ||
|
||
impl Deref for TextUiFramework { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个deref和derefMut我建议删掉,因为他们允许外界对Metadata结构体的直接操作,破坏了封装性
重构了屏幕管理器和textui框架