Смещение для mmap () должно быть выровнено по странице [дублировать]

Много раз это происходит со мной от javascript к моему php api, потому что одна из нескольких причин. Я забыл поставить <?php header('Access-Control-Allow-Origin: *'); ? один. Это полезно для доступа к перекрестным доменам. Другая причина заключается в том, что в jQuery ajax-запросе я указываю конкретный тип данных и возвращаю другой тип данных, поэтому он выдает ошибку.

Последней и самой известной причиной этой ошибки является ошибка синтаксического анализа на запрашиваемой странице. Если вы нажмете URL-адрес этой страницы в своем браузере, более вероятно, вы увидите ошибку синтаксического анализа, и у вас будет номер строки для решения проблемы.

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

3
задан Steve H 9 April 2014 в 19:08
поделиться

3 ответа

Эти вычисления предполагают, что размер страницы - это мощность 2 (что имеет место для всех систем, о которых я знаю), например

PageSize = 4096 = 2^12 = 1000000000000 (binary)

Тогда ( записанные как двоичные числа)

PageSize-1    = 00...00111111111111
~(PageSize-1) = 11...11000000000000

, что означает, что

(VirtualAddr & ~(PageSize-1))

- VirtualAddr, причем младшие 12 бит установлены на ноль или, другими словами, VirtualAddr округлены вниз до следующего кратного значения 2^12 = PageSize.

Теперь вы можете (надеюсь) увидеть, что в

len = ((PageSize-1)&len) ? ((len+PageSize) & ~(PageSize-1)):len;

первое выражение

 ((PageSize-1)&len)

равно нулю, если len кратно PageSize. В этом случае len остается неизменным. В противном случае (len + PageSize) округляется до следующего кратного значения PageSize.

Поэтому в любом случае len округляется вверх до следующего кратного значения PageSize.

5
ответ дан Martin R 23 August 2018 в 19:42
поделиться

Я думаю, что первый должен быть

VirtualAddr = (VirtualAddr & ~(PageSize-1)) + PageSize; 
1
ответ дан Ashkan 23 August 2018 в 19:42
поделиться

Этот однострочный лайнер сделает это - если он уже выровнен по горизонтали, он не перейдет к следующей границе страницы:

aligned = ((unsigned long) a & (getpagesize()-1)) ? (void *) (((unsigned long) a+getpagesize()) & ~(getpagesize()-1)) : a;

Этот однострочный лайнер будет делать это - если он уже выровнен по горизонтали, будет не перейти к следующей границе страницы:

, если вы действительно сделали хотите перейти на следующую границу страницы, даже если она уже выровнена - просто выполните:

aligned = (void *) (((unsigned long) a+getpagesize()) & ~(getpagesize()-1))

Это также должно избегать всех предупреждений компилятора.

getpagesize() - это POSIX. #include <unistd.h>, чтобы избежать предупреждений.

0
ответ дан Brad 23 August 2018 в 19:42
поделиться
Другие вопросы по тегам:

Похожие вопросы: