OpenSolaris.org
 
솔라리스에서 새로운 커널 쓰레드를 실행할 때 cpr이 시스템을 정지시켜 쓰레드가 안전하게 정지할 수 있도록 하기 위해서는 규약을 따라야 합니다. 이 규약은 커널 쓰레드에게 시스템이 곧 셧다운 될 것이라는 것을 알릴 수 있도록 개발되었습니다. Cpr은 시스템의 모든 쓰레드들이 올바르게 정지함으로써 페이지가 상태파일에 저장되어서 커널 메모리가 바뀌지 않도록 하는 것을 요구합니다.

fsflush() 의 동작은 콜백 프로토콜이 어떻게 동작하는지에 대한 좋은 예시 입니다.

#include <sys/callb.h>

fsflush 쓰레드의 초기화 과정에서 메인 서비스 루프에 진입 하기 전에 fsflush는 CALLB_CPR_INIT 매크로를 실행 합니다. 이것은 자료구조를 초기화 하고 콜백 테이블에 있는 쓰레드에 진입합니다. (callb.c 참조)

예를 들어,

  • CALLB_CPR_INIT(&cprinfo, &fsflush_lock, callb_generic_cpr, "fsflush");
    • cprinfo 는 쓰레드 기반에 "callb_cpr_t cprinfo"로 정의 됩니다. 이것은 로컬 혹은 정적이 될 수 있지만 반드시 CALLB_CPR_EXIT 이 호출 될때 까지 존재 해야 합니다. 이 것은 쓰레드가 블록 되거나 cpr을 위한 다른 cv가 블록 될때 사용 되는 플래그들의 셋 혹은 조건 변수들을 포함 합니다. 그러나 내용은 불투명합니다; 구조에 접근 하는 것은 오직 외부적으로 범용 콜백 코드나 매크로에 의해서 가능합니다.
    • fsflush_lock 은 mutext 로써 자료 구조를 보호 합니다. 종종 커널 쓰레드는 이 콜백 프로토콜에 을 사용하여 기존에 존재 하는 뮤텍스에 오버로드 되어질 수 있습니다. Fsflush() 는 클럭 쓰레드가 다시 실행하도록 시그널을 줄때 까지 블록하고 있는 cv와 같은 뮤텍스를 사용합니다.
    • callb_generic_cpr 은 함수 포인터로써 CALLB_CPR_INIT 매크로 콜에 3번째 매개변수로 하드코딩되어야 합니다.
    • "fsflush" 는 콜백 테이블에서 이 특정한 쓰레드를 인식하는 문자열 입니다. 이 것은 묘사적이어야 하고 짧아야 하고 유일해야 하고 최대 길이는 23 문자 입니다.
    주의: 만약 이미 cpr이 시스템을 정지 시키기 전에 CALLB_CPR_INIT() 이 실행된다면 커널 쓰레드는 시스템이 cpr에 의해 다시 동작되기 전에 블록될것입니다.

    커널 쓰레드의 서비스 루프 내에서:

    쓰레드가 안전하게 정지 할 수 있는 상태에 도달 했을때 그것은 CALLB_CPR_SAFE_BEGIN 매크로를 호출합니다. 이 호출에 가장 최적의 장소는 쓰레드가 특정한 일을 완료한 직후나 다른 일을 시작하기 전에 입니다.

    예를 들어,

  • CALLB_CPR_SAFE_BEGIN(&cprinfo);
    • cprinfo 는 반드시 위의 CALLB_CPR_INIT 매크로의 첫번째 인수와 동일 해야 합니다. 다시 말해서 이 것은 쓰레드와 cpr이 동시에 접근하는 자료 구조로써 콜백 메카니즘이 동작하도록 합니다. 이 콜을 실행 시키기 전에 쓰레드는 반드시 CALLB_CPR_INIT 의 두번째 인수로 명시된 락을 소유 하고 있어야 합니다.
    쓰레드가 어떠한 일을 시작하기 전 어떠한 방해도 받지 않아야 할 때에 그것은 반드시 더 이상 정지 되기에 안전하지 않음을 명시해야 합니다. 이것은 CALLB_CPR_SAFE_END 매크로를 실행 함으로써 가능합니다:

    예를 들어,

  • CALLB_CPR_SAFE_END(&cprinfo, &fsflush_lock);
    • cprinfo 는 반드시 위의 CALLB_CPR_INIT 매크로의 첫번째 인수와 동일해야 합니다.
    • fsflush_lock 은 cv_wait() 콜에서 사용될 락을 나타 냅니다. cv_wait() 은 자료구조 내의 플래그에서 cpr이 아직 쓰레드가 기다리기도록 가르 킬때 실행 됩니다. 대부분의 경우에서 이 인수는 CALLB_CPR_INIT 의 두번째 인수와 동일 합니다. 알아 두어야 할 점은 fsflush() 가 동일한 락을 사용한다는 것입니다.
    Fsflush() 는 가장 간단한 예제 입니다. 왜냐하면 종료 하지 않는 커널 쓰레드이기 때문입니다. 만약 새로운 커널 쓰레드가 종료가 가능하다면 그때는 추가적인 매크로 실행이 필요 합니다. 이러한 종류의 쓰레드의 가장 좋은 예제는 nfs_async_start() 입니다. 위에서 기술된 3가지 매크로는 종료가 가능한 쓰레드에서도 똑같이 사용 가능합니다. 추가적으로 쓰레드가 종료되기 전에 반드시 CALLB_CPR_EXIT 매크로를 실행 해야 합니다. 이 호출은 모든 쓰레드 엔트리가 콜백 테이블에서 완벽히 삭제 됐음을 보장합니다.

    예를 들어,

  • CALLB_CPR_EXIT(&cprinfo);
    • cprinfo 는 반드시 CALLB_CPR_INIT 매크로의 첫번째 인수와 동일해야 합니다.
CALLB_CPR_INIT 매크로 실행시에 첫번째 인수로 넘겨지는 락은 반드시 CALLB_CPR_EXIT 가 실행될때까지 유지되어야 합니다. *** 주의 *** CALLB_CPR_EXIT 은 인수로 넘겨지는 락에서 mutex_exit() 을 수행합니다. 만약 존재하는 커널 쓰레드가 cpr 프로토콜과 동조하도록 수정됐을때 그리고 만약 쓰레드가 cprinfo 구조체를 보호 하기 위한 락을 공유하고 있을때는 반드시 락을 두번 해제 하면 안된다는 것을 기억하시기 바랍니다. 만약 공유된 락을 위한 mutex_exit 가 존재 한다면 그것은 반드시 제거되어야 합니다.

주의: callb.h 내의 매크로 정의는 더 이상 필요로 하지 않는 플래그를 참조 하고 있습니다. 또한 여기에 설명된 프로토콜을 준수해야 하는지에 대한 이유가 thread.hthread.c 에 커멘트될 것입니다.

"오픈솔라리스" 카테고리의 다른 글

2006/07/23 15:11 2006/07/23 15:11

TRACKBACK :: http://blog.sdnkorea.com/blog/trackback/122

댓글을 달아 주세요

  1. 박정숙  수정/삭제  댓글쓰기

    좋은 정보 감사해요~

    2007/09/19 04:18
[로그인][오픈아이디란?]

◀ Prev 1  ... 364 365 366 367 368 369 370 371 372  ... 626  Next ▶