Неужели в Дарвине нет мрэмапа? - PullRequest
15 голосов
/ 19 августа 2010

Я пытаюсь выяснить, как переназначить отображенные в памяти файлы на Mac (когда я хочу расширить доступное пространство).

Я вижу, что у наших друзей в мире Linux есть mremap, но я не могу найти такую ​​функцию в заголовках на моем Mac./Developer/SDKs/MacOSX10.6.sdk/usr/include/sys/mman.h имеет следующее:

  • mmap
  • mprotect
  • msync
  • munlock
  • munmap
  • но нет mremap

man mremap подтверждает мои страхи.

В настоящее время у меня есть munmap и mmmap если я хочу изменить размер отображаемого файла, что подразумевает аннулирование всех загруженных страниц.Должен быть лучший способ.Конечно?

Я пытаюсь написать код, который будет работать на Mac OS X и Linux.Я мог бы довольствоваться макросом для использования наилучшей функции в каждом случае, если бы у меня было , но я бы предпочел сделать это правильно.

Ответы [ 4 ]

5 голосов
/ 29 декабря 2010

Если вам нужно уменьшить карту, просто munmap часть в конце, которую вы хотите удалить.

Если вам нужно увеличить карту, вы можете mmap правильное смещениес MAP_FIXED по адресам чуть выше старой карты, но вы должны быть осторожны, чтобы не отобразить что-то еще, что уже есть ...

Вышеупомянутый текст под вычеркиванием являетсяужасная идея;MAP_FIXED в корне неверно, если вы уже не знаете, что находится по адресу назначения и не хотите атомарно его заменить.Если вы пытаетесь сопоставить что-то новое, если диапазон адресов свободен, вам нужно использовать mmap с запрошенным адресом, но без MAP_FIXED и посмотреть, удастся ли вам и даст ли вы запрошенный адрес;если это удастся, но с другим адресом, вы захотите отменить отображение только что созданного сопоставления и предположить, что размещение по запрошенному адресу было невозможно.

1 голос
/ 03 апреля 2011

Если вы расширяете достаточно большие куски (скажем, 64 МБ, но это зависит от того, насколько быстро он растет), то стоимость аннулирования старой карты будет незначительной.Как всегда, проведите тестирование, прежде чем приступить к решению проблемы.

0 голосов
/ 20 августа 2010

Вы можете увеличить файл до большого размера (создав дыру) и отобразить все это. Если файл является постоянным, я рекомендую заполнить дыру вызовами записи, а не записью в отображении, так как в противном случае блоки файла могут быть излишне фрагментированы на диске.

0 голосов
/ 19 августа 2010

У меня нет опыта работы с отображением памяти, но похоже, что вы можете временно отобразить один и тот же файл дважды, чтобы расширить отображение без потери чего-либо.

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 );
}

Вывод zxxxxxxxxxyyyyyy.....

Полагаю, если вы решитесь на это, возможно, выйдет из адресного пространства быстрее, чем с mremap. Но в любом случае ничто не гарантировано, и, с другой стороны, это может быть столь же безопасно.

...