NOMBRE¶
mremap - 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>.
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.
VÉASE TAMBIÉN¶
getpagesize(2),
realloc(3),
malloc(3),
brk(2),
sbrk(2),
mmap(2)
Su libro de texto favorito de Sistemas Operativos para más información
sobre la memoria paginada. Por ejemplo:
Sistemas Operativos Modernos
por Andrew S. Tannenbaum,
Inside Linux por Randolf Bentson, o
The
Design of the UNIX Operating System por Maurice J. Bach.