在項目中,有一個時間關鍵的操作,而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 上時間關鍵性應用的性能。