mirror of
https://github.com/servo/servo.git
synced 2025-07-25 16:20:36 +01:00
Auto merge of #6547 - Ms2ger:workqueue-reference, r=pcwalton
Borrow the QueueData for WorkQueue::run. This allows us to get rid of the raw pointers and unsafe dereferencing in the parallel layout implementation. <!-- Reviewable:start --> [<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/6547) <!-- Reviewable:end -->
This commit is contained in:
commit
a3821bf240
4 changed files with 46 additions and 47 deletions
|
@ -129,9 +129,7 @@ pub struct SharedLayoutContext {
|
||||||
pub goal: ReflowGoal,
|
pub goal: ReflowGoal,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct SharedLayoutContextWrapper(pub *const SharedLayoutContext);
|
unsafe impl Send for SharedLayoutContext {}
|
||||||
|
|
||||||
unsafe impl Send for SharedLayoutContextWrapper {}
|
|
||||||
|
|
||||||
pub struct LayoutContext<'a> {
|
pub struct LayoutContext<'a> {
|
||||||
pub shared: &'a SharedLayoutContext,
|
pub shared: &'a SharedLayoutContext,
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
use animation;
|
use animation;
|
||||||
use construct::ConstructionResult;
|
use construct::ConstructionResult;
|
||||||
use context::{SharedLayoutContext, SharedLayoutContextWrapper, heap_size_of_local_context};
|
use context::{SharedLayoutContext, heap_size_of_local_context};
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
use data::LayoutDataWrapper;
|
use data::LayoutDataWrapper;
|
||||||
use display_list_builder::ToGfxColor;
|
use display_list_builder::ToGfxColor;
|
||||||
|
@ -108,7 +108,7 @@ pub struct LayoutTaskData {
|
||||||
pub stylist: Box<Stylist>,
|
pub stylist: Box<Stylist>,
|
||||||
|
|
||||||
/// The workers that we use for parallel operation.
|
/// The workers that we use for parallel operation.
|
||||||
pub parallel_traversal: Option<WorkQueue<SharedLayoutContextWrapper, WorkQueueData>>,
|
pub parallel_traversal: Option<WorkQueue<SharedLayoutContext, WorkQueueData>>,
|
||||||
|
|
||||||
/// The dirty rect. Used during display list construction.
|
/// The dirty rect. Used during display list construction.
|
||||||
pub dirty: Rect<Au>,
|
pub dirty: Rect<Au>,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
#![allow(unsafe_code)]
|
#![allow(unsafe_code)]
|
||||||
|
|
||||||
use context::{LayoutContext, SharedLayoutContextWrapper, SharedLayoutContext};
|
use context::{LayoutContext, SharedLayoutContext};
|
||||||
use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
|
use flow::{Flow, MutableFlowUtils, PreorderFlowTraversal, PostorderFlowTraversal};
|
||||||
use flow;
|
use flow;
|
||||||
use flow_ref::FlowRef;
|
use flow_ref::FlowRef;
|
||||||
|
@ -88,29 +88,29 @@ pub type UnsafeFlowList = (Box<Vec<UnsafeLayoutNode>>, usize);
|
||||||
|
|
||||||
pub type ChunkedDomTraversalFunction =
|
pub type ChunkedDomTraversalFunction =
|
||||||
extern "Rust" fn(UnsafeLayoutNodeList,
|
extern "Rust" fn(UnsafeLayoutNodeList,
|
||||||
&mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNodeList>);
|
&mut WorkerProxy<SharedLayoutContext,UnsafeLayoutNodeList>);
|
||||||
|
|
||||||
pub type DomTraversalFunction =
|
pub type DomTraversalFunction =
|
||||||
extern "Rust" fn(UnsafeLayoutNode,
|
extern "Rust" fn(UnsafeLayoutNode,
|
||||||
&mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNodeList>);
|
&mut WorkerProxy<SharedLayoutContext,UnsafeLayoutNodeList>);
|
||||||
|
|
||||||
pub type ChunkedFlowTraversalFunction =
|
pub type ChunkedFlowTraversalFunction =
|
||||||
extern "Rust" fn(UnsafeFlowList, &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>);
|
extern "Rust" fn(UnsafeFlowList, &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>);
|
||||||
|
|
||||||
pub type FlowTraversalFunction =
|
pub type FlowTraversalFunction =
|
||||||
extern "Rust" fn(UnsafeFlow, &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>);
|
extern "Rust" fn(UnsafeFlow, &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>);
|
||||||
|
|
||||||
/// A parallel top-down DOM traversal.
|
/// A parallel top-down DOM traversal.
|
||||||
pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
|
pub trait ParallelPreorderDomTraversal : PreorderDomTraversal {
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
nodes: UnsafeLayoutNodeList,
|
nodes: UnsafeLayoutNodeList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNodeList>);
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeLayoutNodeList>);
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn run_parallel_helper(
|
fn run_parallel_helper(
|
||||||
&self,
|
&self,
|
||||||
unsafe_nodes: UnsafeLayoutNodeList,
|
unsafe_nodes: UnsafeLayoutNodeList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNodeList>,
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeLayoutNodeList>,
|
||||||
top_down_func: ChunkedDomTraversalFunction,
|
top_down_func: ChunkedDomTraversalFunction,
|
||||||
bottom_up_func: DomTraversalFunction) {
|
bottom_up_func: DomTraversalFunction) {
|
||||||
let mut discovered_child_nodes = Vec::new();
|
let mut discovered_child_nodes = Vec::new();
|
||||||
|
@ -169,7 +169,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal {
|
||||||
/// fetch-and-subtract the parent's children count.
|
/// fetch-and-subtract the parent's children count.
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
mut unsafe_node: UnsafeLayoutNode,
|
mut unsafe_node: UnsafeLayoutNode,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeLayoutNodeList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeLayoutNodeList>) {
|
||||||
loop {
|
loop {
|
||||||
// Get a real layout node.
|
// Get a real layout node.
|
||||||
let node: LayoutNode = unsafe {
|
let node: LayoutNode = unsafe {
|
||||||
|
@ -179,7 +179,7 @@ trait ParallelPostorderDomTraversal : PostorderDomTraversal {
|
||||||
// Perform the appropriate operation.
|
// Perform the appropriate operation.
|
||||||
self.process(node);
|
self.process(node);
|
||||||
|
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
|
|
||||||
let parent = match node.layout_parent_node(layout_context.shared) {
|
let parent = match node.layout_parent_node(layout_context.shared) {
|
||||||
|
@ -239,7 +239,7 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
|
||||||
/// fetch-and-subtract the parent's children count.
|
/// fetch-and-subtract the parent's children count.
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
mut unsafe_flow: UnsafeFlow,
|
mut unsafe_flow: UnsafeFlow,
|
||||||
_: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>) {
|
_: &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>) {
|
||||||
loop {
|
loop {
|
||||||
unsafe {
|
unsafe {
|
||||||
// Get a real flow.
|
// Get a real flow.
|
||||||
|
@ -285,14 +285,14 @@ trait ParallelPostorderFlowTraversal : PostorderFlowTraversal {
|
||||||
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
|
trait ParallelPreorderFlowTraversal : PreorderFlowTraversal {
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
unsafe_flows: UnsafeFlowList,
|
unsafe_flows: UnsafeFlowList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>);
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>);
|
||||||
|
|
||||||
fn should_record_thread_ids(&self) -> bool;
|
fn should_record_thread_ids(&self) -> bool;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn run_parallel_helper(&self,
|
fn run_parallel_helper(&self,
|
||||||
unsafe_flows: UnsafeFlowList,
|
unsafe_flows: UnsafeFlowList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>,
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>,
|
||||||
top_down_func: ChunkedFlowTraversalFunction,
|
top_down_func: ChunkedFlowTraversalFunction,
|
||||||
bottom_up_func: FlowTraversalFunction) {
|
bottom_up_func: FlowTraversalFunction) {
|
||||||
let mut discovered_child_flows = Vec::new();
|
let mut discovered_child_flows = Vec::new();
|
||||||
|
@ -338,7 +338,7 @@ impl<'a> ParallelPostorderFlowTraversal for BubbleISizes<'a> {}
|
||||||
impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
|
impl<'a> ParallelPreorderFlowTraversal for AssignISizes<'a> {
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
unsafe_flows: UnsafeFlowList,
|
unsafe_flows: UnsafeFlowList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>) {
|
||||||
self.run_parallel_helper(unsafe_flows,
|
self.run_parallel_helper(unsafe_flows,
|
||||||
proxy,
|
proxy,
|
||||||
assign_inline_sizes,
|
assign_inline_sizes,
|
||||||
|
@ -355,7 +355,7 @@ impl<'a> ParallelPostorderFlowTraversal for AssignBSizesAndStoreOverflow<'a> {}
|
||||||
impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> {
|
impl<'a> ParallelPreorderFlowTraversal for ComputeAbsolutePositions<'a> {
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
unsafe_flows: UnsafeFlowList,
|
unsafe_flows: UnsafeFlowList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlowList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>) {
|
||||||
self.run_parallel_helper(unsafe_flows,
|
self.run_parallel_helper(unsafe_flows,
|
||||||
proxy,
|
proxy,
|
||||||
compute_absolute_positions,
|
compute_absolute_positions,
|
||||||
|
@ -374,14 +374,14 @@ impl<'a> ParallelPostorderDomTraversal for ConstructFlows<'a> {}
|
||||||
impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> {
|
impl <'a> ParallelPreorderDomTraversal for RecalcStyleForNode<'a> {
|
||||||
fn run_parallel(&self,
|
fn run_parallel(&self,
|
||||||
unsafe_nodes: UnsafeLayoutNodeList,
|
unsafe_nodes: UnsafeLayoutNodeList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNodeList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeLayoutNodeList>) {
|
||||||
self.run_parallel_helper(unsafe_nodes, proxy, recalc_style, construct_flows)
|
self.run_parallel_helper(unsafe_nodes, proxy, recalc_style, construct_flows)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn recalc_style(unsafe_nodes: UnsafeLayoutNodeList,
|
fn recalc_style(unsafe_nodes: UnsafeLayoutNodeList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNodeList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeLayoutNodeList>) {
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let recalc_style_for_node_traversal = RecalcStyleForNode {
|
let recalc_style_for_node_traversal = RecalcStyleForNode {
|
||||||
layout_context: &layout_context,
|
layout_context: &layout_context,
|
||||||
|
@ -390,8 +390,8 @@ fn recalc_style(unsafe_nodes: UnsafeLayoutNodeList,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn construct_flows(unsafe_node: UnsafeLayoutNode,
|
fn construct_flows(unsafe_node: UnsafeLayoutNode,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeLayoutNodeList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeLayoutNodeList>) {
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let construct_flows_traversal = ConstructFlows {
|
let construct_flows_traversal = ConstructFlows {
|
||||||
layout_context: &layout_context,
|
layout_context: &layout_context,
|
||||||
|
@ -400,8 +400,8 @@ fn construct_flows(unsafe_node: UnsafeLayoutNode,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_inline_sizes(unsafe_flows: UnsafeFlowList,
|
fn assign_inline_sizes(unsafe_flows: UnsafeFlowList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>) {
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let assign_inline_sizes_traversal = AssignISizes {
|
let assign_inline_sizes_traversal = AssignISizes {
|
||||||
layout_context: &layout_context,
|
layout_context: &layout_context,
|
||||||
|
@ -411,8 +411,8 @@ fn assign_inline_sizes(unsafe_flows: UnsafeFlowList,
|
||||||
|
|
||||||
fn assign_block_sizes_and_store_overflow(
|
fn assign_block_sizes_and_store_overflow(
|
||||||
unsafe_flow: UnsafeFlow,
|
unsafe_flow: UnsafeFlow,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper,UnsafeFlowList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext,UnsafeFlowList>) {
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow {
|
let assign_block_sizes_traversal = AssignBSizesAndStoreOverflow {
|
||||||
layout_context: &layout_context,
|
layout_context: &layout_context,
|
||||||
|
@ -422,8 +422,8 @@ fn assign_block_sizes_and_store_overflow(
|
||||||
|
|
||||||
fn compute_absolute_positions(
|
fn compute_absolute_positions(
|
||||||
unsafe_flows: UnsafeFlowList,
|
unsafe_flows: UnsafeFlowList,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlowList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>) {
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let compute_absolute_positions_traversal = ComputeAbsolutePositions {
|
let compute_absolute_positions_traversal = ComputeAbsolutePositions {
|
||||||
layout_context: &layout_context,
|
layout_context: &layout_context,
|
||||||
|
@ -432,8 +432,8 @@ fn compute_absolute_positions(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list(unsafe_flow: UnsafeFlow,
|
fn build_display_list(unsafe_flow: UnsafeFlow,
|
||||||
proxy: &mut WorkerProxy<SharedLayoutContextWrapper, UnsafeFlowList>) {
|
proxy: &mut WorkerProxy<SharedLayoutContext, UnsafeFlowList>) {
|
||||||
let shared_layout_context = unsafe { &*(proxy.user_data().0) };
|
let shared_layout_context = proxy.user_data();
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
|
|
||||||
let build_display_list_traversal = BuildDisplayList {
|
let build_display_list_traversal = BuildDisplayList {
|
||||||
|
@ -444,20 +444,20 @@ fn build_display_list(unsafe_flow: UnsafeFlow,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_queue_with_custom_work_data_type<To,F>(
|
fn run_queue_with_custom_work_data_type<To,F>(
|
||||||
queue: &mut WorkQueue<SharedLayoutContextWrapper, WorkQueueData>,
|
queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>,
|
||||||
callback: F,
|
callback: F,
|
||||||
shared_layout_context: &SharedLayoutContext)
|
shared_layout_context: &SharedLayoutContext)
|
||||||
where To: 'static + Send, F: FnOnce(&mut WorkQueue<SharedLayoutContextWrapper,To>) {
|
where To: 'static + Send, F: FnOnce(&mut WorkQueue<SharedLayoutContext,To>) {
|
||||||
let queue: &mut WorkQueue<SharedLayoutContextWrapper,To> = unsafe {
|
let queue: &mut WorkQueue<SharedLayoutContext,To> = unsafe {
|
||||||
mem::transmute(queue)
|
mem::transmute(queue)
|
||||||
};
|
};
|
||||||
callback(queue);
|
callback(queue);
|
||||||
queue.run(SharedLayoutContextWrapper(shared_layout_context as *const _));
|
queue.run(shared_layout_context);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn traverse_dom_preorder(root: LayoutNode,
|
pub fn traverse_dom_preorder(root: LayoutNode,
|
||||||
shared_layout_context: &SharedLayoutContext,
|
shared_layout_context: &SharedLayoutContext,
|
||||||
queue: &mut WorkQueue<SharedLayoutContextWrapper, WorkQueueData>) {
|
queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>) {
|
||||||
run_queue_with_custom_work_data_type(queue, |queue| {
|
run_queue_with_custom_work_data_type(queue, |queue| {
|
||||||
queue.push(WorkUnit {
|
queue.push(WorkUnit {
|
||||||
fun: recalc_style,
|
fun: recalc_style,
|
||||||
|
@ -471,7 +471,7 @@ pub fn traverse_flow_tree_preorder(
|
||||||
profiler_metadata: ProfilerMetadata,
|
profiler_metadata: ProfilerMetadata,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
shared_layout_context: &SharedLayoutContext,
|
shared_layout_context: &SharedLayoutContext,
|
||||||
queue: &mut WorkQueue<SharedLayoutContextWrapper, WorkQueueData>) {
|
queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>) {
|
||||||
if opts::get().bubble_inline_sizes_separately {
|
if opts::get().bubble_inline_sizes_separately {
|
||||||
let layout_context = LayoutContext::new(shared_layout_context);
|
let layout_context = LayoutContext::new(shared_layout_context);
|
||||||
let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
|
let bubble_inline_sizes = BubbleISizes { layout_context: &layout_context };
|
||||||
|
@ -494,7 +494,7 @@ pub fn build_display_list_for_subtree(
|
||||||
profiler_metadata: ProfilerMetadata,
|
profiler_metadata: ProfilerMetadata,
|
||||||
time_profiler_chan: time::ProfilerChan,
|
time_profiler_chan: time::ProfilerChan,
|
||||||
shared_layout_context: &SharedLayoutContext,
|
shared_layout_context: &SharedLayoutContext,
|
||||||
queue: &mut WorkQueue<SharedLayoutContextWrapper, WorkQueueData>) {
|
queue: &mut WorkQueue<SharedLayoutContext, WorkQueueData>) {
|
||||||
run_queue_with_custom_work_data_type(queue, |queue| {
|
run_queue_with_custom_work_data_type(queue, |queue| {
|
||||||
profile(time::ProfilerCategory::LayoutParallelWarmup, profiler_metadata,
|
profile(time::ProfilerCategory::LayoutParallelWarmup, profiler_metadata,
|
||||||
time_profiler_chan, || {
|
time_profiler_chan, || {
|
||||||
|
|
|
@ -169,7 +169,10 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
|
||||||
let mut proxy = WorkerProxy {
|
let mut proxy = WorkerProxy {
|
||||||
worker: &mut deque,
|
worker: &mut deque,
|
||||||
ref_count: ref_count,
|
ref_count: ref_count,
|
||||||
queue_data: queue_data,
|
// queue_data is kept alive in the stack frame of
|
||||||
|
// WorkQueue::run until we send the
|
||||||
|
// SupervisorMsg::ReturnDeque message below.
|
||||||
|
queue_data: unsafe { &*queue_data },
|
||||||
worker_index: self.index as u8,
|
worker_index: self.index as u8,
|
||||||
};
|
};
|
||||||
(work_unit.fun)(work_unit.data, &mut proxy);
|
(work_unit.fun)(work_unit.data, &mut proxy);
|
||||||
|
@ -193,7 +196,7 @@ impl<QueueData: Send, WorkData: Send> WorkerThread<QueueData, WorkData> {
|
||||||
pub struct WorkerProxy<'a, QueueData: 'a, WorkData: 'a> {
|
pub struct WorkerProxy<'a, QueueData: 'a, WorkData: 'a> {
|
||||||
worker: &'a mut Worker<WorkUnit<QueueData, WorkData>>,
|
worker: &'a mut Worker<WorkUnit<QueueData, WorkData>>,
|
||||||
ref_count: *mut AtomicUsize,
|
ref_count: *mut AtomicUsize,
|
||||||
queue_data: *const QueueData,
|
queue_data: &'a QueueData,
|
||||||
worker_index: u8,
|
worker_index: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,10 +212,8 @@ impl<'a, QueueData: 'static, WorkData: Send + 'static> WorkerProxy<'a, QueueData
|
||||||
|
|
||||||
/// Retrieves the queue user data.
|
/// Retrieves the queue user data.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn user_data<'b>(&'b self) -> &'b QueueData {
|
pub fn user_data(&self) -> &'a QueueData {
|
||||||
unsafe {
|
self.queue_data
|
||||||
mem::transmute(self.queue_data)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the index of the worker.
|
/// Retrieves the index of the worker.
|
||||||
|
@ -302,13 +303,13 @@ impl<QueueData: Send, WorkData: Send> WorkQueue<QueueData, WorkData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Synchronously runs all the enqueued tasks and waits for them to complete.
|
/// Synchronously runs all the enqueued tasks and waits for them to complete.
|
||||||
pub fn run(&mut self, data: QueueData) {
|
pub fn run(&mut self, data: &QueueData) {
|
||||||
// Tell the workers to start.
|
// Tell the workers to start.
|
||||||
let mut work_count = AtomicUsize::new(self.work_count);
|
let mut work_count = AtomicUsize::new(self.work_count);
|
||||||
for worker in self.workers.iter_mut() {
|
for worker in self.workers.iter_mut() {
|
||||||
worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(),
|
worker.chan.send(WorkerMsg::Start(worker.deque.take().unwrap(),
|
||||||
&mut work_count,
|
&mut work_count,
|
||||||
&data)).unwrap()
|
data)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Wait for the work to finish.
|
// Wait for the work to finish.
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue