C / Posix Вопросы - PullRequest
       39

C / Posix Вопросы

3 голосов
/ 17 июня 2011

Я работал две недели над JamVM, небольшой, но мощной виртуальной машиной Java.

Теперь я пытаюсь понять, как реализована память, и я застрял на двух глупых проблемах C:

char *mem = (char*)mmap(0, args->max_heap, PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANON, -1, 0);

-> Параметр -1 обозначает дескриптор файла, что это значит? (Я недавно прочитал Mmap Man, но не нашел его, может быть, я неправильно понял ...).

heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1&)~(OBJECT_GRAIN-1)) HEADER_SIZE;

-> Что такое 1 &? Я не нахожу это в спецификации C ...

Спасибо

Yann

Ответы [ 2 ]

4 голосов
/ 17 июня 2011

В ответ на ваш первый вопрос. Из справочной страницы .

fd должен быть допустимым файловым дескриптором, если не установлен MAP_ANONYMOUS. Если MAP_ANONYMOUS установлен, то fd игнорируется в Linux. Однако некоторые реализации требуют, чтобы fd было равно -1, если указано MAP_ANONYMOUS (или MAP_ANON), и переносимые приложения должны это гарантировать.

Так что -1, потому что MAP_ANONYMOUS используется.

2 голосов
/ 17 июня 2011

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

Второй вопрос - синтаксическая ошибка (возможно, опечатка). Это, вероятно, должно быть что-то вроде:

heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1)
    &~(OBJECT_GRAIN-1)) - HEADER_SIZE;

В этом случае, OBJECT_GRAIN будет степенью двойки, и это способ добиться согласованности с этой силой. Например, если бы это было 8, то ~(OBJECT_GRAIN-1) было бы ~7 (~00...00111<sub>2</sub>, то есть ~11...11000<sub>2</sub>), которое, когда AND со значением, можно было бы использовать для принудительного приведения этого значения к кратному 8 меньше или равно ему.

На самом деле, это определенно ошибка транскрипции где-то (не обязательно для вас), потому что, когда я загружаю JamVM с здесь и смотрю в src/alloc.c, я получаю:

void initialiseAlloc(InitArgs *args) {
    char *mem = (char*)mmap(0, args->max_heap, PROT_READ|PROT_WRITE,
                                               MAP_PRIVATE|MAP_ANON, -1, 0);
    :
    << a couple of irrelevant lines >>
    :    
    /* Align heapbase so that start of heap + HEADER_SIZE is object aligned */
    heapbase = (char*)(((uintptr_t)mem+HEADER_SIZE+OBJECT_GRAIN-1)&
               ~(OBJECT_GRAIN-1))-HEADER_SIZE;

(обратите внимание, что в вашей версии также отсутствует - непосредственно перед HEADER_SIZE, что указывает на проблемы с транскрипцией).

...