NAME

cacheflush - 인스트럭션 캐시 및/또는 데이터 캐시의 내용물 비우기

SYNOPSIS

#include <sys/cachectl.h>

int cacheflush(void *addr, int nbytes, int cache);

주의: 일부 아키텍처에는 이 시스템 호출에 대한 glibc 래퍼가 없다. NOTES 참고.

DESCRIPTION

cacheflush()addr에서 (addr+nbytes-1)까지 범위의 사용자 주소에 대해 표시된 캐시(들)의 내용물을 비운다. cache는 다음 중 하나일 수 있다.

ICACHE
인스트럭션 캐시를 비운다.
DCACHE
변경을 메모리로 기록하고 영향 받는 유효한 캐시 라인들을 무효화한다.
BCACHE
(ICACHE|DCACHE)와 같다.

RETURN VALUE

cacheflush()는 성공 시 0을 반환한다. 오류 시 -1을 반환하며 오류를 나타내도록 errno를 설정한다.

ERRORS

EFAULT
addr에서 (addr+nbytes-1)까지의 주소 범위 일부 내지 전부가 접근 가능하지 않다.
EINVAL
cacheICACHE, DCACHE, BCACHE 중 하나가 아니다. (하지만 BUGS 참고.)

CONFORMING TO

역사적으로 이 시스템 호출은 RISC/os, IRIX, Ultrix, NetBSD, OpenBSD, FreeBSD를 포함한 모든 MIPS 유닉스 변종들에서 (그리고 일부 비유닉스 MIPS 운영 체제들에서도) 사용 가능했다. 그래서 MIPS 운영 체제들에서는 이 호출의 존재가 사실상 표준이다.

경고

이식 가능해야 하는 프로그램에서는 cacheflush()를 사용하지 말아야 한다. 리눅스에서 이 호출은 MIPS 아키텍처에서 처음 등장했다. 요즘은 몇몇 다른 아키텍처에서도 cacheflush() 시스템 호출을 제공하지만 인자가 다르다.

NOTES

아키텍처별 차이

glibc에서 ARC, CSKY, MIPS, NIOS2 아키텍처에 대해 SYNOPSIS에 있는 원형으로 이 시스템 호출의 래퍼를 제공한다.

몇몇 다른 아키텍처에서는 리눅스에서 다른 인자로 이 시스템 호출을 제공한다.

M68K:
int cacheflush(unsigned long addr, int scope, int cache,
               unsigned long len);
SH:
int cacheflush(unsigned long addr, unsigned long len, int op);
NDS32:
int cacheflush(unsigned int start, unsigned int end, int cache);

위 아키텍처들에선 glibc에서 이 시스템 호출의 래퍼를 제공하지 않는다. syscall(2)을 이용해 호출해야 한다.

GCC의 대안

이 시스템 호출에서 제공하는 세밀한 제어가 필요하지 않다면 GCC 내장 함수인 __builtin___clear_cache()를 이용하는 게 좋을 수도 있다. GCC 및 호환 컴파일러에서 지원하는 플랫폼 전반에서 이식성 있는 인터페이스를 제공해 준다.

void __builtin___clear_cache(void *begin, void *end);

인스트럭션 캐시 비우기가 필요치 않은 플랫폼에선 __builtin___clear_cache()가 아무 효력이 없다.

주의: 일부 GCC 호환 컴파일러에선 이 내장 함수의 원형에서 매개변수에 void * 대신 char *를 쓴다.

BUGS

2.6.11보다 오래된 리눅스 커널에서는 addrnbytes 인자를 무시하며, 그래서 이 함수의 비용이 꽤 높아진다. 항상 캐시 전체를 비운다.

이 함수는 항상 cache 인자로 BCACHE를 전달받은 것처럼 동작하며 cache 인자에 대해 어떤 오류 검사도 하지 않는다.


2021-03-22