	TASK_USER {| TASK_PRIVILEGED}
	TASK_KERNEL

	TASK_STATIC
	TASK_CLONED

	TASK_HANDLER - call by handler
	TASK_SYSCALL - call by user, actually it is called by handler since it
		       has already entered in handler mode by syscall. but the
		       context that we are interested in is the user's. it is
		       set only when fork() called at the moment

	STACK_SHARED

	use TF_* when masking or use TASK_* when requsting

# Task Management

~~관련 리소스가 아직 정리되지 않은 좀비 태스크는 init 태스크에서 마무리
처리된다. 즉, 적절한 시점에 init 태스크가 활성화되어야만 보다 많은 가용
메모리를 확보할 수 있다. 가령, 수많은 스레드가 반복 생성될 때 연산을 마무리한
스레드를 제때에 정리해주지 않으면 곧 가용 메모리 공간을 모두 소진하게 된다.
이를 방지하기 위해 해당 업무를 처리하는 init 태스크의 우선순위는 런타임에
동적으로 변한다. 일례로 init 태스크의 기본 우선순위는 `LEAST_PRIORIITY` 이지만,
리얼타임 태스크가 스래드를 생성/삭제한다면 init 태스크의 우선순위는 순간적으로
해당 리얼타임 태스크의 우선순위로 도약한다. 이는 init 태스크의 실행 기회를
확보하여 해당 업무를 처리하기 위함이다.~~

리얼타임 태스크 수행중에 init 태스크의 우선순위를 상향조정하면 리얼타임
태스크의 cpu 점유시간이 그만큼 줄어든다. 메모리 사용은 사용자에게 맡기고 init
태스크의 우선순위는 최하위 순위를 유지하는 것이 리얼타임 특성을 유지하는
방법이겠다.

## Run-time Statistics

각 태스크별로 실행시간을 측정할 수 있다. 측정단위는 tick으로 1 tick보다 작은
시간은 측정할 수 없다. 즉, 실행시간이 1 tick(20ms at 50Hz) 미만인 태스크의
실행시간은 측정되지 않고 0으로 기록된다.

## 태스크 자료구조 동기화

상태와 같은 태스크 자료구조는 매우 빈번하게 변경되기 때문에 이를 lock으로 매번
동기화하기에는 오버헤드가 너무 크다. 그러므로 태스크 자료구조를 변경하는 지점을
제한해야 한다.

1. 스케쥴러에서 문맥전환시에 _오직_ 런큐 list만 변경
  - 즉, 런큐 삽입/삭제 동작은 반드시 인터럽트 금지 상태에서 이루어져야 한다
2. 또는 자기자신만을 변경

현재 `set_task_*` 사용 전에는 스핀락을 사용하고 있지만 `set_tast_*`와
`get_task_*` 류의 매크로는 모두 atomic 연산으로 이루어진다.
