]> git.itanic.dy.fi Git - rrdd/commitdiff
worker_thread: Drop process priority when executing low priority work
authorTimo Kokkonen <timo.t.kokkonen@iki.fi>
Sat, 14 Jan 2017 15:32:40 +0000 (17:32 +0200)
committerTimo Kokkonen <timo.t.kokkonen@iki.fi>
Sat, 14 Jan 2017 15:32:40 +0000 (17:32 +0200)
When executing low priority work, it is a good idea to nice() the
process priority as well so that the executing of the work is truly
run as a low priority work. This decreases the interference the work
might have on the rest of the system.

To achieve this, the work executing loop is rewritten. Instead of
having a loop that always tries to execute the highest priority work,
separate the low priority and high priority handling in separate
loops. This simplifies the logic quite a bit. Furthermore, there is
really no need to convert a low priority worker back to executing high
priority work. When queuing work, a new worker thread is always
spawned whenever a high priority work is queued. Thus, there is no
really any chance a low priority worker could pick up any high
priority work once it has finished low priority work.

Now we no longer can do that as it is not possible to rise a thread
priority back up once it lowered its priority.

The executing logic of the worker thread is thus much simpler now.

Signed-off-by: Timo Kokkonen <timo.t.kokkonen@iki.fi>
process.c

index 98033f0a5f4bc5a0650c4f7e94cc54a9fa2ef310..13fe7e58fbd5a0f6e828e72d0bbff0e0df11575b 100644 (file)
--- a/process.c
+++ b/process.c
@@ -83,8 +83,7 @@ static int run_work_on_queue(struct work_queue *queue)
 
 static void *worker_thread(void *arg)
 {
-       int stop_working = 0;
-       int work_done = 0;
+       int ret;
        char name[16];
 
        mutex_lock(&work_stats_mutex);
@@ -97,38 +96,46 @@ static void *worker_thread(void *arg)
 
        pr_info("Worker started\n");
 
-       while (!stop_working) {
-               while (1) {
-                       int prio;
-
-                       /*
-                        * Execute as much work from the high priority
-                        * queue as possible. Once there are no more
-                        * high prio work left, break out the loop and
-                        * see if we still need this many workers.
-                        */
-                       for (prio = 0; prio < WORK_PRIORITIES_NUM; prio++) {
-                               work_done =
-                                       run_work_on_queue(&work_queues[prio]);
-                               if (work_done)
-                                       break;
-                       }
+       /* Execute all high priority work from the queue */
+       while (run_work_on_queue(&work_queues[WORK_PRIORITY_HIGH]))
+               ;
+       /*
+        * All high priority work is now done, see if we have enough
+        * workers executing low priority worl. Continue from there if
+        * needed.
+        */
+       mutex_lock(&work_stats_mutex);
+       if (workers_active > max_jobs)
+               goto out_unlock;
 
-                       if (!work_done || prio != WORK_PRIORITY_HIGH)
-                               break;
-               }
+       mutex_unlock(&work_stats_mutex);
 
-               mutex_lock(&work_stats_mutex);
-               if (workers_active > max_jobs || !work_done) {
-                       workers_active--;
-                       pr_info("Worker exiting, %d left active\n",
-                               workers_active);
-                       if (!workers_active)
-                               worker_count = 0;
-                       stop_working = 1;
-               }
-               mutex_unlock(&work_stats_mutex);
-       }
+       /*
+        * Start executing the low priority work. Drop the nice value
+        * as this really is low priority stuff
+        */
+       ret = nice(19);
+       pr_info("Worker priority dropped to %d\n", ret);
+
+       while (run_work_on_queue(&work_queues[WORK_PRIORITY_LOW]))
+               ;
+
+       /* All done, exit */
+       mutex_lock(&work_stats_mutex);
+out_unlock:
+       workers_active--;
+       pr_info("Worker exiting, %d left active\n",
+               workers_active);
+
+       /*
+        * Last exiting worker zeroes the worker_count. This
+        * ensures next time we start spawning worker threads
+        * the first thread will have number zero on its name.
+        */
+       if (!workers_active)
+               worker_count = 0;
+
+       mutex_unlock(&work_stats_mutex);
 
        return NULL;
 }