# RT scheduler: 우선순위별 대기열에서 다음 대상을 고르기

v6.18.37 / kernel/sched/rt.c

RT 스케줄러는 우선순위마다 대기열을 두고, 비어 있지 않은 우선순위를 비트맵으로 빠르게 찾습니다. 같은 우선순위 안에서는 큐의 순서가 중요합니다. 여기서는 pick_next_rt_entity 전체를 읽되 entity가 task 자체와 항상 같은 것은 아니라는 점도 함께 봅니다.

## pick_next_rt_entity

```c

static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)
{
	struct rt_prio_array *array = &rt_rq->active;
	struct sched_rt_entity *next = NULL;
	struct list_head *queue;
	int idx;

	idx = sched_find_first_bit(array->bitmap);
	BUG_ON(idx >= MAX_RT_PRIO);

	queue = array->queue + idx;
	if (WARN_ON_ONCE(list_empty(queue)))
		return NULL;
	next = list_entry(queue->next, struct sched_rt_entity, run_list);

	return next;
}

```

### 1665행

```c

static struct sched_rt_entity *pick_next_rt_entity(struct rt_rq *rt_rq)

```

RT 실행 큐에서 다음 scheduling entity를 고릅니다. 반환형은 task_struct가 아니라 sched_rt_entity 포인터입니다.

### 1667행

```c

	struct rt_prio_array *array = &rt_rq->active;

```

현재 활성 우선순위 배열을 가리킵니다. 비트맵과 우선순위별 연결 리스트가 여기에 있습니다.

### 1668행

```c

	struct sched_rt_entity *next = NULL;

```

선택 결과를 담을 포인터를 NULL로 초기화합니다.

### 1669행

```c

	struct list_head *queue;

```

선택한 우선순위의 리스트 머리를 담을 변수를 준비합니다.

### 1670행

```c

	int idx;

```

비트맵에서 찾은 내부 우선순위 인덱스를 저장합니다.

### 1672행

```c

	idx = sched_find_first_bit(array->bitmap);

```

비어 있지 않은 우선순위 중 첫 비트를 찾습니다. 내부 번호가 작은 후보를 먼저 고릅니다.

### 1673행

```c

	BUG_ON(idx >= MAX_RT_PRIO);

```

유효 RT 우선순위를 찾았다는 전제가 깨지면 커널 버그로 처리합니다. 정상 경로의 일상적인 빈 큐 처리가 아닙니다.

### 1675행

```c

	queue = array->queue + idx;

```

찾은 우선순위에 해당하는 리스트 머리 주소를 계산합니다.

### 1676행

```c

	if (WARN_ON_ONCE(list_empty(queue)))

```

비트맵이 알려 준 큐가 실제로 비어 있으면 한 번 경고합니다. 요약 정보와 실제 목록의 일관성을 확인합니다.

### 1677행

```c

		return NULL;

```

불일치 상태에서 잘못된 entity를 따라가지 않고 NULL을 반환합니다.

### 1678행

```c

	next = list_entry(queue->next, struct sched_rt_entity, run_list);

```

첫 리스트 노드의 주소에서 run_list를 포함한 sched_rt_entity 주소를 구합니다. 매크로는 멤버 위치 차이를 이용합니다.

### 1680행

```c

	return next;

```

선택한 entity를 상위 선택 경로에 넘깁니다. 그룹 계층이나 최종 task 판단은 호출자가 이어서 합니다.

