mremap(2) re-asocia una dirección de memoria virtual

SINOPSIS

#include <unistd.h>
#include <sys/mman.h>

void *mremap(void *vieja_dir, size_t viejo_tam , size_t nuevo_tam, unsigned long flags);

DESCRIPCIÓN

mremap expande (o encoge) una asociación existente de memoria, moviéndola potencialmente a la vez (según se controle por el argumento flags y según el espacio de direcciones virtuales disponible).

vieja_dir es la dirección antigua del bloque de memoria virtual que Ud. quiere expandir (o encoger). Observe que vieja_dir tiene que tener alineamiento de página. viejo_tam es el antiguo tamaño del bloque de memoria virtual. nuevo_tam es el tamaño pedido del bloque de memoria virtual tras el cambio de tamaño.

El argumento flags es un mapa de bits de opciones.

En Linux la memoria se divide en páginas. Un proceso de usuario tiene (uno o) varios segmentos de memoria virtual lineales. Cada segmento de memoria virtual tiene una o más asociaciones a páginas de memoria real (en la tabla de páginas). Cada segmento de memoria virtual tiene su propia protección (derechos de acceso), que pueden producir una violación de segmento si a la memoria se accede incorrectamente (p.ej., por escribir en un segmento de lectura exclusiva). Acceder a memoria virtual fuera de los segmentos también producirá una violación de segmento.

mremap emplea el esquema de tabla de páginas de Linux. mremap cambia la asociación entre direcciones virtuales y páginas de memoria. Esto puede emplearse para implementar un realloc muy eficiente.

FLAGS

MREMAP_MAYMOVE
indica si la operación, en vez de fallar, debería cambiar la dirección virtual si el cambio de tamaño no puede hacerse en el espacio virtual actual.

VALOR DEVUELTO

En caso de éxito, mremap devuelve un puntero a la nueva área de memoria virtual. En caso de error, se devuelve -1 y se pone un valor apropiado en errno.

ERRORES

EINVAL
Se ha dado un argumento inválido. Lo más probable es que vieja_dir no tenga alineamiento de página.
EFAULT
"Segmentation fault", o sea, "fallo de segmento". Alguna dirección del rango vieja_dir a vieja_dir+viejo_tam es una dirección de memoria virtual inválida para este proceso. También uno puede obtener EFAULT incluso si existen asociaciones que cubren el espacio entero pedido, pero esas asociaciones son de tipos diferentes.
EAGAIN
El segmento de memoria está bloqueado y no puede re-asociarse.
ENOMEM
El área de memoria no puede expandirse en la dirección virtual en curso, y la opción MREMAP_MAYMOVE no está puesta en flags. O bien, no hay bastante memoria (virtual) disponible.

OBSERVACIONES

Con las cabeceras actuales de glibc, para obtener la definición de MREMAP_MAYMOVE, necesita definir _GNU_SOURCE antes de incluir <sys/mman.h>.

CONFORME A

Esta llamada es específica de Linux, y no debería emplearse en programas que se pretendan transportables. 4.2BSD tenía una llamada igual (nunca implementada realmente) mremap(2) con una semántica completamente diferente.