Skip to content

Commit

Permalink
use seqlock for AccountStorage count and status tracking (solana-labs…
Browse files Browse the repository at this point in the history
…#34356)

use seqlock for appendvec count and status tracking

Co-authored-by: HaoranYi <haoran.yi@solana.com>
  • Loading branch information
HaoranYi and HaoranYi authored Dec 8, 2023
1 parent cfb16ab commit c43edd2
Showing 1 changed file with 18 additions and 17 deletions.
35 changes: 18 additions & 17 deletions accounts-db/src/accounts_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ use {
log::*,
rand::{thread_rng, Rng},
rayon::{prelude::*, ThreadPool},
seqlock::SeqLock,
serde::{Deserialize, Serialize},
smallvec::SmallVec,
solana_measure::{measure::Measure, measure_us},
Expand Down Expand Up @@ -1012,7 +1013,7 @@ pub struct AccountStorageEntry {
/// any accounts in it
/// status corresponding to the storage, lets us know that
/// the append_vec, once maxed out, then emptied, can be reclaimed
count_and_status: RwLock<(usize, AccountStorageStatus)>,
count_and_status: SeqLock<(usize, AccountStorageStatus)>,

/// This is the total number of accounts stored ever since initialized to keep
/// track of lifetime count of all store operations. And this differs from
Expand All @@ -1035,7 +1036,7 @@ impl AccountStorageEntry {
id: AtomicAppendVecId::new(id),
slot: AtomicU64::new(slot),
accounts,
count_and_status: RwLock::new((0, AccountStorageStatus::Available)),
count_and_status: SeqLock::new((0, AccountStorageStatus::Available)),
approx_store_count: AtomicUsize::new(0),
alive_bytes: AtomicUsize::new(0),
}
Expand All @@ -1051,14 +1052,14 @@ impl AccountStorageEntry {
id: AtomicAppendVecId::new(id),
slot: AtomicU64::new(slot),
accounts,
count_and_status: RwLock::new((0, AccountStorageStatus::Available)),
count_and_status: SeqLock::new((0, AccountStorageStatus::Available)),
approx_store_count: AtomicUsize::new(num_accounts),
alive_bytes: AtomicUsize::new(0),
}
}

pub fn set_status(&self, mut status: AccountStorageStatus) {
let mut count_and_status = self.count_and_status.write().unwrap();
let mut count_and_status = self.count_and_status.lock_write();

let count = count_and_status.0;

Expand All @@ -1079,7 +1080,7 @@ impl AccountStorageEntry {
}

pub fn recycle(&self, slot: Slot, id: AppendVecId) {
let mut count_and_status = self.count_and_status.write().unwrap();
let mut count_and_status = self.count_and_status.lock_write();
self.accounts.reset();
*count_and_status = (0, AccountStorageStatus::Available);
self.slot.store(slot, Ordering::Release);
Expand All @@ -1089,11 +1090,11 @@ impl AccountStorageEntry {
}

pub fn status(&self) -> AccountStorageStatus {
self.count_and_status.read().unwrap().1
self.count_and_status.read().1
}

pub fn count(&self) -> usize {
self.count_and_status.read().unwrap().0
self.count_and_status.read().0
}

pub fn approx_stored_count(&self) -> usize {
Expand Down Expand Up @@ -1133,14 +1134,14 @@ impl AccountStorageEntry {
}

fn add_account(&self, num_bytes: usize) {
let mut count_and_status = self.count_and_status.write().unwrap();
let mut count_and_status = self.count_and_status.lock_write();
*count_and_status = (count_and_status.0 + 1, count_and_status.1);
self.approx_store_count.fetch_add(1, Ordering::Relaxed);
self.alive_bytes.fetch_add(num_bytes, Ordering::SeqCst);
}

fn try_available(&self) -> bool {
let mut count_and_status = self.count_and_status.write().unwrap();
let mut count_and_status = self.count_and_status.lock_write();
let (count, status) = *count_and_status;

if status == AccountStorageStatus::Available {
Expand All @@ -1156,7 +1157,7 @@ impl AccountStorageEntry {
}

fn remove_account(&self, num_bytes: usize, reset_accounts: bool) -> usize {
let mut count_and_status = self.count_and_status.write().unwrap();
let mut count_and_status = self.count_and_status.lock_write();
let (mut count, mut status) = *count_and_status;

if count == 1 && status == AccountStorageStatus::Full && reset_accounts {
Expand Down Expand Up @@ -9423,7 +9424,7 @@ impl AccountsDb {
store.count(),
);
{
let mut count_and_status = store.count_and_status.write().unwrap();
let mut count_and_status = store.count_and_status.lock_write();
assert_eq!(count_and_status.0, 0);
count_and_status.0 = entry.count;
}
Expand All @@ -9436,7 +9437,7 @@ impl AccountsDb {
);
} else {
trace!("id: {} clearing count", id);
store.count_and_status.write().unwrap().0 = 0;
store.count_and_status.lock_write().0 = 0;
}
}
storage_size_storages_time.stop();
Expand All @@ -9453,7 +9454,7 @@ impl AccountsDb {
" slot: {} id: {} count_and_status: {:?} approx_store_count: {} len: {} capacity: {} (recycled: {:?})",
entry.slot(),
entry.append_vec_id(),
*entry.count_and_status.read().unwrap(),
entry.count_and_status.read(),
entry.approx_store_count.load(Ordering::Relaxed),
entry.accounts.len(),
entry.accounts.capacity(),
Expand Down Expand Up @@ -9491,7 +9492,7 @@ impl AccountsDb {
" slot: {} id: {} count_and_status: {:?} approx_store_count: {} len: {} capacity: {}",
slot,
entry.append_vec_id(),
*entry.count_and_status.read().unwrap(),
entry.count_and_status.read(),
entry.approx_store_count.load(Ordering::Relaxed),
entry.accounts.len(),
entry.accounts.capacity(),
Expand Down Expand Up @@ -15796,7 +15797,7 @@ pub mod tests {
// fake out the store count to avoid the assert
for (_, store) in accounts.storage.iter() {
store.alive_bytes.store(0, Ordering::Release);
let mut count_and_status = store.count_and_status.write().unwrap();
let mut count_and_status = store.count_and_status.lock_write();
count_and_status.0 = 0;
}

Expand All @@ -15815,14 +15816,14 @@ pub mod tests {
);

for (_, store) in accounts.storage.iter() {
assert_eq!(store.count_and_status.read().unwrap().0, 0);
assert_eq!(store.count_and_status.read().0, 0);
assert_eq!(store.alive_bytes.load(Ordering::Acquire), 0);
}
accounts.set_storage_count_and_alive_bytes(dashmap, &mut GenerateIndexTimings::default());
assert_eq!(accounts.storage.len(), 1);
for (_, store) in accounts.storage.iter() {
assert_eq!(store.append_vec_id(), 0);
assert_eq!(store.count_and_status.read().unwrap().0, count);
assert_eq!(store.count_and_status.read().0, count);
assert_eq!(store.alive_bytes.load(Ordering::Acquire), 2);
}
}
Expand Down

0 comments on commit c43edd2

Please sign in to comment.