Stefan Lucke schrieb:
> 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;
This line is never executed.
> 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;
this too.
> case emSigTimer: // signal timer mode
> *timeoutUS -= cSigTimer::Sleep(*timeoutUS, lowLimitUS);
> break;
> }
> }
> -- snip --
>
> With these two modifications vdr did _not_ hang after the 40min sleep.
>
because got_signal is never set to false... And thus there is no
sleeping at all.
This will break the syncing completely. Maybe you don't notice it with
DirectFB, because there is still the syncing to the Refreshrate.
> 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.
>
Well, maybe we should move the whole syncing to cVideo::Action() and
introduce a picture queue, then we could get rid of the oldPictureMutex
at all... I will think about this..
>> 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.
>>
GetRelTime() and TimePassed() is anyway a code duplication, that should
be fixed too. I would just limit the time which on can measure with
GetRelTime() and TimePassed() to a reasonable time, lets say 15min or
so. That is save to keep in 32bit. On longer waits GetRelTime() should
just return the max value for 15min.
I will send a patch this evening.
Bye,
Martin
_______________________________________________
Softdevice-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/softdevice-devel