-
Notifications
You must be signed in to change notification settings - Fork 13
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
[#closes 243] Procdump debug & Refactor console struct. #286
Conversation
kernel-rs/src/console.rs
Outdated
match cin { | ||
// Print process list. | ||
m if m == ctrl('P') => { | ||
m if m == ctrl('P') => unsafe { |
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.
해당 block만 unsafe 하다고 판단했습니다. 나머지 block은 Console::putc->Uart::putc_sync->UartCtrlRegs::read
로 safety가 reduce 됩니다.
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.
이 block은 왜 unsafe한가요?
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.
ProcessSystem::dump->
p.info.get_mut_unchecked()'를 통해 ProcInfo에 접근합니다.
dump의 unsafe block을 특정지어서 safety를 reduce 해봤습니다.
safety에 대해서 미팅 때 여쭤보겠습니다.
kernel-rs/src/console.rs
Outdated
}; | ||
} | ||
|
||
unsafe fn write(&mut self, src: UVAddr, n: i32) -> i32 { | ||
unsafe fn write(&self, src: UVAddr, n: i32) -> 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.
write/read/intr
함수들의 소유를 struct Terminal
로 옮기는 편이 좋을까요?
그 경우 intr
는 putc
를 사용하고 있어서 kernel()
을 부르게 됩니다.
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.
- 수정한다면,
write
도uart
를 사용하고 있어서kernel()
을 불러야 할 것 같습니다. - 아래
Printer::Write
과 같은 정책을 사용하는 것이 좋다고 생각합니다. (둘 다 각자 소유 / 다Console
이 소유)
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.
@anemoneflower 소유권 표현 상으로는 kernel()을 부르더라도 Terminal으로 이동하는 것이 좋다는 말씀이시죠?
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.
소유권만 보면 Terminal
과 Printer
가 각각 소유하는 것이 맞는 것 같습니다. 그런데, 코드 구조 상으로는 Console
이 다 소유하는 것이 더 깔끔해 보입니다.. Printer
와 Terminal
이 Console
에서만 사용되기 때문에 Console
의 소유로 남겨도 괜찮을 것 같은데, 다른 분들의 의견은 어떠신가요?
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.
저는 ownership을 중점적으로 생각해 Terminal
과 Printer
가 각각 소유하면 좋겠습니다! 추가로 아래의 현재 kaist-cp/rv6의 구현처럼, write/read/intr
을 실행하기 전 consoleread/consolewrite/consoleintr
에서 lock()
을 실행하면 소유권을 더욱 명확히 나타낼 수 있다고 생각합니다!
Lines 201 to 204 in 53d87f7
unsafe fn consolewrite(src: UVAddr, n: i32) -> i32 { | |
let mut console = kernel().console.lock(); | |
console.write(src, n) | |
} |
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.
@jeehoonkang 교수님, 현재 논점이 global function kernel()
의 사용을 지양하는 것과 ownership을 조금 더 세분화하는 것 중에 선택하는 것입니다. 교수님의 의견이 궁금합니다.
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.
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.
같은 질문을 드리고자 하는데 왜 &self로 해도 안전한가요? 여러 쓰레드가 동시 접근해도 문제가 안생기나요?
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.
- terminal에 lock을 잡고 있습니다.
- Uart::putc의 경우 uart.tx_lock으로 보호됩니다. 여러 쓰레드가 동시에 접근하면 어떤 문제가 생길 수 있나요?
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.
감사합니다.. 다만 제가 console, terminal, printer, uart 사이의 관계에 대해 잘 파악하기 어렵습니다. 혹시 주석으로 얘네들이 뭐 하는건지 남겨주시면 감사하겠습니다.
아울러 원래 xv6의 의도를 100% 반영하는지, 아니면 좀 바뀐 부분이 있는지 궁금합니다.
@jeehoonkang
결론적으로 말하자면 의도를 100% 반영한다고 생각합니다. 결국 세 struct가 전부 User와 interact 하는 Console device와 관련된 interface라는 점에서도 의미를 더욱 명확히 표현하고 있다고 생각합니다. xv6의 조금은 정돈되지 못한 표현들이 rust의 ownership을 통해 정리가 된 것 같습니다. |
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.
수고하셨습니다! 저는 ownership 위주로 고민해봤습니다 👍👍
kernel-rs/src/console.rs
Outdated
}; | ||
} | ||
|
||
unsafe fn write(&mut self, src: UVAddr, n: i32) -> i32 { | ||
unsafe fn write(&self, src: UVAddr, n: i32) -> 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.
저는 ownership을 중점적으로 생각해 Terminal
과 Printer
가 각각 소유하면 좋겠습니다! 추가로 아래의 현재 kaist-cp/rv6의 구현처럼, write/read/intr
을 실행하기 전 consoleread/consolewrite/consoleintr
에서 lock()
을 실행하면 소유권을 더욱 명확히 나타낼 수 있다고 생각합니다!
Lines 201 to 204 in 53d87f7
unsafe fn consolewrite(src: UVAddr, n: i32) -> i32 { | |
let mut console = kernel().console.lock(); | |
console.write(src, n) | |
} |
@jeehoonkang ping 리뷰 요청드립니다. |
@efenniht #186 (comment) 이 부분에 대한 refactoring도 진행된 것 같은데, 확인 부탁드립니다. struct Console이 모듈이라기보다는 Console device의 추상화가 되었기 때문에 interrupt를 받는다고 생각해도 괜찮을까요? |
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.
일반적으로 이 PR이 달성하고자하는 바를 잘 모르겠습니다.
pub fn uartintr(&self) { | ||
self.uart.intr() | ||
} | ||
|
||
/// Send one character to the uart. | ||
pub fn putc(&mut self, c: i32) { | ||
pub fn putc(&self, c: 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.
여전히 이게 &self인게 이해가 잘 안갑니다. 여러 thread가 동시에 putc를 부르면 어떻게 되나요?
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.
생각해봤는데, 명확히 어떤 문제가 생기는지 reasoning이 잘 안됩니다. 면담 때 이런 경우에 어떻게 reasoning 할 수 있는지 가르침을 청해도 될까요?
Uart::putc_sync는 interrupt disable을 통해 synchronization을 handling 중입니다.
kernel-rs/src/console.rs
Outdated
}; | ||
} | ||
|
||
unsafe fn write(&mut self, src: UVAddr, n: i32) -> i32 { | ||
unsafe fn write(&self, src: UVAddr, n: i32) -> 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.
같은 질문을 드리고자 하는데 왜 &self로 해도 안전한가요? 여러 쓰레드가 동시 접근해도 문제가 안생기나요?
kernel-rs/src/console.rs
Outdated
|
||
unsafe fn read(&self, dst: UVAddr, n: i32) -> i32 { | ||
let mut terminal = self.terminal.lock(); | ||
terminal.read(dst, n) |
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.
이렇게 terminal로 바로 보내는 함수들이 많다면, console이라는 abstraction이 틀린 걸지도 모르겠습니다. 어떻게 보시나요?
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.
이전 커밋 상태로 role back 하겠습니다. 그쪽 디자인이 옳은 것 같아서요.
- console이라는 abstraction을 만든 이유가 uart의 ownership을 분명히하고자 하는 것인데, 이런식으로 terminal을 부르는게 그 의미를 담지 못하는 것 같습니다.
- b2c26c4 에서는 console의 uart를 이용하는 방식이었는데, 해당 디자인에서는 console abstraction의 존재 의미를 잘 살리고 있다고 생각하여 role back 하겠습니다.
- 혹시 맥락이 잘못되었다면 말씀해주세요.
kernel-rs/src/console.rs
Outdated
for i in 0..n { | ||
let mut c = [0 as u8]; | ||
if VAddr::copyin(&mut c, UVAddr::new(src.into_usize() + (i as usize))).is_err() { | ||
return i; | ||
} | ||
self.uart.putc(c[0] as i32); | ||
kernel().console.uart.putc(c[0] as 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.
저는 이건 잘못된 디자인이라고 생각합니다. uart의 소유권에 대한 명확한 정립이 먼저 필요한 것 같아요.
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.
생각해봤는데, 이러한 디자인을 사용하는 것이 잘못된 것이 맞는 것 같습니다. 이번 PR의 목적 중 하나가 uart의 소유권을 console이 가지도록 하는 것인데, 이렇게 사용하면 의미가 퇴색되는 것 같습니다.
b2c26c4 에서처럼 uart의 소유권을 console이 지니는 것을 분명히 하여 console의 존재 의미를 살리는 방식으로 role back 하겠습니다.
kernel-rs/src/console.rs
Outdated
match cin { | ||
// Print process list. | ||
m if m == ctrl('P') => { | ||
m if m == ctrl('P') => unsafe { |
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.
이 block은 왜 unsafe한가요?
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.
putc의 multithread 접근에 대해서 조금 더 생각해보겠습니다.
kernel-rs/src/console.rs
Outdated
}; | ||
} | ||
|
||
unsafe fn write(&mut self, src: UVAddr, n: i32) -> i32 { | ||
unsafe fn write(&self, src: UVAddr, n: i32) -> 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.
- terminal에 lock을 잡고 있습니다.
- Uart::putc의 경우 uart.tx_lock으로 보호됩니다. 여러 쓰레드가 동시에 접근하면 어떤 문제가 생길 수 있나요?
kernel-rs/src/console.rs
Outdated
match cin { | ||
// Print process list. | ||
m if m == ctrl('P') => { | ||
m if m == ctrl('P') => unsafe { |
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.
ProcessSystem::dump->
p.info.get_mut_unchecked()'를 통해 ProcInfo에 접근합니다.
dump의 unsafe block을 특정지어서 safety를 reduce 해봤습니다.
safety에 대해서 미팅 때 여쭤보겠습니다.
kernel-rs/src/console.rs
Outdated
|
||
unsafe fn read(&self, dst: UVAddr, n: i32) -> i32 { | ||
let mut terminal = self.terminal.lock(); | ||
terminal.read(dst, n) |
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.
이전 커밋 상태로 role back 하겠습니다. 그쪽 디자인이 옳은 것 같아서요.
- console이라는 abstraction을 만든 이유가 uart의 ownership을 분명히하고자 하는 것인데, 이런식으로 terminal을 부르는게 그 의미를 담지 못하는 것 같습니다.
- b2c26c4 에서는 console의 uart를 이용하는 방식이었는데, 해당 디자인에서는 console abstraction의 존재 의미를 잘 살리고 있다고 생각하여 role back 하겠습니다.
- 혹시 맥락이 잘못되었다면 말씀해주세요.
kernel-rs/src/console.rs
Outdated
for i in 0..n { | ||
let mut c = [0 as u8]; | ||
if VAddr::copyin(&mut c, UVAddr::new(src.into_usize() + (i as usize))).is_err() { | ||
return i; | ||
} | ||
self.uart.putc(c[0] as i32); | ||
kernel().console.uart.putc(c[0] as 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.
생각해봤는데, 이러한 디자인을 사용하는 것이 잘못된 것이 맞는 것 같습니다. 이번 PR의 목적 중 하나가 uart의 소유권을 console이 가지도록 하는 것인데, 이렇게 사용하면 의미가 퇴색되는 것 같습니다.
b2c26c4 에서처럼 uart의 소유권을 console이 지니는 것을 분명히 하여 console의 존재 의미를 살리는 방식으로 role back 하겠습니다.
우선 procdump debugging만 하는 정도에서 PR을 마무리하고 console/printer/uart refactoring은 추후에 별도의 issue로 다루기로 해서 close합니다. |
구현 상 아직 논의가 필요한 부분이 있지만, 리뷰 부탁드립니다.
#276 의 논의가 너무 길어지고 #281 이후 resolve 하기 힘든 conflict가 많이 생겨서 새롭게 PR을 작성했습니다.
Processsystem::dump
출력 시 null character recognizing 문제 해결.MAXPROCNAME
으로 정의했습니다.Console / Printer / Uart
의 Ownership을 정돈했습니다.struct Console
을 변경했습니다.struct Console
를struct Terminal
이라는 임시 이름으로 변경했습니다.struct Printer
와struct Terminal(구 Console)
을 분리해야합니다.Terminal
은 user program의 input output logging,Printer
는println!
매크로를 위해 존재합니다.pr.lock
과cons.lock
은 항상 따로 잡힙니다.Uart
가 하나만 존재하게 하는 ownership 정리가 필요합니다.