Crate jobsys[][src]

Lockless Work Stealing Job System.

Features

  • Lockless work stealing queue
  • 0 runtime allocations
  • Jobs are executed from closures
  • Chaining and grouping of jobs
  • Parallel for_each abstraction

General Notes

This crate provides job system with 0 allocation overhead at runtime. What this means in practice is, that once the instance is created, there are no more memory allocations required to execute jobs.

Jobs are allocated from a Job Pool with a fixed capacity. Each thread gets their own pool and queue. The system uses a fixed storage space where it stores the closure for each job. The default storage is set to 64 bytes. This can be extended to 128 by enabling the feature “job_storage_128”.

When a Job finishes execution there is a possibility to start other jobs. See JobSystem::chain() for more details.

Additionally, it’s recommended that, in order to avoid running out of jobs during execution, you regularly ensure that you all your previous jobs have finished executing.

Finally, this crate runs on rust stable and has been tested with rust 1.50.0 with the 2018 edition.

Panics

Due to the queues having a fixed size, if we start filling all the queues up to full capacity there is a small chance that a worker thread may not be able to queue chained jobs. When this happens the system will panic as there is no way to recover from this. The queues come with debug asserts which will detect this situation.

Examples

Start and Wait

let mut js = jobsys::JobSystem::new(4, 512).unwrap();
let mut handle = js.create(|| { println!("Hello World!");}).unwrap();
js.run(&mut handle).expect("Failed to run job");
js.wait(&mut handle);

Grouping

Ensure one job does not complete until other jobs have finished as well.

let mut js = jobsys::JobSystem::new(4, 512).unwrap();
let mut parent = js.create(|| {}).unwrap();
let mut child = js.create_with_parent(&mut parent, || { println!("Hello World!");}).unwrap();
js.run(&child).expect("Failed to start child");
js.run(&parent).expect("Failed to start parent");
js.wait(&parent); // Parent will only finish when both it and its child have finished

Chaining

Launch new jobs as soon as one job completes.

let mut js = jobsys::JobSystem::new(4, 512).unwrap();
let mut first = js.create(|| { println!("Hello World Chained!");}).unwrap();
let mut second = js.create(|| { println!("Hello World Chained!");}).unwrap();
js.chain(&mut first, &second).expect("Failed to chain job, maximum chain count exceeded");
js.run(&first).expect("Failed to start job");
js.wait(&second); // Second will only be executed after first completes

Parallel

See for_each() and for_each_with_result() for more details.

let mut js = jobsys::JobSystem::new(4, 512).unwrap();
let mut array = [0_u32; 100];
js.for_each(|slice: &mut [u32], start, _end| {
        for i in 0..slice.len() {
            slice[i] = (start + i) as u32;
        }
    },
    &mut array).expect("Failed to start jobs");

Structs

JobHandle

Handle which represents an allocated job.

JobSystem

Work Stealing JobSystem.

Enums

Error