#c #linux-kernel #scheduled-tasks #scheduler
#c #linux-ядро #запланированные задачи #планировщик
Вопрос:
Из исходного кода ядра:
static void __sched notrace __schedule(bool preempt)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct rq_flags rf;
struct rq *rq;
int cpu;
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr; // <=================(1)
.....
В чем разница между current
и prev
в строке (1) выше?
Добавление a printk()
после этой строки:
static void __sched notrace __schedule(bool preempt)
{
struct task_struct *prev, *next;
unsigned long *switch_count;
struct rq_flags rf;
struct rq *rq;
int cpu;
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;
//if(prev->pid != current->pid)
printk("the prev->pid =%d, The current = %d n", prev->pid, current->pid); // <===========(2)
schedule_debug(prev);
if (sched_feat(HRTICK))
hrtick_clear(rq);
Результирующие журналы из (2):
[ 4184.164038] the prev->pid =0, The current = 0
[ 4184.165365] the prev->pid =12, The current = 12
[ 4186.008068] the prev->pid =0, The current = 0
[ 4186.009396] the prev->pid =30, The current = 30
[ 4188.008046] the prev->pid =0, The current = 0
[ 4188.009334] the prev->pid =30, The current = 30
[ 4188.164041] the prev->pid =0, The current = 0
[ 4188.165315] the prev->pid =12, The current = 12
[ 4190.008047] the prev->pid =0, The current = 0
[ 4190.009431] the prev->pid =30, The current = 30
На дисплеях показано, что результат тот же.
- почему бы не использовать
current
вместо
cpu = smp_processor_id();
rq = cpu_rq(cpu);
prev = rq->curr;
Комментарии:
1. Способ его выполнения отключает упреждение. Использование
current
может иметь условия гонки.
Ответ №1:
prev
это переменная, используемая для временного запоминания текущей задачи при замене ее новой в очереди выполнения. Конечно, если вы посмотрите на prev
это точно сразу после того, как сделаете prev = rq->curr
, у вас будет prev == rq->curr == current
, так как это было только что назначено.
Если вы хотите проверить, какая задача выбирается для следующего запуска, вам придется позаботиться об этом, когда __schedule()
это произойдет:
next = pick_next_task(rq, prev, amp;rf);
Теперь next
будет отличаться от prev
.
Комментарии:
1. Член структуры
curr
, а неcurrent
2. @MarcoBonelli Спасибо за ваш ответ, мне интересно, почему бы не использовать
current
вместо « cpu = smp_processor_id(); rq = cpu_rq (cpu); prev = rq-> curr; «3. @Joeys посмотрите на это так: алгоритм планировщика имеет дело с очередями выполнения, и он должен работать независимо от того, существует глобальная
current
переменная или нет. Таким образом, структуры и код, реализующий алгоритм, не зависят от внешних факторов. Планировщику все равно, чтоcurrent
существует, это просто глобальная переменная (фактически макрос), которая существует для удобства, когда в ней нуждаются другие части кода ядра.