[블로그 통합으로 이전해 온 자료] -
1. "원자 문맥에서 수행 중(spinlock, seqlock RUC lock 등..)일
때에는 절대로 잠들어서는 안된다."
2. 인터럽트를 비 활성화 시켰을 때에도 잠들 수 없다.
3. semaphore를 보유한 동안 잠드는것은 이 semaphore를 기다리는
다른 프로세스도 잠들게 한다. (주의!!)
3. 잠들기 전에 기다리던 조건을 정말로 충족하는지 확인해야 한다.
4. 누군가 깨울것이라는 확인 없이 잠들어서는 안된다.
대기 큐 wait_queue_t
<linux/wait.h>
DECLARE_WAIT_QUEUE_HEAD( wq );
wait_queue_head_t wq;
init_waitqueue_head( &wq );
condition 조건이 참 일때까지 잠든다는데.. 그러면 깨운다는 의미가 없지 않나?
wait_event( wq, condition );
wait_event_interruptible( wq, condition ); <-- 주로 사용
wait_event_timeout( wq, condition, timeout );
wait_event_interruptible_timeout( wq, condition, timeout );
void wake_up( wait_queue_head_t *queue );
void wake_up_interruptible( wait_queue_head_t *queue );
DEFINE_WAIT( wait );
wait_queue_t wait;
init_wait( &wait );
// 상호배제 대기를 설정하면 해당 항목은 대기 큐 맨 끝에 추가하고, 이 설정을 하지 않으면
// 대기 큐 맨 앞에 추가한다.
// wake_up() 상호배제 대기 설정을 한 첫 번째 프로세스만 깨운후 멈춘다.
// wake_up() 은 동일한 함수를 사용.
// state는 TASK_UNINTERRUPTIBLE 이거나 TASK_INTERRUPTIBLE이 된다.
void prepare_to_wait( wait_queue_head_t *queue, wait_queue_t *wait, int state );
void prepare_to_wait_exclusive( wait_queue_head_t *queue, wait_queue_t *wait, int state );
void finish_wait( wait_queue_head_t *queue, wait_queue_t *wait );
example>
잠들 프로세스가 접근한 드라이버 코드
prepare_to_wait( &wq, &wait, TASK_INTERRUPTIBLE ); // 혹은
prepare_to_wait_exclusive( &wq, &wait, TASK_INTERRUPTIBLE );
if ( condition )
schedule( );
finish_wait( &wq, &wait );
if ( signal_pending( current ) )
return -ERESTARTSYS;
'실습 > 리눅스 커널' 카테고리의 다른 글
커널 타이머, 태스크릿, 작업큐 (0) | 2021.02.08 |
---|---|
드라이버 코드의 실행 지연 (0) | 2021.02.08 |
커널에서 condition race 제거 (0) | 2021.02.08 |
Kernel Module 컴파일을 위한 Makefile 만들기 (0) | 2021.02.08 |
Kernel Module - template (0) | 2021.02.08 |