SPL(9)

명칭
splbio, splclock, splhigh, splimp, splnet, splsoftclock, splsofttty, splstatclock, spltty, splvm, spl0, splx - 세치기 우선도의 조작

서식
<sys/types.h> <sys/systm.h> intrmask_t splbio(void) intrmask_t splclock(void) intrmask_t splhigh(void) intrmask_t splimp(void) intrmask_t splnet(void) intrmask_t splsoftclock(void) intrmask_t splsofttty(void) intrmask_t splstatclock(void) intrmask_t spltty(void) void spl0(void) void splx(intrmask_t ipl)

해설
spl() 함수 패밀리는 CPU 의 세치기 우선도의 “레벨” (을)를 설정합니다. 이것은 블록 된 우선도 레벨의 인터럽트 처리기의 실행을 억제합니다. 인터럽트 처리기에 의해 조사 혹은 수정되었을 것이다 데이터 area를 조사 혹은 수정하는 드라이버의 “synchronous” 부분(사용자 프로세스를 대표해 실행되는 부분)에서 사용됩니다.

통상 각각의 세치기를 사용하는 드라이버는, config 파일의 키워드에 의해 1 개의 세치기 우선도 그룹에 할당할 수 있습니다. 예를 들면,

    device foo0 at isa?  port 0x0815 irq 12 tty

(은)는, 세치기 12 를 “tty” 우선도 그룹에 할당합니다. 시스템은 자동적으로 xxx 그룹의 세치기를 우선도가 splxxx () 이상때에 불리는 대로 준비합니다.

splx() 함수는 끼어들어 우선도 레벨을 절대적인 수치로 설정합니다. 이것은 다른 세치기 레벨 함수가 돌려준 값을 로컬의 변수에 보존해, 다음에 원의 우선도 레벨에 되돌리기 위해서(때문에) splx() (을)를 사용하는 일을 의도하고 있습니다.

spl0() 함수는 모든 인터럽트 처리기를 블록 하지 않는 값에 우선도를 감소시킵니다. 다만, AST(비동기 시스템 트랩)는 시스템이 유저 모드로 돌아올 때까지 는 블록 됩니다.

여러가지 디바이스 드라이버의 세치기 우선도 그룹의 전통적인 할당은, 대체로 다음과 같이 분류할 수 있습니다.

splnet()
    모든 네트워크 인터페이스 드라이버.

splbio()
    모든 버퍼 입출력 (즉 디스크등)의 드라이버.

spltty()
    기본적으로는 네트워크 이외의 통신 디바이스입니다만, 사실상은 네트워크와 디스크 이외의 모든 드라이버.

반환값
splx() 및 spl0() 이외의 모든 함수는, 조작전의 우선도의 값을 돌려줍니다.

사용예
이하는, 표준적인 사용예입니다.

    struct foo_softc {
    	...
    	int flags;
    #define	FOO_ASLEEP	1
    #define	FOO_READY	2
    } foo_softc[NFOO];
    int
    foowrite(...)
    {
    	struct foo_softc *sc;
    	int s, error;
    	...
    	s = spltty();
    	if (! (sc->flags & FOO_READY)) {
    		/* 준비가 되어 있지 않습니다, 대기하지 않으면 안됩니다 */
    		sc->flags |= FOO_ASLEEP;
    		error = tsleep(sc, PZERO, "foordy", 0);
    		sc->flags &= ~FOO_ASLEEP;
    	}
    	sc->flags &= ~FOO_READY;
    	splx(s);
    	...
    }
    void
    foointr(...)
    {
    	struct foo_softc *sc;
    	...
    	sc->flags |= FOO_READY;
    	if (sc->flags & FOO_ASLEEP)
    		/* 누군가가 우리를 기다리고 있습니다, 일으켜 주세요 */
    		wakeup(sc);
    	...
    }

인터럽트 처리기는 절대로 우선도 레벨을 감소시켜서는 안된, 이라고 하는 것에 주의해 주세요. 자동적으로, 자신의 레벨의 세치기 우선도에 증가 당합니다. 즉, 같은 그룹의 모든 세치기는 블록 됩니다.

역사
세치기 우선도 레벨은 조기의 버젼의 Unix 로 등장했습니다. 전통적이게는 이름은 아니고 숫자가 사용되고 있어, 그 레벨까지의 모두를 포함해 (우선도 5 는 레벨 5 까지의 모두를 블록 합니다) 있던 일이 알려져 있습니다. 이것은 FreeBSD 에는 들어맞지 않습니다. 전통적인 이름 ‘level’ (은)는 아직껏 캐릭터 ‘l’ (으)로서 각각의 함수나 변수의 이름에 반영되고 있습니다. 그러나, 실제로는 이미 레벨이 아니고, 오히려 다른(부분적으로 포함된) 함수군이 시스템이 있는 기간 블록 됩니다. 역사적인 번호에 의한 방법은 단순해 차례 그대로의 세치기 우선도 레벨 그룹이라고 간주할 수가 있습니다.

저자
이 메뉴얼 페이지는 Jörg Wunsch 하지만 썼습니다.