mirror of
				https://github.com/TomHarte/CLK.git
				synced 2025-10-31 05:16:08 +00:00 
			
		
		
		
	This has become the general producer mutex, might as well name it as such.
This commit is contained in:
		| @@ -33,7 +33,7 @@ uint8_t *BufferingScanTarget::begin_data(size_t required_length, size_t required | |||||||
| 	assert(required_alignment); | 	assert(required_alignment); | ||||||
|  |  | ||||||
| 	// Acquire the standard producer lock, nominally over write_pointers_. | 	// Acquire the standard producer lock, nominally over write_pointers_. | ||||||
| 	std::lock_guard lock_guard(write_pointers_mutex_); | 	std::lock_guard lock_guard(producer_mutex_); | ||||||
|  |  | ||||||
| 	// If allocation has already failed on this line, continue the trend. | 	// If allocation has already failed on this line, continue the trend. | ||||||
| 	if(allocation_has_failed_) return nullptr; | 	if(allocation_has_failed_) return nullptr; | ||||||
| @@ -85,7 +85,7 @@ uint8_t *BufferingScanTarget::begin_data(size_t required_length, size_t required | |||||||
|  |  | ||||||
| void BufferingScanTarget::end_data(size_t actual_length) { | void BufferingScanTarget::end_data(size_t actual_length) { | ||||||
| 	// Acquire the producer lock. | 	// Acquire the producer lock. | ||||||
| 	std::lock_guard lock_guard(write_pointers_mutex_); | 	std::lock_guard lock_guard(producer_mutex_); | ||||||
|  |  | ||||||
| 	// Do nothing if no data write is actually ongoing. | 	// Do nothing if no data write is actually ongoing. | ||||||
| 	if(allocation_has_failed_ || !data_is_allocated_) return; | 	if(allocation_has_failed_ || !data_is_allocated_) return; | ||||||
| @@ -117,7 +117,7 @@ void BufferingScanTarget::end_data(size_t actual_length) { | |||||||
| // MARK: - Producer; scans. | // MARK: - Producer; scans. | ||||||
|  |  | ||||||
| Outputs::Display::ScanTarget::Scan *BufferingScanTarget::begin_scan() { | Outputs::Display::ScanTarget::Scan *BufferingScanTarget::begin_scan() { | ||||||
| 	std::lock_guard lock_guard(write_pointers_mutex_); | 	std::lock_guard lock_guard(producer_mutex_); | ||||||
|  |  | ||||||
| 	// If there's already an allocation failure on this line, do no work. | 	// If there's already an allocation failure on this line, do no work. | ||||||
| 	if(allocation_has_failed_) { | 	if(allocation_has_failed_) { | ||||||
| @@ -148,7 +148,7 @@ Outputs::Display::ScanTarget::Scan *BufferingScanTarget::begin_scan() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void BufferingScanTarget::end_scan() { | void BufferingScanTarget::end_scan() { | ||||||
| 	std::lock_guard lock_guard(write_pointers_mutex_); | 	std::lock_guard lock_guard(producer_mutex_); | ||||||
|  |  | ||||||
| 	// Complete the scan only if one is afoot. | 	// Complete the scan only if one is afoot. | ||||||
| 	if(vended_scan_) { | 	if(vended_scan_) { | ||||||
| @@ -174,7 +174,7 @@ void BufferingScanTarget::end_scan() { | |||||||
| // MARK: - Producer; lines. | // MARK: - Producer; lines. | ||||||
|  |  | ||||||
| void BufferingScanTarget::announce(Event event, bool is_visible, const Outputs::Display::ScanTarget::Scan::EndPoint &location, uint8_t composite_amplitude) { | void BufferingScanTarget::announce(Event event, bool is_visible, const Outputs::Display::ScanTarget::Scan::EndPoint &location, uint8_t composite_amplitude) { | ||||||
| 	std::lock_guard lock_guard(write_pointers_mutex_); | 	std::lock_guard lock_guard(producer_mutex_); | ||||||
|  |  | ||||||
| 	// Forward the event to the display metrics tracker. | 	// Forward the event to the display metrics tracker. | ||||||
| 	display_metrics_.announce_event(event); | 	display_metrics_.announce_event(event); | ||||||
| @@ -277,7 +277,7 @@ const Outputs::Display::Metrics &BufferingScanTarget::display_metrics() { | |||||||
| } | } | ||||||
|  |  | ||||||
| void BufferingScanTarget::set_write_area(uint8_t *base) { | void BufferingScanTarget::set_write_area(uint8_t *base) { | ||||||
| 	std::lock_guard lock_guard(write_pointers_mutex_); | 	std::lock_guard lock_guard(producer_mutex_); | ||||||
| 	write_area_ = base; | 	write_area_ = base; | ||||||
| 	data_type_size_ = Outputs::Display::size_for_data_type(modals_.input_data_type); | 	data_type_size_ = Outputs::Display::size_for_data_type(modals_.input_data_type); | ||||||
| 	write_pointers_ = submit_pointers_ = read_pointers_ = PointerSet(); | 	write_pointers_ = submit_pointers_ = read_pointers_ = PointerSet(); | ||||||
|   | |||||||
| @@ -201,10 +201,13 @@ class BufferingScanTarget: public Outputs::Display::ScanTarget { | |||||||
| 		/// This is used as a spinlock to guard `perform` calls. | 		/// This is used as a spinlock to guard `perform` calls. | ||||||
| 		std::atomic_flag is_updating_; | 		std::atomic_flag is_updating_; | ||||||
|  |  | ||||||
| 		/// A mutex for gettng access to write_pointers_; access to write_pointers_, | 		/// A mutex for gettng access to anything the producer modifies — i.e. the write_pointers_, | ||||||
| 		/// data_type_size_ or write_area_texture_ is almost never contended, so this | 		/// data_type_size_ and write_area_texture_, and all other state to do with capturing | ||||||
| 		/// is cheap for the main use case. | 		/// data, scans and lines. | ||||||
| 		std::mutex write_pointers_mutex_; | 		/// | ||||||
|  | 		/// This is almost never contended. The main collision is a user-prompted change of modals while the | ||||||
|  | 		/// emulation thread is running. | ||||||
|  | 		std::mutex producer_mutex_; | ||||||
|  |  | ||||||
| 		/// A pointer to the next thing that should be provided to the caller for data. | 		/// A pointer to the next thing that should be provided to the caller for data. | ||||||
| 		PointerSet write_pointers_; | 		PointerSet write_pointers_; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user