Skip to content

Commit

Permalink
(almost) encansulate Runtime into Zalsa
Browse files Browse the repository at this point in the history
The distinction is dumb and should go away.
But we still need it for a bit.
  • Loading branch information
nikomatsakis committed Jul 27, 2024
1 parent 1acef75 commit 475c3bb
Show file tree
Hide file tree
Showing 21 changed files with 136 additions and 111 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ rustc-hash = "2.0.0"
salsa-macro-rules = { version = "0.1.0", path = "components/salsa-macro-rules" }
salsa-macros = { path = "components/salsa-macros" }
smallvec = "1.0.0"
lazy_static = "1.5.0"

[dev-dependencies]
annotate-snippets = "0.11.4"
Expand Down
6 changes: 3 additions & 3 deletions components/salsa-macro-rules/src/setup_input_struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,12 +86,12 @@ macro_rules! setup_input_struct {
})
}

pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, &mut $zalsa::Runtime) {
pub fn ingredient_mut(db: &mut dyn $zalsa::Database) -> (&mut $zalsa_struct::IngredientImpl<Self>, $zalsa::Revision) {
let zalsa_mut = db.zalsa_mut();
let index = zalsa_mut.add_or_lookup_jar_by_type(&<$zalsa_struct::JarImpl<$Configuration>>::default());
let (ingredient, runtime) = zalsa_mut.lookup_ingredient_mut(index);
let (ingredient, current_revision) = zalsa_mut.lookup_ingredient_mut(index);
let ingredient = ingredient.assert_type_mut::<$zalsa_struct::IngredientImpl<Self>>();
(ingredient, runtime)
(ingredient, current_revision)
}
}

Expand Down
5 changes: 2 additions & 3 deletions src/accumulator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,7 @@ impl<A: Accumulator> IngredientImpl<A> {

pub fn push(&self, db: &dyn crate::Database, value: A) {
local_state::attach(db, |state| {
let runtime = db.zalsa().runtime();
let current_revision = runtime.current_revision();
let current_revision = db.zalsa().current_revision();
let (active_query, _) = match state.active_query() {
Some(pair) => pair,
None => {
Expand Down Expand Up @@ -163,7 +162,7 @@ impl<A: Accumulator> Ingredient for IngredientImpl<A> {
output_key: Option<crate::Id>,
) {
assert!(output_key.is_none());
let current_revision = db.zalsa().runtime().current_revision();
let current_revision = db.zalsa().current_revision();
if let Some(mut v) = self.map.get_mut(&executor) {
// The value is still valid in the new revision.
v.produced_at = current_revision;
Expand Down
7 changes: 4 additions & 3 deletions src/active_query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ use crate::{
durability::Durability,
hash::{FxIndexMap, FxIndexSet},
key::{DatabaseKeyIndex, DependencyIndex},
local_state::EMPTY_DEPENDENCIES,
tracked_struct::Disambiguator,
Cycle, Revision, Runtime,
Cycle, Revision,
};

use super::local_state::{EdgeKind, QueryEdges, QueryOrigin, QueryRevisions};
Expand Down Expand Up @@ -86,9 +87,9 @@ impl ActiveQuery {
self.input_outputs.contains(&(EdgeKind::Output, key))
}

pub(crate) fn revisions(&self, runtime: &Runtime) -> QueryRevisions {
pub(crate) fn revisions(&self) -> QueryRevisions {
let input_outputs = if self.input_outputs.is_empty() {
runtime.empty_dependencies()
EMPTY_DEPENDENCIES.clone()
} else {
self.input_outputs.iter().copied().collect()
};
Expand Down
10 changes: 5 additions & 5 deletions src/database.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ pub trait Database: ZalsaDatabase + AsDynDatabase {
/// will block until that snapshot is dropped -- if that snapshot
/// is owned by the current thread, this could trigger deadlock.
fn synthetic_write(&mut self, durability: Durability) {
let runtime = self.zalsa_mut().runtime_mut();
runtime.new_revision();
runtime.report_tracked_write(durability);
let zalsa_mut = self.zalsa_mut();
zalsa_mut.new_revision();
zalsa_mut.report_tracked_write(durability);
}

/// Reports that the query depends on some state unknown to salsa.
Expand All @@ -33,7 +33,7 @@ pub trait Database: ZalsaDatabase + AsDynDatabase {
fn report_untracked_read(&self) {
let db = self.as_dyn_database();
local_state::attach(db, |state| {
state.report_untracked_read(db.zalsa().runtime().current_revision())
state.report_untracked_read(db.zalsa().current_revision())
})
}

Expand Down Expand Up @@ -65,7 +65,7 @@ impl<T: Database> AsDynDatabase for T {
}

pub fn current_revision<Db: ?Sized + Database>(db: &Db) -> Revision {
db.zalsa().runtime().current_revision()
db.zalsa().current_revision()
}

impl dyn Database {
Expand Down
2 changes: 1 addition & 1 deletion src/function/accumulated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ where
{
local_state::attach(db, |local_state| {
let zalsa = db.zalsa();
let current_revision = zalsa.runtime().current_revision();
let current_revision = zalsa.current_revision();

let Some(accumulator) = <accumulator::IngredientImpl<A>>::from_db(db) else {
return vec![];
Expand Down
14 changes: 2 additions & 12 deletions src/function/execute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ where
opt_old_memo: Option<Arc<Memo<C::Output<'_>>>>,
) -> StampedValue<&C::Output<'db>> {
let zalsa = db.zalsa();
let runtime = zalsa.runtime();
let revision_now = runtime.current_revision();
let revision_now = zalsa.current_revision();
let database_key_index = active_query.database_key_index;

tracing::info!("{:?}: executing query", database_key_index);
Expand Down Expand Up @@ -68,16 +67,7 @@ where
}
}
};
let mut revisions = active_query.pop(runtime);

// We assume that query is side-effect free -- that is, does
// not mutate the "inputs" to the query system. Sanity check
// that assumption here, at least to the best of our ability.
assert_eq!(
runtime.current_revision(),
revision_now,
"revision altered during query execution",
);
let mut revisions = active_query.pop();

// If the new value is equal to the old one, then it didn't
// really change, even if some of its inputs have. So we can
Expand Down
4 changes: 2 additions & 2 deletions src/function/fetch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ where
let memo_guard = self.memo_map.get(key);
if let Some(memo) = &memo_guard {
if memo.value.is_some() {
let runtime = db.zalsa().runtime();
if self.shallow_verify_memo(db, runtime, self.database_key_index(key), memo) {
let zalsa = db.zalsa();
if self.shallow_verify_memo(db, zalsa, self.database_key_index(key), memo) {
let value = unsafe {
// Unsafety invariant: memo is present in memo_map
self.extend_memo_lifetime(memo).unwrap()
Expand Down
26 changes: 15 additions & 11 deletions src/function/maybe_changed_after.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::{
key::DatabaseKeyIndex,
local_state::{self, ActiveQueryGuard, EdgeKind, LocalState, QueryOrigin},
runtime::StampedValue,
storage::ZalsaDatabase as _,
AsDynDatabase as _, Id, Revision, Runtime,
storage::{Zalsa, ZalsaDatabase as _},
AsDynDatabase as _, Id, Revision,
};

use super::{memo::Memo, Configuration, IngredientImpl};
Expand All @@ -21,7 +21,7 @@ where
revision: Revision,
) -> bool {
local_state::attach(db.as_dyn_database(), |local_state| {
let runtime = db.zalsa().runtime();
let zalsa = db.zalsa();
local_state.unwind_if_revision_cancelled(db.as_dyn_database());

loop {
Expand All @@ -34,7 +34,7 @@ where
// Check if we have a verified version: this is the hot path.
let memo_guard = self.memo_map.get(key);
if let Some(memo) = &memo_guard {
if self.shallow_verify_memo(db, runtime, database_key_index, memo) {
if self.shallow_verify_memo(db, zalsa, database_key_index, memo) {
return memo.revisions.changed_at > revision;
}
drop(memo_guard); // release the arc-swap guard before cold path
Expand Down Expand Up @@ -102,12 +102,12 @@ where
pub(super) fn shallow_verify_memo(
&self,
db: &C::DbView,
runtime: &Runtime,
zalsa: &dyn Zalsa,
database_key_index: DatabaseKeyIndex,
memo: &Memo<C::Output<'_>>,
) -> bool {
let verified_at = memo.verified_at.load();
let revision_now = runtime.current_revision();
let revision_now = zalsa.current_revision();

tracing::debug!("{database_key_index:?}: shallow_verify_memo(memo = {memo:#?})",);

Expand All @@ -116,10 +116,10 @@ where
return true;
}

if memo.check_durability(runtime) {
if memo.check_durability(zalsa) {
// No input of the suitable durability has changed since last verified.
let db = db.as_dyn_database();
memo.mark_as_verified(db, runtime, database_key_index);
memo.mark_as_verified(db, revision_now, database_key_index);
memo.mark_outputs_as_verified(db, database_key_index);
return true;
}
Expand All @@ -141,12 +141,12 @@ where
old_memo: &Memo<C::Output<'_>>,
active_query: &ActiveQueryGuard<'_>,
) -> bool {
let runtime = db.zalsa().runtime();
let zalsa = db.zalsa();
let database_key_index = active_query.database_key_index;

tracing::debug!("{database_key_index:?}: deep_verify_memo(old_memo = {old_memo:#?})",);

if self.shallow_verify_memo(db, runtime, database_key_index, old_memo) {
if self.shallow_verify_memo(db, zalsa, database_key_index, old_memo) {
return true;
}

Expand Down Expand Up @@ -215,7 +215,11 @@ where
}
}

old_memo.mark_as_verified(db.as_dyn_database(), runtime, database_key_index);
old_memo.mark_as_verified(
db.as_dyn_database(),
zalsa.current_revision(),
database_key_index,
);
true
}
}
12 changes: 6 additions & 6 deletions src/function/memo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use arc_swap::{ArcSwap, Guard};
use crossbeam::atomic::AtomicCell;

use crate::{
hash::FxDashMap, key::DatabaseKeyIndex, local_state::QueryRevisions, Event, EventKind, Id,
Revision, Runtime,
hash::FxDashMap, key::DatabaseKeyIndex, local_state::QueryRevisions, storage::Zalsa, Event,
EventKind, Id, Revision,
};

use super::Configuration;
Expand Down Expand Up @@ -129,8 +129,8 @@ impl<V> Memo<V> {
}
}
/// True if this memo is known not to have changed based on its durability.
pub(super) fn check_durability(&self, runtime: &Runtime) -> bool {
let last_changed = runtime.last_changed_revision(self.revisions.durability);
pub(super) fn check_durability(&self, zalsa: &dyn Zalsa) -> bool {
let last_changed = zalsa.last_changed_revision(self.revisions.durability);
let verified_at = self.verified_at.load();
tracing::debug!(
"check_durability(last_changed={:?} <= verified_at={:?}) = {:?}",
Expand All @@ -146,7 +146,7 @@ impl<V> Memo<V> {
pub(super) fn mark_as_verified(
&self,
db: &dyn crate::Database,
runtime: &crate::Runtime,
revision_now: Revision,
database_key_index: DatabaseKeyIndex,
) {
db.salsa_event(Event {
Expand All @@ -156,7 +156,7 @@ impl<V> Memo<V> {
},
});

self.verified_at.store(runtime.current_revision());
self.verified_at.store(revision_now);
}

pub(super) fn mark_outputs_as_verified(
Expand Down
10 changes: 7 additions & 3 deletions src/function/specify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ where
// - a result that is verified in the current revision, because it was set, which will use the set value
// - a result that is NOT verified and has untracked inputs, which will re-execute (and likely panic)

let revision = db.zalsa().runtime().current_revision();
let revision = db.zalsa().current_revision();
let mut revisions = QueryRevisions {
changed_at: current_deps.changed_at,
durability: current_deps.durability,
Expand Down Expand Up @@ -101,7 +101,7 @@ where
executor: DatabaseKeyIndex,
key: Id,
) {
let runtime = db.zalsa().runtime();
let zalsa = db.zalsa();

let memo = match self.memo_map.get(key) {
Some(m) => m,
Expand All @@ -119,6 +119,10 @@ where
}

let database_key_index = self.database_key_index(key);
memo.mark_as_verified(db.as_dyn_database(), runtime, database_key_index);
memo.mark_as_verified(
db.as_dyn_database(),
zalsa.current_revision(),
database_key_index,
);
}
}
2 changes: 1 addition & 1 deletion src/function/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ impl SyncMap {
local_state: &LocalState,
database_key_index: DatabaseKeyIndex,
) -> Option<ClaimGuard<'me>> {
let runtime = db.zalsa().runtime();
let runtime = db.zalsa().runtimex();
let thread_id = std::thread::current().id();
match self.sync_map.entry(database_key_index.key_index) {
dashmap::mapref::entry::Entry::Vacant(entry) => {
Expand Down
2 changes: 1 addition & 1 deletion src/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ impl<Db: Database> Handle<Db> {
/// same database!
fn cancel_others(&mut self) {
let zalsa = self.db().zalsa();
zalsa.runtime().set_cancellation_flag();
zalsa.set_cancellation_flag();

self.db().salsa_event(Event {
thread_id: std::thread::current().id(),
Expand Down
6 changes: 2 additions & 4 deletions src/input.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ use crate::{
key::{DatabaseKeyIndex, DependencyIndex},
local_state::{self, QueryOrigin},
plumbing::{Jar, Stamp},
runtime::Runtime,
storage::IngredientIndex,
Database, Durability, Id, Revision,
};
Expand Down Expand Up @@ -121,18 +120,17 @@ impl<C: Configuration> IngredientImpl<C> {
/// * `setter`, function that modifies the fields tuple; should only modify the element for `field_index`
pub fn set_field<R>(
&mut self,
runtime: &mut Runtime,
current_revision: Revision,
id: C::Struct,
field_index: usize,
durability: Durability,
setter: impl FnOnce(&mut C::Fields) -> R,
) -> R {
let revision = runtime.current_revision();
let id: Id = id.as_id();
let mut r = self.struct_map.update(id);
let stamp = &mut r.stamps[field_index];
stamp.durability = durability;
stamp.changed_at = revision;
stamp.changed_at = current_revision;
setter(&mut r.fields)
}

Expand Down
12 changes: 6 additions & 6 deletions src/input/setter.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::marker::PhantomData;

use crate::input::{Configuration, IngredientImpl};
use crate::{Durability, Runtime};
use crate::{Durability, Revision};

/// Setter for a field of an input.
pub trait Setter: Sized {
Expand All @@ -12,7 +12,7 @@ pub trait Setter: Sized {

#[must_use]
pub struct SetterImpl<'setter, C: Configuration, S, F> {
runtime: &'setter mut Runtime,
current_revision: Revision,
id: C::Struct,
ingredient: &'setter mut IngredientImpl<C>,
durability: Durability,
Expand All @@ -27,14 +27,14 @@ where
S: FnOnce(&mut C::Fields, F) -> F,
{
pub fn new(
runtime: &'setter mut Runtime,
current_revision: Revision,
id: C::Struct,
field_index: usize,
ingredient: &'setter mut IngredientImpl<C>,
setter: S,
) -> Self {
SetterImpl {
runtime,
current_revision,
id,
field_index,
ingredient,
Expand All @@ -59,7 +59,7 @@ where

fn to(self, value: F) -> F {
let Self {
runtime,
current_revision,
id,
ingredient,
durability,
Expand All @@ -68,7 +68,7 @@ where
phantom: _,
} = self;

ingredient.set_field(runtime, id, field_index, durability, |tuple| {
ingredient.set_field(current_revision, id, field_index, durability, |tuple| {
setter(tuple, value)
})
}
Expand Down
Loading

0 comments on commit 475c3bb

Please sign in to comment.