현재 스레드 외부에다 작업을 시작하도록 지시하고 끝나기를 기다릴 때 사용. 세마포어를 LOCKED 상태로 하여 사용할 수도 있지만, 세마포어는 거의 항상 세마포어를 획득할 수 있을 때에 치중하여 최적화되어 왔다. 따라서 이럴 때는 completion 을 사용하는 것이 좋다. 구현은 kernel/sched.c 를 참조.
1. completion 초기화
<linux/completion.h>를 포함하여야 한다. 자료 타입은 struct completion.
1.1. Compile time 초기화
DECLARE_COMPLETION(my_completion);
1.2. Runtime 초기화
struct completion my_completion;
/* … */
init_completion(&my completion);
/* … */
init_completion(&my completion);
2. 완료 기다리기
인터럽트가 불가능한 대기(죽일 수 없는 프로세스를 만들 수도 있다)를 수행한다. LONG_MAX 만큼 대기.
void wait_for_completion(struct completion *c);
timeout 이 있는 인터럽트가 불가능한 대기. timeout 값을 리턴한다. 따라서 expire 되면 0을, 완료되면 남은 timeout 값(jiffies 값)을 리턴한다.
unsigned long wait_for_completion_timeout(struct completion *x, unsigned long timeout);
인터럽트가 가능한 대기를 수행한다.(추가필요:인터럽트 받으면 바로 리턴?)
int wait_for_completion_interruptible(struct completion *x);
인터럽트가 가능한 대기의 timeout 버전
unsigned long wait_for_completion_interruptible_timeout(struct completion *x, unsigned long timeout);
죽일 수 있는 대기(TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)를 수행한다.(추가 필요:kill받으면 바로 리턴?)
int wait_for_completion_killable(struct completion *x);
Blocking 없는 wait_for_completion. complete 되지 않았으면 바로 0을 리턴한다.
bool try_wait_for_completion(struct completion *x);
3. 완료 이벤트 알리기
completion을 기다리는 스레드(waiter)가 있는지 확인한다. waiter가 있으면(wait_for_completion()이 진행 중이면) 0을, 없으면 1을 리턴한다.
bool completion_done(completion *x);
대기 중인 스레드 하나만 깨우기void complete(struct completion *c);
모든 스레드 깨우기
void complete_all(struct completion *c);
4. 재사용을 위해 다시 초기화하기
INIT_COMPLETION(struct completion c);
5. 모듈 종료 함수에서 종료 후 완료를 기다리리고 알릴 때(나중에 추가하기:이 함수 없어졌나?)
void complete_and_exit(struct completion *c, long retval);