Come faccio a allocare i buffer di memoria che può essere recuperato dal sistema operativo per il caching in un'estensione del kernel di Mac OS X?
Domanda
Sulla base di documentazione e fonte XNU ho letto, ho capito che le cache di Mac OS X file I / O utilizzando la cache buffer unificata (UBC). L'UBC cresce così grande come si può sulla base di RAM disponibile, ma le pagine UBC sono alcuni dei primi a essere sacrificati quando la memoria si stringe.
Nel mio autista, mi occupo di vari metadati su disco. Mi piacerebbe essere in grado di utilizzare l'UBC o un meccanismo simile a mantenere MRU cache di questi dati in giro per accelerare le cose, ma dare al kernel la possibilità di riprendere quel ricordo ogni volta che è necessario. I metadati però non rappresenta file di dati, e quindi non rientra direttamente nel dominio del UBC. Esiste un meccanismo di livello inferiore che posso usare, o posso in qualche modo utilizzare solo la parte della UBC che si occupa dei tamponi stessi?
Al momento sto a caccia in tutto il codice sorgente di HFS + per cercare di capire se e come le cache filesystem metadati, sia pure senza molto successo.
L'alternativa principale è ovviamente quello di prenotare una regione di memoria specifica per le cache e fare la mia abbattimento LRU. Posso scegliere una dimensione della cache fissa o utilizzare una sorta di euristica, ma è sempre intenzione di utilizzare troppo poca memoria RAM quando è abbondante e troppo quando non lo è.
Aggiornamento:
Dopo aver cercato un po ', ho trovato che le istanze di IOBufferMemoryDescriptor
possono essere creati con l'opzione kIOMemoryPurgeable
. Questo ti permette di chiamare IOMemoryDescriptor::setPurgeable()
su di esso per segnare la memoria "fair game" per scartare. Ci proverò e aggiornare la questione con i risultati.
Soluzione
Hai ragione. Imposta kIOMemoryPurgeable
come una delle opzioni quando si richiede la memoria. Si inizia come volatile, e può essere paging, ma non verrà eliminato.
Quando si vuole lasciare che il sistema operativo disfarsene, chiamata setPurgeable(kIOMemoryPurgeableVolatile, &oldState );
e il sistema operativo scarterà, se necessario, invece di paging su disco.
Quando si vuole accedere alla memoria, è necessario chiamare setPurgeable(kIOMemoryPurgeableKeepCurrent, &oldState );
e controllo if(oldState != kIOMemoryPurgeableEmpty)
che sarà vero se la memoria è ancora disponibile, e falso se è stato scartato.
Mi sarebbe interessato a sapere se è stato eseguito in qualsiasi cattura.