在项目中,有一个时间关键的操作,而Linux本身是分时型操作系统,虽然绝大部分情况可以满足时间上的要求,但是,时间分布的离散性还是有点大。考虑引入Linux Real Time 补丁,研究发现,即使引入这个补丁,依然无法到达RTOS的水平,而且使用起来还比较复杂。后来阅读workqueue代码发现,项目使用的Linux 3.18存在一个highpri workqueue,决定试验它的行为是否如它的名字所描述的那样。
试验代码如下:
#define HIGHPRI_SCHED_WORK(w) queue_work_on(WORK_CPU_UNBOUND, system_highpri_wq, w)
struct work_struct work_n1, work_n2, work_h;
static void work_normal_1(struct work_struct *work)
{
struct timeval t;
u64 usec = 0;
static int cnt1 = 0;
printk("%s enter", __FUNCTION__);
do_gettimeofday(&t);
usec = t.tv_sec*1000000+t.tv_usec;
for (;;)
{
do_gettimeofday(&t);
if (t.tv_sec*1000000+t.tv_usec > usec + 3000)
{
cnt1++;
printk("wn1 = %d\n", cnt1);
if (cnt1 >= 3)
break;
usec = t.tv_sec*1000000+t.tv_usec;
}
}
printk("%s exit", __FUNCTION__);
}
static void work_normal_2(struct work_struct *work)
{
struct timeval t;
u64 usec = 0;
static int cnt2 = 0;
printk("%s enter\n", __FUNCTION__);
do_gettimeofday(&t);
usec = t.tv_sec*1000000+t.tv_usec;
for (;;)
{
do_gettimeofday(&t);
if (t.tv_sec*1000000+t.tv_usec > usec + 3000)
{
cnt2++;
printk("wn2 = %d\n", cnt2);
if (cnt2 >= 3)
break;
usec = t.tv_sec*1000000+t.tv_usec;
}
}
printk("%s exit\n", __FUNCTION__);
}
static void work_high(struct work_struct *work)
{
struct timeval t;
u64 usec = 0;
static int cnth = 0;
printk("%s enter\n", __FUNCTION__);
do_gettimeofday(&t);
usec = t.tv_sec*1000000+t.tv_usec;
for (;;)
{
do_gettimeofday(&t);
if (t.tv_sec*1000000+t.tv_usec > usec + 3000)
{
cnth++;
printk("wnh = %d\n", cnth);
if (cnth >= 3)
break;
usec = t.tv_sec*1000000+t.tv_usec;
}
}
printk("%s exit\n", __FUNCTION__);
}
struct hrtimer test_timer;
static enum hrtimer_restart test_timer_isr(struct hrtimer *timer)
{
schedule_work(&work_n1);
schedule_work(&work_n2);
HIGHPRI_SCHED_WORK(&work_h);
return HRTIMER_NORESTART;
}
测试代码运行结果如下:
从这个log来看,highpri workqueue具有优先被执行的功能,可以进一步优化 Linux 上时间关键性应用的性能。