parent
0aa4dc904e
commit
bec5835289
|
@ -267,12 +267,6 @@ pub fn verify_shreds_gpu(
|
||||||
sigverify::copy_return_values(&v_sig_lens, &out, &mut rvs);
|
sigverify::copy_return_values(&v_sig_lens, &out, &mut rvs);
|
||||||
|
|
||||||
inc_new_counter_debug!("ed25519_shred_verify_gpu", count);
|
inc_new_counter_debug!("ed25519_shred_verify_gpu", count);
|
||||||
recycler_cache.buffer().recycle(out);
|
|
||||||
recycler_cache.buffer().recycle(pubkeys);
|
|
||||||
recycler_cache.offsets().recycle(signature_offsets);
|
|
||||||
recycler_cache.offsets().recycle(pubkey_offsets);
|
|
||||||
recycler_cache.offsets().recycle(msg_sizes);
|
|
||||||
recycler_cache.offsets().recycle(msg_start_offsets);
|
|
||||||
rvs
|
rvs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,12 +461,6 @@ pub fn sign_shreds_gpu(
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
inc_new_counter_debug!("ed25519_shred_sign_gpu", count);
|
inc_new_counter_debug!("ed25519_shred_sign_gpu", count);
|
||||||
recycler_cache.buffer().recycle(signatures_out);
|
|
||||||
recycler_cache.buffer().recycle(pubkeys);
|
|
||||||
recycler_cache.offsets().recycle(signature_offsets);
|
|
||||||
recycler_cache.offsets().recycle(pubkey_offsets);
|
|
||||||
recycler_cache.offsets().recycle(msg_sizes);
|
|
||||||
recycler_cache.offsets().recycle(msg_start_offsets);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -6,12 +6,13 @@
|
||||||
// cannot be paged to disk. The cuda driver provides these interfaces to pin and unpin memory.
|
// cannot be paged to disk. The cuda driver provides these interfaces to pin and unpin memory.
|
||||||
|
|
||||||
use crate::perf_libs;
|
use crate::perf_libs;
|
||||||
use crate::recycler::Reset;
|
use crate::recycler::{RecyclerX, Reset};
|
||||||
use rand::seq::SliceRandom;
|
use rand::seq::SliceRandom;
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::slice::SliceIndex;
|
use std::slice::SliceIndex;
|
||||||
|
use std::sync::{Arc, Weak};
|
||||||
|
|
||||||
use std::os::raw::c_int;
|
use std::os::raw::c_int;
|
||||||
|
|
||||||
|
@ -57,29 +58,33 @@ pub fn unpin<T>(_mem: *mut T) {
|
||||||
// page-pinned. Controlled by flags in case user only wants
|
// page-pinned. Controlled by flags in case user only wants
|
||||||
// to pin in certain circumstances.
|
// to pin in certain circumstances.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct PinnedVec<T> {
|
pub struct PinnedVec<T: Default + Clone + Sized> {
|
||||||
x: Vec<T>,
|
x: Vec<T>,
|
||||||
pinned: bool,
|
pinned: bool,
|
||||||
pinnable: bool,
|
pinnable: bool,
|
||||||
|
recycler: Option<Weak<RecyclerX<PinnedVec<T>>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default + Clone> Reset for PinnedVec<T> {
|
impl<T: Default + Clone + Sized> Reset for PinnedVec<T> {
|
||||||
fn reset(&mut self) {
|
fn reset(&mut self) {
|
||||||
self.resize(0, T::default());
|
self.resize(0, T::default());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn warm(&mut self, size_hint: usize) {
|
fn warm(&mut self, size_hint: usize) {
|
||||||
self.set_pinnable();
|
self.set_pinnable();
|
||||||
self.resize(size_hint, T::default());
|
self.resize(size_hint, T::default());
|
||||||
}
|
}
|
||||||
|
fn set_recycler(&mut self, recycler: Weak<RecyclerX<Self>>) {
|
||||||
|
self.recycler = Some(recycler);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Default for PinnedVec<T> {
|
impl<T: Clone + Default + Sized> Default for PinnedVec<T> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
x: Vec::new(),
|
x: Vec::new(),
|
||||||
pinned: false,
|
pinned: false,
|
||||||
pinnable: false,
|
pinnable: false,
|
||||||
|
recycler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +93,7 @@ pub struct PinnedIter<'a, T>(std::slice::Iter<'a, T>);
|
||||||
|
|
||||||
pub struct PinnedIterMut<'a, T>(std::slice::IterMut<'a, T>);
|
pub struct PinnedIterMut<'a, T>(std::slice::IterMut<'a, T>);
|
||||||
|
|
||||||
impl<'a, T> Iterator for PinnedIter<'a, T> {
|
impl<'a, T: Clone + Default + Sized> Iterator for PinnedIter<'a, T> {
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
@ -96,7 +101,7 @@ impl<'a, T> Iterator for PinnedIter<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> Iterator for PinnedIterMut<'a, T> {
|
impl<'a, T: Clone + Default + Sized> Iterator for PinnedIterMut<'a, T> {
|
||||||
type Item = &'a mut T;
|
type Item = &'a mut T;
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
|
@ -104,7 +109,7 @@ impl<'a, T> Iterator for PinnedIterMut<'a, T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> IntoIterator for &'a mut PinnedVec<T> {
|
impl<'a, T: Clone + Default + Sized> IntoIterator for &'a mut PinnedVec<T> {
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
type IntoIter = PinnedIter<'a, T>;
|
type IntoIter = PinnedIter<'a, T>;
|
||||||
|
|
||||||
|
@ -113,7 +118,7 @@ impl<'a, T> IntoIterator for &'a mut PinnedVec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T> IntoIterator for &'a PinnedVec<T> {
|
impl<'a, T: Clone + Default + Sized> IntoIterator for &'a PinnedVec<T> {
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
type IntoIter = PinnedIter<'a, T>;
|
type IntoIter = PinnedIter<'a, T>;
|
||||||
|
|
||||||
|
@ -122,7 +127,7 @@ impl<'a, T> IntoIterator for &'a PinnedVec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, I: SliceIndex<[T]>> Index<I> for PinnedVec<T> {
|
impl<T: Clone + Default + Sized, I: SliceIndex<[T]>> Index<I> for PinnedVec<T> {
|
||||||
type Output = I::Output;
|
type Output = I::Output;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -131,14 +136,14 @@ impl<T, I: SliceIndex<[T]>> Index<I> for PinnedVec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, I: SliceIndex<[T]>> IndexMut<I> for PinnedVec<T> {
|
impl<T: Clone + Default + Sized, I: SliceIndex<[T]>> IndexMut<I> for PinnedVec<T> {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
fn index_mut(&mut self, index: I) -> &mut Self::Output {
|
||||||
&mut self.x[index]
|
&mut self.x[index]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> PinnedVec<T> {
|
impl<T: Clone + Default + Sized> PinnedVec<T> {
|
||||||
pub fn iter(&self) -> PinnedIter<T> {
|
pub fn iter(&self) -> PinnedIter<T> {
|
||||||
PinnedIter(self.x.iter())
|
PinnedIter(self.x.iter())
|
||||||
}
|
}
|
||||||
|
@ -148,7 +153,7 @@ impl<T> PinnedVec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, T: Send + Sync> IntoParallelIterator for &'a PinnedVec<T> {
|
impl<'a, T: Clone + Send + Sync + Default + Sized> IntoParallelIterator for &'a PinnedVec<T> {
|
||||||
type Iter = rayon::slice::Iter<'a, T>;
|
type Iter = rayon::slice::Iter<'a, T>;
|
||||||
type Item = &'a T;
|
type Item = &'a T;
|
||||||
fn into_par_iter(self) -> Self::Iter {
|
fn into_par_iter(self) -> Self::Iter {
|
||||||
|
@ -156,7 +161,7 @@ impl<'a, T: Send + Sync> IntoParallelIterator for &'a PinnedVec<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> PinnedVec<T> {
|
impl<T: Clone + Default + Sized> PinnedVec<T> {
|
||||||
pub fn reserve_and_pin(&mut self, size: usize) {
|
pub fn reserve_and_pin(&mut self, size: usize) {
|
||||||
if self.x.capacity() < size {
|
if self.x.capacity() < size {
|
||||||
if self.pinned {
|
if self.pinned {
|
||||||
|
@ -181,6 +186,7 @@ impl<T: Clone> PinnedVec<T> {
|
||||||
x: source,
|
x: source,
|
||||||
pinned: false,
|
pinned: false,
|
||||||
pinnable: false,
|
pinnable: false,
|
||||||
|
recycler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -190,6 +196,7 @@ impl<T: Clone> PinnedVec<T> {
|
||||||
x,
|
x,
|
||||||
pinned: false,
|
pinned: false,
|
||||||
pinnable: false,
|
pinnable: false,
|
||||||
|
recycler: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -272,9 +279,13 @@ impl<T: Clone> PinnedVec<T> {
|
||||||
self.pinned = true;
|
self.pinned = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn recycler_ref(&self) -> Option<Arc<RecyclerX<Self>>> {
|
||||||
|
let r = self.recycler.as_ref()?;
|
||||||
|
r.upgrade()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Clone> Clone for PinnedVec<T> {
|
impl<T: Clone + Default + Sized> Clone for PinnedVec<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
let mut x = self.x.clone();
|
let mut x = self.x.clone();
|
||||||
let pinned = if self.pinned {
|
let pinned = if self.pinned {
|
||||||
|
@ -293,12 +304,18 @@ impl<T: Clone> Clone for PinnedVec<T> {
|
||||||
x,
|
x,
|
||||||
pinned,
|
pinned,
|
||||||
pinnable: self.pinnable,
|
pinnable: self.pinnable,
|
||||||
|
recycler: self.recycler.clone(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Drop for PinnedVec<T> {
|
impl<T: Sized + Default + Clone> Drop for PinnedVec<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
|
if let Some(strong) = self.recycler_ref() {
|
||||||
|
let mut vec = PinnedVec::default();
|
||||||
|
std::mem::swap(&mut vec, self);
|
||||||
|
strong.recycle(vec);
|
||||||
|
}
|
||||||
if self.pinned {
|
if self.pinned {
|
||||||
unpin(self.x.as_mut_ptr());
|
unpin(self.x.as_mut_ptr());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
//! The `packet` module defines data structures and methods to pull data from the network.
|
//! The `packet` module defines data structures and methods to pull data from the network.
|
||||||
use crate::{
|
use crate::{cuda_runtime::PinnedVec, recycler::Recycler};
|
||||||
cuda_runtime::PinnedVec,
|
|
||||||
recycler::{Recycler, Reset},
|
|
||||||
};
|
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
pub use solana_sdk::packet::{Meta, Packet, PACKET_DATA_SIZE};
|
pub use solana_sdk::packet::{Meta, Packet, PACKET_DATA_SIZE};
|
||||||
use std::{mem, net::SocketAddr};
|
use std::net::SocketAddr;
|
||||||
|
|
||||||
pub const NUM_PACKETS: usize = 1024 * 8;
|
pub const NUM_PACKETS: usize = 1024 * 8;
|
||||||
|
|
||||||
|
@ -16,38 +13,13 @@ pub const PACKETS_BATCH_SIZE: usize = (PACKETS_PER_BATCH * PACKET_DATA_SIZE);
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Packets {
|
pub struct Packets {
|
||||||
pub packets: PinnedVec<Packet>,
|
pub packets: PinnedVec<Packet>,
|
||||||
|
|
||||||
recycler: Option<PacketsRecycler>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Packets {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
if let Some(ref recycler) = self.recycler {
|
|
||||||
let old = mem::replace(&mut self.packets, PinnedVec::default());
|
|
||||||
recycler.recycle(old)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Reset for Packets {
|
|
||||||
fn reset(&mut self) {
|
|
||||||
self.packets.resize(0, Packet::default());
|
|
||||||
}
|
|
||||||
|
|
||||||
fn warm(&mut self, size_hint: usize) {
|
|
||||||
self.packets.set_pinnable();
|
|
||||||
self.packets.resize(size_hint, Packet::default());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//auto derive doesn't support large arrays
|
//auto derive doesn't support large arrays
|
||||||
impl Default for Packets {
|
impl Default for Packets {
|
||||||
fn default() -> Packets {
|
fn default() -> Packets {
|
||||||
let packets = PinnedVec::with_capacity(NUM_RCVMMSGS);
|
let packets = PinnedVec::with_capacity(NUM_RCVMMSGS);
|
||||||
Packets {
|
Packets { packets }
|
||||||
packets,
|
|
||||||
recycler: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,19 +28,13 @@ pub type PacketsRecycler = Recycler<PinnedVec<Packet>>;
|
||||||
impl Packets {
|
impl Packets {
|
||||||
pub fn new(packets: Vec<Packet>) -> Self {
|
pub fn new(packets: Vec<Packet>) -> Self {
|
||||||
let packets = PinnedVec::from_vec(packets);
|
let packets = PinnedVec::from_vec(packets);
|
||||||
Self {
|
Self { packets }
|
||||||
packets,
|
|
||||||
recycler: None,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_with_recycler(recycler: PacketsRecycler, size: usize, name: &'static str) -> Self {
|
pub fn new_with_recycler(recycler: PacketsRecycler, size: usize, name: &'static str) -> Self {
|
||||||
let mut packets = recycler.allocate(name);
|
let mut packets = recycler.allocate(name);
|
||||||
packets.reserve_and_pin(size);
|
packets.reserve_and_pin(size);
|
||||||
Packets {
|
Packets { packets }
|
||||||
packets,
|
|
||||||
recycler: Some(recycler),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pub fn new_with_recycler_data(
|
pub fn new_with_recycler_data(
|
||||||
recycler: &PacketsRecycler,
|
recycler: &PacketsRecycler,
|
||||||
|
@ -142,15 +108,6 @@ mod tests {
|
||||||
use solana_sdk::signature::{Keypair, KeypairUtil};
|
use solana_sdk::signature::{Keypair, KeypairUtil};
|
||||||
use solana_sdk::system_transaction;
|
use solana_sdk::system_transaction;
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_packets_reset() {
|
|
||||||
let mut packets = Packets::default();
|
|
||||||
packets.packets.resize(10, Packet::default());
|
|
||||||
assert_eq!(packets.packets.len(), 10);
|
|
||||||
packets.reset();
|
|
||||||
assert_eq!(packets.packets.len(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_to_packets() {
|
fn test_to_packets() {
|
||||||
let keypair = Keypair::new();
|
let keypair = Keypair::new();
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex, Weak};
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct RecyclerStats {
|
struct RecyclerStats {
|
||||||
|
@ -11,38 +11,36 @@ struct RecyclerStats {
|
||||||
max_gc: AtomicUsize,
|
max_gc: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Clone, Default)]
|
||||||
pub struct Recycler<T> {
|
pub struct Recycler<T> {
|
||||||
gc: Arc<Mutex<Vec<T>>>,
|
recycler: Arc<RecyclerX<T>>,
|
||||||
stats: Arc<RecyclerStats>,
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct RecyclerX<T> {
|
||||||
|
gc: Mutex<Vec<T>>,
|
||||||
|
stats: RecyclerStats,
|
||||||
id: usize,
|
id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default> Default for Recycler<T> {
|
impl<T: Default> Default for RecyclerX<T> {
|
||||||
fn default() -> Recycler<T> {
|
fn default() -> RecyclerX<T> {
|
||||||
let id = thread_rng().gen_range(0, 1000);
|
let id = thread_rng().gen_range(0, 1000);
|
||||||
trace!("new recycler..{}", id);
|
trace!("new recycler..{}", id);
|
||||||
Recycler {
|
RecyclerX {
|
||||||
gc: Arc::new(Mutex::new(vec![])),
|
gc: Mutex::new(vec![]),
|
||||||
stats: Arc::new(RecyclerStats::default()),
|
stats: RecyclerStats::default(),
|
||||||
id,
|
id,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default> Clone for Recycler<T> {
|
|
||||||
fn clone(&self) -> Recycler<T> {
|
|
||||||
Recycler {
|
|
||||||
gc: self.gc.clone(),
|
|
||||||
stats: self.stats.clone(),
|
|
||||||
id: self.id,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait Reset {
|
pub trait Reset {
|
||||||
fn reset(&mut self);
|
fn reset(&mut self);
|
||||||
fn warm(&mut self, size_hint: usize);
|
fn warm(&mut self, size_hint: usize);
|
||||||
|
fn set_recycler(&mut self, recycler: Weak<RecyclerX<Self>>)
|
||||||
|
where
|
||||||
|
Self: std::marker::Sized;
|
||||||
}
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -57,7 +55,7 @@ fn warm_recyclers() -> bool {
|
||||||
WARM_RECYCLERS.load(Ordering::Relaxed)
|
WARM_RECYCLERS.load(Ordering::Relaxed)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Default + Reset> Recycler<T> {
|
impl<T: Default + Reset + Sized> Recycler<T> {
|
||||||
pub fn warmed(num: usize, size_hint: usize) -> Self {
|
pub fn warmed(num: usize, size_hint: usize) -> Self {
|
||||||
let new = Self::default();
|
let new = Self::default();
|
||||||
if warm_recyclers() {
|
if warm_recyclers() {
|
||||||
|
@ -68,37 +66,44 @@ impl<T: Default + Reset> Recycler<T> {
|
||||||
item
|
item
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
warmed_items.into_iter().for_each(|i| new.recycle(i));
|
warmed_items
|
||||||
|
.into_iter()
|
||||||
|
.for_each(|i| new.recycler.recycle(i));
|
||||||
}
|
}
|
||||||
new
|
new
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn allocate(&self, name: &'static str) -> T {
|
pub fn allocate(&self, name: &'static str) -> T {
|
||||||
let new = self
|
let new = self
|
||||||
|
.recycler
|
||||||
.gc
|
.gc
|
||||||
.lock()
|
.lock()
|
||||||
.expect("recycler lock in pb fn allocate")
|
.expect("recycler lock in pb fn allocate")
|
||||||
.pop();
|
.pop();
|
||||||
|
|
||||||
if let Some(mut x) = new {
|
if let Some(mut x) = new {
|
||||||
self.stats.reuse.fetch_add(1, Ordering::Relaxed);
|
self.recycler.stats.reuse.fetch_add(1, Ordering::Relaxed);
|
||||||
x.reset();
|
x.reset();
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
let total = self.stats.total.fetch_add(1, Ordering::Relaxed);
|
let total = self.recycler.stats.total.fetch_add(1, Ordering::Relaxed);
|
||||||
trace!(
|
trace!(
|
||||||
"allocating new: total {} {:?} id: {} reuse: {} max_gc: {}",
|
"allocating new: total {} {:?} id: {} reuse: {} max_gc: {}",
|
||||||
total,
|
total,
|
||||||
name,
|
name,
|
||||||
self.id,
|
self.recycler.id,
|
||||||
self.stats.reuse.load(Ordering::Relaxed),
|
self.recycler.stats.reuse.load(Ordering::Relaxed),
|
||||||
self.stats.max_gc.load(Ordering::Relaxed),
|
self.recycler.stats.max_gc.load(Ordering::Relaxed),
|
||||||
);
|
);
|
||||||
|
|
||||||
T::default()
|
let mut t = T::default();
|
||||||
|
t.set_recycler(Arc::downgrade(&self.recycler));
|
||||||
|
t
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Default + Reset> RecyclerX<T> {
|
||||||
pub fn recycle(&self, x: T) {
|
pub fn recycle(&self, x: T) {
|
||||||
let len = {
|
let len = {
|
||||||
let mut gc = self.gc.lock().expect("recycler lock in pub fn recycle");
|
let mut gc = self.gc.lock().expect("recycler lock in pub fn recycle");
|
||||||
|
@ -135,6 +140,7 @@ mod tests {
|
||||||
*self = 10;
|
*self = 10;
|
||||||
}
|
}
|
||||||
fn warm(&mut self, _size_hint: usize) {}
|
fn warm(&mut self, _size_hint: usize) {}
|
||||||
|
fn set_recycler(&mut self, _recycler: Weak<RecyclerX<Self>>) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -144,10 +150,10 @@ mod tests {
|
||||||
assert_eq!(y, 0);
|
assert_eq!(y, 0);
|
||||||
y = 20;
|
y = 20;
|
||||||
let recycler2 = recycler.clone();
|
let recycler2 = recycler.clone();
|
||||||
recycler2.recycle(y);
|
recycler2.recycler.recycle(y);
|
||||||
assert_eq!(recycler.gc.lock().unwrap().len(), 1);
|
assert_eq!(recycler.recycler.gc.lock().unwrap().len(), 1);
|
||||||
let z = recycler.allocate("test_recycler2");
|
let z = recycler.allocate("test_recycler2");
|
||||||
assert_eq!(z, 10);
|
assert_eq!(z, 10);
|
||||||
assert_eq!(recycler.gc.lock().unwrap().len(), 0);
|
assert_eq!(recycler.recycler.gc.lock().unwrap().len(), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -365,11 +365,6 @@ pub fn ed25519_verify(
|
||||||
trace!("done verify");
|
trace!("done verify");
|
||||||
copy_return_values(&sig_lens, &out, &mut rvs);
|
copy_return_values(&sig_lens, &out, &mut rvs);
|
||||||
inc_new_counter_debug!("ed25519_verify_gpu", count);
|
inc_new_counter_debug!("ed25519_verify_gpu", count);
|
||||||
recycler_out.recycle(out);
|
|
||||||
recycler.recycle(signature_offsets);
|
|
||||||
recycler.recycle(pubkey_offsets);
|
|
||||||
recycler.recycle(msg_sizes);
|
|
||||||
recycler.recycle(msg_start_offsets);
|
|
||||||
rvs
|
rvs
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue