Chris Wilson <[email protected]> writes:

> The solution employed here is to undo the busy demotion after a period
> of idleness. Currently the idle boost is applied only once for a fresh
> client when it becomes selectable. The change is to apply that boost for
> all clients that remain ready for the entire duration of idle timeslice -
> eventually these old busy clients will be promoted sufficiently to
> be granted a ScheduleSlice.

I think your analysis is spot-on, but the fix doesn't seem to match. By
changing smart_check_tick only when it is older than 'idle', you're
effectively just bumping smart_priority every other pass through the
loop. Which explains why you get no starvation; all ready clients get priority
bumps every other pass through the loop. But that includes the clients
which are actually running, which definitely isn't what we want.

I think what we want to do is simply increase the priority of clients
which haven't run in a while, instead of clients which haven't been
ready for a while. That's easy to check; we know the last time a client
ran as that's stored in smart_start_tick.

Please give this patch a try and see if it has the same effect.

From a96c954443ab7cb907abda12c540d8b60e78e803 Mon Sep 17 00:00:00 2001
From: Keith Packard <[email protected]>
Date: Wed, 22 Jan 2014 11:01:59 -0800
Subject: [PATCH] dix: Praise clients which haven't run for a while, rather
 than idle clients

A client which is ready, but hasn't run for a while, should receive
the same benefit as one which has simply been idle for a while. Use
the smart_start_tick to see how long it has been since a client has
run instead of smart_check_tick, which got reset each time a client
was ready, even if it didn't get to run.

Signed-off-by: Keith Packard <[email protected]>
---
 dix/dispatch.c      | 6 ++----
 include/dixstruct.h | 1 -
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/dix/dispatch.c b/dix/dispatch.c
index e28270c..57f9fc0 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -260,12 +260,11 @@ SmartScheduleClient(int *clientReady, int nready)
     for (i = 0; i < nready; i++) {
         client = clientReady[i];
         pClient = clients[client];
-        /* Praise clients which are idle */
-        if ((now - pClient->smart_check_tick) >= idle) {
+        /* Praise clients which haven't run in a while */
+        if ((now - pClient->smart_start_tick) >= idle) {
             if (pClient->smart_priority < 0)
                 pClient->smart_priority++;
         }
-        pClient->smart_check_tick = now;
 
         /* check priority to select best client */
         robin =
@@ -3424,7 +3423,6 @@ InitClient(ClientPtr client, int i, void *ospriv)
     QueryMinMaxKeyCodes(&client->minKC, &client->maxKC);
     client->smart_start_tick = SmartScheduleTime;
     client->smart_stop_tick = SmartScheduleTime;
-    client->smart_check_tick = SmartScheduleTime;
     client->clientIds = NULL;
 }
 
diff --git a/include/dixstruct.h b/include/dixstruct.h
index a11729b..6c13895 100644
--- a/include/dixstruct.h
+++ b/include/dixstruct.h
@@ -106,7 +106,6 @@ typedef struct _Client {
 
     int smart_start_tick;
     int smart_stop_tick;
-    int smart_check_tick;
 
     DeviceIntPtr clientPtr;
     ClientIdPtr clientIds;
-- 
1.8.5.3

-- 
[email protected]

Attachment: pgpxmk_78nUDo.pgp
Description: PGP signature

_______________________________________________
[email protected]: X.Org development
Archives: http://lists.x.org/archives/xorg-devel
Info: http://lists.x.org/mailman/listinfo/xorg-devel

Reply via email to