Use LinkedList to store WorkItem to avoid additional heap allocation

This commit is contained in:
Chen Chengjun
2024-11-01 10:14:28 +08:00
committed by Tate, Hongliang Tian
parent 2ac6e0e126
commit 846b3ba169
5 changed files with 28 additions and 18 deletions

View File

@ -92,11 +92,11 @@ impl LineDiscipline {
pub fn new(send_signal: LdiscSignalSender) -> Arc<Self> {
Arc::new_cyclic(move |line_ref: &Weak<LineDiscipline>| {
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)),

View File

@ -106,7 +106,7 @@ fn create_process_timer_callback(process_ref: &Weak<Process>) -> 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(

View File

@ -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(),

View File

@ -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<F>(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<Arc<WorkItem>>,
pending_work_items: LinkedList<WorkItemAdapter>,
}
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<Arc<WorkItem>> {
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 {

View File

@ -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<dyn Fn() + Send + Sync>,
cpu_affinity: CpuSet,
was_pending: AtomicBool,
link: LinkedListAtomicLink,
}
intrusive_adapter!(pub(super) WorkItemAdapter = Arc<WorkItem>: WorkItem { link: LinkedListAtomicLink });
impl WorkItem {
pub fn new(work_func: Box<dyn Fn() + Send + Sync>) -> WorkItem {
pub fn new(work_func: Box<dyn Fn() + Send + Sync>) -> Arc<WorkItem> {
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 {