Pregunta

Estoy tratando de encontrar la manera de volver a asignar los archivos mapeados en memoria en un Mac (cuando quiero ampliar el espacio disponible).

Me ver a nuestros amigos en el mundo de Linux tienen mremap pero no puedo encontrar ninguna tal función en los encabezados en mi Mac. /Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h tiene la siguiente:

  • mmap
  • mprotect
  • msync
  • munlock
  • munmap
  • pero sin mremap

man mremap confirma mis temores.

Actualmente estoy tener que munmap y mmmap si quiero cambiar el tamaño el tamaño del archivo asignado, lo que implica que invalida todas las páginas cargadas. Tiene que haber una mejor manera. Seguramente?

Estoy tratando de escribir código que funcione en Mac OS X y Linux. Podría conformarse con una macro para utilizar la función de mejor en cada caso si Had a, pero yo prefiero hacerlo correctamente.

¿Fue útil?

Solución

Puede ftruncate el archivo a un tamaño grande (la creación de un agujero) y mmap todos de la misma. Si el archivo es persistente recomiendo llenar el agujero con las llamadas de escritura en lugar de escribir en el mapeo, como por lo demás bloques del archivo pueden quedar innecesariamente fragmentado en el disco.

Otros consejos

Si necesita reducir el tamaño del mapa, simplemente munmap la parte al final que desea eliminar.

Si necesita ampliar el mapa, puede mmap el correcto desplazamiento con MAP_FIXED a las direcciones justo por encima del viejo mapa, pero hay que tener cuidado de que no se asignan sobre alguna otra cosa que ya está allí. ..

El texto anterior en virtud de ponches es una idea terrible; MAP_FIXED es fundamentalmente erróneo a menos que ya sabe lo que está en la dirección de destino y desea reemplazar atómicamente ella. Si usted está tratando de asignar de manera oportunista algo nuevo si el rango de direcciones es libre, es necesario el uso mmap con una dirección solicitada pero sin MAP_FIXED y ver si tiene éxito y le da la dirección solicitada; si tiene éxito, pero con una dirección diferente querrá desasignar la nueva asignación que acaba de crear y asumir que la asignación de la dirección solicitada no fue posible.

Si expande en trozos suficientemente grandes (digamos, 64 MB, pero depende de lo rápido que crece), entonces el costo de invalidar el mapa de edad es insignificante. Como siempre, punto de referencia antes de asumir un problema.

No tengo ninguna experiencia con el mapeo de memoria, pero parece que puede asignar temporalmente el mismo archivo dos veces como un medio para ampliar el mapeo sin perder nada.

int main() {
    int fd;
    char *fp, *fp2, *pen;

      /* create 1K file */
    fd = open( "mmap_data.txt", O_RDWR | O_CREAT, 0777 );
    lseek( fd, 1000, SEEK_SET );
    write( fd, "a", 1 );

      /* map and populate it */
    fp = mmap( NULL, 1000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );
    pen = memset( fp, 'x', 1000 );

      /* expand to 8K and establish overlapping mapping */
    lseek( fd, 8000, SEEK_SET );
    write( fd, "b", 1 );
    fp2 = mmap( NULL, 7000, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0 );

      /* demonstrate that mappings alias */
    *fp = 'z';
    printf( "%c ", *fp2 );

      /* eliminate first mapping */
    munmap( fp, 1000 );

      /* populate second mapping */
    pen = memset( fp2+10, 'y', 7000 );

      /* wrap up */
    munmap( fp2, 7000 );
    close( fd );
    printf( "%d\n", errno );
}

La salida es zxxxxxxxxxyyyyyy.....

supongo que, si se libra en esto, puede ser posible que se quede sin espacio de direcciones más rápido que con mremap. Pero nada está garantizado en ambos sentidos y puede ser que por el contrario ser tan seguro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top