From: Pauli Nieminen <[email protected]> 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 <[email protected]> --- dix/dixutils.c | 220 +++++++++++++++++++++++++++++++++++++------------------- include/dix.h | 16 ++++ 2 files changed, 163 insertions(+), 73 deletions(-) diff --git a/dix/dixutils.c b/dix/dixutils.c index 470bb5d..a4cfd2e 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,29 @@ 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.handlers[i].BlockHandler; i++) { + } + + for (j = i + 1; j < block.num; j++) { + if (block.handlers[j].BlockHandler) + continue; + block.handlers[i] = block.handlers[j]; + i++; + } + block.num = i + 1; + block.deleted = FALSE; } - --inHandler; + --block.inHandler; } /** @@ -414,92 +428,152 @@ 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.handlers[i].WakeupHandler; i++) { + } + + for (j = i + 1; j < wakeup.num; j++) { + if (wakeup.handlers[j].WakeupHandler) + continue; + wakeup.handlers[i] = wakeup.handlers[j]; + i++; + } + wakeup.num = i + 1; + wakeup.deleted = FALSE; } - --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; + block.deleted = TRUE; + block.handlers[i].BlockHandler = NULL; + } 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--; + wakeup.deleted = TRUE; + wakeup.handlers[i].WakeupHandler = NULL; + } 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 a282a08..2211d0e 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 _______________________________________________ [email protected]: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: http://lists.x.org/mailman/listinfo/xorg-devel
