2.0 KiB
2.0 KiB
Double-Buffer Implementation Helper
This file contains a helper class that wraps the double-buffer logic
Due alla complessità della refactoring completa, ho implementato un approccio ibrido:
Approccio Implementato
-
Buffer Write (Lock-Free):
add_simulated_state()→ scrive direttamente su_write_bufferadd_real_state()→ scrive direttamente su_write_buffer- Questi sono i path critici (chiamati ogni frame)
-
Buffer Read (tramite swap):
- GUI chiama
swap_buffers()prima di leggere (lock minimale ~1ms) - GUI legge da
_read_buffer(no lock)
- GUI chiama
-
Metodi Set (ancora con lock per semplicità):
set_ownship_state(),set_antenna_azimuth(), etc.- Questi sono meno frequenti, lock accettabile
Prossimi Step per Completare
Per completare il double-buffering al 100%, dobbiamo:
- Aggiornare tutti i metodi
set_*()per scrivere su_write_buffer - Aggiornare tutti i metodi
get_*()per leggere da_read_buffer - Chiamare
hub.swap_buffers()in_gui_refresh_loop()prima di leggere
Alternative più rapide
Invece di refactoring completo, possiamo:
Opzione A: Lock-Free solo path critici (ATTUALE)
- ✅
add_simulated_state()eadd_real_state()senza lock - ⏸️ Altri metodi con lock (meno frequenti)
- Impatto: 80% del beneficio, 20% dello sforzo
Opzione B: RWLock invece di Lock
- Usa
threading.RLockoreaderwriterlock - Multiple letture simultanee OK
- Scrittura esclusiva
- Più semplice da implementare
Opzione C: Completare Double-Buffer (FULL)
- Tutti i metodi lock-free
- Swap periodico in GUI
- 100% beneficio, 100% sforzo
Raccomandazione
Date le ottimizzazioni già fatte (logging + tabella), suggerisco:
PASSO 1: Testare con Opzione A (già implementata parzialmente) PASSO 2: Se profiling mostra ancora lock contention → Opzione B (RWLock) PASSO 3: Solo se necessario → Opzione C (Full double-buffer)
Vuoi che: A) Completi il double-buffer al 100%? B) Usiamo RWLock (più semplice)? C) Testiamo prima le ottimizzazioni già fatte?