2011-07-04 13 views
6

El siguiente es el código que estoy usando para mmaping un archivo en ubuntu con hugepages, pero esta llamada falla con el "argumento inválido". Sin embargo, cuando paso indicador MAP_ANON sin parámetro de descriptor de archivo en mmap, entonces funciona. No puedo entender la posible razón detrás de esto.Ubuntu 10.04, error al usar MAP_HUGETLB con MAP_SHARED

En segundo lugar, no puedo entender por qué se permite mmaping de archivos con MAP_PRIVATE cuando esta bandera en sí misma significa que no se escribirá ningún cambio en el archivo. Esto siempre se puede lograr usando MAP_ANON, o hay algo que me falta?

¿Alguien me puede ayudar con esto?

int32_t main(int32_t argc, char** argv) { 
int32_t map_length = 16*1024*1024; // 16 MB , huge page size is 2 MB 
int32_t protection = PROT_READ | PROT_WRITE; 
int32_t flags = MAP_SHARED | MAP_HUGETLB; 
int32_t file__ = open("test",O_RDWR|O_CREAT | O_LARGEFILE,s_IRWXU | S_IRGRP | S_IROTH); 
if(file__ < 0) { 
    std::cerr << "Unable to open file\n"; 
    return -1; 
} 

if (ftruncate(file__, map_length) < 0) { 
    std::cerr 
    << "main :: unable to truncate the file\n" 
    << "main :: " << strerror(errno) << "\n" 
    << "main :: error number is " << errno << "\n"; 
    return -1; 
} 
void *addr= mmap(NULL, map_length, protection, flags, file__, 0); 
if (addr == MAP_FAILED) { 
    perror("mmap"); 
    return -1; 
} 
const char* msg = "Hello World\n"; 
int32_t len = strlen(msg); 
memcpy(addr,msg,len); 
munmap(addr, map_length); 
close(file__); 
return 0; 
} 
+0

'int32_t main' es un error. Según el estándar de C++, el tipo de retorno de 'main' y el tipo de' argc' deberían ser ambos '' int'. –

+0

larsmans, ¿eso afecta la salida del programa? En mi arquitectura, int es igual que int32_t, por lo que no debería importar nada. Pero desde el punto de vista estándar no está bien, estoy de acuerdo. (Anteriormente cometí un error al escribir este comentario) – Faraz

+0

Faraz: No, él solo estaba curioseando. – BjoernD

Respuesta

4

Ambas preguntas se reducen a un mismo punto: El uso de mmap() se puede obtener dos tipos de asignaciones: la memoria y archivos anónimos.

La memoria anónima es (como se indica en la página de manual) no respaldada por ningún archivo en el sistema de archivos. En cambio, la memoria que recupera de una llamada MAP_ANON a mmap() es una memoria de sistema simple. El usuario principal de esta interfaz es la biblioteca C que lo utiliza para obtener almacenamiento de respaldo para malloc/free. Entonces, usar MAP_ANON explícitamente dice que no quieres mapear un archivo.

Memoria respaldada por archivos tipo de mezclas en un archivo (o porciones) en el espacio de direcciones de su aplicación. En este caso, el contenido de la memoria está respaldado por el contenido del archivo. Piense en el indicador MAP_PRIVATE como la primera asignación de memoria para el archivo y luego copiando el contenido en esta memoria. En verdad, esto no será lo que está haciendo el kernel, pero pretendemos.

HUGE_TLB es una función que el kernel proporciona para la memoria anónima (consulte Documentation/vm/hugetlb-page.txt como se menciona en la página man de mmap()). Esta debería ser la razón por la cual su llamada a mmap() falla cuando usa HUGETLB para un archivo. * Editar: no completamente correcto. Hay un sistema de archivos RAM (hugetlbfs) que admite páginas enormes. Sin embargo, las asignaciones de huge_tlb no funcionarán en archivos arbitrarios, ya que entiendo los documentos. *

Para detalles sobre cómo usar HUGE_TLB y el sistema de archivos en memoria correspondiente (hugetlbfs), es posible que desee considerar los siguientes artículos en LWN:

+0

he escrito que mmap está fallando con el error "argumento inválido", que es la cadena que obtienes cuando haces strerno (22) – Faraz

+1

Revisé toda la documentación antes de escribir esta consulta y no hay claridad en ninguna parte. Estaré encantado de leer algo similar a "MAP_HUGETLB funciona solo con MAP_ANON". En segundo lugar, después de montar hugetlbfs podemos hacer un mmap respaldado con enormes páginas (en este fs). Si, de hecho, MAP_HUGETLB no es compatible con mmap respaldado por archivos, ¿cómo podemos usar hugepages para mmap respaldado por archivos en ese fs? Tiene que haber algo que falta, ¿verdad? – Faraz

+0

Editado mi respuesta. – BjoernD

0

Adición MAP_PRIVATE a las banderas fijas esto por mí.

+0

La página mmap dice que solo puede especificar una de MAP_SHARED o MAP_PRIVATE, no ambas. http://man7.org/linux/man-pages/man2/mmap.2.html –

Cuestiones relacionadas