Copy-on-write
# Copy-on-write

La cosiddetta strategia copy-on-write (espressione inglese approssimativamente traducibile con "copia in caso di scrittura") è una tecnica di ottimizzazione informatica mirante alla riduzione delle operazioni di duplicazione delle risorse del sistema (generalmente strutture dati o aree di memoria) attraverso l'eliminazione delle copie non necessarie.

## Principio di funzionamento

Durante lo svolgimento delle normali operazioni di un programma o di un sistema operativo è possibile che si renda necessaria la duplicazione di una risorsa, ovvero la creazione di una nuova risorsa avente contenuto iniziale (o, più genericamente, stato iniziale) identico a quello dell'originale.

Immediatamente dopo la duplicazione e per tutto il tempo in cui nessuna delle due risorse viene modificata, esse sono, di fatto, indistinguibili; durante questo lasso di tempo la reale esistenza di due copie indipendenti non è strettamente necessaria: il sistema può limitarsi a simulare l'operazione di duplicazione, mantenendo l'esistenza di un'unica copia e gestendo attraverso di essa, in modo del tutto trasparente ai richiedenti, tutte le operazioni di lettura destinate ad una qualsiasi delle due.

La vera e propria duplicazione della risorsa può essere posticipata fino al momento in cui l'esistenza di due risorse indipendenti si rende realmente necessaria, cioè in corrispondenza di un'operazione di modifica dello stato (generalmente la scrittura di un nuovo contenuto, da cui il nome di copy-on-write) di una qualsiasi delle copie fittizie.

Il vantaggio principale della strategia copy-on-write risiede nel fatto che se una risorsa duplicata viene successivamente liberata o distrutta senza che nel frattempo né l'originale né la copia siano mai stati modificati, il sistema ha effettivamente evitato una duplicazione non necessaria, con conseguente risparmio di tempo. Il copy-on-write è quindi tanto più vantaggioso quanto più onerosa è l'operazione di duplicazione e quanto più infrequenti sono le operazioni di scrittura.

## Implementazione

### Virtualizzazione delle risorse

L'implementazione di una strategia copy-on-write impone che, nel sistema, l'identificazione delle risorse interessate sia svincolata ed indipendente (almeno dal punto di vista degli utilizzatori) dalla loro effettiva collocazione fisica; è cioè necessario che tali risorse siano virtualizzate.

Ciò che gli utilizzatori conoscono ed usano è un identificatore di risorsa virtuale, attraverso il quale richiedere al sistema l'accesso alla risorsa; il sistema, per parte sua, associa ciascun identificatore alle informazioni necessarie per poter accedere alla vera e propria risorsa fisica. Nel seguito si indicheranno convenzionalmente:

* con $I_X$ l'identificatore di una generica risorsa virtuale;
* con la scrittura $I_X$ → R l'associazione intercorrente tra l'identificatore $I_X$ e la risorsa fisica R.

### Duplicazione della risorsa virtuale

Nella situazione normale, ogni risorsa fisica è associata ad un unico identificatore:

* $I_A$ → $R_1$

Quando il sistema riceve la richiesta di duplicare la risorsa virtuale $I_A,$ viene generata una nuova risorsa virtuale $I_B$ ma non viene creata alcuna nuova risorsa fisica: il nuovo identificatore viene anch'esso associato alla risorsa fisica $R_1:$

* $I_A$ → $R_1$
* $I_B$ → $R_1$

La risorsa fisica $R_1$ non viene ancora duplicata: a partire da questo momento essa diventa la rappresentazione concreta, uguale ed indistinguibile, di entrambe le risorse virtuali, e attraverso di essa il sistema gestisce tutti gli accessi in lettura effettuati tramite gli identificatori $I_A$ e $I_B.$

Per una corretta gestione del copy-on-write il sistema deve tenere traccia del fatto che $I_A$ e $I_B$ non stanno realmente condividendo la risorsa fisica $R_1,$ e che pertanto un eventuale tentativo di accedere in scrittura alla risorsa tramite uno qualsiasi di essi deve essere intercettato e opportunamente gestito in modo da non ripercuotersi sugli altri.

### Scrittura di una risorsa virtuale

Ipotizzando che si renda necessaria un'operazione di scrittura (ad esempio sulla risorsa virtuale $I_A),$ il sistema constata che tale identificatore si riferisce ad una risorsa fisica condivisa in regime di copy-on-write e conseguentemente:

* intercetta e sospende l'operazione di scrittura
* crea una nuova risorsa fisica $R_2$ come copia di $R_1$
* associa l'identificatore $I_A$ a $R_2$

A questo punto il sistema si trova nel seguente stato:

* $I_A$ → $R_2$
* $I_B$ → $R_1$

L'operazione di scrittura inizialmente sospesa può quindi proseguire, modificando lo stato di $R_2$ senza interferire con quello di $R_1,$ che continua ad essere accessibile tramite l'identificatore $I_B.$

## Principali applicazioni

La tecnica del copy-on-write è spesso utilizzata dai sistemi operativi per la gestione delle pagine di memoria in regime di memoria virtuale: le pagine condivise possono essere marcate come di sola lettura in modo tale che gli accessi in scrittura vengano intercettati dalla MMU del processore, che solleva un'eccezione e passa il controllo ad un'apposita funzione di gestione del kernel che provvede alla duplicazione fisica della pagina interessata prima che la scrittura venga ripresa ed eseguita.

Il copy-on-write può ad esempio essere sfruttato quando un processo richiede (attraverso la chiamata di sistema fork o analoga) la creazione di un nuovo processo figlio, inizialmente identico a sé stesso, oppure per ottimizzare la creazione di buffer di grandi dimensioni, in particolare se sparsi.

