Skip to content

Commit de01099

Browse files
committed
Align type cache seqlock writer protocol with CPython
1 parent b0ad917 commit de01099

File tree

2 files changed

+26
-1
lines changed

2 files changed

+26
-1
lines changed

crates/compiler-core/src/bytecode.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,10 @@ impl CodeUnits {
623623
///
624624
/// # Safety
625625
/// - `index` must be in bounds.
626+
/// - `value` must be `0` or a valid `*const PyObject` encoded as `usize`.
627+
/// - Callers must follow the cache invalidation/upgrade protocol:
628+
/// invalidate the version guard before writing and publish the new
629+
/// version after writing.
626630
pub unsafe fn write_cache_ptr(&self, index: usize, value: usize) {
627631
self.pointer_cache[index].store(value, Ordering::Relaxed);
628632
}

crates/vm/src/builtins/type.rs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,28 @@ impl TypeCacheEntry {
104104

105105
#[inline]
106106
fn begin_write(&self) {
107-
self.sequence.fetch_add(1, Ordering::AcqRel);
107+
let mut seq = self.sequence.load(Ordering::Acquire);
108+
loop {
109+
while (seq & 1) != 0 {
110+
core::hint::spin_loop();
111+
seq = self.sequence.load(Ordering::Acquire);
112+
}
113+
match self.sequence.compare_exchange_weak(
114+
seq,
115+
seq.wrapping_add(1),
116+
Ordering::AcqRel,
117+
Ordering::Acquire,
118+
) {
119+
Ok(_) => {
120+
core::sync::atomic::fence(Ordering::Release);
121+
break;
122+
}
123+
Err(observed) => {
124+
core::hint::spin_loop();
125+
seq = observed;
126+
}
127+
}
128+
}
108129
}
109130

110131
#[inline]

0 commit comments

Comments
 (0)