2016-01-01 8 views
5

Mam zestaw plików, których długości są wielokrotnościami rozmiaru strony mojego systemu operacyjnego (FreeBSD 10). Chciałbym te pliki na kolejne strony pamięci RAM, dzięki czemu będę mógł traktować kolekcję plików jako jedną dużą tablicę danych.Jak znaleźć dziury w przestrzeni adresowej?

Korzystając z funkcji przenośnych, w jaki sposób mogę znaleźć wystarczająco duży obszar niezmapowanej przestrzeni adresowej, aby mieć pewność, że seria wywołań mmap() w tym regionie zakończy się sukcesem?

+0

Czy mogę wiedzieć, co próbujesz zrobić? – Downvoter

+0

@cad Patrz pierwszy akapit. Zasadniczo mam zestaw danych, który jest podzielony na wiele plików i chcę zmapować go do ciągłego obszaru pamięci, aby traktować go jako jeden. – fuz

+0

Czy możesz 'mmap()' pierwszy plik pozwalający o/s wybrać adres dla ciebie, a następnie spróbuj mapować inne pliki z nim? Spodziewałbym się, że to działa dobrze - ale nie testowałem go na żadnym systemie, a najmniej na FreeBSD 10. –

Odpowiedz

5

Wykonaj następujące kroki:

  1. Najpierw obliczyć całkowity rozmiar potrzebnego wyliczanie plików i zsumowanie ich rozmiary.
  2. Mapuj pojedynczy obszar anonimowej pamięci o tym rozmiarze za pomocą mmap. Jeśli to się nie powiedzie, przegrywasz.
  3. Zapisz wskaźnik i unmap obszar (w rzeczywistości unmap może nie być konieczny, jeśli system mmap systemu o stałym adresie niejawnie mapuje poprzedni nakładający się region).
  4. Zamapuj pierwszy plik pod tym adresem za pomocą odpowiedniej flagi MAP_FIXED.
  5. Zwiększ adres o wielkość pliku.
  6. Wykonaj pętlę do kroku 4, aż wszystkie pliki zostaną zmapowane.

Powinno to być w pełni przenośne dla dowolnego systemu POSIX, ale niektóre systemy mogą mieć dziwactwa, które uniemożliwiają tę metodę. Spróbuj.

+1

Świetny pomysł!Aby uzyskać początkowe mapowanie sond, mogę utworzyć plik rozrzedzony o wymaganej długości i mapach, ponieważ mój system operacyjny nie pozwoli mi mapować więcej anonimowej pamięci niż pamięci RAM (o ile mi wiadomo). – fuz

+0

@FUZxxl: Dobra uwaga, nie myślałem o tym szczególnym przypadku. – chqrlie

+2

O tak, nie musisz nawet odmieniać obszaru - 'mmap' będzie szczęśliwie mapować nad nim z' MAP_FIXED', jeśli o mnie chodzi. – fuz

1

Można uzyskać duży obszar, w którym rozmiar jest sumą rozmiarów wszystkich plików, przy użyciu MAP_PRIVATE | MAP_ANON i ochrony PROT_NONE, co uniemożliwi niepotrzebne obciążanie pamięci przez system operacyjny.

Spowoduje to rezerwację, ale pamięć nie zostanie zatwierdzona.

Następnie można otworzyć plik filename1 pod adresem [baseAddr, size1) i otworzyć filename2 pod adresem [baseAddr + size1, baseAddr + size1 + size2) i tak dalej.

Wierzę, że flagi tego są MAP_FIXED | MAP_PRIVATE.

+0

FreeBSD nie ma 'MAP_NORESERVE'. – fuz

+0

Przeczytaj uważnie. To jest strona manuala z SunOS 5.10. – fuz

+0

Wierzę, że powinno to nadal działać bez 'MAP_NORESERVE'. To spowodowałoby jedynie rezerwację przestrzeni wymiany, co nie jest częstym problemem. –

Powiązane problemy