[PATCH 01/11] dix: Refactor block and wakup handlers

Pauli ext-pauli.nieminen at nokia.com
Fri Dec 31 09:30:59 PST 2010


From: Pauli Nieminen <ext-pauli.nieminen at nokia.com>

It is common use case in server that only block or wakeup handler is
used. To provide API for that case block handlers have to be split to
separate structures.

Moving deleted to separate structure improves memory use and cache
locality for common case when handlers are not deleted.

Signed-off-by: Pauli Nieminen <ext-pauli.nieminen at nokia.com>
---
 dix/dixutils.c |  224 +++++++++++++++++++++++++++++++++++++------------------
 include/dix.h  |   16 ++++
 2 files changed, 167 insertions(+), 73 deletions(-)

diff --git a/dix/dixutils.c b/dix/dixutils.c
index 104363b..05eb5ef 100644
--- a/dix/dixutils.c
+++ b/dix/dixutils.c
@@ -359,16 +359,29 @@ NoopDDA(void)
 
 typedef struct _BlockHandler {
     BlockHandlerProcPtr BlockHandler;
-    WakeupHandlerProcPtr WakeupHandler;
     pointer blockData;
-    Bool    deleted;
 } BlockHandlerRec, *BlockHandlerPtr;
 
-static BlockHandlerPtr	handlers;
-static int		numHandlers;
-static int		sizeHandlers;
-static Bool		inHandler;
-static Bool		handlerDeleted;
+typedef struct _WakeupHandler {
+    WakeupHandlerProcPtr WakeupHandler;
+    pointer blockData;
+} WakeupHandlerRec, *WakeupHandlerPtr;
+
+struct {
+    BlockHandlerPtr handlers;
+    int num;
+    int size;
+    int inHandler;
+    Bool *deleted;
+} block;
+
+struct {
+    WakeupHandlerPtr handlers;
+    int num;
+    int size;
+    int inHandler;
+    Bool *deleted;
+} wakeup;
 
 /**
  * 
@@ -380,28 +393,30 @@ BlockHandler(pointer pTimeout, pointer pReadmask)
 {
     int i, j;
     
-    ++inHandler;
+    ++block.inHandler;
     for (i = 0; i < screenInfo.numScreens; i++)
 	(* screenInfo.screens[i]->BlockHandler)(i, 
 				screenInfo.screens[i]->blockData,
 				pTimeout, pReadmask);
-    for (i = 0; i < numHandlers; i++)
-	(*handlers[i].BlockHandler) (handlers[i].blockData,
+    for (i = 0; i < block.num; i++)
+	(*block.handlers[i].BlockHandler) (block.handlers[i].blockData,
 				     pTimeout, pReadmask);
-    if (handlerDeleted)
+    if (block.deleted)
     {
-	for (i = 0; i < numHandlers;)
-	    if (handlers[i].deleted)
-	    {
-	    	for (j = i; j < numHandlers - 1; j++)
-		    handlers[j] = handlers[j+1];
-	    	numHandlers--;
-	    }
-	    else
-		i++;
-	handlerDeleted = FALSE;
+	for (i = 0; !block.deleted[i]; i++) {
+	}
+
+	for (j = i + 1; j < block.num; j++) {
+	    if (block.deleted[j])
+		continue;
+	    block.handlers[i] = block.handlers[j];
+	    i++;
+	}
+	block.num -= j - i;
+	free(block.deleted);
+	block.deleted = NULL;
     }
-    --inHandler;
+    --block.inHandler;
 }
 
 /**
@@ -414,92 +429,155 @@ WakeupHandler(int result, pointer pReadmask)
 {
     int i, j;
 
-    ++inHandler;
-    for (i = numHandlers - 1; i >= 0; i--)
-	(*handlers[i].WakeupHandler) (handlers[i].blockData,
+    ++wakeup.inHandler;
+    for (i = wakeup.num - 1; i >= 0; i--)
+	(*wakeup.handlers[i].WakeupHandler) (wakeup.handlers[i].blockData,
 				      result, pReadmask);
     for (i = 0; i < screenInfo.numScreens; i++)
 	(* screenInfo.screens[i]->WakeupHandler)(i, 
 				screenInfo.screens[i]->wakeupData,
 				result, pReadmask);
-    if (handlerDeleted)
+    if (wakeup.deleted)
     {
-	for (i = 0; i < numHandlers;)
-	    if (handlers[i].deleted)
-	    {
-	    	for (j = i; j < numHandlers - 1; j++)
-		    handlers[j] = handlers[j+1];
-	    	numHandlers--;
-	    }
-	    else
-		i++;
-	handlerDeleted = FALSE;
+	for (i = 0; !wakeup.deleted[i]; i++) {
+	}
+
+	for (j = i + 1; j < wakeup.num; j++) {
+	    if (wakeup.deleted[j])
+		continue;
+	    wakeup.handlers[i] = wakeup.handlers[j];
+	    i++;
+	}
+	wakeup.num -=  j - i;
+	free(wakeup.deleted);
+	wakeup.deleted = NULL;
     }
-    --inHandler;
+    --wakeup.inHandler;
 }
 
-/**
- * Reentrant with BlockHandler and WakeupHandler, except wakeup won't
- * get called until next time
- */
 Bool
-RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler, 
-                                WakeupHandlerProcPtr wakeupHandler, 
-                                pointer blockData)
+RegisterBlockHandler (BlockHandlerProcPtr blockHandler,
+                       pointer blockData)
 {
     BlockHandlerPtr new;
 
-    if (numHandlers >= sizeHandlers)
+    if (block.num >= block.size)
+    {
+	new = realloc(block.handlers, (block.num + 1) * sizeof (*new));
+	if (!new)
+	    return FALSE;
+	block.handlers = new;
+	block.size = block.num + 1;
+    }
+
+    block.handlers[block.num].BlockHandler = blockHandler;
+    block.handlers[block.num].blockData = blockData;
+    block.num++;
+    return TRUE;
+}
+
+Bool
+RegisterWakeupHandler (WakeupHandlerProcPtr wakeupHandler,
+                       pointer blockData)
+{
+    WakeupHandlerPtr new;
+
+    if (wakeup.num >= wakeup.size)
     {
-        new = (BlockHandlerPtr) realloc(handlers, (numHandlers + 1) *
-				      	  sizeof (BlockHandlerRec));
-    	if (!new)
+	new = realloc(wakeup.handlers, (wakeup.num + 1) * sizeof (*new));
+	if (!new)
 	    return FALSE;
-    	handlers = new;
-	sizeHandlers = numHandlers + 1;
+	wakeup.handlers = new;
+	wakeup.size = wakeup.num + 1;
     }
-    handlers[numHandlers].BlockHandler = blockHandler;
-    handlers[numHandlers].WakeupHandler = wakeupHandler;
-    handlers[numHandlers].blockData = blockData;
-    handlers[numHandlers].deleted = FALSE;
-    numHandlers = numHandlers + 1;
+
+    wakeup.handlers[wakeup.num].WakeupHandler = wakeupHandler;
+    wakeup.handlers[wakeup.num].blockData = blockData;
+    wakeup.num++;
     return TRUE;
 }
 
 void
-RemoveBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler, 
-                              WakeupHandlerProcPtr wakeupHandler, 
-                              pointer blockData)
+RemoveBlockHandler (BlockHandlerProcPtr blockHandler,
+                    pointer blockData)
 {
     int	    i;
 
-    for (i = 0; i < numHandlers; i++)
-	if (handlers[i].BlockHandler == blockHandler &&
-	    handlers[i].WakeupHandler == wakeupHandler &&
-	    handlers[i].blockData == blockData)
+    for (i = 0; i < block.num; i++)
+	if (block.handlers[i].BlockHandler == blockHandler &&
+		block.handlers[i].blockData == blockData)
 	{
-	    if (inHandler)
+	    if (block.inHandler)
 	    {
-		handlerDeleted = TRUE;
-		handlers[i].deleted = TRUE;
+		if (!block.deleted)
+		    block.deleted = calloc(block.num, sizeof(*block.deleted));
+		block.deleted[i] = TRUE;
+	    } else {
+		for (; i < block.num - 1; i++)
+		    block.handlers[i] = block.handlers[i+1];
+		block.num--;
 	    }
-	    else
+	    break;
+	}
+}
+
+void
+RemoveWakeupHandler (WakeupHandlerProcPtr wakeupHandler,
+                     pointer blockData)
+{
+    int	    i;
+
+    for (i = 0; i < wakeup.num; i++)
+	if (wakeup.handlers[i].WakeupHandler == wakeupHandler &&
+		wakeup.handlers[i].blockData == blockData)
+	{
+	    if (wakeup.inHandler)
 	    {
-	    	for (; i < numHandlers - 1; i++)
-		    handlers[i] = handlers[i+1];
-	    	numHandlers--;
+		if (!wakeup.deleted)
+		    wakeup.deleted = calloc(wakeup.num, sizeof(*wakeup.deleted));
+		wakeup.deleted[i] = TRUE;
+	    } else {
+		for (; i < wakeup.num - 1; i++)
+		    wakeup.handlers[i] = wakeup.handlers[i+1];
+		wakeup.num--;
 	    }
 	    break;
 	}
 }
 
+/**
+ * Reentrant with BlockHandler
+ */
+Bool
+RegisterBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
+                                WakeupHandlerProcPtr wakeupHandler,
+                                pointer blockData)
+{
+    if (!RegisterBlockHandler (blockHandler, blockData))
+	return FALSE;
+    if (!RegisterWakeupHandler (wakeupHandler, blockData)) {
+	RemoveBlockHandler(blockHandler, blockData);
+	return FALSE;
+    }
+    return TRUE;
+}
+
+void
+RemoveBlockAndWakeupHandlers (BlockHandlerProcPtr blockHandler,
+                              WakeupHandlerProcPtr wakeupHandler,
+                              pointer blockData)
+{
+    RemoveBlockHandler(blockHandler, blockData);
+    RemoveWakeupHandler(wakeupHandler, blockData);
+}
+
 void
 InitBlockAndWakeupHandlers (void)
 {
-    free(handlers);
-    handlers = (BlockHandlerPtr) 0;
-    numHandlers = 0;
-    sizeHandlers = 0;
+    free(block.handlers);
+    free(wakeup.handlers);
+    memset(&block, 0, sizeof(block));
+    memset(&wakeup, 0, sizeof(wakeup));
 }
 
 /*
diff --git a/include/dix.h b/include/dix.h
index 7485e8e..13e20e4 100644
--- a/include/dix.h
+++ b/include/dix.h
@@ -242,6 +242,22 @@ typedef void (* WakeupHandlerProcPtr)(
     int /* result */,
     pointer /* pReadmask */);
 
+extern _X_EXPORT Bool RegisterBlockHandler(
+    BlockHandlerProcPtr /*blockHandler*/,
+    pointer /*blockData*/);
+
+extern _X_EXPORT void RemoveBlockHandler(
+    BlockHandlerProcPtr /*blockHandler*/,
+    pointer /*blockData*/);
+
+extern _X_EXPORT Bool RegisterWakeupHandler(
+    WakeupHandlerProcPtr /*wakeupHandler*/,
+    pointer /*blockData*/);
+
+extern _X_EXPORT void RemoveWakeupHandler(
+    WakeupHandlerProcPtr /*wakeupHandler*/,
+    pointer /*blockData*/);
+
 extern _X_EXPORT Bool RegisterBlockAndWakeupHandlers(
     BlockHandlerProcPtr /*blockHandler*/,
     WakeupHandlerProcPtr /*wakeupHandler*/,
-- 
1.7.0.4



More information about the xorg-devel mailing list