Unverified Commit 98349512 authored by Mike Gabriel's avatar Mike Gabriel

Merge branch 'sunweaver-pr/idletime-counter' into 3.6.x

Attributes GH PR #713: https://github.com/ArcticaProject/nx-libs/pull/713 Reviewed by Ulrich Sibiller <uli42@gmx.de> -- Tue, 3 Jul 2018 15:24:31 +0200 (CEST)
parents 72f11ee8 222153af
...@@ -232,19 +232,10 @@ ProcDPMSForceLevel(client) ...@@ -232,19 +232,10 @@ ProcDPMSForceLevel(client)
if (!DPMSEnabled) if (!DPMSEnabled)
return BadMatch; return BadMatch;
if (stuff->level == DPMSModeOn) { if (stuff->level != DPMSModeOn &&
lastDeviceEventTime.milliseconds = stuff->level != DPMSModeStandby &&
GetTimeInMillis(); stuff->level != DPMSModeSuspend &&
} else if (stuff->level == DPMSModeStandby) { stuff->level != DPMSModeOff) {
lastDeviceEventTime.milliseconds =
GetTimeInMillis() - DPMSStandbyTime;
} else if (stuff->level == DPMSModeSuspend) {
lastDeviceEventTime.milliseconds =
GetTimeInMillis() - DPMSSuspendTime;
} else if (stuff->level == DPMSModeOff) {
lastDeviceEventTime.milliseconds =
GetTimeInMillis() - DPMSOffTime;
} else {
client->errorValue = stuff->level; client->errorValue = stuff->level;
return BadValue; return BadValue;
} }
......
...@@ -241,6 +241,11 @@ SyncInitServerTime( ...@@ -241,6 +241,11 @@ SyncInitServerTime(
); );
static void static void
SyncInitIdleTime(
void
);
static void
SyncResetProc( SyncResetProc(
ExtensionEntry * /* extEntry */ ExtensionEntry * /* extEntry */
); );
...@@ -2365,6 +2370,7 @@ SyncExtensionInit(void) ...@@ -2365,6 +2370,7 @@ SyncExtensionInit(void)
* because there is always a servertime counter. * because there is always a servertime counter.
*/ */
SyncInitServerTime(); SyncInitServerTime();
SyncInitIdleTime();
#ifdef DEBUG #ifdef DEBUG
fprintf(stderr, "Sync Extension %d.%d\n", fprintf(stderr, "Sync Extension %d.%d\n",
...@@ -2485,3 +2491,156 @@ SyncInitServerTime() ...@@ -2485,3 +2491,156 @@ SyncInitServerTime()
ServertimeQueryValue, ServertimeBracketValues); ServertimeQueryValue, ServertimeBracketValues);
pnext_time = NULL; pnext_time = NULL;
} }
/*
* IDLETIME implementation
*/
static SyncCounter *IdleTimeCounter;
static XSyncValue *pIdleTimeValueLess;
static XSyncValue *pIdleTimeValueGreater;
static void
IdleTimeQueryValue (pointer pCounter, CARD64 *pValue_return)
{
CARD32 idle = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
XSyncIntsToValue (pValue_return, idle, 0);
}
static void
IdleTimeBlockHandler (pointer env, struct timeval **wt, pointer LastSelectMask)
{
XSyncValue idle, old_idle;
SyncTriggerList *list = IdleTimeCounter->pTriglist;
SyncTrigger *trig;
if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
return;
old_idle = IdleTimeCounter->value;
IdleTimeQueryValue (NULL, &idle);
IdleTimeCounter->value = idle; /* push, so CheckTrigger works */
if (pIdleTimeValueLess &&
XSyncValueLessOrEqual (idle, *pIdleTimeValueLess))
{
/*
* 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
* want level or edge trigger. Check the trigger list against the
* current idle time, and if any succeed, bomb out of select()
* immediately so we can reschedule.
*/
for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
trig = list->pTrigger;
if (trig->CheckTrigger(trig, old_idle)) {
AdjustWaitForDelay(wt, 0);
break;
}
}
/*
* We've been called exactly on the idle time, but we have a
* NegativeTransition trigger which requires a transition from an
* idle time greater than this. Schedule a wakeup for the next
* millisecond so we won't miss a transition.
*/
if (XSyncValueEqual (idle, *pIdleTimeValueLess))
AdjustWaitForDelay(wt, 1);
}
else if (pIdleTimeValueGreater)
{
/*
* There's a threshold in the positive direction. If we've been
* idle less than it, schedule a wakeup for sometime in the future.
* If we've been idle more than it, and someone wants to know about
* that level-triggered, schedule an immediate wakeup.
*/
unsigned long timeout = -1;
if (XSyncValueLessThan (idle, *pIdleTimeValueGreater)) {
XSyncValue value;
Bool overflow;
XSyncValueSubtract (&value, *pIdleTimeValueGreater,
idle, &overflow);
timeout = min(timeout, XSyncValueLow32 (value));
} else {
for (list = IdleTimeCounter->pTriglist; list; list = list->next) {
trig = list->pTrigger;
if (trig->CheckTrigger(trig, old_idle)) {
timeout = min(timeout, 0);
break;
}
}
}
AdjustWaitForDelay (wt, timeout);
}
IdleTimeCounter->value = old_idle; /* pop */
}
static void
IdleTimeWakeupHandler (pointer env,
int rc,
pointer LastSelectMask)
{
XSyncValue idle;
if (!pIdleTimeValueLess && !pIdleTimeValueGreater)
return;
IdleTimeQueryValue (NULL, &idle);
if ((pIdleTimeValueGreater &&
XSyncValueGreaterOrEqual (idle, *pIdleTimeValueGreater)) ||
(pIdleTimeValueLess &&
XSyncValueLessOrEqual (idle, *pIdleTimeValueLess)))
{
SyncChangeCounter (IdleTimeCounter, idle);
}
}
static void
IdleTimeBracketValues (pointer pCounter,
CARD64 *pbracket_less,
CARD64 *pbracket_greater)
{
Bool registered = (pIdleTimeValueLess || pIdleTimeValueGreater);
if (registered && !pbracket_less && !pbracket_greater)
{
RemoveBlockAndWakeupHandlers(IdleTimeBlockHandler,
IdleTimeWakeupHandler,
NULL);
}
else if (!registered && (pbracket_less || pbracket_greater))
{
RegisterBlockAndWakeupHandlers(IdleTimeBlockHandler,
IdleTimeWakeupHandler,
NULL);
}
pIdleTimeValueGreater = pbracket_greater;
pIdleTimeValueLess = pbracket_less;
}
static void
SyncInitIdleTime (void)
{
CARD64 resolution;
XSyncValue idle;
IdleTimeQueryValue (NULL, &idle);
XSyncIntToValue (&resolution, 4);
IdleTimeCounter = SyncCreateSystemCounter ("IDLETIME", idle, resolution,
XSyncCounterUnrestricted,
IdleTimeQueryValue,
IdleTimeBracketValues);
pIdleTimeValueLess = pIdleTimeValueGreater = NULL;
}
...@@ -3348,8 +3348,6 @@ SaveScreens(int on, int mode) ...@@ -3348,8 +3348,6 @@ SaveScreens(int on, int mode)
if (on == SCREEN_SAVER_FORCER) if (on == SCREEN_SAVER_FORCER)
{ {
UpdateCurrentTimeIf();
lastDeviceEventTime = currentTime;
if (mode == ScreenSaverReset) if (mode == ScreenSaverReset)
what = SCREEN_SAVER_OFF; what = SCREEN_SAVER_OFF;
else else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment