adds a generic implementation of Gossip{Read,Write}Lock (#18559)

This commit is contained in:
behzad nouri 2021-07-10 14:13:52 +00:00 committed by GitHub
parent 335ac82a1a
commit fd9c10c2e2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 44 additions and 78 deletions

View File

@ -14,7 +14,9 @@
//! Bank needs to provide an interface for us to query the stake weight //! Bank needs to provide an interface for us to query the stake weight
use { use {
crate::{ crate::{
cluster_info_metrics::{submit_gossip_stats, Counter, GossipStats, ScopedTimer}, cluster_info_metrics::{
submit_gossip_stats, Counter, GossipStats, ScopedTimer, TimedGuard,
},
contact_info::ContactInfo, contact_info::ContactInfo,
crds::{Crds, Cursor}, crds::{Crds, Cursor},
crds_gossip::CrdsGossip, crds_gossip::CrdsGossip,
@ -73,7 +75,7 @@ use {
io::BufReader, io::BufReader,
iter::repeat, iter::repeat,
net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket}, net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener, UdpSocket},
ops::{Deref, DerefMut, Div}, ops::{Deref, Div},
path::{Path, PathBuf}, path::{Path, PathBuf},
result::Result, result::Result,
sync::{ sync::{
@ -137,78 +139,6 @@ pub enum ClusterInfoError {
BadGossipAddress, BadGossipAddress,
} }
struct GossipWriteLock<'a> {
gossip: RwLockWriteGuard<'a, CrdsGossip>,
timer: Measure,
counter: &'a Counter,
}
impl<'a> GossipWriteLock<'a> {
fn new(
gossip: RwLockWriteGuard<'a, CrdsGossip>,
label: &'static str,
counter: &'a Counter,
) -> Self {
Self {
gossip,
timer: Measure::start(label),
counter,
}
}
}
impl<'a> Deref for GossipWriteLock<'a> {
type Target = RwLockWriteGuard<'a, CrdsGossip>;
fn deref(&self) -> &Self::Target {
&self.gossip
}
}
impl<'a> DerefMut for GossipWriteLock<'a> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.gossip
}
}
impl<'a> Drop for GossipWriteLock<'a> {
fn drop(&mut self) {
self.counter.add_measure(&mut self.timer);
}
}
struct GossipReadLock<'a> {
gossip: RwLockReadGuard<'a, CrdsGossip>,
timer: Measure,
counter: &'a Counter,
}
impl<'a> GossipReadLock<'a> {
fn new(
gossip: RwLockReadGuard<'a, CrdsGossip>,
label: &'static str,
counter: &'a Counter,
) -> Self {
Self {
gossip,
timer: Measure::start(label),
counter,
}
}
}
impl<'a> Deref for GossipReadLock<'a> {
type Target = RwLockReadGuard<'a, CrdsGossip>;
fn deref(&self) -> &Self::Target {
&self.gossip
}
}
impl<'a> Drop for GossipReadLock<'a> {
fn drop(&mut self) {
self.counter.add_measure(&mut self.timer);
}
}
pub struct ClusterInfo { pub struct ClusterInfo {
/// The network /// The network
pub gossip: RwLock<CrdsGossip>, pub gossip: RwLock<CrdsGossip>,
@ -986,16 +916,16 @@ impl ClusterInfo {
&'a self, &'a self,
label: &'static str, label: &'static str,
counter: &'a Counter, counter: &'a Counter,
) -> GossipReadLock<'a> { ) -> TimedGuard<'a, RwLockReadGuard<CrdsGossip>> {
GossipReadLock::new(self.gossip.read().unwrap(), label, counter) TimedGuard::new(self.gossip.read().unwrap(), label, counter)
} }
fn time_gossip_write_lock<'a>( fn time_gossip_write_lock<'a>(
&'a self, &'a self,
label: &'static str, label: &'static str,
counter: &'a Counter, counter: &'a Counter,
) -> GossipWriteLock<'a> { ) -> TimedGuard<'a, RwLockWriteGuard<CrdsGossip>> {
GossipWriteLock::new(self.gossip.write().unwrap(), label, counter) TimedGuard::new(self.gossip.write().unwrap(), label, counter)
} }
pub fn push_message(&self, message: CrdsValue) { pub fn push_message(&self, message: CrdsValue) {

View File

@ -4,6 +4,7 @@ use {
solana_sdk::pubkey::Pubkey, solana_sdk::pubkey::Pubkey,
std::{ std::{
collections::HashMap, collections::HashMap,
ops::{Deref, DerefMut},
sync::{ sync::{
atomic::{AtomicU64, Ordering}, atomic::{AtomicU64, Ordering},
RwLock, RwLock,
@ -28,6 +29,12 @@ impl Counter {
} }
} }
pub(crate) struct TimedGuard<'a, T> {
guard: T,
timer: Measure,
counter: &'a Counter,
}
pub(crate) struct ScopedTimer<'a> { pub(crate) struct ScopedTimer<'a> {
clock: Instant, clock: Instant,
metric: &'a AtomicU64, metric: &'a AtomicU64,
@ -52,6 +59,35 @@ impl Drop for ScopedTimer<'_> {
} }
} }
impl<'a, T> TimedGuard<'a, T> {
pub(crate) fn new(guard: T, label: &'static str, counter: &'a Counter) -> Self {
Self {
guard,
timer: Measure::start(label),
counter,
}
}
}
impl<'a, T> Deref for TimedGuard<'a, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.guard
}
}
impl<'a, T> DerefMut for TimedGuard<'a, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.guard
}
}
impl<'a, T> Drop for TimedGuard<'a, T> {
fn drop(&mut self) {
self.counter.add_measure(&mut self.timer);
}
}
#[derive(Default)] #[derive(Default)]
pub(crate) struct GossipStats { pub(crate) struct GossipStats {
pub(crate) all_tvu_peers: Counter, pub(crate) all_tvu_peers: Counter,