From b6cd761e01102ca7d2913265f1bfda180fcdb446 Mon Sep 17 00:00:00 2001 From: eldpswp99 Date: Sun, 22 Aug 2021 13:36:33 +0900 Subject: [PATCH 1/2] make dict iterator use atomic operation --- vm/src/builtins/dict.rs | 10 +++------- vm/src/dictdatatype.rs | 13 ++++++++++++- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 42e383f84..98ab6dc16 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -578,7 +578,7 @@ impl Iterator for DictIter { type Item = (PyObjectRef, PyObjectRef); fn next(&mut self) -> Option { - self.dict.entries.next_entry(&mut self.position) + self.dict.entries._next_entry(&mut self.position) } fn size_hint(&self) -> (usize, Option) { @@ -718,12 +718,8 @@ macro_rules! dict_iterator { "dictionary changed size during iteration".to_owned(), )); } - let mut position = zelf.position.load(); - match zelf.dict.entries.next_entry(&mut position) { - Some((key, value)) => { - zelf.position.store(position); - Ok(($result_fn)(vm, key, value)) - } + match zelf.dict.entries.next_entry(&zelf.position) { + Some((key, value)) => Ok(($result_fn)(vm, key, value)), None => { zelf.status.store(IterStatus::Exhausted); Err(vm.new_stop_iteration()) diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 86d80b722..4ad605533 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -477,7 +477,7 @@ impl Dict { self.read().size() } - pub fn next_entry(&self, position: &mut EntryIndex) -> Option<(PyObjectRef, T)> { + pub fn _next_entry(&self, position: &mut EntryIndex) -> Option<(PyObjectRef, T)> { let inner = self.read(); loop { let entry = inner.entries.get(*position)?; @@ -488,6 +488,17 @@ impl Dict { } } + pub fn next_entry(&self, position: &AtomicCell) -> Option<(PyObjectRef, T)> { + let inner = self.read(); + loop { + let position_usize = position.fetch_add(1); + let entry = inner.entries.get(position_usize)?; + if let Some(entry) = entry { + break Some((entry.key.clone(), entry.value.clone())); + } + } + } + pub fn next_entry_reversed(&self, position: &AtomicCell) -> Option<(PyObjectRef, T)> { let inner = self.read(); loop { From 19ce63720022d8e1afabe4dc2683a4137d6ceb1d Mon Sep 17 00:00:00 2001 From: eldpswp99 Date: Sun, 22 Aug 2021 19:00:54 +0900 Subject: [PATCH 2/2] change function name to represent atomic function --- vm/src/builtins/dict.rs | 6 +++--- vm/src/dictdatatype.rs | 9 ++++++--- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/vm/src/builtins/dict.rs b/vm/src/builtins/dict.rs index 98ab6dc16..a4bca4e5f 100644 --- a/vm/src/builtins/dict.rs +++ b/vm/src/builtins/dict.rs @@ -578,7 +578,7 @@ impl Iterator for DictIter { type Item = (PyObjectRef, PyObjectRef); fn next(&mut self) -> Option { - self.dict.entries._next_entry(&mut self.position) + self.dict.entries.next_entry(&mut self.position) } fn size_hint(&self) -> (usize, Option) { @@ -718,7 +718,7 @@ macro_rules! dict_iterator { "dictionary changed size during iteration".to_owned(), )); } - match zelf.dict.entries.next_entry(&zelf.position) { + match zelf.dict.entries.next_entry_atomic(&zelf.position) { Some((key, value)) => Ok(($result_fn)(vm, key, value)), None => { zelf.status.store(IterStatus::Exhausted); @@ -778,7 +778,7 @@ macro_rules! dict_iterator { "dictionary changed size during iteration".to_owned(), )); } - match zelf.dict.entries.next_entry_reversed(&zelf.position) { + match zelf.dict.entries.next_entry_atomic_reversed(&zelf.position) { Some((key, value)) => Ok(($result_fn)(vm, key, value)), None => { zelf.status.store(IterStatus::Exhausted); diff --git a/vm/src/dictdatatype.rs b/vm/src/dictdatatype.rs index 4ad605533..78c3c2cb1 100644 --- a/vm/src/dictdatatype.rs +++ b/vm/src/dictdatatype.rs @@ -477,7 +477,7 @@ impl Dict { self.read().size() } - pub fn _next_entry(&self, position: &mut EntryIndex) -> Option<(PyObjectRef, T)> { + pub fn next_entry(&self, position: &mut EntryIndex) -> Option<(PyObjectRef, T)> { let inner = self.read(); loop { let entry = inner.entries.get(*position)?; @@ -488,7 +488,7 @@ impl Dict { } } - pub fn next_entry(&self, position: &AtomicCell) -> Option<(PyObjectRef, T)> { + pub fn next_entry_atomic(&self, position: &AtomicCell) -> Option<(PyObjectRef, T)> { let inner = self.read(); loop { let position_usize = position.fetch_add(1); @@ -499,7 +499,10 @@ impl Dict { } } - pub fn next_entry_reversed(&self, position: &AtomicCell) -> Option<(PyObjectRef, T)> { + pub fn next_entry_atomic_reversed( + &self, + position: &AtomicCell, + ) -> Option<(PyObjectRef, T)> { let inner = self.read(); loop { let position_usize = position.fetch_add(1);