martes, 9 de marzo de 2010

mremap()

Aldo Ramirez Mendoza
COMANDO
mremap - re-asocia una dirección de memoria virtual
SINOPSIS
#include
#include
void *mremap(void *old_dir, size_t old_tam , size_t new_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).
old_dir es la dirección antigua del bloque de memoria virtual que se quiere expandir (o encoger). Observe que old_dir tiene que tener alineamiento de página. old_tam es el antiguo tamaño del bloque de memoria virtual. new_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 (serie 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.

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.




EJEMPLO
-----------------------------------------------------
#include
#include
#include

#define SIZE (10)
#define NEWSIZE (200)

int main()
{
char *string;
int i=0,j=0;
//string=(char *)malloc(SIZE*sizeof(char));
string=(char *)mmap(0,SIZE*sizeof(char),PROT_READ|PROT_WRITE,MAP_ANONYMOUS|MAP_SHARED,NULL,NULL);

for (i=0; i<(SIZE-1); i++)
string[i]=((j++)+48);
string[i]='\0';

printf("Contenido de string=\"%s\"\n",string);
//exit(0);
/**********************************************/
j=0;
string=(char *)mremap(string,SIZE*sizeof(char),NEWSIZE*sizeof(char),0);

if(string==-1){ printf("Error al asignar memoria\n");exit(-1); }

for (i=0; i<(NEWSIZE-1); i++)
{string[i]=((j++)+48); if ((j+48)==128) j=0;}
string[i]='\0';
printf("Contenido de string=\"%s\"\n",string);


}


-----------------------------------------------------

No hay comentarios:

Publicar un comentario