Я скоро начнет стучать головой о стену:Измерение времени задача проводит между 2 точками в Linux (задача профилирования)
Это очень просто на самом деле, я хочу, чтобы измерить время задача затрачиваемое между 2 точками (в Linux - 1 ядро - 1 процессор). За это время задача должна иметь полный контроль над ЦП и НЕ прерываться любой другой задачей или прерываниями HW.
Для этого I'v создал модуль ядра, чтобы убедиться, что вышеуказанные критерии выполнены. В этом модуле ядра я пытался:
Во-первых, отключить IRQs:
- Я использовал spin_lock_irqsave()/spin_lock_irqrestore() - Какой я полагаю, это правильный путь, чтобы быть уверенным, что все локальные прерывания отключены, и моя задача имеет процессор для него в критической области.
Затем
- Используется preempt_disable() -> С текущей = моя задача, то логически ядро должно продолжать выполнение своей задачи, пока не включите упреждение -> Не работает (my_task-> nvcsw и my_task-> nivcsw показывают, что ЖКС произошло -> моя задача-получил вытеснен)
Я попытался увеличить приоритет моей задачи путем изменения my_task-> ПРИО и my_task-> static_prio 1 -> самый высокий приоритет в реальном времени (my_task-> policy = SCHED_FIFO) ...
Не работает (my_task-> nvcsw и my_task-> nivcsw показывают, что произошел csw -> my-task получил preempted), а my_task-> prio получил новый prio (120) планировщиком, который я предполагаю. ..
Есть ли какой-либо способ детерминировать гарантию того, что задача не будет прервана/вызвана в Linux? Есть ли способ заставить планировщика выполнить задачу (на короткое время 50-500us), пока она не будет выполнена?
Вот мой код, чтобы включить/отключить компоненты ОС (задача в вопросе посылает включить/отключить команды до и после критической области, используя Procfs и обработаны этим переключателем):
// Handle request
switch(enable){
// Disable OS
case COS_OS_DISABLE:
// Disable preemption
preempt_disable()
// Save policy
last_policy = pTask->policy;
// Save task priorities
last_prio = pTask->prio;
last_static_prio = pTask->static_prio;
last_normal_prio = pTask->normal_prio;
last_rt_priority = pTask->rt_priority;
// Set priorities to highest real time prio
pTask->prio = 1;
pTask->static_prio = 1;
pTask->normal_prio = 1;
pTask->rt_priority = 1;
// Set scheduler policy to FIFO
pTask->policy = SCHED_FIFO;
// Lock kernel: It will disable interrupts _locally_, but the spinlock itself will guarantee the global lock, so it will guarantee that there is only one thread-of-control within the region(s) protected by that lock.
spin_lock_irqsave(&mr_lock , flags);
break;
// Default: Enable OS always
case COS_OS_ENABLE:
default:
// Reset task priorities
pTask->prio = last_prio;
pTask->static_prio = last_static_prio;
pTask->normal_prio = last_normal_prio;
pTask->rt_priority = last_rt_priority;
// Reset scheduler policy
pTask->policy = last_policy;
// Unlock kernel
spin_unlock_irqrestore(&mr_lock , flags);
// Enable preemption
preempt_enable();
break;
}
Итак, «задача» означает «задача для пользователя»? –
Да, задача пользовательского пространства. Он коммутирует с ядром через procfs. Он отправляет команды включения/выключения OS (обработанные кодом выше). Задача пользовательского пространства также измеряет время между этими двумя командами (что странно, так как все прерывания должны быть отключены) ... но все же я мог бы измерять время между ними (может быть поведение без явного ядра) – user3297145