diff --git a/kernel/src/device/tty/line_discipline.rs b/kernel/src/device/tty/line_discipline.rs index ad9c7fdc9..b5737fafe 100644 --- a/kernel/src/device/tty/line_discipline.rs +++ b/kernel/src/device/tty/line_discipline.rs @@ -92,11 +92,11 @@ impl LineDiscipline { pub fn new(send_signal: LdiscSignalSender) -> Arc { Arc::new_cyclic(move |line_ref: &Weak| { let line_discipline = line_ref.clone(); - let work_item = Arc::new(WorkItem::new(Box::new(move || { + let work_item = WorkItem::new(Box::new(move || { if let Some(line_discipline) = line_discipline.upgrade() { line_discipline.send_signal_after(); } - }))); + })); Self { current_line: SpinLock::new(CurrentLine::default()), read_buffer: SpinLock::new(RingBuffer::new(BUFFER_CAPACITY)), diff --git a/kernel/src/process/process/timer_manager.rs b/kernel/src/process/process/timer_manager.rs index bb42b073e..fed03baa1 100644 --- a/kernel/src/process/process/timer_manager.rs +++ b/kernel/src/process/process/timer_manager.rs @@ -106,7 +106,7 @@ fn create_process_timer_callback(process_ref: &Weak) -> impl Fn() + Clo }; let work_func = Box::new(sent_signal); - let work_item = Arc::new(WorkItem::new(work_func)); + let work_item = WorkItem::new(work_func); move || { submit_work_item( diff --git a/kernel/src/syscall/timer_create.rs b/kernel/src/syscall/timer_create.rs index 5723e36bb..21ea1621b 100644 --- a/kernel/src/syscall/timer_create.rs +++ b/kernel/src/syscall/timer_create.rs @@ -95,7 +95,7 @@ pub fn sys_timer_create( }; let work_func = sent_signal; - let work_item = Arc::new(WorkItem::new(work_func)); + let work_item = WorkItem::new(work_func); let func = move || { submit_work_item( work_item.clone(), diff --git a/kernel/src/thread/work_queue/mod.rs b/kernel/src/thread/work_queue/mod.rs index 4190c6b9e..a0b818542 100644 --- a/kernel/src/thread/work_queue/mod.rs +++ b/kernel/src/thread/work_queue/mod.rs @@ -64,9 +64,10 @@ //! //! ``` +use intrusive_collections::linked_list::LinkedList; use ostd::cpu::{CpuId, CpuSet}; use spin::Once; -use work_item::WorkItem; +use work_item::{WorkItem, WorkItemAdapter}; use worker_pool::WorkerPool; use crate::prelude::*; @@ -86,7 +87,7 @@ pub fn submit_work_func(work_func: F, work_priority: WorkPriority) where F: Fn() + Send + Sync + 'static, { - let work_item = Arc::new(WorkItem::new(Box::new(work_func))); + let work_item = WorkItem::new(Box::new(work_func)); submit_work_item(work_item, work_priority); } @@ -112,7 +113,7 @@ pub struct WorkQueue { } struct WorkQueueInner { - pending_work_items: Vec>, + pending_work_items: LinkedList, } impl WorkQueue { @@ -122,7 +123,7 @@ impl WorkQueue { let queue = Arc::new(WorkQueue { worker_pool: worker_pool.clone(), inner: SpinLock::new(WorkQueueInner { - pending_work_items: Vec::new(), + pending_work_items: LinkedList::new(WorkItemAdapter::NEW), }), }); worker_pool @@ -141,7 +142,7 @@ impl WorkQueue { .disable_irq() .lock() .pending_work_items - .push(work_item); + .push_back(work_item); true } @@ -150,12 +151,16 @@ impl WorkQueue { /// the calling worker is located. fn dequeue(&self, request_cpu: CpuId) -> Option> { let mut inner = self.inner.disable_irq().lock(); - let index = inner - .pending_work_items - .iter() - .position(|item| item.is_valid_cpu(request_cpu))?; - let item = inner.pending_work_items.remove(index); - Some(item) + let mut cursor = inner.pending_work_items.front_mut(); + while let Some(item) = cursor.get() { + if item.is_valid_cpu(request_cpu) { + return cursor.remove(); + } + + cursor.move_next(); + } + + None } fn has_pending_work_items(&self, request_cpu: CpuId) -> bool { diff --git a/kernel/src/thread/work_queue/work_item.rs b/kernel/src/thread/work_queue/work_item.rs index c561343da..36a7c94c1 100644 --- a/kernel/src/thread/work_queue/work_item.rs +++ b/kernel/src/thread/work_queue/work_item.rs @@ -4,6 +4,7 @@ use core::sync::atomic::{AtomicBool, Ordering}; +use intrusive_collections::{intrusive_adapter, LinkedListAtomicLink}; use ostd::cpu::{CpuId, CpuSet}; use crate::prelude::*; @@ -13,16 +14,20 @@ pub struct WorkItem { work_func: Box, cpu_affinity: CpuSet, was_pending: AtomicBool, + link: LinkedListAtomicLink, } +intrusive_adapter!(pub(super) WorkItemAdapter = Arc: WorkItem { link: LinkedListAtomicLink }); + impl WorkItem { - pub fn new(work_func: Box) -> WorkItem { + pub fn new(work_func: Box) -> Arc { let cpu_affinity = CpuSet::new_full(); - WorkItem { + Arc::new(WorkItem { work_func, cpu_affinity, was_pending: AtomicBool::new(false), - } + link: LinkedListAtomicLink::new(), + }) } pub fn cpu_affinity(&self) -> &CpuSet {