mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-02 00:01:16 +00:00
Add find_task
This commit is contained in:
parent
8d1fad334f
commit
aea125549a
3 changed files with 48 additions and 3 deletions
|
@ -12,6 +12,8 @@ use roc_module::ident::{Ident, ModuleName};
|
|||
use roc_module::symbol::{IdentIds, Interns, ModuleId, ModuleIds, Symbol};
|
||||
use roc_parse::ast::{self, Attempting, ExposesEntry, ImportsEntry};
|
||||
use roc_parse::module::module_defs;
|
||||
use crossbeam::deque::{Injector, Steal, Stealer, Worker};
|
||||
use std::iter;
|
||||
use roc_parse::parser::{Fail, Parser, State};
|
||||
use roc_region::all::{Located, Region};
|
||||
use roc_solve::module::SolvedModule;
|
||||
|
@ -157,7 +159,7 @@ type MsgReceiver = mpsc::Receiver<Msg>;
|
|||
/// specializations, so if none of their specializations changed, we don't even need
|
||||
/// to rebuild the module and can link in the cached one directly.)
|
||||
#[allow(clippy::cognitive_complexity)]
|
||||
pub async fn load<'a>(
|
||||
pub fn load<'a>(
|
||||
stdlib: &StdLib,
|
||||
src_dir: PathBuf,
|
||||
filename: PathBuf,
|
||||
|
@ -543,6 +545,35 @@ fn load_module(
|
|||
load_filename(filename, msg_tx, module_ids)
|
||||
}
|
||||
|
||||
/// Find a task according to the following algorithm:
|
||||
///
|
||||
/// 1. Look in a local Worker queue. If it has a task, pop it off the queue and return it.
|
||||
/// 2. If that queue was empty, ask the global queue for a task.
|
||||
/// 3. If the global queue is also empty, iterate through each Stealer (each Worker queue has a
|
||||
/// corresponding Stealer, which can steal from it. Stealers can be shared across threads.)
|
||||
///
|
||||
/// Based on https://docs.rs/crossbeam/0.7.3/crossbeam/deque/index.html#examples
|
||||
fn find_task<T>(
|
||||
local: &Worker<T>,
|
||||
global: &Injector<T>,
|
||||
stealers: &[Stealer<T>],
|
||||
) -> Option<T> {
|
||||
// Pop a task from the local queue, if not empty.
|
||||
local.pop().or_else(|| {
|
||||
// Otherwise, we need to look for a task elsewhere.
|
||||
iter::repeat_with(|| {
|
||||
// Try stealing a task from the global queue.
|
||||
global.steal()
|
||||
// Or try stealing a task from one of the other threads.
|
||||
.or_else(|| stealers.iter().map(|s| s.steal()).collect())
|
||||
})
|
||||
// Loop while no task was stolen and any steal operation needs to be retried.
|
||||
.find(|s| !s.is_retry())
|
||||
// Extract the stolen task, if there is one.
|
||||
.and_then(|s| s.success())
|
||||
})
|
||||
}
|
||||
|
||||
fn parse_src(
|
||||
filename: PathBuf,
|
||||
msg_tx: MsgSender,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue