neuromorphic-drivers 0.16.3

Neuromorphic devices drivers
Documentation
pub struct Flagged<Configuration> {
    configuration: Configuration,
    updated: bool,
}

pub struct Updater<Configuration> {
    flagged_configuration_and_condition:
        std::sync::Arc<(std::sync::Mutex<Flagged<Configuration>>, std::sync::Condvar)>,
    thread: Option<std::thread::JoinHandle<()>>,
    running: std::sync::Arc<std::sync::atomic::AtomicBool>,
}

impl<Configuration: Clone + Send + 'static> Updater<Configuration> {
    pub fn new<ContextType, Update>(
        initial_configuration: Configuration,
        context: ContextType,
        update: Update,
    ) -> Self
    where
        ContextType: Send + 'static,
        Update: Fn(ContextType, &Configuration, &Configuration) -> ContextType + Send + 'static,
    {
        let previous_configuration = initial_configuration.clone();
        let flagged_configuration_and_condition = std::sync::Arc::new((
            std::sync::Mutex::new(Flagged {
                configuration: initial_configuration,
                updated: false,
            }),
            std::sync::Condvar::new(),
        ));
        let thread_flagged_configuration_and_condition =
            flagged_configuration_and_condition.clone();
        let running = std::sync::Arc::new(std::sync::atomic::AtomicBool::new(true));
        let thread_running = running.clone();
        Self {
            flagged_configuration_and_condition,
            thread: Some(std::thread::spawn(move || {
                let mut context = context;
                let mut previous_configuration = previous_configuration;
                while thread_running.load(std::sync::atomic::Ordering::Acquire) {
                    let configuration = {
                        let (lock, condvar) = &*thread_flagged_configuration_and_condition;
                        let mut flagged_configuration = lock
                            .lock()
                            .expect("flagged configuration mutex is not poisoned");
                        if !flagged_configuration.updated {
                            flagged_configuration = condvar
                                .wait_timeout(
                                    flagged_configuration,
                                    std::time::Duration::from_millis(100),
                                )
                                .expect("flagged configuration mutex is not poisoned")
                                .0;
                        }
                        if flagged_configuration.updated {
                            flagged_configuration.updated = false;
                            Some(flagged_configuration.configuration.clone())
                        } else {
                            None
                        }
                    };
                    if let Some(configuration) = configuration {
                        context = update(context, &previous_configuration, &configuration);
                        previous_configuration = configuration;
                    }
                }
            })),
            running,
        }
    }

    pub fn update(&self, configuration: Configuration) {
        let (lock, condvar) = &*self.flagged_configuration_and_condition;
        let mut flagged_configuration = lock
            .lock()
            .expect("flagged configuration mutex is not poisoned");
        flagged_configuration.configuration = configuration;
        flagged_configuration.updated = true;
        condvar.notify_one();
    }

    pub fn current_configuration(&self) -> Configuration {
        self.flagged_configuration_and_condition
            .0
            .lock()
            .expect("flagged configuration mutex is not poisoned")
            .configuration
            .clone()
    }
}

impl<Configuration> Drop for Updater<Configuration> {
    fn drop(&mut self) {
        self.running
            .store(false, std::sync::atomic::Ordering::Release);
        if let Some(thread) = self.thread.take() {
            thread.join().expect("not joining self");
        }
    }
}