From 6253d80e1df763f255ddab81076d9de2700ba635 Mon Sep 17 00:00:00 2001 From: function2-llx Date: Fri, 15 May 2020 21:11:52 +0800 Subject: [PATCH] fix bug of Condvar::notify: remove from queue when wake up --- kernel/src/fs/fcntl.rs | 13 ++++++++----- kernel/src/sync/condvar.rs | 16 ++++++++++++---- kernel/src/syscall/misc.rs | 5 +++++ kernel/src/syscall/mod.rs | 2 +- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/kernel/src/fs/fcntl.rs b/kernel/src/fs/fcntl.rs index 86132ddb..cf5b4ba0 100644 --- a/kernel/src/fs/fcntl.rs +++ b/kernel/src/fs/fcntl.rs @@ -1,11 +1,14 @@ // currently support x86_64 only // copy from fcntl.h -pub const F_DUPFD: usize = 0; /* dup */ -pub const F_GETFD: usize = 1; /* get close_on_exec */ -pub const F_SETFD: usize = 2; /* set/clear close_on_exec */ -pub const F_GETFL: usize = 3; /* get file->f_flags */ -pub const F_SETFL: usize = 4; /* set file->f_flags */ +pub const F_DUPFD: usize = 0; /* dup */ +pub const F_GETFD: usize = 1; /* get close_on_exec */ +pub const F_SETFD: usize = 2; /* set/clear close_on_exec */ +pub const F_GETFL: usize = 3; /* get file->f_flags */ +pub const F_SETFL: usize = 4; /* set file->f_flags */ +pub const F_GETLK: usize = 5; /* Get record locking info. */ +pub const F_SETLK: usize = 6; /* Set record locking info (non-blocking). */ +pub const F_SETLKW: usize = 7; /* Set record locking info (blocking). */ const F_LINUX_SPECIFIC_BASE: usize = 1024; diff --git a/kernel/src/sync/condvar.rs b/kernel/src/sync/condvar.rs index 3fadb1d6..c3a4c2a2 100644 --- a/kernel/src/sync/condvar.rs +++ b/kernel/src/sync/condvar.rs @@ -142,32 +142,40 @@ impl Condvar { } pub fn notify_one(&self) { - if let Some(t) = self.wait_queue.lock().front() { + let mut queue = self.wait_queue.lock(); + if let Some(t) = queue.front() { self.epoll_callback(t); t.unpark(); + queue.pop_front(); } + } pub fn notify_all(&self) { - let queue = self.wait_queue.lock(); + let mut queue = self.wait_queue.lock(); for t in queue.iter() { self.epoll_callback(t); t.unpark(); } + queue.clear(); } + /// Notify up to `n` waiters. /// Return the number of waiters that were woken up. pub fn notify_n(&self, n: usize) -> usize { let mut count = 0; - let queue = self.wait_queue.lock(); + let mut queue = self.wait_queue.lock(); for t in queue.iter() { if count >= n { break; } + self.epoll_callback(t); t.unpark(); count += 1; } - + for _ in 0..count { + queue.pop_front(); + } count } diff --git a/kernel/src/syscall/misc.rs b/kernel/src/syscall/misc.rs index fbdb747c..a9c2163f 100644 --- a/kernel/src/syscall/misc.rs +++ b/kernel/src/syscall/misc.rs @@ -58,6 +58,11 @@ impl Syscall<'_> { Ok(0) } + pub fn sys_tkill(&mut self, tgid: i32, tid: i32, sig: i32) -> SysResult { + info!("tkill: [{}] tgid: {}, tid: {}, sig: {}", thread::current().id(), tgid, tid, sig); + self.unimplemented("tkill", Ok(0)) + } + pub fn sys_futex( &mut self, uaddr: usize, diff --git a/kernel/src/syscall/mod.rs b/kernel/src/syscall/mod.rs index 3c6cf66a..aafc7af8 100644 --- a/kernel/src/syscall/mod.rs +++ b/kernel/src/syscall/mod.rs @@ -283,7 +283,7 @@ impl Syscall<'_> { args[2] as i32, args[3] as *const TimeSpec, ), - SYS_TKILL => self.unimplemented("tkill", Ok(0)), + SYS_TKILL => self.sys_tkill(args[0] as i32, args[1] as i32, args[2] as i32), // time SYS_NANOSLEEP => self.sys_nanosleep(args[0] as *const TimeSpec),