2016-01-01 24 views
5

Ho un set di file le cui lunghezze sono tutte multiple della dimensione della pagina del mio sistema operativo (FreeBSD 10). Vorrei convertire questi file in pagine consecutive di RAM da mmap(), dandomi la possibilità di trattare una raccolta di file come una vasta serie di dati.Come trovare buchi nello spazio degli indirizzi?

Preferibilmente utilizzando le funzioni portatili, come posso trovare una regione sufficientemente ampia di spazio degli indirizzi non mappati in modo da poter essere sicuro che una serie di chiamate mmap() in questa regione avrà esito positivo?

+0

Posso sapere cosa stai provando? – Downvoter

+0

@cad Vedere il primo paragrafo. Fondamentalmente, ho un set di dati che è diviso in più file e voglio mapparlo in una regione di memoria continua per trattarlo come uno. – fuz

+0

Puoi 'mmap()' il primo file a lasciare che l'o/s scelga l'indirizzo per te, quindi prova a mappare gli altri file in modo contiguo con quello? Mi aspetto che funzioni ragionevolmente bene, ma non l'ho testato su nessun sistema, men che meno FreeBSD 10. –

risposta

5

procedere come segue:

  1. prima calcolare la dimensione totale necessaria per l'enumerazione dei file e sommando le loro dimensioni.
  2. Mappare una singola area di memoria anonima di questa dimensione con mmap. Se questo fallisce, perdi.
  3. Salvare il puntatore e unmap l'area (in realtà, unmap potrebbe non essere necessario se il proprio sistema mmap con un indirizzo fisso annulla implicitamente qualsiasi area sovrapposta precedente).
  4. Mappare il primo file a questo indirizzo con il flag MAP_FIXED appropriato.
  5. Incrementa l'indirizzo in base alla dimensione del file.
  6. loop to step 4 fino a quando tutti i file sono stati stampati.

Questo dovrebbe essere completamente portatile per qualsiasi sistema POSIX, ma alcuni sistemi operativi potrebbero avere stranezze che impediscono questo metodo. Provalo.

+1

Ottima idea!Per ottenere la mappatura iniziale della sonda, posso creare un file sparse della lunghezza e della mappa desiderate che, come il mio sistema operativo, non mi consentirà di mappare più memoria anonima di quanto non abbia RAM (per quanto mi riguarda). – fuz

+0

@FUZxxl: buon punto, non ho pensato a questo caso speciale. – chqrlie

+2

Oh sì, non è nemmeno necessario rimuovere la mappatura dall'area-'mmap' sarà felicemente mappato su di esso con 'MAP_FIXED' per quanto mi riguarda. – fuz

1

È possibile mmap un'ampia area in cui la dimensione è la somma delle dimensioni di tutti i file, utilizzando MAP_PRIVATE | MAP_ANON e la protezione PROT_NONE che impedirebbe al sistema operativo di caricare inutilmente le spese di memoria.

Questo riserva ma non memorizza memoria.

È quindi possibile aprire il file filename1 allo [baseAddr, size1) e aprire filename2 allo [baseAddr + size1, baseAddr + size1 + size2) e così via.

Credo che le bandiere per questo sono MAP_FIXED | MAP_PRIVATE.

+0

FreeBSD non ha 'MAP_NORESERVE'. – fuz

+0

Leggere attentamente. Questa è la pagina di manuale di SunOS 5.10. – fuz

+0

Credo che questo dovrebbe funzionare anche senza 'MAP_NORESERVE'. Ciò causerebbe solo la prenotazione dello spazio di swap anche, che spesso non è un problema. –

Problemi correlati