[MPlayer-dev-eng] [PATCH] ao_dart

KO Myung-Hun komh at chollian.net
Tue Feb 17 16:47:14 CET 2009


Hi/2.

Reimar Döffinger wrote:
> On Tue, Feb 17, 2009 at 11:58:27AM +0900, KO Myung-Hun wrote:
>   
>> Reimar Döffinger wrote:
>>     
>>> On Mon, Feb 16, 2009 at 10:17:01PM +0900, KO Myung-Hun wrote:
>>>   
>>>       
>>>> +static volatile int m_nBufSize = 0;
>>>> +static volatile int m_nBufLen = 0;
>>>> +static volatile int m_iBufPos = 0;
>>>>         
>>> You are writing m_nBufLen from both threads, thus your code is not
>>> thread-safe.
>>> E.g. ao_jack and libavutil/fifo.c should be thread-safe implementations
>>> for this one reader, one writer case (or you can use locking), ao_jack
>>> is a bit better optimized for this specific use.
>>> They also do not need modulus-operation which you use and can be quite 
>>> slow.
>>>       
>> Ok. I introduced m_iBufReadPos, m_iBufWritePos and m_fBufFull instead of 
>> m_nBufLen and m_iBufPos.
>>     
>
> That still has other issues. I know of only one lock-free thread-safe
> buffer type (and even that assumes atomic reads/writes, so it would
> break on e.g. a 16 bit microcontroller), and dropping the volatile is
> not such a good idea (yes, I know I referred you to fifo.c which does
> not use it, but using it is a bit safe with minimal effort).
>   

Ok. I restored it.

> Note that I assume that OS/2 implements non-cooperative scheduling, i.e.
> a thread switch can happen at any point of the code, and that
> dart_audio_callback executes in a different thread than the MPlayer
> core.
>
>   

Exactly.

>>>> +    opt_t subopts[] = {
>>>>     
>>>>         
>>> const
>>>       
>> Ok. But it generates the following warning.
>>
>> -----
>> libao2/ao_dart.c: In function 'init':
>> libao2/ao_dart.c:169: warning: passing argument 2 of 'subopt_parse' 
>> discards qualifiers from pointer target type
>> -----
>>     
>
> Oh, I am sorry. The const is indeed wrong, I was thinking about fixing
> it but never did it.
>
>   

No problem, removed it. ^^

>>>> +    // mask off all floating-point exceptions
>>>> +    _control87(MCW_EM, MCW_EM);
>>>>         
>>> Hm. Quite ugly, and you don't restore them in uninit.
>>> Also explaining why they are needed would be good (performance reasons,
>>> crash, and is it a bug in DART or a documented requirement - and no,
>>> no need to research, just write what you know already).
>>>       
>> Why ugly ? Anyway it's a way to avoid SIG_FPE, which is well-known problem 
>> on OS/2.
>>     
>
> Which does not explain what exactly this code is doing in an ao
> (changing that kind of thing is not commonly expected from an ao).
> There is also the obvious questions what causes a SIG_FPE, correctly
> written code should not cause any.
>
>   

Some AAC encoded movie causes SIG_FPE(underflow) in libfaad2.

If you want, I would provide it with you. It's about 380MB.

>> Some OS/2 PM(GUI) DLLs enable SIG_FPE but does not disable it 
>> again.
>>     
>
> So it is a bug workaround?
>
>   

I think so.

>> The reason why I didn't restore it, is that enabling SIG_FPE seems to be a 
>> bug as the above.
>>     
>
> Ok, but so what does enable it, the dartPlay function?
>   

Some PM DLLs loaded at init time. So SIG_FPE should be disabled after 
all the PM DLLs are loaded. And if there is a problem, it would be 
dartInit() because it loads system DLL dynamically.

>   
>> +static inline int query_buffer_len(void)
>> +{
>> +    int iBufLen = m_iBufWritePos - m_iBufReadPos;
>> +
>> +    if (iBufLen < 0 || m_fBufFull)
>> +        iBufLen += m_nBufSize;
>> +
>> +    return iBufLen;
>>     
>
> You essentially split the write position into two part, thus write to it
> are not atomic.
> E.g. here the MPlayer core thread could have updated m_iBufWritePos but
> not yet finished setting m_fBufFull to 1.
> query_buffer_len would then return 0 instead of m_nBufSize.
>
>   

Ah, I missed it.

>> +    m_iBufWritePos = end_pos;
>> +    if (m_iBufWritePos == m_iBufReadPos)
>> +        m_fBufFull = 1;
>>     
>
> I am not aware of any lock-less thread-safe fifo that allows a
> completely full buffer, and I am fairly certain that such a thing does
> not exist.
> Unless you want to spend many hours on this I think you have only two
> options to come up with correct code:
> 1) copy a (hopefully) correct implementation from somewhere, which as
> little changes as possible and avoiding to think too much (because that
> is likely to introduce bugs).
> 2) Use the proper thread-locking constructs.
>
>   

Ok. I've implemented atomic-operation using DosEnterCritSec() and 
DosExitCritSec(). That suspends all other threads and this resumes them 
again.

> But since I was promised that I will not have to maintain OS/2 code, I
> will not object to such self-contained parts to be applied as-is,
> I just want to be sure anyone who cares knows the code is not correct,
> even if hardly anyone will see it fail.
>   

No problem. I also want codes everyone can agree with.

-- 
KO Myung-Hun

Using Mozilla SeaMonkey 1.1.14
Under OS/2 Warp 4 for Korean with FixPak #15
On AMD ThunderBird 1 GHz with 512 MB RAM

Korean OS/2 User Community : http://www.ecomstation.co.kr


-------------- next part --------------
An embedded and charset-unspecified text was scrubbed...
Name: dart.diff
URL: <http://lists.mplayerhq.hu/pipermail/mplayer-dev-eng/attachments/20090218/666da43c/attachment.txt>


More information about the MPlayer-dev-eng mailing list