fn record_or_hash(
        next_record: &mut Option<Record>,
        poh_recorder: &Arc<Mutex<PohRecorder>>,
        timing: &mut PohTiming,
        record_receiver: &Receiver<Record>,
        hashes_per_batch: u64,
        poh: &Arc<Mutex<Poh>>,
        target_ns_per_tick: u64,
    ) -> bool {
        match next_record.take() {
            Some(mut record) => {
                // received message to record
                // so, record for as long as we have queued up record requests
                let mut lock_time = Measure::start("lock");
                let mut poh_recorder_l = poh_recorder.lock().unwrap();
                lock_time.stop();
                timing.total_lock_time_ns += lock_time.as_ns();
                let mut record_time = Measure::start("record");
                loop {
                    let res = poh_recorder_l.record(
                        record.slot,
                        record.mixin,
                        std::mem::take(&mut record.transactions),
                    );
                    let _ = record.sender.send(res); // what do we do on failure here? Ignore for now.
                    timing.num_hashes += 1; // note: may have also ticked inside record

                    let new_record_result = record_receiver.try_recv();
                    match new_record_result {
                        Ok(new_record) => {
                            // we already have second request to record, so record again while we still have the mutex
                            record = new_record;
                        }
                        Err(_) => {
                            break;
                        }
                    }
                }
                record_time.stop();
                timing.total_record_time_us += record_time.as_us();
                // PohRecorder.record would have ticked if it needed to, so should_tick will be false
            }
            None => {
                // did not receive instructions to record, so hash until we notice we've been asked to record (or we need to tick) and then remember what to record
                let mut lock_time = Measure::start("lock");
                let mut poh_l = poh.lock().unwrap();
                lock_time.stop();
                timing.total_lock_time_ns += lock_time.as_ns();
                loop {
                    timing.num_hashes += hashes_per_batch;
                    let mut hash_time = Measure::start("hash");
                    let should_tick = poh_l.hash(hashes_per_batch);
                    let ideal_time = poh_l.target_poh_time(target_ns_per_tick);
                    hash_time.stop();
                    timing.total_hash_time_ns += hash_time.as_ns();
                    if should_tick {
                        // nothing else can be done. tick required.
                        return true;
                    }
                    // check to see if a record request has been sent
                    if let Ok(record) = record_receiver.try_recv() {
                        // remember the record we just received as the next record to occur
                        *next_record = Some(record);
                        break;
                    }
                    // check to see if we need to wait to catch up to ideal
                    let wait_start = Instant::now();
                    if ideal_time <= wait_start {
                        // no, keep hashing. We still hold the lock.
                        continue;
                    }

                    // busy wait, polling for new records and after dropping poh lock (reset can occur, for example)
                    drop(poh_l);
                    while ideal_time > Instant::now() {
                        // check to see if a record request has been sent
                        if let Ok(record) = record_receiver.try_recv() {
                            // remember the record we just received as the next record to occur
                            *next_record = Some(record);
                            break;
                        }
                    }
                    timing.total_sleep_us += wait_start.elapsed().as_micros() as u64;
                    break;
                }
            }
        };
        false // should_tick = false for all code that reaches here
    }
// returns true if we need to tick
returns true if we need to tick
returns true if we need to tick
fn record_or_hash(
        next_record: &mut Option<Record>,
        poh_recorder: &Arc<Mutex<PohRecorder>>,
        timing: &mut PohTiming,
        record_receiver: &Receiver<Record>,
        hashes_per_batch: u64,
        poh: &Arc<Mutex<Poh>>,
        target_ns_per_tick: u64,
    ) -> bool {
        match next_record.take() {
            Some(mut record) => {
                // received message to record
                // so, record for as long as we have queued up record requests
                let mut lock_time = Measure::start("lock");
                let mut poh_recorder_l = poh_recorder.lock().unwrap();
                lock_time.stop();
                timing.total_lock_time_ns += lock_time.as_ns();
                let mut record_time = Measure::start("record");
                loop {
                    let res = poh_recorder_l.record(
                        record.slot,
                        record.mixin,
                        std::mem::take(&mut record.transactions),
                    );
                    let _ = record.sender.send(res); // what do we do on failure here? Ignore for now.
                    timing.num_hashes += 1; // note: may have also ticked inside record
                    let new_record_result = record_receiver.try_recv();
                    match new_record_result {
                        Ok(new_record) => {
                            // we already have second request to record, so record again while we still have the mutex
                            record = new_record;
                        }
                        Err(_) => {
                            break;
                        }
                    }
                }
                record_time.stop();
                timing.total_record_time_us += record_time.as_us();
                // PohRecorder.record would have ticked if it needed to, so should_tick will be false
            }
            None => {
                // did not receive instructions to record, so hash until we notice we've been asked to record (or we need to tick) and then remember what to record
                let mut lock_time = Measure::start("lock");
                let mut poh_l = poh.lock().unwrap();
                lock_time.stop();
                timing.total_lock_time_ns += lock_time.as_ns();
                loop {
                    timing.num_hashes += hashes_per_batch;
                    let mut hash_time = Measure::start("hash");
                    let should_tick = poh_l.hash(hashes_per_batch);
                    let ideal_time = poh_l.target_poh_time(target_ns_per_tick);
                    hash_time.stop();
                    timing.total_hash_time_ns += hash_time.as_ns();
                    if should_tick {
                        // nothing else can be done. tick required.
                        return true;
                    }
                    // check to see if a record request has been sent
                    if let Ok(record) = record_receiver.try_recv() {
                        // remember the record we just received as the next record to occur
                        *next_record = Some(record);
                        break;
                    }
                    // check to see if we need to wait to catch up to ideal
                    let wait_start = Instant::now();
                    if ideal_time <= wait_start {
                        // no, keep hashing. We still hold the lock.
                        continue;
                    }
                    // busy wait, polling for new records and after dropping poh lock (reset can occur, for example)
                    drop(poh_l);
                    while ideal_time > Instant::now() {
                        // check to see if a record request has been sent
                        if let Ok(record) = record_receiver.try_recv() {
                            // remember the record we just received as the next record to occur
                            *next_record = Some(record);
                            break;
                        }
                    }
                    timing.total_sleep_us += wait_start.elapsed().as_micros() as u64;
                    break;
                }
            }
        };
        false // should_tick = false for all code that reaches here
    }
fn record_or_hash ( next_record : & mut Option < Record > , poh_recorder : & Arc < Mutex < PohRecorder > > , timing : & mut PohTiming , record_receiver : & Receiver < Record > , hashes_per_batch : u64 , poh : & Arc < Mutex < Poh > > , target_ns_per_tick : u64 , ) -> bool { match next_record . take ( ) { Some ( mut record ) => { // received message to record // so, record for as long as we have queued up record requests let mut lock_time = Measure :: start ( " " ) ; let mut poh_recorder_l = poh_recorder . lock ( ) . unwrap ( ) ; lock_time . stop ( ) ; timing . total_lock_time_ns += lock_time . as_ns ( ) ; let mut record_time = Measure :: start ( " " ) ; loop { let res = poh_recorder_l . record ( record . slot , record . mixin , std :: mem :: take ( & mut record . transactions ) , ) ; let _ = record . sender . send ( res ) ; // what do we do on failure here? Ignore for now. timing . num_hashes += 1 ; // note: may have also ticked inside record let new_record_result = record_receiver . try_recv ( ) ; match new_record_result { Ok ( new_record ) => { // we already have second request to record, so record again while we still have the mutex record = new_record ; } Err ( _ ) => { break ; } } } record_time . stop ( ) ; timing . total_record_time_us += record_time . as_us ( ) ; // PohRecorder.record would have ticked if it needed to, so should_tick will be false } None => { // did not receive instructions to record, so hash until we notice we've been asked to record (or we need to tick) and then remember what to record let mut lock_time = Measure :: start ( " " ) ; let mut poh_l = poh . lock ( ) . unwrap ( ) ; lock_time . stop ( ) ; timing . total_lock_time_ns += lock_time . as_ns ( ) ; loop { timing . num_hashes += hashes_per_batch ; let mut hash_time = Measure :: start ( " " ) ; let should_tick = poh_l . hash ( hashes_per_batch ) ; let ideal_time = poh_l . target_poh_time ( target_ns_per_tick ) ; hash_time . stop ( ) ; timing . total_hash_time_ns += hash_time . as_ns ( ) ; if should_tick { // nothing else can be done. tick required. return true ; } // check to see if a record request has been sent if let Ok ( record ) = record_receiver . try_recv ( ) { // remember the record we just received as the next record to occur * next_record = Some ( record ) ; break ; } // check to see if we need to wait to catch up to ideal let wait_start = Instant :: now ( ) ; if ideal_time <= wait_start { // no, keep hashing. We still hold the lock. continue ; } // busy wait, polling for new records and after dropping poh lock (reset can occur, for example) drop ( poh_l ) ; while ideal_time > Instant :: now ( ) { // check to see if a record request has been sent if let Ok ( record ) = record_receiver . try_recv ( ) { // remember the record we just received as the next record to occur * next_record = Some ( record ) ; break ; } } timing . total_sleep_us += wait_start . elapsed ( ) . as_micros ( ) as u64 ; break ; } } } ; false // should_tick = false for all code that reaches here }
returns true if we need to tick
returns true if we need to tick
next_record
&mut Option<Record>
poh_recorder
&Arc<Mutex<PohRecorder>>
timing
&mut PohTiming
record_receiver
&Receiver<Record>
hashes_per_batch
u64
poh
&Arc<Mutex<Poh>>
target_ns_per_tick
u64