Skip to content

Commit d7e0774

Browse files
committed
Remove inline from validate_same_iteration
1 parent 8d6c02c commit d7e0774

File tree

1 file changed

+44
-106
lines changed

1 file changed

+44
-106
lines changed

src/function/maybe_changed_after.rs

Lines changed: 44 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use rustc_hash::FxHashMap;
22

33
#[cfg(feature = "accumulator")]
44
use crate::accumulator::accumulated_map::InputAccumulatedValues;
5-
use crate::cycle::{CycleRecoveryStrategy, ProvisionalStatus};
5+
use crate::cycle::{CycleHeads, CycleRecoveryStrategy, ProvisionalStatus};
66
use crate::function::memo::{Memo, TryClaimCycleHeadsIter, TryClaimHeadsResult};
77
use crate::function::sync::ClaimResult;
88
use crate::function::{Configuration, IngredientImpl};
@@ -453,6 +453,48 @@ where
453453
database_key_index: DatabaseKeyIndex,
454454
memo: &Memo<'_, C>,
455455
) -> bool {
456+
#[cold]
457+
#[inline(never)]
458+
fn validate_same_iteration_cold(
459+
zalsa: &Zalsa,
460+
zalsa_local: &ZalsaLocal,
461+
cycle_heads: &CycleHeads,
462+
verified_at: Revision,
463+
) -> bool {
464+
let mut cycle_heads_iter = TryClaimCycleHeadsIter::new(zalsa, zalsa_local, cycle_heads);
465+
466+
while let Some(cycle_head) = cycle_heads_iter.next() {
467+
match cycle_head {
468+
TryClaimHeadsResult::Cycle {
469+
head_iteration_count,
470+
current_iteration_count,
471+
verified_at: head_verified_at,
472+
} => {
473+
if head_verified_at != verified_at {
474+
return false;
475+
}
476+
477+
if head_iteration_count != current_iteration_count {
478+
return false;
479+
}
480+
}
481+
TryClaimHeadsResult::Available(available_cycle_head) => {
482+
// Check the cycle heads recursively
483+
if available_cycle_head.is_nested(zalsa) {
484+
available_cycle_head.queue_cycle_heads(&mut cycle_heads_iter);
485+
} else {
486+
return false;
487+
}
488+
}
489+
TryClaimHeadsResult::Finalized | TryClaimHeadsResult::Running(_) => {
490+
return false;
491+
}
492+
}
493+
}
494+
495+
true
496+
}
497+
456498
crate::tracing::trace!(
457499
"{database_key_index:?}: validate_same_iteration(memo = {memo:#?})",
458500
memo = memo.tracing_debug()
@@ -472,111 +514,7 @@ where
472514
return false;
473515
}
474516

475-
let mut cycle_heads_iter = TryClaimCycleHeadsIter::new(zalsa, zalsa_local, cycle_heads);
476-
477-
while let Some(cycle_head) = cycle_heads_iter.next() {
478-
match cycle_head {
479-
TryClaimHeadsResult::Cycle {
480-
head_iteration_count,
481-
current_iteration_count,
482-
verified_at: head_verified_at,
483-
} => {
484-
if head_verified_at != verified_at {
485-
return false;
486-
}
487-
488-
if head_iteration_count != current_iteration_count {
489-
return false;
490-
}
491-
}
492-
TryClaimHeadsResult::Available(available_cycle_head) => {
493-
// Check the cycle heads recursively
494-
if available_cycle_head.is_nested(zalsa) {
495-
available_cycle_head.queue_cycle_heads(&mut cycle_heads_iter);
496-
} else {
497-
return false;
498-
}
499-
}
500-
TryClaimHeadsResult::Finalized | TryClaimHeadsResult::Running(_) => {
501-
return false;
502-
}
503-
}
504-
505-
// // If the cycle head isn't on our stack because:
506-
// //
507-
// // * another thread holds the lock on the cycle head (but it waits for the current query to complete)
508-
// // * we're in `maybe_changed_after` because `maybe_changed_after` doesn't modify the cycle stack
509-
// //
510-
// // check if the latest memo has the same iteration count.
511-
512-
// // However, we've to be careful to skip over fixpoint initial values:
513-
// // If the head is the memo we're trying to validate, always return `None`
514-
// // to force a re-execution of the query. This is necessary because the query
515-
// // has obviously not completed its iteration yet.
516-
// //
517-
// // This should be rare but the `cycle_panic` test fails on some platforms (mainly GitHub actions)
518-
// // without this check. What happens there is that:
519-
// //
520-
// // * query a blocks on query b
521-
// // * query b tries to claim a, fails to do so and inserts the fixpoint initial value
522-
// // * query b completes and has `a` as head. It returns its query result Salsa blocks query b from
523-
// // exiting inside `block_on` (or the thread would complete before the cycle iteration is complete)
524-
// // * query a resumes but panics because of the fixpoint iteration function
525-
// // * query b resumes. It rexecutes its own query which then tries to fetch a (which depends on itself because it's a fixpoint initial value).
526-
// // Without this check, `validate_same_iteration` would return `true` because the latest memo for `a` is the fixpoint initial value.
527-
// // But it should return `false` so that query b's thread re-executes `a` (which then also causes the panic).
528-
// //
529-
// // That's why we always return `None` if the cycle head is the same as the current database key index.
530-
// if cycle_head.database_key_index == database_key_index {
531-
// return false;
532-
// }
533-
534-
// let wait_result = ingredient.wait_for(zalsa, cycle_head.database_key_index.key_index());
535-
536-
// let provisional_status = match wait_result {
537-
// WaitForResult::Running(_) => {
538-
// // This Memo is guaranteed to be outdated because another thread
539-
// // is computing a new value right now
540-
// return None;
541-
// }
542-
// WaitForResult::Available(_claim_guard) => {
543-
// // Nested cycles are released as soon as their query completes
544-
// // and the outer queries are part of their `cycle_heads`.
545-
546-
// let provisional_status = ingredient
547-
// .provisional_status(zalsa, cycle_head.database_key_index.key_index())?;
548-
549-
// if !provisional_status.nested() {
550-
// return None;
551-
// }
552-
553-
// let cycle_heads =
554-
// ingredient.cycle_heads(zalsa, cycle_head.database_key_index.key_index());
555-
556-
// // This doesn't work, unless we need the same check in blocks-on etc.
557-
// if !cycle_heads.contains(&database_key_index) {
558-
// return None;
559-
// }
560-
561-
// provisional_status
562-
// }
563-
// WaitForResult::Cycle => {
564-
// // The head is hold by the current thread or another thread waiting on the
565-
// // result of this thread.
566-
// ingredient
567-
// .provisional_status(zalsa, cycle_head.database_key_index.key_index())?
568-
// }
569-
// };
570-
571-
// if provisional_status.verified_at() == Some(verified_at) {
572-
// provisional_status.iteration()
573-
// } else {
574-
// None
575-
// }
576-
//
577-
}
578-
579-
true
517+
validate_same_iteration_cold(zalsa, zalsa_local, cycle_heads, verified_at)
580518
}
581519

582520
/// VerifyResult::Unchanged if the memo's value and `changed_at` time is up-to-date in the

0 commit comments

Comments
 (0)