- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
/*
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% %
% %
+ N T M a p M e m o r y %
% %
% %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Mmap() emulates the Unix method of the same name.
%
% The format of the NTMapMemory method is:
%
% MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
% int access,int file,MagickOffsetType offset)
%
*/
MagickPrivate void *NTMapMemory(char *address,size_t length,int protection,
int flags,int file,MagickOffsetType offset)
{
DWORD
access_mode,
high_length,
high_offset,
low_length,
low_offset,
protection_mode;
HANDLE
file_handle,
map_handle;
void
*map;
(void) address;
access_mode=0;
file_handle=INVALID_HANDLE_VALUE;
low_length=(DWORD) (length & 0xFFFFFFFFUL);
high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
map_handle=INVALID_HANDLE_VALUE;
map=(void *) NULL;
low_offset=(DWORD) (offset & 0xFFFFFFFFUL);
high_offset=(DWORD) ((offset >> 32) & 0xFFFFFFFFUL);
protection_mode=0;
if (protection & PROT_WRITE)
{
access_mode=FILE_MAP_WRITE;
if (!(flags & MAP_PRIVATE))
protection_mode=PAGE_READWRITE;
else
{
access_mode=FILE_MAP_COPY;
protection_mode=PAGE_WRITECOPY;
}
}
else
if (protection & PROT_READ)
{
access_mode=FILE_MAP_READ;
protection_mode=PAGE_READONLY;
}
if ((file == -1) && (flags & MAP_ANONYMOUS))
file_handle=INVALID_HANDLE_VALUE;
else
file_handle=(HANDLE) _get_osfhandle(file);
map_handle=CreateFileMapping(file_handle,0,protection_mode,high_length,
low_length,0);
if (map_handle)
{
map=(void *) MapViewOfFile(map_handle,access_mode,high_offset,low_offset,
length);
CloseHandle(map_handle);
}
if (map == (void *) NULL)
return((void *) ((char *) MAP_FAILED));
return((void *) ((char *) map));
}
Мумуляция «mmap» в «Винде». Это даже работает, если пофиксить две строчки (кто угадает, какие именно, тому ничего).
Отсюда:
https://github.com/ImageMagick/ImageMagick/blob/master/MagickCore/nt-base.c
Myxa 30.07.2020 00:19 # 0
Метки: #виндовоз, #ленсук, #мумуляция, #целыйпитух.
Myxa 30.07.2020 03:35 # 0
Код (offset >> 32) на 32-битном x86 может выполниться вообще без сдвига (посчитается как просто offset), если offset случайно окажется 32-битным, поэтому безопаснее писать так: Я всё-таки надеюсь на то, что MagickOffsetType шире 32 бит в любом компиляторе (мне лень искать его определение).
И ещё у них забавный гольф: (void *) ((char *) map). Зачем такие многократные приведения указателей?
bormand 30.07.2020 03:36 # 0
3.14159265 30.07.2020 03:44 # 0
> high_length=(DWORD) ((((MagickOffsetType) length) >> 32) & 0xFFFFFFFFUL);
Я с определённых пор возненавидел эти байтоёбские сдвиги, маски.
union и bit fields должны сделать код ГОРАЗДО читабельнее.
Насчёт Ub и прочих багров не уверен. Но можно вместо union скастить в struct.
bormand 30.07.2020 03:47 # 0
3.14159265 30.07.2020 03:49 # 0
Пиздец. Почему они их не починят?
>implementarion defined. Нахуй и впизду.
Ну для MS-онли-компилера может и сойдёт.
bormand 30.07.2020 03:55 # 0
3.14159265 30.07.2020 03:57 # 0
Да.
Ну в стандарт записать как надо ложить.
И пусть ебутся чтобы соотвествовать.
bormand 30.07.2020 04:01 # 0
3.14159265 30.07.2020 03:40 # 0
Но в Луниксе mmap используется не только для файлов, но и как Царская альтернатива mallocу.
Тут к сожалению не реализован сей нюанс. Какой-то VirtualAlloc.
bormand 30.07.2020 03:42 # 0
Myxa 30.07.2020 03:56 # 0
https://github.com/wine-staging/wine-patched/blob/master/dlls/ntdll/virtual.c#L3288
3.14159265 30.07.2020 13:55 # +1
Использование
Какая фабрика )))
gost 30.07.2020 03:49 # 0
Пользователи этого кода рискуют поиметь здоровенные багры. Сам когда-то на это налетал.
bormand 30.07.2020 03:49 # +1
А, понял, в ммап 4к. А в винде 64к.
gost 30.07.2020 03:51 # 0
А, не знал. Ну тогда багры будут с allocation granularity, ага.
bormand 30.07.2020 03:57 # +1
Кроме ебучего mingw, которое иногда падает на форке из-за того что адрес занят.
Myxa 30.07.2020 04:00 # +1
Точнее, не в «mingw», а в «MSYS» (позиксовый слой для «mingw») и в «Cygwin».
3.14159265 30.07.2020 11:32 # +1
Ой, помню этот багор.
И даже не после установки. А во время работы. Собираешь что-то мейком: хуяк система залипла.
Я ещё тогда на 32-битной системе был, это ОЧЕНЬ сильно раздражало. Т.к. виртуальной памяти было не так много.
gost 30.07.2020 04:03 # 0
bormand 30.07.2020 04:06 # 0
Myxa 30.07.2020 04:07 # +1
gost 30.07.2020 04:08 # 0
Впрочем, я сейчас в эту портянку вчитываться не хочу, мне ещё спать идти, желательно без кошмаров про превращение в итератор DWORD64. Так что там могут и другие багры быть.
bormand 30.07.2020 06:14 # +3
Говорят, что для того, чтобы это прекратилось необходимо использовать DWORDLONG.
Myxa 30.07.2020 16:36 # 0
3.14159265 30.07.2020 03:53 # +2
3.14159265 30.07.2020 03:55 # +2
Вот хуй.
Если там huge pages, то может быть и 2Mb и 4Mb (емнип на армах).
guest8 06.08.2020 22:13 # −999
bormand 06.08.2020 22:19 # 0