subspace_farmer/plotter/gpu/
gpu_encoders_manager.rs1use crate::plotter::gpu::GpuRecordsEncoder;
4use event_listener::Event;
5use parking_lot::Mutex;
6use std::num::{NonZeroUsize, TryFromIntError};
7use std::ops::{Deref, DerefMut};
8use std::sync::Arc;
9
10#[derive(Debug)]
13#[must_use]
14pub(super) struct GpuRecordsEncoderGuard<GRE> {
15 inner: Arc<(Mutex<Vec<GRE>>, Event)>,
16 gpu_records_encoder: Option<GRE>,
17}
18
19impl<GRE> Deref for GpuRecordsEncoderGuard<GRE> {
20 type Target = GRE;
21
22 #[inline]
23 fn deref(&self) -> &Self::Target {
24 self.gpu_records_encoder
25 .as_ref()
26 .expect("Value exists until `Drop`; qed")
27 }
28}
29
30impl<GRE> DerefMut for GpuRecordsEncoderGuard<GRE> {
31 #[inline]
32 fn deref_mut(&mut self) -> &mut Self::Target {
33 self.gpu_records_encoder
34 .as_mut()
35 .expect("Value exists until `Drop`; qed")
36 }
37}
38
39impl<GRE> Drop for GpuRecordsEncoderGuard<GRE> {
40 #[inline]
41 fn drop(&mut self) {
42 let (mutex, event) = &*self.inner;
43 mutex.lock().push(
44 self.gpu_records_encoder
45 .take()
46 .expect("Happens only once in `Drop`; qed"),
47 );
48 event.notify_additional(1);
49 }
50}
51
52#[derive(Debug)]
56pub(super) struct GpuRecordsEncoderManager<GRE> {
57 inner: Arc<(Mutex<Vec<GRE>>, Event)>,
58 gpu_records_encoders: NonZeroUsize,
59}
60
61impl<GRE> Clone for GpuRecordsEncoderManager<GRE> {
62 fn clone(&self) -> Self {
63 Self {
64 inner: Arc::clone(&self.inner),
65 gpu_records_encoders: self.gpu_records_encoders,
66 }
67 }
68}
69
70impl<GRE> GpuRecordsEncoderManager<GRE>
71where
72 GRE: GpuRecordsEncoder,
73{
74 pub(super) fn new(gpu_records_encoders: Vec<GRE>) -> Result<Self, TryFromIntError> {
78 let count = gpu_records_encoders.len().try_into()?;
79
80 Ok(Self {
81 inner: Arc::new((Mutex::new(gpu_records_encoders), Event::new())),
82 gpu_records_encoders: count,
83 })
84 }
85
86 pub(super) fn gpu_records_encoders(&self) -> NonZeroUsize {
88 self.gpu_records_encoders
89 }
90
91 pub(super) async fn get_encoder(&self) -> GpuRecordsEncoderGuard<GRE> {
93 let (mutex, event) = &*self.inner;
94
95 let gpu_records_encoder = loop {
96 let listener = event.listen();
97
98 if let Some(thread_pool_pair) = mutex.lock().pop() {
99 break thread_pool_pair;
100 }
101
102 listener.await;
103 };
104
105 GpuRecordsEncoderGuard {
106 inner: Arc::clone(&self.inner),
107 gpu_records_encoder: Some(gpu_records_encoder),
108 }
109 }
110}