[PATCH] EXA: Defragment offscreen memory.
Michel Dänzer
michel at daenzer.net
Sat Feb 21 04:03:51 PST 2009
On Tue, 2009-02-17 at 15:26 -0500, Adam Jackson wrote:
>
> Probably better to run the periodic defragger from a real timer, and arm
> it for 1s in the future from BlockHandler. If the timer ever expires,
> you know you've been idle for a full second, so you can go ahead and do
> some idle work.
How about the below relative diff? It arms a 100ms timer from the
BlockHandler and cancels it from the WakeupHandler if Select() didn't
time out.
100ms is a trade-off between having a chance of expiring on almost but
not quite idle systems and not waking up too often on completely idle
systems. I'm open for suggestions for a better trade-off.
> Technically this has a minor failing when a single request takes more
> than a second but if that ever happens you're not a happy camper
> anyway.
I think that shouldn't be an issue with this: Our WakeupHandler should
cancel the timer if the server has something else to do.
Note though that it's only compile tested so far.
diff --git a/exa/exa.c b/exa/exa.c
index c86de3d..b0c96fb 100644
--- a/exa/exa.c
+++ b/exa/exa.c
@@ -882,6 +882,17 @@ exaCreateScreenResources(ScreenPtr pScreen)
return TRUE;
}
+static CARD32 ExaDefragTimerCallback(OsTimerPtr pTimer, CARD32 time,
+ pointer arg)
+{
+ /* Try and keep the offscreen memory area tidy every now and then when the
+ * server has been idle for at least 100ms.
+ */
+ ExaOffscreenDefragment(arg);
+
+ return 0;
+}
+
static void
ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
pointer pReadmask)
@@ -889,14 +900,29 @@ ExaBlockHandler(int screenNum, pointer blockData, pointer pTimeout,
ScreenPtr pScreen = screenInfo.screens[screenNum];
ExaScreenPriv(pScreen);
- /* Try and keep the offscreen memory area tidy every now and then when we're
- * going idle anyway.
- */
- ExaOffscreenDefragment(pScreen);
-
unwrap(pExaScr, pScreen, BlockHandler);
(*pScreen->BlockHandler) (screenNum, blockData, pTimeout, pReadmask);
wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
+
+ pExaScr->defragTimer = TimerSet(pExaScr->defragTimer, 0, 100,
+ ExaDefragTimerCallback, pScreen);
+}
+
+static void
+ExaWakeupHandler(int screenNum, pointer wakeupData, unsigned long result,
+ pointer pReadmask)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ ExaScreenPriv(pScreen);
+
+ /* Prevent the timer callback from being called if Select() didn't time out.
+ */
+ if (result != 0)
+ TimerCancel(pExaScr->defragTimer);
+
+ unwrap(pExaScr, pScreen, WakeupHandler);
+ (*pScreen->WakeupHandler) (screenNum, wakeupData, result, pReadmask);
+ wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
}
/**
@@ -914,8 +940,13 @@ exaCloseScreen(int i, ScreenPtr pScreen)
if (ps->Glyphs == exaGlyphs)
exaGlyphsFini(pScreen);
+ if (pExaScr->defragTimer)
+ TimerFree(pExaScr->defragTimer);
+
if (pScreen->BlockHandler == ExaBlockHandler)
unwrap(pExaScr, pScreen, BlockHandler);
+ if (pScreen->WakeupHandler == ExaWakeupHandler)
+ unwrap(pExaScr, pScreen, WakeupHandler);
unwrap(pExaScr, pScreen, CreateGC);
unwrap(pExaScr, pScreen, CloseScreen);
unwrap(pExaScr, pScreen, GetImage);
@@ -1076,8 +1107,10 @@ exaDriverInit (ScreenPtr pScreen,
* Replace various fb screen functions
*/
if ((pExaScr->info->flags & EXA_OFFSCREEN_PIXMAPS) &&
- !pExaScr->info->CreatePixmap)
+ !pExaScr->info->CreatePixmap) {
wrap(pExaScr, pScreen, BlockHandler, ExaBlockHandler);
+ wrap(pExaScr, pScreen, WakeupHandler, ExaWakeupHandler);
+ }
wrap(pExaScr, pScreen, CreateGC, exaCreateGC);
wrap(pExaScr, pScreen, CloseScreen, exaCloseScreen);
wrap(pExaScr, pScreen, GetImage, exaGetImage);
diff --git a/exa/exa_priv.h b/exa/exa_priv.h
index f787361..39e1c3d 100644
--- a/exa/exa_priv.h
+++ b/exa/exa_priv.h
@@ -134,6 +134,7 @@ typedef void (*EnableDisableFBAccessProcPtr)(int, Bool);
typedef struct {
ExaDriverPtr info;
ScreenBlockHandlerProcPtr SavedBlockHandler;
+ ScreenWakeupHandlerProcPtr SavedWakeupHandler;
CreateGCProcPtr SavedCreateGC;
CloseScreenProcPtr SavedCloseScreen;
GetImageProcPtr SavedGetImage;
@@ -160,6 +161,7 @@ typedef struct {
Bool optimize_migration;
unsigned offScreenCounter;
CARD32 lastDefragment;
+ OsTimerPtr defragTimer;
/* Holds information on fallbacks that cannot be relayed otherwise. */
unsigned int fallback_flags;
--
Earthling Michel Dänzer | http://www.vmware.com
Libre software enthusiast | Debian, X and DRI developer
More information about the xorg-devel
mailing list