LINUX.ORG.RU

Не понимаю с mmap..


0

0

Только не пинайте, плиз... :)

Вот есть такая программулина:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
size_t total = 0;
void *reserve(size_t size) {
  void *mem = mmap(NULL, size, PROT_READ | PROT_WRITE | PROT_EXEC,
                               MAP_PRIVATE /*| MAP_NORESERVE*/ | MAP_ANONYMOUS,
                   -1, 0);

  if(mem == MAP_FAILED) {
      printf("Cannot reserve memory (%d KB): %s\n", size / 1024, strerror(errno));
      printf("Reserved so far: %d KB\n", total);
      return NULL;
  }
  total += size / 1024;
  printf("Reserved %d KB (total %d KB)\n", size / 1024, total);
  return mem;
}

#define M (1024*1024)

int main() {
  void *mem = reserve(256 * M);
  if (!mem)
     return 0;
  while(reserve(64 * M))
     ;
  return 0;
}

Она последовательно, блоками по 64мб резервирует пространство ровно в
2 гб (я проверял на машинах с 2 гб. и 512 мб. памяти). Таково значение
переменной total в конце работы - а конец наступает, когда mmap
обламывается с ошибкой ENOMEM.

Я не понимаю, почему резервнуть таким образом можно только 2 гб...

Объясните, пожалуйста!
Заранее спасибо.

А какая система? В man mmap (FreeBSD) так и написано:

BUGS

len is limited to 2GB. Mmapping slightly more than 2GB doesn&#8217;t work, but it is possible to map a window of size (filesize % 2GB) for file sizes of slightly less than 2G, 4GB, 6GB and 8GB.

The limit is imposed for a variety of reasons. Most of them have to do with.Fx not wanting to use 64 bit offsets in the VM system due to the extreme performance penalty. So.Fx uses 32bit page indexes and this gives .Fx a maximum of 8TB filesizes. It&#8217;s actually bugs in the filesystem code that causes the limit to be further restricted to 1TB (loss of precision when doing blockno calculations).

Another reason for the 2GB limit is that filesystem metadata can reside at negative offsets. 


hbee ★★★★
()
Ответ на: комментарий от hbee

Система linux (redhat8, suse9.2). Ну это весьма странно - ведь юзерскому процессу отводится больше двух гигов адресного пространства...

jek_
() автор топика
Ответ на: комментарий от jek_

То же самое - лимит 4GB на 32-разрядной платформе, а файловая система для offsets использует знаковый тип, что режет лимит вдвое. По крайней мере, так утверждает дока на libc.

hbee ★★★★
()
Ответ на: комментарий от jek_

ето ещё зависит от ядра. обычнный mmap под линуксом может выделить ДО 3Гб памяти. предел в 3ГБ недостижим. реальный предел 2.8.

тебе нужен mmap64. подробности не расскажу

cvv ★★★★★
()
Ответ на: комментарий от jek_

>По-моему, mmap64 и файлы тут не причём. Я же использую MAP_ANONYMOUS...

причём то что ты не читаеш маны

>файлы тут не причём

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

>mmap64 тут не причём. Я же использую MAP_ANONYMOUS...

mmap64 тоже понимает MAP_ANONYMOUS...

cvv ★★★★★
()

По крайней мере в старых Linux, насколько я помню, карты памяти на IA32 начинали выделяться с первого гигабайта вверх. Ниже этого уровня можно было сделать mmap только через MAP_FIXED.

P.S. сейчас уточню

Murr ★★
()
Ответ на: комментарий от Murr

1 Гб, с которого начинается выделение, определяется константой TASK_UNMAPPED_BASE (asm-i386/processor.h). TASK_UNMAPPED_BASE=TASK_SIZE/3. Константа нужна была в свое время для того, что работал классический механизм brk. Позже стал работать механизм выделения сверху вниз(от предела стека). Так или иначе для поддержки brk не совсем понятно, как сделать нормальным работу mmap. Впрочем, на платформах с большим виртуальным адресным пространством такой проблемы и нет. Она есть только на платформах с очень тесным адресным пр-вом. :)

Murr ★★
()
Ответ на: комментарий от Murr

Понятно. Спасибо за объяснения... Признаться, я забыл, что
вы мне отвечали на тот вопрос. Кроме того, меня тогда интересовали
границы выделения, а сейчас чуть-чуть другое.

Еще раз спасибо.

jek_
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.