mirror of
https://github.com/apache/nuttx.git
synced 2026-05-31 23:40:19 +08:00
sched/wqueue: Improve performance of the work_queue.
This commit improve the performance of the work_queue by reducing unnecessary wdog timer setting. Signed-off-by: ouyangxiangzhen <ouyangxiangzhen@xiaomi.com>
This commit is contained in:
@@ -90,16 +90,6 @@ static int work_qqueue(FAR struct usr_wqueue_s *wqueue,
|
|||||||
work->arg = arg; /* Callback argument */
|
work->arg = arg; /* Callback argument */
|
||||||
work->qtime = clock() + delay; /* Delay until work performed */
|
work->qtime = clock() + delay; /* Delay until work performed */
|
||||||
|
|
||||||
/* delay+1 is to prevent the insufficient sleep time if we are
|
|
||||||
* currently near the boundary to the next tick.
|
|
||||||
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
|
||||||
* | ^ Here we get the current tick
|
|
||||||
* In this case we delay 1 tick, timer will be triggered at
|
|
||||||
* current_tick + 1, which is not enough for at least 1 tick.
|
|
||||||
*/
|
|
||||||
|
|
||||||
work->qtime += 1;
|
|
||||||
|
|
||||||
/* Insert the work into the wait queue sorted by the expired time. */
|
/* Insert the work into the wait queue sorted by the expired time. */
|
||||||
|
|
||||||
head = list_first_entry(&wqueue->q, struct work_s, node);
|
head = list_first_entry(&wqueue->q, struct work_s, node);
|
||||||
|
|||||||
+20
-12
@@ -81,18 +81,13 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
|
|||||||
{
|
{
|
||||||
irqstate_t flags;
|
irqstate_t flags;
|
||||||
clock_t expected;
|
clock_t expected;
|
||||||
bool wake = false;
|
bool retimer;
|
||||||
int ret = OK;
|
|
||||||
|
|
||||||
if (wqueue == NULL || work == NULL || worker == NULL)
|
if (wqueue == NULL || work == NULL || worker == NULL)
|
||||||
{
|
{
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure the work has been canceled. */
|
|
||||||
|
|
||||||
work_cancel_wq(wqueue, work);
|
|
||||||
|
|
||||||
/* delay+1 is to prevent the insufficient sleep time if we are
|
/* delay+1 is to prevent the insufficient sleep time if we are
|
||||||
* currently near the boundary to the next tick.
|
* currently near the boundary to the next tick.
|
||||||
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
* | current_tick | current_tick + 1 | current_tick + 2 | .... |
|
||||||
@@ -109,6 +104,10 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
|
|||||||
|
|
||||||
flags = spin_lock_irqsave(&wqueue->lock);
|
flags = spin_lock_irqsave(&wqueue->lock);
|
||||||
|
|
||||||
|
/* Ensure the work has been removed. */
|
||||||
|
|
||||||
|
retimer = work_available(work) ? false : work_remove(wqueue, work);
|
||||||
|
|
||||||
/* Initialize the work structure. */
|
/* Initialize the work structure. */
|
||||||
|
|
||||||
work->worker = worker; /* Work callback. non-NULL means queued */
|
work->worker = worker; /* Work callback. non-NULL means queued */
|
||||||
@@ -116,32 +115,41 @@ int work_queue_period_wq(FAR struct kwork_wqueue_s *wqueue,
|
|||||||
work->qtime = expected; /* Expected time */
|
work->qtime = expected; /* Expected time */
|
||||||
work->period = period; /* Periodical delay */
|
work->period = period; /* Periodical delay */
|
||||||
|
|
||||||
/* Insert to the pending list of the wqueue. */
|
|
||||||
|
|
||||||
if (delay)
|
if (delay)
|
||||||
{
|
{
|
||||||
|
/* Insert to the pending list of the wqueue. */
|
||||||
|
|
||||||
if (work_insert_pending(wqueue, work))
|
if (work_insert_pending(wqueue, work))
|
||||||
{
|
{
|
||||||
/* Start the timer if the work is the earliest expired work. */
|
/* Start the timer if the work is the earliest expired work. */
|
||||||
|
|
||||||
ret = wd_start_abstick(&wqueue->timer, work->qtime,
|
retimer = false;
|
||||||
|
wd_start_abstick(&wqueue->timer, work->qtime,
|
||||||
work_timer_expired, (wdparm_t)wqueue);
|
work_timer_expired, (wdparm_t)wqueue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* Insert to the expired list of the wqueue. */
|
||||||
|
|
||||||
list_add_tail(&wqueue->expired, &work->node);
|
list_add_tail(&wqueue->expired, &work->node);
|
||||||
wake = true;
|
}
|
||||||
|
|
||||||
|
if (retimer)
|
||||||
|
{
|
||||||
|
work_timer_reset(wqueue);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock_irqrestore(&wqueue->lock, flags);
|
spin_unlock_irqrestore(&wqueue->lock, flags);
|
||||||
|
|
||||||
if (wake)
|
if (!delay)
|
||||||
{
|
{
|
||||||
|
/* Immediately wake up the worker thread. */
|
||||||
|
|
||||||
nxsem_post(&wqueue->sem);
|
nxsem_post(&wqueue->sem);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int work_queue_period(int qid, FAR struct work_s *work, worker_t worker,
|
int work_queue_period(int qid, FAR struct work_s *work, worker_t worker,
|
||||||
|
|||||||
Reference in New Issue
Block a user