Путать с арифметикой указателя - PullRequest
0 голосов
/ 01 февраля 2020

Может ли кто-нибудь помочь мне понять, что делают эти две строки

buf = (char *)(malloc(2 * pagesize) & pagemask);
buf = (char *)(((long)buf + pagesize) & ∼pagemask);

Я понимаю mallo c, но не уверен, что операция & пытается достичь в обоих выражениях

Размер страницы и маска страницы определяются следующим образом

pagesize = sysconf(_SC_PAGESIZE);
pagemask = pagesize - 1;

Спасибо!

Edit1

Этот код из книги "Unix FileSystems Стив Д. Пэйт

Edit2

Это полный код

#include <sys/unistd.h>
#include <sys/types.h>
#include <fcntl.h>
#include “sys/fs/vx_ioctl.h”

#define MB (1024 * 1024)

main(int argc, char argv[])
{
    char        *buf;
    int         i, fd, advisory;
    long        pagesize, pagemask;

    if (argc != 2) {
        exit(1);
    }
    if (strcmp(argv[1], “VX_SEQ”) == 0) {
        advisory = VX_SEQ;
    } else if (strcmp(argv[1], “VX_RANDOM”) == 0) {
        advisory = VX_RANDOM;
    } else if (strcmp(argv[1], “VX_DIRECT”) == 0) {
        advisory = VX_DIRECT;
    }
    pagesize = sysconf(_SC_PAGESIZE);
    pagemask = pagesize - 1;
    buf = (char *)(malloc(2 * pagesize) & pagemask);
    buf = (char *)(((long)buf + pagesize) & ∼pagemask);

    fd = open(“myfile”, O_RDWR);
    ioctl(fd, VX_SETCACHE, advisory);
    for (i=0 ; i<MB ; i++) {
         read(fd, buf, 4096);
    }
}

1 Ответ

1 голос
/ 02 февраля 2020

Предварительные замечания

  • "Страницы" памяти всегда (ну, фактически всегда) имеют размер, равный степени 2. Это означает, что для данного размера страницы старшие биты адрес обозначает страницу, а младшие биты - смещение на странице.
  • Не пишите такой код. Делать явные преобразования; использовать несколько простых инструкций; попробуйте использовать более значимые имена переменных (например, offset_into_page = ((const uintptr_t) address) & page_mask;) и т. д.

Первая строка

В строке first выполняется следующее:

  1. Выделить память на 2 страницы.
  2. Обрабатывая адрес как число, сохраняйте только биты смещения на странице, на которой начинается выделенная область.

Мне не понятно, почему это полезно.

Вторая строка

Строка second делает следующее:

  1. Лечить адрес buf в виде числа (хотя изогнутым, подверженным ошибкам и непереносимым способом).
  2. Переместитесь на одну страницу вперед от адреса buf.
  3. Сохраните биты страницы адреса - получение первого выровненного по границе страницы адреса в буфере.

Это жертвует частью пространства, выделенного для buf, выравнивая его (и сохраняя в фактически выделенном пространстве .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...