mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-17 12:47:16 +00:00
Use LinkedList to store WorkItem to avoid additional heap allocation
This commit is contained in:
parent
2ac6e0e126
commit
846b3ba169
@ -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)),
|
||||
|
@ -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(
|
||||
|
@ -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(),
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
Loading…
x
Reference in New Issue
Block a user