Skip to content

Commit

Permalink
Merge pull request #224 from Imberflur/replace-trustcell-with-atomicr…
Browse files Browse the repository at this point in the history
…efcell
  • Loading branch information
Imberflur authored Apr 25, 2023
2 parents 493d504 + b57f065 commit e898794
Show file tree
Hide file tree
Showing 8 changed files with 78 additions and 730 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ rust-version = "1.59.0"
[dependencies]
ahash = "0.7.6"
arrayvec = "0.7.2"
atomic_refcell = "0.1.10" # part of public API
rayon = { version = "1.5.0", optional = true }
shred-derive = { path = "shred-derive", version = "0.6.3", optional = true }
smallvec = "1.6.1"
Expand Down
21 changes: 13 additions & 8 deletions benches/bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,11 +241,14 @@ fn bench_fetching(b: &mut Bencher) {

#[bench]
fn bench_indirection_refs(b: &mut Bencher) {
use shred::cell::{Ref, TrustCell};
use shred::cell::{AtomicRef, AtomicRefCell};
use std::ops::Deref;

let cell = TrustCell::new(Box::new(10));
let refs: Vec<Ref<'_, Box<usize>>> = std::iter::repeat(cell.borrow()).take(10000).collect();
let cell = AtomicRefCell::new(Box::new(10));
let borrow = cell.borrow();
let refs: Vec<AtomicRef<'_, Box<usize>>> = std::iter::repeat_with(|| AtomicRef::clone(&borrow))
.take(10000)
.collect();

b.iter(|| {
let sum: usize = refs.iter().map(|v| v.deref().deref()).sum();
Expand All @@ -255,13 +258,15 @@ fn bench_indirection_refs(b: &mut Bencher) {

#[bench]
fn bench_direct_refs(b: &mut Bencher) {
use shred::cell::{Ref, TrustCell};
use shred::cell::{AtomicRef, AtomicRefCell};
use std::ops::Deref;

let cell = TrustCell::new(Box::new(10));
let refs: Vec<Ref<'_, usize>> = std::iter::repeat(cell.borrow().map(Box::as_ref))
.take(10000)
.collect();
let cell = AtomicRefCell::new(Box::new(10));
let mapped_borrow = AtomicRef::map(cell.borrow(), Box::as_ref);
let refs: Vec<AtomicRef<'_, usize>> =
std::iter::repeat_with(|| AtomicRef::clone(&mapped_borrow))
.take(10000)
.collect();

b.iter(|| {
let sum: usize = refs.iter().map(|v| v.deref()).sum();
Expand Down
52 changes: 25 additions & 27 deletions examples/dyn_sys_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extern crate shred;
use ahash::AHashMap as HashMap;

use shred::{
cell::{Ref, RefMut},
cell::{AtomicRef, AtomicRefMut},
Accessor, AccessorCow, CastFrom, DispatcherBuilder, DynamicSystemData, MetaTable, Read,
Resource, ResourceId, System, SystemData, World,
};
Expand Down Expand Up @@ -54,32 +54,20 @@ impl<'a> System<'a> for DynamicSystem {
let reads: Vec<&dyn Reflection> = data
.reads
.iter()
.map(|resource| {
// explicitly use the type because we're dealing with `&Resource` which is
// implemented by a lot of types; we don't want to accidentally
// get a `&Box<Resource>` and cast it to a `&Resource`.
let res = Box::as_ref(resource);

meta.get(res).expect("Not registered in meta table")
})
.map(|resource| meta.get(&**resource).expect("Not registered in meta table"))
.collect();

let writes: Vec<&mut dyn Reflection> = data
.writes
.iter_mut()
.map(|resource| {
// explicitly use the type because we're dealing with `&mut Resource` which is
// implemented by a lot of types; we don't want to accidentally get a
// `&mut Box<Resource>` and cast it to a `&mut Resource`.
let res = Box::as_mut(resource);

// For some reason this needs a type ascription, otherwise Rust will think it's
// a `&mut (Reflection + '_)` (as opposed to `&mut (Reflection + 'static)`.
let res: &mut dyn Reflection = meta.get_mut(res).expect(
// a `&mut (Reflaction + '_)` (as opposed to `&mut (Reflection + 'static)`. (Note this
// isn't needed in newer rust version but fails on the MSRV of 1.59.0).
let res: &mut dyn Reflection = meta.get_mut(&mut **resource).expect(
"Not registered in meta \
table",
);

res
})
.collect();
Expand Down Expand Up @@ -150,37 +138,47 @@ struct ScriptInput<'a> {

struct ScriptSystemData<'a> {
meta_table: Read<'a, ReflectionTable>,
reads: Vec<Ref<'a, Box<dyn Resource + 'static>>>,
writes: Vec<RefMut<'a, Box<dyn Resource + 'static>>>,
reads: Vec<AtomicRef<'a, dyn Resource + 'static>>,
writes: Vec<AtomicRefMut<'a, dyn Resource + 'static>>,
}

impl<'a> DynamicSystemData<'a> for ScriptSystemData<'a> {
type Accessor = Dependencies;

fn setup(_accessor: &Dependencies, _res: &mut World) {}

fn fetch(access: &Dependencies, res: &'a World) -> Self {
fn fetch(access: &Dependencies, world: &'a World) -> Self {
let reads = access
.reads
.iter()
.map(|id| {
res.try_fetch_internal(id.clone())
.expect("bug: the requested resource does not exist")
.borrow()
let id = id.clone();
// SAFETY: We don't expose mutable reference to the Box or swap it out.
let res = unsafe { world.try_fetch_internal(id) };
AtomicRef::map(
res.expect("bug: the requested resource does not exist")
.borrow(),
Box::as_ref,
)
})
.collect();
let writes = access
.writes
.iter()
.map(|id| {
res.try_fetch_internal(id.clone())
.expect("bug: the requested resource does not exist")
.borrow_mut()
let id = id.clone();
// SAFETY: We don't expose mutable reference to the Box or swap it out.
let res = unsafe { world.try_fetch_internal(id) };
AtomicRefMut::map(
res.expect("bug: the requested resource does not exist")
.borrow_mut(),
Box::as_mut,
)
})
.collect();

ScriptSystemData {
meta_table: SystemData::fetch(res),
meta_table: SystemData::fetch(world),
reads,
writes,
}
Expand Down
Loading

0 comments on commit e898794

Please sign in to comment.