Multithreading 在linux中测量任务在两个点之间花费的时间(任务评测)

Multithreading 在linux中测量任务在两个点之间花费的时间(任务评测),multithreading,linux-kernel,scheduler,thread-priority,preemption,Multithreading,Linux Kernel,Scheduler,Thread Priority,Preemption,我很快就会开始把头撞到墙上: 这真的很简单,我想测量一个任务在2点之间花费的时间(在Linux-1 core-1 CPU中)。 在此期间,任务必须完全控制CPU,并且不会被任何其他任务或硬件中断中断 为了实现这一点,我创建了一个内核模块,以确保满足上述标准。 在这个内核模块中,我尝试: 首先,禁用IRQ: 我已经使用了spin\u lock\u irqsave()/spin\u lock\u irqrestore()-我认为这是确保所有本地中断都被禁用的正确方法,并且我的任务在关键区域有自己的

我很快就会开始把头撞到墙上:

这真的很简单,我想测量一个任务在2点之间花费的时间(在Linux-1 core-1 CPU中)。 在此期间,任务必须完全控制CPU,并且不会被任何其他任务或硬件中断中断

为了实现这一点,我创建了一个内核模块,以确保满足上述标准。 在这个内核模块中,我尝试:

首先,禁用IRQ:

  • 我已经使用了spin\u lock\u irqsave()/spin\u lock\u irqrestore()-我认为这是确保所有本地中断都被禁用的正确方法,并且我的任务在关键区域有自己的cpu
那么

  • 使用了preempt_disable()->因为current=my task,那么从逻辑上讲内核应该继续运行我的任务,直到我重新启用preemption->不起作用(my_task->nvcsw和my_task->nivcsw显示csw已经发生->我的任务被抢占)
我试图通过将我的任务->优先级和我的任务->静态优先级更改为1->最高实时优先级(我的任务->策略=调度FIFO)来提高任务的优先级

也不工作(我的任务->nvcsw和我的任务->nivcsw显示csw已发生->我的任务被抢占),我的任务->优先级由调度程序获得新的优先级(120)

有没有办法确定地保证在Linux中任务不会被中断/抢占?有没有办法强迫调度程序运行一个任务(短时间50-500秒),直到它完成

下面是我的代码,用于启用/禁用部分操作系统(所讨论的任务使用procfs在关键区域前后发送启用/禁用命令,并由此开关处理):


禁用中断只允许用于内核代码,并且只允许在短时间内禁用。 对于股票内核,不可能让用户空间任务完全控制CPU


如果只想测量用户空间任务使用的时间,可以正常运行任务并使用忽略中断;但是,这不会阻止中断处理程序的任何缓存效果。

所以说“任务”是指“用户空间任务”?是的,是指用户空间任务。它通过procfs与内核通信。它发送一个enable/disable操作系统命令(由上面的代码处理)。用户空间任务还测量这两个命令之间的时间(这很奇怪,因为所有中断都应该被禁用)。。。但我仍然可以测量两个时间(无滴答的内核行为可能是)之间的时间,以获得您的答案。这也是我所怀疑的(用户空间任务永远无法完全控制CPU)。。。真倒霉我无法使用perf,因为我需要分析用户空间程序的一小部分(而不是整个程序)。。。有没有办法在内核空间中执行应用程序?
// 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;
}