MMAP(2)

명칭
mmap - 메모리의 할당, 또는 파일 또는 디바이스의 메모리에의 MAP

프로그램 라이브러리
libc

서식
<sys/types.h> <sys/mman.h> void * mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)

해설
mmap() 함수는, addr (을)를 시점으로서 최대로 len 바이트가 연속하는 페이지에, fd 에 의해 기술되는 오브젝트의 바이트 오프셋(offset) offset 의 위치로부터 시작되는 부분을 MAP 되도록(듯이) 합니다. len 하지만 페이지 사이즈의 배수가 아닌 경우, MAP 된 area는 지정의 범위를 넘어 확장될지도 모릅니다. 이러한 확장에 의해 MAP 된 오브젝트의 말단을 넘은 부분은 0 으로 묻을 수 있습니다.

addr 하지만 0 이 아닌 경우, 이것은 시스템에의 힌트로서 사용됩니다 (시스템의 편의를 위해서(때문에), area의 실제의 주소는 지정된 주소와는 다를 가능성이 있습니다). addr 하지만 0 의 경우, 주소는 시스템에 의해 선택됩니다. area의 실제의 개시 주소가 돌려주어집니다. mmap 하지만 처리에 성공하면(자), 확보된 주소 범위의 이전의 매핑은 삭제됩니다.

보호 (area에의 액세스 허가)는 prot 인수로, 이하의 값의 논리합 (or) (을)를 취한 값으로 지정합니다.

PROT_NONE
    페이지는 액세스 할 수 없습니다.
PROT_READ
    페이지는 읽기 할 수 있습니다.
PROT_WRITE
    페이지는 기록 할 수 있습니다.
PROT_EXEC
    페이지는 실행 가능합니다.

flags 파라미터는, MAP 된 오브젝트의 타입, 매핑 옵션, 및 MAP 된 페이지의 카피에 대해서 행해진 수정이, 프로세스에 고유한가 또는 외로부터의 참조와 공유되는지를 지정합니다. 공유, 매핑 타입, 및 옵션은, 이하의 값의 논리합 (or) (을)를 취한 값으로 flags 인수로 지정합니다.

MAP_ANON
    어느 특정의 파일과도 대응하고 있지 않는 익명 메모리를 MAP 합니다. MAP_ANON (을)를 작성하는데 사용된다 파일 기술자는 -1 일 필요가 있습니다. offset 파라미터는 무시됩니다.

MAP_FIXED
    시스템이, 지정된 주소와 다른 주소를 선택하는 것을 허용 하지 않습니다. 지정된 주소를 사용할 수 없는 경우, mmap() (은)는 처리에 실패합니다. MAP_FIXED 하지만 지정되어 있는 경우, addr (은)는 페이지 사이즈의 배수일 필요가 있습니다. 이 옵션의 사용은 추천할 수 없습니다.

MAP_HASSEMAPHORE
    area에 semaphore가 포함되어 있을 가능성이 있는 것, 특수한 처리가 필요한 가능성이 있는 것을 커널에 통지합니다.

MAP_NOCORE
    area는 코어 파일에 포함되지 않습니다.

MAP_NOSYNC
    (은)는 이 VM MAP를 경유해 더럽혀진 데이터를, 함부로는 아니고 (통상은 페이쟈에 의해) 필요한 때만 물리적인 미디어에 플래시 하도록(듯이) 합니다. 보통, 이 옵션에 의해, 갱신 demon는 이 MAP로 더럽혀진 페이지를 플래시 하지 않게 됩니다. 이것에 의해, 파일 백업 된 공유 메모리의 매핑을 사용해 무관계한 프로세스의 사이에 메모리아크세스를 효율적으로 공유하는 것이 할 수 있게 됩니다. 이 옵션이 없으면 더럽혀진 VM 페이지는 번민 (통상 30-60 초 마다)에 디스크에 플래시 될지도 모르지 않고, 그러한 동작을 필요로 하지 않는 경우 (예를 들면 IPC 를 위해서(때문에) 파일을 이용한 공유 mmap area를 이용하고 있는 경우) 퍼포먼스에 문제가 나오는 일이 있습니다. MAP_NOSYNC (을)를 사용하고 있을까에 관계없이, VM/ 파일 시스템의 일관성은 유지되는 것에 주의해 주세요. 이 옵션은 UNIX 플랫폼간에 ( 아직) 이식성은 없습니다만, 몇개의 플랫폼에서는 디폴트로 같은 동작을 하도록(듯이) 실장되고 있을지도 모릅니다.

    경고! ftruncate(2) (을)를 사용 파일을 확장하고 나서, 즉 파일에 큰 구멍을 뚫고 나서, 그 구멍을 공유 mmap() (을)를 수정해 묻는 경우, 심각한 파일 단편화가 생길 가능성이 있습니다. 이 단편화를 피하기 위해서(때문에), mmap() 그리고 그 area를 수정하기 전에, 신규에 확장한 area에 0 을 write() 해, 파일의 배킹 스토어를 사전에 할당해 둘 필요가 있습니다. 디스크에의 플래시가 완전히 랜덤에 생기기 (위해)때문에, 단편화 문제에 특히 민감한 것은, MAP_NOSYNC 페이지입니다.

    같은 것이, MAP_NOSYNC (을)를 사용 파일 베이스의 공유 메모 restore를 실장하는 경우에도 말할 수 있습니다. ftruncate() 해 배킹 스토어를 만드는 것이 아니라, 0 을 write() 해 배킹 스토어를 만드는 것을 추천 합니다. 예를 들어, “dd if=filename of=/dev/null bs=32k” (을)를 사용하는 등 해 거대한 파일을 시퀀셜에 읽어들이면서, “iostat 1” (을)를 호출하는 것으로 얻을 수 있다 KB/t (전송 1 회 쯤의 킬로바이트수)를 관찰하는 것으로 파일 단편화의 테스트가 가능합니다.

    fsync(2) 함수는 모든 오염된 데이터와 파일에 관련 지을 수 있었던 메타데이타 (NOSYNC 가 더러워진 VM 데이터를 포함한다)(을)를 물리적 매체에 플래시 합니다. sync(8) 명령와 sync(2) 시스템 콜은, 오염된 NOSYNC VM 의 데이터를 통상 플래시 하지 않습니다. msync(2) 시스템 콜은 BSD 그리고 정합성이 있는 파일 시스템의 버퍼 캐쉬가 실장되었으므로 폐지되었습니다. 그렇지만, 더러워진 VM 페이지와 파일 시스템을 묶어 물리적 매체에 곧바로(나중에는 아니고) 플래시 시키는 용도에 사용되는 일도 있습니다.

MAP_PRIVATE
    수정은 프로세스 고유하게 행해집니다.

MAP_SHARED
    수정은 공유됩니다.

MAP_STACK
    이 옵션을 이용할 수 있는 것은, 시스템의 커널을 컴파일 할 경우에 VM_STACK (을)를 정의해 컴파일 했을 경우만입니다. 이것은 i386 에 관해서만 디폴트입니다. 다른 아키텍쳐로 이 옵션을 유효하게 하고 싶은 경우는, /etc/make.conf 안에서 -DVM_STACK (을)를 COPTFLAGS 에 추가하는 방법을 검토해 주세요. MAP_STACK 하 MAP_ANON 및 0 의 offset 지정을 포함합니다. fd (은)는 -1 나오지 않으면 안되어, prot 에는 적어도 PROT_READ (와)과 PROT_WRITE 하지만 들어가 있을 필요가 있습니다. 이 옵션은, 스택의 선두를 개시점으로 해 하부에 성장하는, 사이즈가 최대로 len 바이트까지 성장하는 메모리 area를 작성합니다. 스택의 선두는, 호출로부터 돌려주어진 개시 주소에 len 바이트를 더한 것이 됩니다. 가장 성장했을 경우의 스택의 하단은, 호출에 의해 돌려주어지는 개시 주소가 됩니다.

close(2) 함수는 페이지를 안 MAP 하지 않습니다. 상세한 것에 대하여는 munmap(2) (을)를 참조해 주세요.

현재의 설계에서는 프로세스는 스왑 공간의 위치를 지정할 수 없습니다. 장래는, 추가의 매핑 타입 MAP_SWAP (을)를 정의할지도 모릅니다. 이 경우, 파일 기술자 인수에는 스왑을 행해야 할 파일 또는 디바이스를 지정합니다.

반환값
정상적으로 완료하면(자), mmap() (은)는, MAP 된 area를 가리키는 포인터를 돌려줍니다. 그렇지 않은 경우는 치 MAP_FAILED 하지만 돌려주어져 에러를 나타내기 위해서(때문에) errno 하지만 설정됩니다.

에러
mmap() (은)는 다음의 경우에 실패합니다.

[EACCES]
    플래그 PROT_READ 하지만 prot 파라미터의 일부로서 지정되었습니다만, fd 하지만 읽기용으로 열리고 있지 않았습니다. 플래그 MAP_SHARED (와)과 PROT_WRITE 하지만 flags (와)과 prot 파라미터의 일부로서 지정되었습니다만, fd (은)는 기록용으로 열리고 있지 않았습니다.

[EBADF]
    fd 하지만 유효한 열린 파일의 기술자가 아닙니다.

[EINVAL]
    MAP_FIXED 하지만 지정되어 addr 파라미터가 페이지 경계에 정렬되어 있지 않은지, 또는 지정의 주소의 일부가 유저 프로세스의 유효한 address 공간의 밖이 됩니다.

[EINVAL]
    len 하지만 부였습니다.

[EINVAL]
    MAP_ANON 하지만 지정되어 fd 파라미터가 -1 가 아니었습니다.

[EINVAL]
    MAP_ANON 하지만 지정되지 않고, fd 하지만 통상의 파일 또는 캐릭터형 특수 파일을 참조하고 있었었습니다.

[EINVAL]
    offset 하지만 페이지 경계에 정렬하고 있었었습니다 (후술 하는 「 버그 의 장」을 참조).

[ENOMEM]
    MAP_FIXED 하지만 지정되어 있습니다만, addr 파라미터가 주어지고 있지 않습니다. MAP_ANON 하지만 지정되어 이용할 수 있는 메모리가 불충분했습니다. sysctl 치 vm.nax_proc_mmap 그리고 지정되었다 프로세스 마다의 mmap 한계에 이르렀습니다.

관련 항목
madvise(2), mincore(2), mlock(2), mprotect(2), msync(2), munlock(2), munmap(2), getpagesize(3)

버그
len (은)는 2GB 로 한정됩니다. 2GB 를 조금 웃도는 매핑은 기능합니다만, 2GB, 4GB, 6GB, 및 8GB 보다 조금 적은 파일 사이즈에 대해 (파일 사이즈 % 2GB)의 사이즈의 윈도우를 MAP 할 수 있습니다.

제약은 다채로운 이유로부터 생기고 있습니다. 그 대부분은, 퍼포먼스상의 현저한 패널티이기 때문에, FreeBSD 그럼 VM 시스템내에서 64 비트의 오프셋(offset)를 사용하고 싶지 않은 것과 관계하고 있습니다. 따라서 FreeBSD (은)는 32 비트의 페이지 인덱스를 사용하고 있어, 이것에 의해 FreeBSD 그럼 최고로 8TB 까지의 파일 사이즈를 이용할 수 있습니다. 실제로는 한층 더 제약이 부과되어 사용 가능 사이즈는 1TB 까지입니다만, 이것은, 파일 시스템 코드내의 버그에 의하는 것입니다 (블록 번호 계산을 행하고 있을 때의 자리수 빠짐).

2GB 제한의 또 하나의 이유는, 파이르시스템메타데이타가 부의 오프셋(offset)에 존재할 수 있다고 하는 것입니다.