5.1.3. Mapped File Operations

S rozmachem stránkování se stalo běžné, že každá stránka paměti je spojena s daty na disku, což je možné v principu využít také pro přístup k souborům, pokud operační systém dá aplikacím možnost specifikovat, s jakými daty na disku jsou stránky spojené. Tato možnost se označuje termínem memory mapped files.

Memory mapped files uměl například již MULTICS kolem roku 1965, dnes je podporují prakticky všechny systémy včetně Linuxu a Windows.

Typickými operacemi je dvojice map a unmap, kde map říká, kterou část kterého souboru mapovat kam do paměti, unmap pak toto mapování ruší. Inherentním problémem memory mapped files je problém změny délky souboru při zápisu, neboť nelze prostě říci, že zápis za namapovaný blok paměti má soubor prodloužit. Další problémy vznikají v situaci, kdy se pro přístup k souboru používají současně stream i mapped operace, tam operační systém zpravidla převádí stream operace na mapped přístup k bufferům kernelu.

5.1.3.1. Example: Linux Mapped File Operations

void *mmap (void *start, size_t length,
            int prot, int flags,
            int fd, off_t offset);
int munmap (void *start, size_t length);

Pokud flags neuvádějí jinak, adresa se bere pouze jako nápověda, systém může namapovat soubor od jiné adresy, kterou vrátí. Adresa musí být zarovnána na hranici stránky. To je pochopitelné, paměťově mapované soubory implementuje file systém ve spolupráci se správcem virtuální paměti, který žádá o data při výpadcích stránek.

Na rozdíl od adresy už nemusí být délka zarovnána na hranici stránky, pro kratší soubory bude poslední stránka doplněna nulami a data zapsaná za konec souboru se při odmapování souboru zahodí.

Ochrana daná parametrem prot je PROT_READ, PROT_WRITE, PROT_EXEC nebo PROT_NONE, případně kombinace, ale opět kvůli způsobu implementace je jasné, že ne všechny kombinace budou k dispozici.

Hlavní flags jsou MAP_SHARED pro normální sdílení změn, MAP_PRIVATE pro vytváření kopíí technikou copy on write, MAP_FIXED při požadavku mapovat právě na uvedenou adresu, MAP_ANONYMOUS pro mapování bez souboru.

Flags MAP_PRIVATE a MAP_FIXED mají zřejmý význam při nahrávání aplikací do paměti.

void *mremap (
  void *old_address, size_t old_size,
  size_t new_size, unsigned long flags);

Snad jediný zajímavý flag MREMAP_MAYMOVE.

int msync (void *start, size_t length, int flags);
int posix_madvise (void *addr, size_t len, int advice);

Advice can be given on future use of the mapped file. Flags describing the future use include POSIX_MADV_NORMAL for no predictable pattern, POSIX_MADV_SEQUENTIAL and POSIX_MADV_RANDOM for specific patterns, and POSIX_MADV_WILLNEED and POSIX_MADV_DONTNEED to determine whether data will be accessed in the near future.

5.1.3.2. Example: Windows Mapped File Operations

HANDLE CreateFileMapping (HANDLE hFile,
                          LPSECURITY_ATTRIBUTES lpFileMappingAttributes,
                          DWORD flProtect,
                          DWORD dwMaximumSizeHigh,
                          DWORD dwMaximumSizeLow,
                          LPCTSTR lpName);

Toto volání vytvoří abstraktní objekt reprezentující mapovaný soubor, ještě ale nic nenamapuje.

Flagy PAGE_READONLY, PAGE_READWRITE, PAGE_READCOPY, význam zřejmý. Flag SEC_COMMIT vyžaduje přidělení fyzického prostoru v paměti či na disku. Flag SEC_IMAGE upozorňuje na mapování spustitelného souboru. Flag SEC_NOCACHE, význam zřejmý. Flag SEC_RESERVE vyžaduje rezervaci bez přidělení fyzického prostoru v paměti či na disku.

Handle souboru může být 0xFFFFFFFF, pak musí být uvedena i velikost mapovaného bloku, systém vyhradí požadovaný prostor podobně jako při odkládání paměti při stránkování.

LPVOID MapViewOfFile (HANDLE hFileMappingObject, DWORD dwDesiredAccess,
                      DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow,
                      DWORD dwNumberOfBytesToMap);
LPVOID MapViewOfFileEx (HANDLE hFileMappingObject, DWORD dwDesiredAccess,
                        DWORD dwFileOffsetHigh, DWORD dwFileOffsetLow,
                        DWORD dwNumberOfBytesToMap, LPVOID lpBaseAddress);
BOOL UnmapViewOfFile (LPCVOID lpBaseAddress);

Namapuje objekt reprezentující mapovaný soubor.

Flags FILE_MAP_WRITE, FILE_MAP_READ, FILE_MAP_ALL_ACCESS, FILE_MAP_COPY. Teď opravdu nevím, co se stane, když tyto flagy odporují flagům u CreateFileMapping, asi chyba.