From 1f12f059ef994e0b9b68fbd1f1556d0285c96b8b Mon Sep 17 00:00:00 2001 From: Jamey Sharp Date: Wed, 14 Mar 2012 17:22:18 -0700 Subject: [PATCH 1/9] sync: Use a linked list instead of an array for SysCounterList. Signed-off-by: Jamey Sharp Reviewed-by: Peter Hutterer Signed-off-by: Peter Hutterer --- Xext/sync.c | 53 +++++++++++++------------------------------------- Xext/syncsrv.h | 3 +++ 2 files changed, 17 insertions(+), 39 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index f2bcd2512..fe0eac0e7 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -87,8 +87,7 @@ static RESTYPE RTAwait; static RESTYPE RTAlarm; static RESTYPE RTAlarmClient; static RESTYPE RTFence; -static int SyncNumSystemCounters = 0; -static SyncCounter **SysCounterList = NULL; +static struct xorg_list SysCounterList; static int SyncNumInvalidCounterWarnings = 0; #define MAX_INVALID_COUNTER_WARNINGS 5 @@ -932,12 +931,6 @@ SyncCreateSystemCounter(const char *name, { SyncCounter *pCounter; - SysCounterList = realloc(SysCounterList, - (SyncNumSystemCounters + - 1) * sizeof(SyncCounter *)); - if (!SysCounterList) - return NULL; - /* this function may be called before SYNC has been initialized, so we * have to make sure RTCounter is created. */ @@ -959,6 +952,7 @@ SyncCreateSystemCounter(const char *name, return pCounter; } pCounter->pSysCounterInfo = psci; + psci->pCounter = pCounter; psci->name = name; psci->resolution = resolution; psci->counterType = counterType; @@ -966,7 +960,7 @@ SyncCreateSystemCounter(const char *name, psci->BracketValues = BracketValues; XSyncMaxValue(&psci->bracket_greater); XSyncMinValue(&psci->bracket_less); - SysCounterList[SyncNumSystemCounters++] = pCounter; + xorg_list_add(&psci->entry, &SysCounterList); } return pCounter; } @@ -1111,26 +1105,8 @@ FreeCounter(void *env, XID id) free(ptl); /* destroy the trigger list as we go */ } if (IsSystemCounter(pCounter)) { - int i, found = 0; - + xorg_list_del(&pCounter->pSysCounterInfo->entry); free(pCounter->pSysCounterInfo); - - /* find the counter in the list of system counters and remove it */ - - if (SysCounterList) { - for (i = 0; i < SyncNumSystemCounters; i++) { - if (SysCounterList[i] == pCounter) { - found = i; - break; - } - } - if (found < (SyncNumSystemCounters - 1)) { - for (i = found; i < SyncNumSystemCounters - 1; i++) { - SysCounterList[i] = SysCounterList[i + 1]; - } - } - } - SyncNumSystemCounters--; } free(pCounter); return Success; @@ -1221,20 +1197,20 @@ static int ProcSyncListSystemCounters(ClientPtr client) { xSyncListSystemCountersReply rep; - int i, len; + SysCounterInfo *psci; + int len = 0; xSyncSystemCounter *list = NULL, *walklist = NULL; REQUEST_SIZE_MATCH(xSyncListSystemCountersReq); rep.type = X_Reply; rep.sequenceNumber = client->sequence; - rep.nCounters = SyncNumSystemCounters; - - for (i = len = 0; i < SyncNumSystemCounters; i++) { - const char *name = SysCounterList[i]->pSysCounterInfo->name; + rep.nCounters = 0; + xorg_list_for_each_entry(psci, &SysCounterList, entry) { /* pad to 4 byte boundary */ - len += pad_to_int32(sz_xSyncSystemCounter + strlen(name)); + len += pad_to_int32(sz_xSyncSystemCounter + strlen(psci->name)); + ++rep.nCounters; } if (len) { @@ -1251,12 +1227,11 @@ ProcSyncListSystemCounters(ClientPtr client) swapl(&rep.nCounters); } - for (i = 0; i < SyncNumSystemCounters; i++) { + xorg_list_for_each_entry(psci, &SysCounterList, entry) { int namelen; char *pname_in_reply; - SysCounterInfo *psci = SysCounterList[i]->pSysCounterInfo; - walklist->counter = SysCounterList[i]->sync.id; + walklist->counter = psci->pCounter->sync.id; walklist->resolution_hi = XSyncValueHigh32(psci->resolution); walklist->resolution_lo = XSyncValueLow32(psci->resolution); namelen = strlen(psci->name); @@ -2441,8 +2416,6 @@ SAlarmNotifyEvent(xSyncAlarmNotifyEvent * from, xSyncAlarmNotifyEvent * to) static void SyncResetProc(ExtensionEntry * extEntry) { - free(SysCounterList); - SysCounterList = NULL; RTCounter = 0; } @@ -2455,6 +2428,8 @@ SyncExtensionInit(void) ExtensionEntry *extEntry; int s; + xorg_list_init(&SysCounterList); + for (s = 0; s < screenInfo.numScreens; s++) miSyncSetup(screenInfo.screens[s]); diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 1e59dedfe..f2f7a0fb9 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -51,6 +51,7 @@ PERFORMANCE OF THIS SOFTWARE. #ifndef _SYNCSRV_H_ #define _SYNCSRV_H_ +#include "list.h" #include "misync.h" #include "misyncstr.h" @@ -74,6 +75,7 @@ typedef void (*SyncSystemCounterBracketValues)(pointer counter, ); typedef struct _SysCounterInfo { + SyncCounter *pCounter; const char *name; CARD64 resolution; CARD64 bracket_greater; @@ -81,6 +83,7 @@ typedef struct _SysCounterInfo { SyncCounterType counterType; /* how can this counter change */ SyncSystemCounterQueryValue QueryValue; SyncSystemCounterBracketValues BracketValues; + struct xorg_list entry; } SysCounterInfo; typedef struct _SyncAlarmClientList { From 43eb2f2758dfc6ca5a49afce97cc5baea8caf9f5 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Mar 2012 15:27:56 +1000 Subject: [PATCH 2/9] Xext: localise use of IdleTimeCounter Instead of referring to the global IdleTimeCounter everywhere, only do it once and use a local variable for the rest. Cleanup for future features, no functional changes. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index fe0eac0e7..54a9fbb9d 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2595,16 +2595,17 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) static void IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) { + SyncCounter *counter = IdleTimeCounter; XSyncValue idle, old_idle; - SyncTriggerList *list = IdleTimeCounter->sync.pTriglist; + SyncTriggerList *list = counter->sync.pTriglist; SyncTrigger *trig; if (!pIdleTimeValueLess && !pIdleTimeValueGreater) return; - old_idle = IdleTimeCounter->value; + old_idle = counter->value; IdleTimeQueryValue(NULL, &idle); - IdleTimeCounter->value = idle; /* push, so CheckTrigger works */ + counter->value = idle; /* push, so CheckTrigger works */ if (pIdleTimeValueLess && XSyncValueLessOrEqual(idle, *pIdleTimeValueLess)) { /* @@ -2615,7 +2616,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) * immediately so we can reschedule. */ - for (list = IdleTimeCounter->sync.pTriglist; list; list = list->next) { + for (list = counter->sync.pTriglist; list; list = list->next) { trig = list->pTrigger; if (trig->CheckTrigger(trig, old_idle)) { AdjustWaitForDelay(wt, 0); @@ -2648,7 +2649,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) timeout = min(timeout, XSyncValueLow32(value)); } else { - for (list = IdleTimeCounter->sync.pTriglist; list; + for (list = counter->sync.pTriglist; list; list = list->next) { trig = list->pTrigger; if (trig->CheckTrigger(trig, old_idle)) { @@ -2661,12 +2662,13 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) AdjustWaitForDelay(wt, timeout); } - IdleTimeCounter->value = old_idle; /* pop */ + counter->value = old_idle; /* pop */ } static void IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask) { + SyncCounter *counter = IdleTimeCounter; XSyncValue idle; if (!pIdleTimeValueLess && !pIdleTimeValueGreater) @@ -2678,7 +2680,7 @@ IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask) XSyncValueGreaterOrEqual(idle, *pIdleTimeValueGreater)) || (pIdleTimeValueLess && XSyncValueLessOrEqual(idle, *pIdleTimeValueLess))) { - SyncChangeCounter(IdleTimeCounter, idle); + SyncChangeCounter(counter, idle); } } From 3ddae647c307005309daa2d5dfe4bc6acb8170ab Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Mar 2012 15:31:39 +1000 Subject: [PATCH 3/9] Xext: localise pIdleTimeValueLess/Greater Cleanup for future features, no functional changes. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 54a9fbb9d..0bc0fb872 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2596,18 +2596,20 @@ static void IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) { SyncCounter *counter = IdleTimeCounter; + XSyncValue *less = pIdleTimeValueLess, + *greater = pIdleTimeValueGreater; XSyncValue idle, old_idle; SyncTriggerList *list = counter->sync.pTriglist; SyncTrigger *trig; - if (!pIdleTimeValueLess && !pIdleTimeValueGreater) + if (!less && !greater) return; old_idle = counter->value; IdleTimeQueryValue(NULL, &idle); counter->value = idle; /* push, so CheckTrigger works */ - if (pIdleTimeValueLess && XSyncValueLessOrEqual(idle, *pIdleTimeValueLess)) { + if (less && XSyncValueLessOrEqual(idle, *less)) { /* * We've been idle for less than the threshold value, and someone * wants to know about that, but now we need to know whether they @@ -2629,10 +2631,10 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) * idle time greater than this. Schedule a wakeup for the next * millisecond so we won't miss a transition. */ - if (XSyncValueEqual(idle, *pIdleTimeValueLess)) + if (XSyncValueEqual(idle, *less)) AdjustWaitForDelay(wt, 1); } - else if (pIdleTimeValueGreater) { + else if (greater) { /* * There's a threshold in the positive direction. If we've been * idle less than it, schedule a wakeup for sometime in the future. @@ -2641,11 +2643,11 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) */ unsigned long timeout = -1; - if (XSyncValueLessThan(idle, *pIdleTimeValueGreater)) { + if (XSyncValueLessThan(idle, *greater)) { XSyncValue value; Bool overflow; - XSyncValueSubtract(&value, *pIdleTimeValueGreater, idle, &overflow); + XSyncValueSubtract(&value, *greater, idle, &overflow); timeout = min(timeout, XSyncValueLow32(value)); } else { @@ -2670,16 +2672,16 @@ IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask) { SyncCounter *counter = IdleTimeCounter; XSyncValue idle; + XSyncValue *less = pIdleTimeValueLess, + *greater = pIdleTimeValueGreater; - if (!pIdleTimeValueLess && !pIdleTimeValueGreater) + if (!less && !greater) return; IdleTimeQueryValue(NULL, &idle); - if ((pIdleTimeValueGreater && - XSyncValueGreaterOrEqual(idle, *pIdleTimeValueGreater)) || - (pIdleTimeValueLess && - XSyncValueLessOrEqual(idle, *pIdleTimeValueLess))) { + if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) || + (less && XSyncValueLessOrEqual(idle, *less))) { SyncChangeCounter(counter, idle); } } @@ -2688,7 +2690,9 @@ static void IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less, CARD64 * pbracket_greater) { - Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater); + XSyncValue *less = pIdleTimeValueLess, + *greater = pIdleTimeValueGreater; + Bool registered = (less || greater); if (registered && !pbracket_less && !pbracket_greater) { RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler, From 90e6dc6de1ac339212989fd8e54131b196ebb369 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Mar 2012 09:28:15 +1000 Subject: [PATCH 4/9] Xext: add a private field to SyncSystemCounters Will be used to store counter-specific data. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 10 ++++++++++ Xext/syncsrv.h | 1 + 2 files changed, 11 insertions(+) diff --git a/Xext/sync.c b/Xext/sync.c index 0bc0fb872..a692b6e29 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -113,6 +113,14 @@ static void SyncInitServerTime(void); static void SyncInitIdleTime(void); +static inline void* +SysCounterGetPrivate(SyncCounter *counter) +{ + BUG_WARN(!IsSystemCounter(counter)); + + return counter->pSysCounterInfo ? counter->pSysCounterInfo->private : NULL; +} + static Bool SyncCheckWarnIsCounter(const SyncObject * pSync, const char *warning) { @@ -958,6 +966,7 @@ SyncCreateSystemCounter(const char *name, psci->counterType = counterType; psci->QueryValue = QueryValue; psci->BracketValues = BracketValues; + psci->private = NULL; XSyncMaxValue(&psci->bracket_greater); XSyncMinValue(&psci->bracket_less); xorg_list_add(&psci->entry, &SysCounterList); @@ -1106,6 +1115,7 @@ FreeCounter(void *env, XID id) } if (IsSystemCounter(pCounter)) { xorg_list_del(&pCounter->pSysCounterInfo->entry); + free(pCounter->pSysCounterInfo->private); free(pCounter->pSysCounterInfo); } free(pCounter); diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index f2f7a0fb9..2fa868790 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -83,6 +83,7 @@ typedef struct _SysCounterInfo { SyncCounterType counterType; /* how can this counter change */ SyncSystemCounterQueryValue QueryValue; SyncSystemCounterBracketValues BracketValues; + void *private; struct xorg_list entry; } SysCounterInfo; From d9553b2bbe06fba0b209218ffed9465edd79b4d2 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Mar 2012 09:29:39 +1000 Subject: [PATCH 5/9] Xext: pass the counter into block/wakeup handlers No functional changes, currently unused. Preparation work, we don't need a global variable if we can pass the counters around anyway. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index a692b6e29..94972ead9 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2603,7 +2603,7 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) } static void -IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) +IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask) { SyncCounter *counter = IdleTimeCounter; XSyncValue *less = pIdleTimeValueLess, @@ -2678,7 +2678,7 @@ IdleTimeBlockHandler(pointer env, struct timeval **wt, pointer LastSelectMask) } static void -IdleTimeWakeupHandler(pointer env, int rc, pointer LastSelectMask) +IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask) { SyncCounter *counter = IdleTimeCounter; XSyncValue idle; @@ -2706,11 +2706,11 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less, if (registered && !pbracket_less && !pbracket_greater) { RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler, - IdleTimeWakeupHandler, NULL); + IdleTimeWakeupHandler, pCounter); } else if (!registered && (pbracket_less || pbracket_greater)) { RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler, - IdleTimeWakeupHandler, NULL); + IdleTimeWakeupHandler, pCounter); } pIdleTimeValueGreater = pbracket_greater; From f1b28aea4156f0381ea733ad2afbdd1f34f75599 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Mar 2012 09:31:09 +1000 Subject: [PATCH 6/9] Xext: store the bracket values for idle counters in the private And drop the three global variables, we have a reference to the counter everywhere now. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 94972ead9..3c6ac5bd2 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2590,9 +2590,10 @@ SyncInitServerTime(void) * IDLETIME implementation */ -static SyncCounter *IdleTimeCounter; -static XSyncValue *pIdleTimeValueLess; -static XSyncValue *pIdleTimeValueGreater; +typedef struct { + XSyncValue *value_less; + XSyncValue *value_greater; +} IdleCounterPriv; static void IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) @@ -2605,9 +2606,10 @@ IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) static void IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMask) { - SyncCounter *counter = IdleTimeCounter; - XSyncValue *less = pIdleTimeValueLess, - *greater = pIdleTimeValueGreater; + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + XSyncValue *less = priv->value_less, + *greater = priv->value_greater; XSyncValue idle, old_idle; SyncTriggerList *list = counter->sync.pTriglist; SyncTrigger *trig; @@ -2680,10 +2682,11 @@ IdleTimeBlockHandler(pointer pCounter, struct timeval **wt, pointer LastSelectMa static void IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask) { - SyncCounter *counter = IdleTimeCounter; + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + XSyncValue *less = priv->value_less, + *greater = priv->value_greater; XSyncValue idle; - XSyncValue *less = pIdleTimeValueLess, - *greater = pIdleTimeValueGreater; if (!less && !greater) return; @@ -2700,8 +2703,10 @@ static void IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less, CARD64 * pbracket_greater) { - XSyncValue *less = pIdleTimeValueLess, - *greater = pIdleTimeValueGreater; + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + XSyncValue *less = priv->value_less, + *greater = priv->value_greater; Bool registered = (less || greater); if (registered && !pbracket_less && !pbracket_greater) { @@ -2713,8 +2718,8 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less, IdleTimeWakeupHandler, pCounter); } - pIdleTimeValueGreater = pbracket_greater; - pIdleTimeValueLess = pbracket_less; + priv->value_greater = pbracket_greater; + priv->value_less = pbracket_less; } static void @@ -2722,14 +2727,18 @@ SyncInitIdleTime(void) { CARD64 resolution; XSyncValue idle; + IdleCounterPriv *priv = malloc(sizeof(IdleCounterPriv)); + SyncCounter *idle_time_counter; IdleTimeQueryValue(NULL, &idle); XSyncIntToValue(&resolution, 4); - IdleTimeCounter = SyncCreateSystemCounter("IDLETIME", idle, resolution, - XSyncCounterUnrestricted, - IdleTimeQueryValue, - IdleTimeBracketValues); + idle_time_counter = SyncCreateSystemCounter("IDLETIME", idle, resolution, + XSyncCounterUnrestricted, + IdleTimeQueryValue, + IdleTimeBracketValues); - pIdleTimeValueLess = pIdleTimeValueGreater = NULL; + priv->value_less = priv->value_greater = NULL; + + idle_time_counter->pSysCounterInfo->private = priv; } From 20cf0ef825e3f14b0688b691691e0aeba0a4860a Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Tue, 13 Mar 2012 10:21:23 +1000 Subject: [PATCH 7/9] Xext: strdup() the SystemSyncCounter name Required for future dynamic names. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 3 ++- Xext/syncsrv.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 3c6ac5bd2..25379bbec 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -961,7 +961,7 @@ SyncCreateSystemCounter(const char *name, } pCounter->pSysCounterInfo = psci; psci->pCounter = pCounter; - psci->name = name; + psci->name = strdup(name); psci->resolution = resolution; psci->counterType = counterType; psci->QueryValue = QueryValue; @@ -1115,6 +1115,7 @@ FreeCounter(void *env, XID id) } if (IsSystemCounter(pCounter)) { xorg_list_del(&pCounter->pSysCounterInfo->entry); + free(pCounter->pSysCounterInfo->name); free(pCounter->pSysCounterInfo->private); free(pCounter->pSysCounterInfo); } diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index 2fa868790..d29c361cc 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -76,7 +76,7 @@ typedef void (*SyncSystemCounterBracketValues)(pointer counter, typedef struct _SysCounterInfo { SyncCounter *pCounter; - const char *name; + char *name; CARD64 resolution; CARD64 bracket_greater; CARD64 bracket_less; From 6aef209ebc2e54f5465da505a780f7b4cc273ee0 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Mar 2012 13:51:02 +1000 Subject: [PATCH 8/9] Change lastDeviceIdleTime to be per-device Preparation work for per-device idle counters. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/saver.c | 7 +++++-- Xext/sync.c | 2 +- Xi/exevents.c | 2 +- dix/events.c | 13 +++++++------ dix/globals.c | 2 +- dix/window.c | 4 +++- hw/kdrive/src/kinput.c | 3 ++- include/dix.h | 3 ++- include/dixstruct.h | 2 +- os/WaitFor.c | 2 +- os/xdmcp.c | 2 +- 11 files changed, 25 insertions(+), 17 deletions(-) diff --git a/Xext/saver.c b/Xext/saver.c index 159153c23..61fc044d7 100644 --- a/Xext/saver.c +++ b/Xext/saver.c @@ -46,6 +46,7 @@ in this Software without prior written authorization from the X Consortium. #include "cursorstr.h" #include "colormapst.h" #include "xace.h" +#include "inputstr.h" #ifdef PANORAMIX #include "panoramiX.h" #include "panoramiXsrv.h" @@ -388,8 +389,10 @@ ScreenSaverFreeSuspend(pointer value, XID id) if (screenIsSaved != SCREEN_SAVER_ON) #endif { + DeviceIntPtr dev; UpdateCurrentTimeIf(); - lastDeviceEventTime = currentTime; + nt_list_for_each_entry(dev, inputInfo.devices, next) + lastDeviceEventTime[dev->id] = currentTime; SetScreenSaverTimer(); } } @@ -672,7 +675,7 @@ ProcScreenSaverQueryInfo(ClientPtr client) pPriv = GetScreenPrivate(pDraw->pScreen); UpdateCurrentTime(); - lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; + lastInput = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds; rep.type = X_Reply; rep.length = 0; diff --git a/Xext/sync.c b/Xext/sync.c index 25379bbec..8217e7662 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -2599,7 +2599,7 @@ typedef struct { static void IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) { - CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds; + CARD32 idle = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds; XSyncIntsToValue(pValue_return, idle, 0); } diff --git a/Xi/exevents.c b/Xi/exevents.c index f681a8b6f..ff2224094 100644 --- a/Xi/exevents.c +++ b/Xi/exevents.c @@ -1598,7 +1598,7 @@ ProcessDeviceEvent(InternalEvent *ev, DeviceIntPtr device) GetSpritePosition(device, &rootX, &rootY); event->root_x = rootX; event->root_y = rootY; - NoticeEventTime((InternalEvent *) event); + NoticeEventTime((InternalEvent *) event, device); event->corestate = corestate; key = event->detail.key; break; diff --git a/dix/events.c b/dix/events.c index f7b9456ea..447094757 100644 --- a/dix/events.c +++ b/dix/events.c @@ -1055,19 +1055,20 @@ MonthChangedOrBadTime(InternalEvent *ev) } static void -NoticeTime(InternalEvent *ev) +NoticeTime(InternalEvent *ev, DeviceIntPtr dev) { if (ev->any.time < currentTime.milliseconds) MonthChangedOrBadTime(ev); currentTime.milliseconds = ev->any.time; - lastDeviceEventTime = currentTime; + lastDeviceEventTime[XIAllDevices] = currentTime; + lastDeviceEventTime[dev->id] = currentTime; } void -NoticeEventTime(InternalEvent *ev) +NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev) { if (!syncEvents.playingEvents) - NoticeTime(ev); + NoticeTime(ev, dev); } /************************************************************************** @@ -1091,7 +1092,7 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) if (!xorg_list_is_empty(&syncEvents.pending)) tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next); - NoticeTime((InternalEvent *) event); + NoticeTime((InternalEvent *)event, device); /* Fix for key repeating bug. */ if (device->key != NULL && device->key->xkbInfo != NULL && @@ -5163,6 +5164,7 @@ InitEvents(void) for (i = 0; i < MAXDEVICES; i++) { memcpy(&event_filters[i], default_filter, sizeof(default_filter)); + lastDeviceEventTime[i] = currentTime; } syncEvents.replayDev = (DeviceIntPtr) NULL; @@ -5176,7 +5178,6 @@ InitEvents(void) syncEvents.time.milliseconds = 0; /* hardly matters */ currentTime.months = 0; currentTime.milliseconds = GetTimeInMillis(); - lastDeviceEventTime = currentTime; for (i = 0; i < DNPMCOUNT; i++) { DontPropagateMasks[i] = 0; DontPropagateRefCnts[i] = 0; diff --git a/dix/globals.c b/dix/globals.c index c0cae159a..a564575f3 100644 --- a/dix/globals.c +++ b/dix/globals.c @@ -122,7 +122,7 @@ Bool party_like_its_1989 = FALSE; Bool whiteRoot = FALSE; TimeStamp currentTime; -TimeStamp lastDeviceEventTime; +TimeStamp lastDeviceEventTime[MAXDEVICES]; int defaultColorVisualClass = -1; int monitorResolution = 0; diff --git a/dix/window.c b/dix/window.c index a31e78fad..98f5604c9 100644 --- a/dix/window.c +++ b/dix/window.c @@ -3134,8 +3134,10 @@ dixSaveScreens(ClientPtr client, int on, int mode) screenIsSaved = what; if (mode == ScreenSaverReset) { if (on == SCREEN_SAVER_FORCER) { + DeviceIntPtr dev; UpdateCurrentTimeIf(); - lastDeviceEventTime = currentTime; + nt_list_for_each_entry(dev, inputInfo.devices, next) + lastDeviceEventTime[dev->id] = currentTime; } SetScreenSaverTimer(); } diff --git a/hw/kdrive/src/kinput.c b/hw/kdrive/src/kinput.c index 692e511a8..e16fe78f2 100644 --- a/hw/kdrive/src/kinput.c +++ b/hw/kdrive/src/kinput.c @@ -340,7 +340,8 @@ KdEnableInput(void) /* reset screen saver */ ev.any.time = GetTimeInMillis(); - NoticeEventTime(&ev); + NoticeEventTime(&ev, pi->dixdev); + NoticeEventTime(&ev, ki->dixdev); KdUnblockSigio(); } diff --git a/include/dix.h b/include/dix.h index d604e0676..5dc2ac568 100644 --- a/include/dix.h +++ b/include/dix.h @@ -313,7 +313,8 @@ extern _X_EXPORT WindowPtr GetSpriteWindow(DeviceIntPtr pDev); extern _X_EXPORT void -NoticeEventTime(InternalEvent *ev); +NoticeEventTime(InternalEvent *ev, + DeviceIntPtr dev); extern void EnqueueEvent(InternalEvent * /* ev */ , diff --git a/include/dixstruct.h b/include/dixstruct.h index 75685a2dc..b2a168aa8 100644 --- a/include/dixstruct.h +++ b/include/dixstruct.h @@ -156,7 +156,7 @@ typedef struct _WorkQueue { } WorkQueueRec; extern _X_EXPORT TimeStamp currentTime; -extern _X_EXPORT TimeStamp lastDeviceEventTime; +extern _X_EXPORT TimeStamp lastDeviceEventTime[MAXDEVICES]; extern _X_EXPORT int CompareTimeStamps(TimeStamp /*a */ , diff --git a/os/WaitFor.c b/os/WaitFor.c index 4c3be343b..95e64ba45 100644 --- a/os/WaitFor.c +++ b/os/WaitFor.c @@ -547,7 +547,7 @@ NextDPMSTimeout(INT32 timeout) static CARD32 ScreenSaverTimeoutExpire(OsTimerPtr timer, CARD32 now, pointer arg) { - INT32 timeout = now - lastDeviceEventTime.milliseconds; + INT32 timeout = now - lastDeviceEventTime[XIAllDevices].milliseconds; CARD32 nextTimeout = 0; #ifdef DPMSExtension diff --git a/os/xdmcp.c b/os/xdmcp.c index 8d0fbb5a9..87f04b455 100644 --- a/os/xdmcp.c +++ b/os/xdmcp.c @@ -1391,7 +1391,7 @@ recv_alive_msg(unsigned length) if (SessionRunning && AliveSessionID == SessionID) { /* backoff dormancy period */ state = XDM_RUN_SESSION; - if ((GetTimeInMillis() - lastDeviceEventTime.milliseconds) > + if ((GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds) > keepaliveDormancy * 1000) { keepaliveDormancy <<= 1; if (keepaliveDormancy > XDM_MAX_DORMANCY) From d645edd11e7482f98c8b7e0d6c8693285c484907 Mon Sep 17 00:00:00 2001 From: Peter Hutterer Date: Mon, 12 Mar 2012 16:36:31 +1000 Subject: [PATCH 9/9] Xext: Add per-device SyncCounters Previously, we only had one idle alarm that was triggered for all devices, whenever the user used any device, came back from suspend, etc. Add system SyncCounters for each device (named "DEVICEIDLETIME x", with x being the device id) that trigger on that device only. This allows for enabling/disabling devices based on interaction with other devices. Popular use-case: disable the touchpad when the keyboard just above the touchpad stops being idle. Signed-off-by: Peter Hutterer Reviewed-by: Jeremy Huddleston Reviewed-by: Jamey Sharp Reviewed-by: James Jones --- Xext/sync.c | 48 +++++++++++++++++++++++++++++++++++++++++----- Xext/syncsrv.h | 3 +++ dix/devices.c | 8 ++++++++ include/inputstr.h | 2 ++ 4 files changed, 56 insertions(+), 5 deletions(-) diff --git a/Xext/sync.c b/Xext/sync.c index 8217e7662..91968e498 100644 --- a/Xext/sync.c +++ b/Xext/sync.c @@ -69,6 +69,7 @@ PERFORMANCE OF THIS SOFTWARE. #include "syncsrv.h" #include "syncsdk.h" #include "protocol-versions.h" +#include "inputstr.h" #include #if !defined(WIN32) @@ -2594,13 +2595,23 @@ SyncInitServerTime(void) typedef struct { XSyncValue *value_less; XSyncValue *value_greater; + int deviceid; } IdleCounterPriv; static void IdleTimeQueryValue(pointer pCounter, CARD64 * pValue_return) { - CARD32 idle = GetTimeInMillis() - lastDeviceEventTime[XIAllDevices].milliseconds; + int deviceid; + CARD32 idle; + if (pCounter) { + SyncCounter *counter = pCounter; + IdleCounterPriv *priv = SysCounterGetPrivate(counter); + deviceid = priv->deviceid; + } + else + deviceid = XIAllDevices; + idle = GetTimeInMillis() - lastDeviceEventTime[deviceid].milliseconds; XSyncIntsToValue(pValue_return, idle, 0); } @@ -2692,7 +2703,7 @@ IdleTimeWakeupHandler(pointer pCounter, int rc, pointer LastSelectMask) if (!less && !greater) return; - IdleTimeQueryValue(NULL, &idle); + IdleTimeQueryValue(pCounter, &idle); if ((greater && XSyncValueGreaterOrEqual(idle, *greater)) || (less && XSyncValueLessOrEqual(idle, *less))) { @@ -2723,8 +2734,8 @@ IdleTimeBracketValues(pointer pCounter, CARD64 * pbracket_less, priv->value_less = pbracket_less; } -static void -SyncInitIdleTime(void) +static SyncCounter* +init_system_idle_counter(const char *name, int deviceid) { CARD64 resolution; XSyncValue idle; @@ -2734,12 +2745,39 @@ SyncInitIdleTime(void) IdleTimeQueryValue(NULL, &idle); XSyncIntToValue(&resolution, 4); - idle_time_counter = SyncCreateSystemCounter("IDLETIME", idle, resolution, + idle_time_counter = SyncCreateSystemCounter(name, idle, resolution, XSyncCounterUnrestricted, IdleTimeQueryValue, IdleTimeBracketValues); + priv->deviceid = deviceid; priv->value_less = priv->value_greater = NULL; idle_time_counter->pSysCounterInfo->private = priv; + + return idle_time_counter; +} + +static void +SyncInitIdleTime(void) +{ + init_system_idle_counter("IDLETIME", XIAllDevices); +} + +SyncCounter* +SyncInitDeviceIdleTime(DeviceIntPtr dev) +{ + char timer_name[64]; + sprintf(timer_name, "DEVICEIDLETIME %d", dev->id); + + return init_system_idle_counter(timer_name, dev->id); +} + +void SyncRemoveDeviceIdleTime(SyncCounter *counter) +{ + /* FreeAllResources() frees all system counters before the devices are + shut down, check if there are any left before freeing the device's + counter */ + if (!xorg_list_is_empty(&SysCounterList)) + xorg_list_del(&counter->pSysCounterInfo->entry); } diff --git a/Xext/syncsrv.h b/Xext/syncsrv.h index d29c361cc..dbed476f2 100644 --- a/Xext/syncsrv.h +++ b/Xext/syncsrv.h @@ -135,4 +135,7 @@ extern void SyncChangeCounter(SyncCounter *pCounter, extern void SyncDestroySystemCounter(pointer pCounter); extern void SyncExtensionInit(void); + +extern SyncCounter *SyncInitDeviceIdleTime(DeviceIntPtr dev); +extern void SyncRemoveDeviceIdleTime(SyncCounter *counter); #endif /* _SYNCSRV_H_ */ diff --git a/dix/devices.c b/dix/devices.c index 012550443..600f8b738 100644 --- a/dix/devices.c +++ b/dix/devices.c @@ -84,6 +84,7 @@ SOFTWARE. #include "enterleave.h" /* for EnterWindow() */ #include "xserver-properties.h" #include "xichangehierarchy.h" /* For XISendDeviceHierarchyEvent */ +#include "syncsrv.h" /** @file * This file handles input device-related stuff. @@ -406,9 +407,13 @@ EnableDevice(DeviceIntPtr dev, BOOL sendevent) RecalculateMasterButtons(dev); + /* initialise an idle timer for this device*/ + dev->idle_counter = SyncInitDeviceIdleTime(dev); + return TRUE; } + /** * Switch a device off through the driver and push it onto the off_devices * list. A device will not send events while disabled. All clients are @@ -432,6 +437,9 @@ DisableDevice(DeviceIntPtr dev, BOOL sendevent) if (*prev != dev) return FALSE; + SyncRemoveDeviceIdleTime(dev->idle_counter); + dev->idle_counter = NULL; + /* float attached devices */ if (IsMaster(dev)) { for (other = inputInfo.devices; other; other = other->next) { diff --git a/include/inputstr.h b/include/inputstr.h index 841e8052b..5a38924de 100644 --- a/include/inputstr.h +++ b/include/inputstr.h @@ -591,6 +591,8 @@ typedef struct _DeviceIntRec { /* XTest related master device id */ int xtest_master_id; + + struct _SyncCounter *idle_counter; } DeviceIntRec; typedef struct {