mremap(2) verlegt eine virtuelle Speicheradresse

ÜBERSICHT

#define _GNU_SOURCE /* Siehe feature_test_macros(7) */
#include <sys/mman.h>


void *mremap(void *old_address, size_t old_size,
size_t new_size, int flags, … /* void *new_address */);

BESCHREIBUNG

mremap() erweitert (oder verkleinert) eine bestehende Speicherabbildung, potenziell durch gleichzeitiges Verschieben (bestimmt durch das Argument flags und den zur Verfügung stehenden virtuellen Speicherplatz).

old_address ist die alte Adresse des virtuellen Speicherblocks, den man vergrößern (oder verkleinern) möchte. Beachten Sie, dass old_address an den Speicherseiten ausgerichtet sein muss. old_size ist die alte Größe des virtuellen Speicherblocks. new_size ist die angeforderte Größe des virtuellen Speicherblocks nach der Größenänderung. Optional kann ein fünftes Argument, new_address angegeben werden; siehe die folgende Beschreibung von MREMAP_FIXED.

Unter Linux ist der Speicher in Seiten eingeteilt. Ein Benutzerprozess verfügt über (ein oder) mehrere lineare virtuelle Speichersegmente. Jedes virtuelle Speichersegment hat ein oder mehr Verknüpfungen zu realen Speicherseiten (in der Seitentabelle). Jedes virtuelle Speichersegment hat seinen eigenen Schutz (Zugriffsrechte), welcher eine Segmentverletzung (Segmentation violation) verursachen kann, wenn auf den Speicher nicht korrekt zugegriffen wird. Zugreifen auf virtuellen Speicher außerhalb der Segmente verursacht ebenfalls eine Segmentverletzung.

mremap() benutzt das Linux-Schema für »page tables« (Seitentabellen). mremap() ändert die Verknüpfung zwischen virtuellen Adressen und Speicherseiten. Dies kann benutzt werden, um ein sehr effizientes realloc(3) zu implementieren.

Das Bitmasken-Argument flags kann 0 sein oder die folgenden Flags einschließen:

MREMAP_MAYMOVE
Per Voreinstellung schlägt mremap() fehl, wenn an der aktuellen Position nicht ausreichend Platz vorhanden ist, um den Speicherplatz zu vergrößern. Wird dieses Flag angegeben, darf der Kernel die Speicherabbildung an eine neue virtuelle Adresse verlegen, falls das erforderlich ist. Wenn die Abbildung verlegt wurde, werden absolute Zeiger zum Ort der alten Abbildung ungültig. (Es sollten Offsets relativ zum Anfang des Speicherbereichs verwendet werden.)
MREMAP_FIXED (seit Linux 2.3.31)
Dieses Flag dient einem ähnlichen Zweck wie das Flag MAP_FIXED von mmap(2). Wenn dieses Flag angegeben wird, dann akzeptiert mremap() ein fünftes Argument, void *new_address, das eine an Seiten ausgerichtete Adresse angibt, an die das Mapping verschoben werden muss. Alle früheren Mappings auf den von new_address und new_size angegebenen Adressbereich werden verworfen. Falls MREMAP_FIXED angegeben wird, muss ebenfalls MREMAP_MAYMOVE angegeben werden.

Falls das von old_address und old_size angegebene Speichersegment gesperrt ist (mittels mlock(2) oder etwas Ähnlichem), wird diese Sperre aufrecht erhalten, wenn das Speichersegment verschoben oder seine Größe geändert wird. Als Folge davon kann sich die Größe des durch einen Prozess gesperrten Speichers ändern.

RÜCKGABEWERT

Bei Erfolg gibt mremap() einen Zeiger auf den neuen virtuellen Speicherbereich zurück. Im Fehlerfall wird -1 zurückgegeben und errno entsprechend gesetzt.

FEHLER

EAGAIN
Der Aufrufende versuchte, ein gesperrtes Speichersegment zu vergrößern. Das war nicht möglich, ohne die Begrenzung für die Ressource RLIMIT_MEMLOCK zu überschreiten.
EFAULT
»Segmentation fault.« Eine Adresse im Bereich von old_address bis old_address+old_size ist eine ungültige virtuelle Speicheradresse für diesen Prozess. Man erhält sogar EFAULT, wenn Verknüpfungen existieren, die den gesamten angeforderten Adressraum abdecken, aber von unterschiedlichem Typ sind.
EINVAL
Es wurde ein ungültiges Argument angegeben. Mögliche Gründe sind: old_address war nicht an einer Speicherseite ausgerichtet; in flags wurde ein anderer Wert als MREMAP_MAYMOVE oder MREMAP_FIXED angegeben; new_size war null; new_size oder new_address war ungültig; oder der durch new_address and new_size angegebene neue Adressbereich überschnitt sich mit dem durch old_address und old_size angegebenen alten Adressbereich oder MREMAP_FIXED wurde angegeben, ohne zugleich auch MREMAP_MAYMOVE anzugeben.
ENOMEM
Der Speicherbereich kann an der aktuellen virtuellen Adresse nicht erweitert werden und in flags ist das Flag MREMAP_MAYMOVEnicht gesetzt. Oder es gibt nicht genug freien (virtuellen) Speicher.

KONFORM ZU

Dieser Aufruf ist Linux-spezifisch und sollte nicht in Programmen verwendet werden, die portierbar sein sollen.

ANMERKUNGEN

Vor Version 2.4 machte die Glibc die Definition von MREMAP_FIXED nicht verfügbar und der Prototyp für mremap() ließ das Argument new_address nicht zu.

Falls mremap() dazu verwandt wird, einen mit mlock(2) oder äquivalentem gesperrten Bereich zu verschieben oder zu erweitern, wird der Aufruf mremap() sich die beste Mühe geben, den neuen Bereich zu bestücken, wird aber nicht mit ENOMEM fehlschlagen, falls der Bereich nicht bestückt werden kann.

KOLOPHON

Diese Seite ist Teil der Veröffentlichung 4.06 des Projekts Linux-man-pages. Eine Beschreibung des Projekts, Informationen, wie Fehler gemeldet werden können sowie die aktuelle Version dieser Seite finden sich unter https://www.kernel.org/doc/man-pages/.

ÜBERSETZUNG

Die deutsche Übersetzung dieser Handbuchseite wurde von Patrick Rother <[email protected]>, Martin Eberhard Schauer <[email protected]> und Mario Blättermann <[email protected]> erstellt.

Diese Übersetzung ist Freie Dokumentation; lesen Sie die GNU General Public License Version 3 oder neuer bezüglich der Copyright-Bedingungen. Es wird KEINE HAFTUNG übernommen.

Wenn Sie Fehler in der Übersetzung dieser Handbuchseite finden, schicken Sie bitte eine E-Mail an <[email protected]>.