Zitat von Stefan Lucke <[EMAIL PROTECTED]>:
> Zitat von Martin Wache <[EMAIL PROTECTED]>:
>
> > Stefan Lucke schrieb:
> > > On Samstag 30 September 2006 20:04, Marko Mäkelä wrote:
> > >> On Sat, Sep 30, 2006 at 05:32:06PM +0100, Laz wrote:
> > >>> I usually let mine turn itself on and off with nvram-wakeup! I see
> > >>> the problem when I leave it for a short while in the middle of something
> > >>> and get distracted!
> > >> Me too. Sometimes, I hit the Power button followed by some other button
> > >> to suspend the playback and to prevent the system from powering off.
> > >> Then, I'd hit the Power button to resume.
> > >>
> > >>> Hmmm...if you're right about this, how long should it take to overflow?
> > >>> The
> > >>> only counter I can see is a 64-bit integer which looks like it's
> > >>> counting in
> > >>> useconds which would take a few million years to overflow, by my
> > >>> reckoning!
> > >>> Maybe I'm looking in the wrong place and it's a 32-bit counter which
> > >>> would
> > >>> take 1 h 12 min to overflow. Not sure it was taking that long but it's
> > >>> hard
> > >>> to tell.
> > >
> > > Negative values should not harm,as we would return immedeatly.
> > >
> > I think the problem is in cSyncTimer::GetRelTime() which returns an
> > signed int. If GetRelTime() returns a negative number because of an
> > overflow we will actually add that value to delay instead of
> > substracting, when we do the ususal delay-=GetRelTime().
>
> The -= operator is the one which is causing troubles.
That computed value is not only issue in that situation. I managed to
avoid hang by some other changes. With current code we are loosing a signal to
the condition variable.
I did the following changes to sync_timer.c
1. cSigTimer::Sleep() clear signal "got_signal=false;" only if would not sleep.
-- snip --
/* --- cSigTimer --------------------------------------------------------------
*/
int cSigTimer::Sleep(int timeoutUS, int lowLimitUS)
{
if ( timeoutUS < lowLimitUS ) {
got_signal=false;
return GetRelTime();
}
-- snip --
2. cSyncTimer::Sleep(): clear signals "got_signal=false;" only in case of
emUsleepTimer and emRtcTimer.
-- snip --
/* ----------------------------------------------------------------------------
*/
void cSyncTimer::Sleep(int *timeoutUS, int lowLimitUS)
{
switch(syncMode)
{
case emUsleepTimer: // usleep timer mode
while ((*timeoutUS - lowLimitUS) > 2200 && !got_signal)
{
usleep (2200);
*timeoutUS -= GetRelTime ();
}
break;
got_signal=false;
case emRtcTimer: // rtc timer mode
while ((*timeoutUS - lowLimitUS) > 15000 && !got_signal)
{
usleep (10000);
*timeoutUS -= GetRelTime();
}
while ((*timeoutUS - lowLimitUS) > 1200 && !got_signal)
{
uint32_t ts;
if (read(rtcFd, &ts, sizeof(ts)) <= 0)
{
close(rtcFd);
rtcFd = -1;
syncMode = emUsleepTimer;
}
*timeoutUS -= GetRelTime();
}
break;
got_signal=false;
case emSigTimer: // signal timer mode
*timeoutUS -= cSigTimer::Sleep(*timeoutUS, lowLimitUS);
break;
}
}
-- snip --
With these two modifications vdr did _not_ hang after the 40min sleep.
One thing I did not test in case of real long Sync() is in video.c.
Sync() is protected by oldPictureMutex and would lock video thread from
event processing.
> I guess we should
> introduce a private member "clampValue" , and return values of TimePassed()
> and GetRelTime() should be clamped to +/- clampValue if it is nonzero.
>
> The one thing which I cannot recalulate is: I had a sleep time of 27min
> (0x634cc13f usec).
> Time passed between pause/play was about 42min 50sec (0x992f1680 usec) .
>
> >
> > We could avoid this by letting GetRelTime() return some maximum, if
> > there have been overflows. This would fix the pause problem as well as
> > Marco's problem.
> >
> > Bye,
> > Martin
Stefan Lucke
_______________________________________________
Softdevice-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/softdevice-devel