Add synchronisation of multi-threaded system
This commit is contained in:
		@@ -19,3 +19,4 @@ indexmap = { version = "1.5.2", features = ["serde-1"] }
 | 
			
		||||
argh = "0.1.4"
 | 
			
		||||
evalexpr = "6.3.0"
 | 
			
		||||
crossbeam-channel = "0.5.0"
 | 
			
		||||
crossbeam-utils = "0.8.5"
 | 
			
		||||
 
 | 
			
		||||
@@ -108,6 +108,9 @@ fn main() {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let timer = if opt.timings {
 | 
			
		||||
        if let system::System::MultiThreaded(sys) = &sys {
 | 
			
		||||
            sys.synchronise()
 | 
			
		||||
        }
 | 
			
		||||
        Some(std::time::Instant::now())
 | 
			
		||||
    } else {
 | 
			
		||||
        None
 | 
			
		||||
@@ -119,25 +122,30 @@ fn main() {
 | 
			
		||||
        sys.advance(nexttime - itime);
 | 
			
		||||
 | 
			
		||||
        itime = nexttime;
 | 
			
		||||
        sys.output(itime);
 | 
			
		||||
        if itime != ntime {
 | 
			
		||||
            sys.output(itime);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let timer = timer.map(|timer| {
 | 
			
		||||
        if let system::System::MultiThreaded(sys) = &sys {
 | 
			
		||||
            sys.synchronise();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        timer.elapsed()
 | 
			
		||||
    });
 | 
			
		||||
    sys.output(ntime);
 | 
			
		||||
 | 
			
		||||
    let mut outinfo = OutputInformation {
 | 
			
		||||
        filename: opt.output,
 | 
			
		||||
        time_elapsed: timer,
 | 
			
		||||
        ..Default::default()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if !opt.no_progressbar {
 | 
			
		||||
        sys.finish_progressbar();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let mut outinfo = OutputInformation {
 | 
			
		||||
        filename: opt.output,
 | 
			
		||||
        ..Default::default()
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    if let Some(timer) = timer {
 | 
			
		||||
        let duration = timer.elapsed();
 | 
			
		||||
        outinfo.time_elapsed = Some(duration);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    //output.add_timestep(ntime, &sys.fnow);
 | 
			
		||||
 | 
			
		||||
    if opt.error {
 | 
			
		||||
        outinfo.error = Some(sys.error())
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -415,6 +415,7 @@ impl System {
 | 
			
		||||
                for tid in &sys.send {
 | 
			
		||||
                    tid.send(MsgFromHost::ProgressbarDrop).unwrap();
 | 
			
		||||
                }
 | 
			
		||||
                sys.synchronise();
 | 
			
		||||
                let target = sys.progressbar.take().unwrap();
 | 
			
		||||
                target.clear().unwrap();
 | 
			
		||||
            }
 | 
			
		||||
@@ -658,6 +659,17 @@ impl DistributedSystem {
 | 
			
		||||
        target.set_move_cursor(true);
 | 
			
		||||
        self.progressbar = Some(target);
 | 
			
		||||
    }
 | 
			
		||||
    fn send_barrier(&self, barrier: &crossbeam_utils::sync::WaitGroup) {
 | 
			
		||||
        for tid in &self.send {
 | 
			
		||||
            tid.send(MsgFromHost::Barrier(barrier.clone())).unwrap()
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    pub fn synchronise(&self) {
 | 
			
		||||
        // Syncronise before starting the timer
 | 
			
		||||
        let barrier = crossbeam_utils::sync::WaitGroup::new();
 | 
			
		||||
        self.send_barrier(&barrier);
 | 
			
		||||
        barrier.wait();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl Drop for DistributedSystem {
 | 
			
		||||
@@ -687,6 +699,8 @@ enum MsgFromHost {
 | 
			
		||||
    Stop,
 | 
			
		||||
    /// Request the current error
 | 
			
		||||
    Error,
 | 
			
		||||
    /// A barrier that must be waited on
 | 
			
		||||
    Barrier(crossbeam_utils::sync::WaitGroup),
 | 
			
		||||
    /// Progressbar to report progress
 | 
			
		||||
    Progressbar(indicatif::ProgressBar),
 | 
			
		||||
    /// Clear and remove the progressbar
 | 
			
		||||
@@ -760,6 +774,7 @@ impl DistributedSystemPart {
 | 
			
		||||
                MsgFromHost::Output(ntime) => self.output(ntime),
 | 
			
		||||
                MsgFromHost::Stop => return,
 | 
			
		||||
                MsgFromHost::Error => self.send(MsgToHost::Error(self.error())).unwrap(),
 | 
			
		||||
                MsgFromHost::Barrier(barrier) => barrier.wait(),
 | 
			
		||||
                MsgFromHost::Progressbar(pbar) => self.progressbar = Some(pbar),
 | 
			
		||||
                MsgFromHost::ProgressbarDrop => {
 | 
			
		||||
                    let pb = self.progressbar.take().unwrap();
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user