22use alloc:: sync:: Arc ;
33
44use crate :: {
5- loader:: get_app_data_by_name,
6- mm:: { translated_refmut, translated_str} ,
7- task:: {
8- add_task, current_task, current_user_token, exit_current_and_run_next,
9- suspend_current_and_run_next,
10- } ,
5+ loader:: get_app_data_by_name, mm:: { translated_physaddr, translated_refmut, translated_str, MapPermission , VirtAddr } , task:: { add_task, current_task, current_user_token, exit_current_and_run_next, suspend_current_and_run_next, TaskControlBlock } , timer:: get_time_us
116} ;
127
138#[ repr( C ) ]
@@ -78,6 +73,7 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
7873 . iter ( )
7974 . any ( |p| pid == -1 || pid as usize == p. getpid ( ) )
8075 {
76+ debug ! ( "no such pid[{}]" , pid) ;
8177 return -1 ;
8278 // ---- release current PCB
8379 }
@@ -95,8 +91,10 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
9591 let exit_code = child. inner_exclusive_access ( ) . exit_code ;
9692 // ++++ release child PCB
9793 * translated_refmut ( inner. memory_set . token ( ) , exit_code_ptr) = exit_code;
94+ debug ! ( "found pid[{}]" , found_pid) ;
9895 found_pid as isize
9996 } else {
97+ // debug!("pid[{}] is running", pid);
10098 -2
10199 }
102100 // ---- release current PCB automatically
@@ -106,29 +104,83 @@ pub fn sys_waitpid(pid: isize, exit_code_ptr: *mut i32) -> isize {
106104/// HINT: You might reimplement it with virtual memory management.
107105/// HINT: What if [`TimeVal`] is splitted by two pages ?
108106pub fn sys_get_time ( _ts : * mut TimeVal , _tz : usize ) -> isize {
109- trace ! (
110- "kernel:pid[{}] sys_get_time NOT IMPLEMENTED" ,
111- current_task( ) . unwrap( ) . pid. 0
112- ) ;
113- -1
107+ trace ! ( "kernel: sys_get_time" ) ;
108+ let pa = translated_physaddr ( current_user_token ( ) , _ts as * const u8 ) ;
109+ let phy_ts = pa. 0 as * mut TimeVal ;
110+
111+ let us = get_time_us ( ) ;
112+ let time_val = TimeVal {
113+ sec : us / 1_000_000 ,
114+ usec : us % 1_000_000 ,
115+ } ;
116+
117+ unsafe { * phy_ts = time_val } ;
118+ 0
119+ }
120+
121+ #[ derive( Copy , Clone , Debug , Default , Eq , PartialEq ) ]
122+ pub struct Flag ( pub usize ) ;
123+
124+ impl Flag {
125+ pub fn is_readable ( & self ) -> bool {
126+ self . 0 & 0x1 == 0x1
127+ }
128+
129+ pub fn is_writeable ( & self ) -> bool {
130+ self . 0 & 0x2 == 0x2
131+ }
132+
133+ pub fn is_execute ( & self ) -> bool {
134+ self . 0 & 0x4 == 0x4
135+ }
114136}
115137
116- /// YOUR JOB: Implement mmap.
138+ // YOUR JOB: Implement mmap.
117139pub fn sys_mmap ( _start : usize , _len : usize , _port : usize ) -> isize {
118- trace ! (
119- "kernel:pid[{}] sys_mmap NOT IMPLEMENTED" ,
120- current_task( ) . unwrap( ) . pid. 0
121- ) ;
122- -1
140+ trace ! ( "kernel: sys_mmap " ) ;
141+
142+ debug ! ( "mmap start: {}, len: {}, port: {}" , _start, _len, _port) ;
143+
144+ let start_va = VirtAddr :: from ( _start) ;
145+ if !start_va. aligned ( ) {
146+ return -1 ;
147+ }
148+ let end_va: VirtAddr = ( _start + _len) . into ( ) ;
149+ if _port & !0x7 != 0 || _port & 0x7 == 0 {
150+ return -1 ;
151+ }
152+
153+ let mut map_perm: MapPermission = MapPermission :: U ;
154+ let pte_flag = Flag ( _port) ;
155+ if pte_flag. is_readable ( ) {
156+ map_perm |= MapPermission :: R ;
157+ }
158+ if pte_flag. is_writeable ( ) {
159+ map_perm |= MapPermission :: W ;
160+ }
161+ if pte_flag. is_execute ( ) {
162+ map_perm |= MapPermission :: X ;
163+ }
164+
165+ if !current_task ( ) . unwrap ( ) . find_area_insert ( start_va, end_va, map_perm) {
166+ return -1 ;
167+ }
168+ return 0 ;
123169}
124170
125171/// YOUR JOB: Implement munmap.
126172pub fn sys_munmap ( _start : usize , _len : usize ) -> isize {
127- trace ! (
128- "kernel:pid[{}] sys_munmap NOT IMPLEMENTED" ,
129- current_task( ) . unwrap( ) . pid. 0
130- ) ;
131- -1
173+ trace ! ( "kernel: sys_munmap " ) ;
174+ let start_va = VirtAddr :: from ( _start) ;
175+ if !start_va. aligned ( ) {
176+ return -1 ;
177+ }
178+ let end_va: VirtAddr = ( _start + _len) . into ( ) ;
179+
180+ if !current_task ( ) . unwrap ( ) . find_area_remove ( start_va, end_va) {
181+ return -1 ;
182+ }
183+ return 0 ;
132184}
133185
134186/// change data segment size
@@ -148,7 +200,18 @@ pub fn sys_spawn(_path: *const u8) -> isize {
148200 "kernel:pid[{}] sys_spawn NOT IMPLEMENTED" ,
149201 current_task( ) . unwrap( ) . pid. 0
150202 ) ;
151- -1
203+ let token = current_user_token ( ) ;
204+ let path = translated_str ( token, _path) ;
205+ if let Some ( data) = get_app_data_by_name ( & path) {
206+ let new_task: Arc < TaskControlBlock > = current_task ( ) . unwrap ( ) . spawn ( data) ;
207+ let pid = new_task. getpid ( ) as isize ;
208+ add_task ( new_task) ;
209+ debug ! ( "add task pid[{}]" , pid) ;
210+ return pid;
211+ } else {
212+ debug ! ( "kernel: sys spawn error..." ) ;
213+ return -1 ;
214+ }
152215}
153216
154217// YOUR JOB: Set task priority.
@@ -157,5 +220,9 @@ pub fn sys_set_priority(_prio: isize) -> isize {
157220 "kernel:pid[{}] sys_set_priority NOT IMPLEMENTED" ,
158221 current_task( ) . unwrap( ) . pid. 0
159222 ) ;
160- -1
223+ if _prio < 2 {
224+ return -1 ;
225+ }
226+ current_task ( ) . unwrap ( ) . set_priority ( _prio as usize ) ;
227+ return _prio;
161228}
0 commit comments