List Info

Thread: CR: (Take 4) Remove polling inside UNIX audio thread




CR: (Take 4) Remove polling inside UNIX audio thread
user name
2008-04-28 19:35:01
Description
----------------------------------
The audio out class for UNIX is creating a thread that
continuously 
attempts to read from the list of available audio data
buffers, and
then use the device specific method for writting that data
to the audio
device.

This change will introduce a new IHXEvent for letting the
main thread
signal the data writing thread when new data is available
for pushing to
the audio device, instead of having the audio thread do a
bunch of small
micro sleeps while it waits for some new data to push.

If data is available for writting to the device, then a
small sleep is
still added for none ALSA based device, since none ALSA
devices will not
block on write (making it possible for the thread to spin
until the
audio device is ready to accept new data.)

By doing this we remove a source of interrupts that tend to
drive
the CPU into high C0 (full power mode) residency.  This is
especially
true when on a MID device that has the ASound prealloc
buffer max'ed
out, allowing large periods of time for the original output
audio thread
to wait for new blocks of data.

Files Modified
----------------------------------
audio/device/platform/unix/audUnix.cpp
audio/device/pub/platform/unix/audUnix.h

Branches
---------------------------------
HEAD, hxclient_3_1_0_atlas

Index: platform/unix/audUnix.cpp
============================================================
=======
RCS file: /cvsroot/audio/device/platform/unix/audUnix.cpp,v
retrieving revision 1.12
diff -u -r1.12 audUnix.cpp
--- platform/unix/audUnix.cpp	6 Jul 2007 20:21:16
-0000	1.12
+++ platform/unix/audUnix.cpp	28 Apr 2008 20:07:39 -0000
 -73,7
+73,8 
 #include "hxprefs.h"
 #endif 
 
-
+#include "hxtlogutil.h"
+#include "ihxtlogsystem.h"
 
 //-1 is usually considered to be no file descriptor.
 const int CAudioOutUNIX::NO_FILE_DESCRIPTOR = -1;
 -102,6
+103,7 
     m_audioThread(NULL),
     m_bUserWantsThreads(TRUE),
     m_ulSleepTime(0),
+    m_pAvailableDataEvent(NULL),
 #endif
     m_pRollbackBuffer(NULL)
 {
 -114,7
+116,6 
     //Allco our write buffer list. Want to throw from here?
You will,
like
     //it or not.
     m_pWriteList = new CHXSimpleList();
-    
 }
 
 void CAudioOutUNIX::_initAfterContext()
 -142,6
+143,7 
 	CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxWriteListPlayStateLock, m_pContext);
 	CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
m_pContext);
 	CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
m_pContext);
+	CreateInstanceCCF(CLSID_IHXEvent,
(void**)&m_pAvailableDataEvent,
m_pContext);
     }
 #endif    
 
 -194,6
+196,7 
         HX_RELEASE( m_mtxWriteListPlayStateLock );
         HX_RELEASE( m_mtxDeviceStateLock );
         HX_RELEASE( m_audioThread );
+        HX_RELEASE( m_pAvailableDataEvent );
     }
 #endif    
 
 -353,6
+356,8 
     //Wait for it to do so and clean up.
     if( m_bUserWantsThreads )
     {
+        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
event..."); 
+        m_pAvailableDataEvent->SignalEvent();
         m_audioThread->Exit(0);
     }
     
 -778,8
+783,21 
         that->m_mtxDeviceStateLock->Unlock();
         that->m_mtxWriteListPlayStateLock->Unlock();
 
-        //OK, sleep the amount of time it takes to play 1/4
of the
device's buffer.
-        microsleep(that->m_ulSleepTime/4); 
+        if(bReadyToExit == FALSE) 
+	{
+	    if (that->m_pWriteList->GetCount() == 0 ||
that->m_wState ==
RA_AOS_OPEN_PAUSED)
+	    {
+	        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread() waiting for
audio data..."); 
+	        that->m_pAvailableDataEvent->Wait(ALLFS);
+            } 
+            else
+	    {
+#if !defined(HELIX_FEATURE_ALSA)
+	        // OK, sleep the amount of time it takes to play
1/4 of the
device's buffer.
+	        microsleep(that->m_ulSleepTime/4); 
+#endif
+	    }
+	}
     }
 
     //Signal the parent thread that we are done.
 -833,6
+851,7 
     }
 
     UNLOCK(m_mtxWriteListPlayStateLock);
+    HXLOGL4 (HXLOG_ADEV, "CAudioUnixOUT::_PushBits()
writing %i bits",
(int)ulBufLen);
     _WriteBytes(pData, ulBufLen, lCount);
     LOCK(m_mtxWriteListPlayStateLock);
 
 -995,6
+1014,8 
     //grab the data and write it to the device.
     if( m_bUserWantsThreads )
     {
+        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
event..."); 
+        m_pAvailableDataEvent->SignalEvent();
         return RA_AOE_NOERR;
     }
 #endif    
Index: pub/platform/unix/audUnix.h
============================================================
=======
RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
retrieving revision 1.8
diff -u -r1.8 audUnix.h
--- pub/platform/unix/audUnix.h	6 Jul 2007 20:21:19
-0000	1.8
+++ pub/platform/unix/audUnix.h	28 Apr 2008 20:07:39 -0000
 -289,6
+289,7 
     IHXThread*	m_audioThread;
     HXBOOL      m_bUserWantsThreads;
     ULONG32	m_ulSleepTime;
+    IHXEvent*	m_pAvailableDataEvent;
 #endif    
     
   private:


_______________________________________________
Audio-dev mailing list
Audio-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev

  
Re: CR: (Take 4) Remove polling inside UNIX audio thread
country flaguser name
United States
2008-04-29 11:33:05
Why do we only microsleep for non-ALSA drivers? Or, what
is it about OSS/etc. that require the microsleep while
ALSA does not?

I like the idea of an event rather then polling,
overall I think this is a great change to add.

--greg.


Rusty Lynch wrote:
> Description
> ----------------------------------
> The audio out class for UNIX is creating a thread that
continuously 
> attempts to read from the list of available audio data
buffers, and
> then use the device specific method for writting that
data to the audio
> device.
> 
> This change will introduce a new IHXEvent for letting
the main thread
> signal the data writing thread when new data is
available for pushing to
> the audio device, instead of having the audio thread do
a bunch of small
> micro sleeps while it waits for some new data to push.
> 
> If data is available for writting to the device, then a
small sleep is
> still added for none ALSA based device, since none ALSA
devices will not
> block on write (making it possible for the thread to
spin until the
> audio device is ready to accept new data.)
> 
> By doing this we remove a source of interrupts that
tend to drive
> the CPU into high C0 (full power mode) residency.  This
is especially
> true when on a MID device that has the ASound prealloc
buffer max'ed
> out, allowing large periods of time for the original
output audio thread
> to wait for new blocks of data.
> 
> Files Modified
> ----------------------------------
> audio/device/platform/unix/audUnix.cpp
> audio/device/pub/platform/unix/audUnix.h
> 
> Branches
> ---------------------------------
> HEAD, hxclient_3_1_0_atlas
> 
> Index: platform/unix/audUnix.cpp
>
============================================================
=======
> RCS file:
/cvsroot/audio/device/platform/unix/audUnix.cpp,v
> retrieving revision 1.12
> diff -u -r1.12 audUnix.cpp
> --- platform/unix/audUnix.cpp	6 Jul 2007 20:21:16
-0000	1.12
> +++ platform/unix/audUnix.cpp	28 Apr 2008 20:07:39
-0000
>  -73,7 +73,8 
>  #include "hxprefs.h"
>  #endif 
>  
> -
> +#include "hxtlogutil.h"
> +#include "ihxtlogsystem.h"
>  
>  //-1 is usually considered to be no file descriptor.
>  const int CAudioOutUNIX::NO_FILE_DESCRIPTOR = -1;
>  -102,6 +103,7 
>      m_audioThread(NULL),
>      m_bUserWantsThreads(TRUE),
>      m_ulSleepTime(0),
> +    m_pAvailableDataEvent(NULL),
>  #endif
>      m_pRollbackBuffer(NULL)
>  {
>  -114,7 +116,6 
>      //Allco our write buffer list. Want to throw from
here? You will,
> like
>      //it or not.
>      m_pWriteList = new CHXSimpleList();
> -    
>  }
>  
>  void CAudioOutUNIX::_initAfterContext()
>  -142,6 +143,7 
>  	CreateInstanceCCF(CLSID_IHXMutex,
> (void**)&m_mtxWriteListPlayStateLock, m_pContext);
>  	CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
> m_pContext);
>  	CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
> m_pContext);
> +	CreateInstanceCCF(CLSID_IHXEvent,
(void**)&m_pAvailableDataEvent,
> m_pContext);
>      }
>  #endif    
>  
>  -194,6 +196,7 
>          HX_RELEASE( m_mtxWriteListPlayStateLock );
>          HX_RELEASE( m_mtxDeviceStateLock );
>          HX_RELEASE( m_audioThread );
> +        HX_RELEASE( m_pAvailableDataEvent );
>      }
>  #endif    
>  
>  -353,6 +356,8 
>      //Wait for it to do so and clean up.
>      if( m_bUserWantsThreads )
>      {
> +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
> event..."); 
> +        m_pAvailableDataEvent->SignalEvent();
>          m_audioThread->Exit(0);
>      }
>      
>  -778,8 +783,21 
>          that->m_mtxDeviceStateLock->Unlock();
>         
that->m_mtxWriteListPlayStateLock->Unlock();
>  
> -        //OK, sleep the amount of time it takes to
play 1/4 of the
> device's buffer.
> -        microsleep(that->m_ulSleepTime/4); 
> +        if(bReadyToExit == FALSE) 
> +	{
> +	    if (that->m_pWriteList->GetCount() == 0 ||
that->m_wState ==
> RA_AOS_OPEN_PAUSED)
> +	    {
> +	        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread() waiting for
> audio data..."); 
> +	       
that->m_pAvailableDataEvent->Wait(ALLFS);
> +            } 
> +            else
> +	    {
> +#if !defined(HELIX_FEATURE_ALSA)
> +	        // OK, sleep the amount of time it takes to
play 1/4 of the
> device's buffer.
> +	        microsleep(that->m_ulSleepTime/4); 
> +#endif
> +	    }
> +	}
>      }
>  
>      //Signal the parent thread that we are done.
>  -833,6 +851,7 
>      }
>  
>      UNLOCK(m_mtxWriteListPlayStateLock);
> +    HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_PushBits() writing %i bits",
> (int)ulBufLen);
>      _WriteBytes(pData, ulBufLen, lCount);
>      LOCK(m_mtxWriteListPlayStateLock);
>  
>  -995,6 +1014,8 
>      //grab the data and write it to the device.
>      if( m_bUserWantsThreads )
>      {
> +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
> event..."); 
> +        m_pAvailableDataEvent->SignalEvent();
>          return RA_AOE_NOERR;
>      }
>  #endif    
> Index: pub/platform/unix/audUnix.h
>
============================================================
=======
> RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
> retrieving revision 1.8
> diff -u -r1.8 audUnix.h
> --- pub/platform/unix/audUnix.h	6 Jul 2007 20:21:19
-0000	1.8
> +++ pub/platform/unix/audUnix.h	28 Apr 2008 20:07:39
-0000
>  -289,6 +289,7 
>      IHXThread*	m_audioThread;
>      HXBOOL      m_bUserWantsThreads;
>      ULONG32	m_ulSleepTime;
> +    IHXEvent*	m_pAvailableDataEvent;
>  #endif    
>      
>    private:
> 
> 
> 
>
------------------------------------------------------------
------------
> 
> _______________________________________________
> Audio-dev mailing list
> Audio-devhelixcommunity.org
> http://lists.helixcommunity.org/mailman/listinfo/audio
-dev


_______________________________________________
Audio-dev mailing list
Audio-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev

Re: CR: (Take 4) Remove polling inside UNIX audio thread
user name
2008-04-29 12:11:42
When using ALSA we block while trying to write data to the
audio device
if the audio device is full, while other implementations are
setup to do
non-blocking writes.  We sleep on non-alsa systems to keep
from entering
into a tight spin where we have incoming data available, but
the
hardware is not ready to consume more data.

I suspect that it would be ideal for more UNIX systems to
start using
blocking writes to the audio device, and remove the need for
a
microsleep just like an we do for ALSA systems.

    --rusty

On Tue, 2008-04-29 at 09:33 -0700, Greg Wright wrote:
> Why do we only microsleep for non-ALSA drivers? Or,
what
> is it about OSS/etc. that require the microsleep while
> ALSA does not?
> 
> I like the idea of an event rather then polling,
> overall I think this is a great change to add.
> 
> --greg.
> 
> 
> Rusty Lynch wrote:
> > Description
> > ----------------------------------
> > The audio out class for UNIX is creating a thread
that continuously 
> > attempts to read from the list of available audio
data buffers, and
> > then use the device specific method for writting
that data to the audio
> > device.
> > 
> > This change will introduce a new IHXEvent for
letting the main thread
> > signal the data writing thread when new data is
available for pushing to
> > the audio device, instead of having the audio
thread do a bunch of small
> > micro sleeps while it waits for some new data to
push.
> > 
> > If data is available for writting to the device,
then a small sleep is
> > still added for none ALSA based device, since none
ALSA devices will not
> > block on write (making it possible for the thread
to spin until the
> > audio device is ready to accept new data.)
> > 
> > By doing this we remove a source of interrupts
that tend to drive
> > the CPU into high C0 (full power mode) residency. 
This is especially
> > true when on a MID device that has the ASound
prealloc buffer max'ed
> > out, allowing large periods of time for the
original output audio thread
> > to wait for new blocks of data.
> > 
> > Files Modified
> > ----------------------------------
> > audio/device/platform/unix/audUnix.cpp
> > audio/device/pub/platform/unix/audUnix.h
> > 
> > Branches
> > ---------------------------------
> > HEAD, hxclient_3_1_0_atlas
> > 
> > Index: platform/unix/audUnix.cpp
> >
============================================================
=======
> > RCS file:
/cvsroot/audio/device/platform/unix/audUnix.cpp,v
> > retrieving revision 1.12
> > diff -u -r1.12 audUnix.cpp
> > --- platform/unix/audUnix.cpp	6 Jul 2007 20:21:16
-0000	1.12
> > +++ platform/unix/audUnix.cpp	28 Apr 2008 20:07:39
-0000
> >  -73,7 +73,8 
> >  #include "hxprefs.h"
> >  #endif 
> >  
> > -
> > +#include "hxtlogutil.h"
> > +#include "ihxtlogsystem.h"
> >  
> >  //-1 is usually considered to be no file
descriptor.
> >  const int CAudioOutUNIX::NO_FILE_DESCRIPTOR =
-1;
> >  -102,6 +103,7 
> >      m_audioThread(NULL),
> >      m_bUserWantsThreads(TRUE),
> >      m_ulSleepTime(0),
> > +    m_pAvailableDataEvent(NULL),
> >  #endif
> >      m_pRollbackBuffer(NULL)
> >  {
> >  -114,7 +116,6 
> >      //Allco our write buffer list. Want to throw
from here? You will,
> > like
> >      //it or not.
> >      m_pWriteList = new CHXSimpleList();
> > -    
> >  }
> >  
> >  void CAudioOutUNIX::_initAfterContext()
> >  -142,6 +143,7 
> >  	CreateInstanceCCF(CLSID_IHXMutex,
> > (void**)&m_mtxWriteListPlayStateLock,
m_pContext);
> >  	CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
> > m_pContext);
> >  	CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
> > m_pContext);
> > +	CreateInstanceCCF(CLSID_IHXEvent,
(void**)&m_pAvailableDataEvent,
> > m_pContext);
> >      }
> >  #endif    
> >  
> >  -194,6 +196,7 
> >          HX_RELEASE( m_mtxWriteListPlayStateLock
);
> >          HX_RELEASE( m_mtxDeviceStateLock );
> >          HX_RELEASE( m_audioThread );
> > +        HX_RELEASE( m_pAvailableDataEvent );
> >      }
> >  #endif    
> >  
> >  -353,6 +356,8 
> >      //Wait for it to do so and clean up.
> >      if( m_bUserWantsThreads )
> >      {
> > +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
> > event..."); 
> > +        m_pAvailableDataEvent->SignalEvent();
> >          m_audioThread->Exit(0);
> >      }
> >      
> >  -778,8 +783,21 
> >         
that->m_mtxDeviceStateLock->Unlock();
> >         
that->m_mtxWriteListPlayStateLock->Unlock();
> >  
> > -        //OK, sleep the amount of time it takes
to play 1/4 of the
> > device's buffer.
> > -        microsleep(that->m_ulSleepTime/4); 
> > +        if(bReadyToExit == FALSE) 
> > +	{
> > +	    if (that->m_pWriteList->GetCount() ==
0 || that->m_wState ==
> > RA_AOS_OPEN_PAUSED)
> > +	    {
> > +	        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread() waiting for
> > audio data..."); 
> > +	       
that->m_pAvailableDataEvent->Wait(ALLFS);
> > +            } 
> > +            else
> > +	    {
> > +#if !defined(HELIX_FEATURE_ALSA)
> > +	        // OK, sleep the amount of time it takes
to play 1/4 of the
> > device's buffer.
> > +	        microsleep(that->m_ulSleepTime/4); 
> > +#endif
> > +	    }
> > +	}
> >      }
> >  
> >      //Signal the parent thread that we are done.
> >  -833,6 +851,7 
> >      }
> >  
> >      UNLOCK(m_mtxWriteListPlayStateLock);
> > +    HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_PushBits() writing %i bits",
> > (int)ulBufLen);
> >      _WriteBytes(pData, ulBufLen, lCount);
> >      LOCK(m_mtxWriteListPlayStateLock);
> >  
> >  -995,6 +1014,8 
> >      //grab the data and write it to the device.
> >      if( m_bUserWantsThreads )
> >      {
> > +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
> > event..."); 
> > +        m_pAvailableDataEvent->SignalEvent();
> >          return RA_AOE_NOERR;
> >      }
> >  #endif    
> > Index: pub/platform/unix/audUnix.h
> >
============================================================
=======
> > RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
> > retrieving revision 1.8
> > diff -u -r1.8 audUnix.h
> > --- pub/platform/unix/audUnix.h	6 Jul 2007
20:21:19 -0000	1.8
> > +++ pub/platform/unix/audUnix.h	28 Apr 2008
20:07:39 -0000
> >  -289,6 +289,7 
> >      IHXThread*	m_audioThread;
> >      HXBOOL      m_bUserWantsThreads;
> >      ULONG32	m_ulSleepTime;
> > +    IHXEvent*	m_pAvailableDataEvent;
> >  #endif    
> >      
> >    private:
> > 
> > 
> > 
> >
------------------------------------------------------------
------------
> > 
> > _______________________________________________
> > Audio-dev mailing list
> > Audio-devhelixcommunity.org
> > http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
> 

_______________________________________________
Audio-dev mailing list
Audio-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev

Re: CR: (Take 4) Remove polling inside UNIX audio thread
country flaguser name
United States
2008-04-29 12:34:36
Rusty Lynch wrote:
> When using ALSA we block while trying to write data to
the audio device
> if the audio device is full, while other
implementations are setup to do
> non-blocking writes.  We sleep on non-alsa systems to
keep from entering
> into a tight spin where we have incoming data
available, but the
> hardware is not ready to consume more data.

Ok, looks good then.

> 
> I suspect that it would be ideal for more UNIX systems
to start using
> blocking writes to the audio device, and remove the
need for a
> microsleep just like an we do for ALSA systems.

Yeah, for a later time I guess.
--greg.

> 
>     --rusty
> 
> On Tue, 2008-04-29 at 09:33 -0700, Greg Wright wrote:
>> Why do we only microsleep for non-ALSA drivers? Or,
what
>> is it about OSS/etc. that require the microsleep
while
>> ALSA does not?
>>
>> I like the idea of an event rather then polling,
>> overall I think this is a great change to add.
>>
>> --greg.
>>
>>
>> Rusty Lynch wrote:
>>> Description
>>> ----------------------------------
>>> The audio out class for UNIX is creating a
thread that continuously 
>>> attempts to read from the list of available
audio data buffers, and
>>> then use the device specific method for
writting that data to the audio
>>> device.
>>>
>>> This change will introduce a new IHXEvent for
letting the main thread
>>> signal the data writing thread when new data is
available for pushing to
>>> the audio device, instead of having the audio
thread do a bunch of small
>>> micro sleeps while it waits for some new data
to push.
>>>
>>> If data is available for writting to the
device, then a small sleep is
>>> still added for none ALSA based device, since
none ALSA devices will not
>>> block on write (making it possible for the
thread to spin until the
>>> audio device is ready to accept new data.)
>>>
>>> By doing this we remove a source of interrupts
that tend to drive
>>> the CPU into high C0 (full power mode)
residency.  This is especially
>>> true when on a MID device that has the ASound
prealloc buffer max'ed
>>> out, allowing large periods of time for the
original output audio thread
>>> to wait for new blocks of data.
>>>
>>> Files Modified
>>> ----------------------------------
>>> audio/device/platform/unix/audUnix.cpp
>>> audio/device/pub/platform/unix/audUnix.h
>>>
>>> Branches
>>> ---------------------------------
>>> HEAD, hxclient_3_1_0_atlas
>>>
>>> Index: platform/unix/audUnix.cpp
>>>
============================================================
=======
>>> RCS file:
/cvsroot/audio/device/platform/unix/audUnix.cpp,v
>>> retrieving revision 1.12
>>> diff -u -r1.12 audUnix.cpp
>>> --- platform/unix/audUnix.cpp	6 Jul 2007
20:21:16 -0000	1.12
>>> +++ platform/unix/audUnix.cpp	28 Apr 2008
20:07:39 -0000
>>>  -73,7 +73,8 
>>>  #include "hxprefs.h"
>>>  #endif 
>>>  
>>> -
>>> +#include "hxtlogutil.h"
>>> +#include "ihxtlogsystem.h"
>>>  
>>>  //-1 is usually considered to be no file
descriptor.
>>>  const int CAudioOutUNIX::NO_FILE_DESCRIPTOR =
-1;
>>>  -102,6 +103,7 
>>>      m_audioThread(NULL),
>>>      m_bUserWantsThreads(TRUE),
>>>      m_ulSleepTime(0),
>>> +    m_pAvailableDataEvent(NULL),
>>>  #endif
>>>      m_pRollbackBuffer(NULL)
>>>  {
>>>  -114,7 +116,6 
>>>      //Allco our write buffer list. Want to
throw from here? You will,
>>> like
>>>      //it or not.
>>>      m_pWriteList = new CHXSimpleList();
>>> -    
>>>  }
>>>  
>>>  void CAudioOutUNIX::_initAfterContext()
>>>  -142,6 +143,7 
>>>  	CreateInstanceCCF(CLSID_IHXMutex,
>>> (void**)&m_mtxWriteListPlayStateLock,
m_pContext);
>>>  	CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
>>> m_pContext);
>>>  	CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
>>> m_pContext);
>>> +	CreateInstanceCCF(CLSID_IHXEvent,
(void**)&m_pAvailableDataEvent,
>>> m_pContext);
>>>      }
>>>  #endif    
>>>  
>>>  -194,6 +196,7 
>>>          HX_RELEASE(
m_mtxWriteListPlayStateLock );
>>>          HX_RELEASE( m_mtxDeviceStateLock );
>>>          HX_RELEASE( m_audioThread );
>>> +        HX_RELEASE( m_pAvailableDataEvent );
>>>      }
>>>  #endif    
>>>  
>>>  -353,6 +356,8 
>>>      //Wait for it to do so and clean up.
>>>      if( m_bUserWantsThreads )
>>>      {
>>> +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
>>> event..."); 
>>> +       
m_pAvailableDataEvent->SignalEvent();
>>>          m_audioThread->Exit(0);
>>>      }
>>>      
>>>  -778,8 +783,21 
>>>         
that->m_mtxDeviceStateLock->Unlock();
>>>         
that->m_mtxWriteListPlayStateLock->Unlock();
>>>  
>>> -        //OK, sleep the amount of time it
takes to play 1/4 of the
>>> device's buffer.
>>> -        microsleep(that->m_ulSleepTime/4);

>>> +        if(bReadyToExit == FALSE) 
>>> +	{
>>> +	    if (that->m_pWriteList->GetCount()
== 0 || that->m_wState ==
>>> RA_AOS_OPEN_PAUSED)
>>> +	    {
>>> +	        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread() waiting for
>>> audio data..."); 
>>> +	       
that->m_pAvailableDataEvent->Wait(ALLFS);
>>> +            } 
>>> +            else
>>> +	    {
>>> +#if !defined(HELIX_FEATURE_ALSA)
>>> +	        // OK, sleep the amount of time it
takes to play 1/4 of the
>>> device's buffer.
>>> +	        microsleep(that->m_ulSleepTime/4);

>>> +#endif
>>> +	    }
>>> +	}
>>>      }
>>>  
>>>      //Signal the parent thread that we are
done.
>>>  -833,6 +851,7 
>>>      }
>>>  
>>>      UNLOCK(m_mtxWriteListPlayStateLock);
>>> +    HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_PushBits() writing %i bits",
>>> (int)ulBufLen);
>>>      _WriteBytes(pData, ulBufLen, lCount);
>>>      LOCK(m_mtxWriteListPlayStateLock);
>>>  
>>>  -995,6 +1014,8 
>>>      //grab the data and write it to the
device.
>>>      if( m_bUserWantsThreads )
>>>      {
>>> +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
>>> event..."); 
>>> +       
m_pAvailableDataEvent->SignalEvent();
>>>          return RA_AOE_NOERR;
>>>      }
>>>  #endif    
>>> Index: pub/platform/unix/audUnix.h
>>>
============================================================
=======
>>> RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
>>> retrieving revision 1.8
>>> diff -u -r1.8 audUnix.h
>>> --- pub/platform/unix/audUnix.h	6 Jul 2007
20:21:19 -0000	1.8
>>> +++ pub/platform/unix/audUnix.h	28 Apr 2008
20:07:39 -0000
>>>  -289,6 +289,7 
>>>      IHXThread*	m_audioThread;
>>>      HXBOOL      m_bUserWantsThreads;
>>>      ULONG32	m_ulSleepTime;
>>> +    IHXEvent*	m_pAvailableDataEvent;
>>>  #endif    
>>>      
>>>    private:
>>>
>>>
>>>
>>>
------------------------------------------------------------
------------
>>>
>>>
_______________________________________________
>>> Audio-dev mailing list
>>> Audio-devhelixcommunity.org
>>> http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
> 


_______________________________________________
Audio-dev mailing list
Audio-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev

Re: CR: (Take 4) Remove polling inside UNIX audio thread
user name
2008-04-29 12:53:59
Changes have been applied to HEAD and hxclient_3_1_0_atlas

On Tue, 2008-04-29 at 10:34 -0700, Greg Wright wrote:
> Rusty Lynch wrote:
> > When using ALSA we block while trying to write
data to the audio device
> > if the audio device is full, while other
implementations are setup to do
> > non-blocking writes.  We sleep on non-alsa systems
to keep from entering
> > into a tight spin where we have incoming data
available, but the
> > hardware is not ready to consume more data.
> 
> Ok, looks good then.
> 
> > 
> > I suspect that it would be ideal for more UNIX
systems to start using
> > blocking writes to the audio device, and remove
the need for a
> > microsleep just like an we do for ALSA systems.
> 
> Yeah, for a later time I guess.
> --greg.
> 
> > 
> >     --rusty
> > 
> > On Tue, 2008-04-29 at 09:33 -0700, Greg Wright
wrote:
> >> Why do we only microsleep for non-ALSA
drivers? Or, what
> >> is it about OSS/etc. that require the
microsleep while
> >> ALSA does not?
> >>
> >> I like the idea of an event rather then
polling,
> >> overall I think this is a great change to
add.
> >>
> >> --greg.
> >>
> >>
> >> Rusty Lynch wrote:
> >>> Description
> >>> ----------------------------------
> >>> The audio out class for UNIX is creating a
thread that continuously 
> >>> attempts to read from the list of
available audio data buffers, and
> >>> then use the device specific method for
writting that data to the audio
> >>> device.
> >>>
> >>> This change will introduce a new IHXEvent
for letting the main thread
> >>> signal the data writing thread when new
data is available for pushing to
> >>> the audio device, instead of having the
audio thread do a bunch of small
> >>> micro sleeps while it waits for some new
data to push.
> >>>
> >>> If data is available for writting to the
device, then a small sleep is
> >>> still added for none ALSA based device,
since none ALSA devices will not
> >>> block on write (making it possible for the
thread to spin until the
> >>> audio device is ready to accept new
data.)
> >>>
> >>> By doing this we remove a source of
interrupts that tend to drive
> >>> the CPU into high C0 (full power mode)
residency.  This is especially
> >>> true when on a MID device that has the
ASound prealloc buffer max'ed
> >>> out, allowing large periods of time for
the original output audio thread
> >>> to wait for new blocks of data.
> >>>
> >>> Files Modified
> >>> ----------------------------------
> >>> audio/device/platform/unix/audUnix.cpp
> >>> audio/device/pub/platform/unix/audUnix.h
> >>>
> >>> Branches
> >>> ---------------------------------
> >>> HEAD, hxclient_3_1_0_atlas
> >>>
> >>> Index: platform/unix/audUnix.cpp
> >>>
============================================================
=======
> >>> RCS file:
/cvsroot/audio/device/platform/unix/audUnix.cpp,v
> >>> retrieving revision 1.12
> >>> diff -u -r1.12 audUnix.cpp
> >>> --- platform/unix/audUnix.cpp	6 Jul 2007
20:21:16 -0000	1.12
> >>> +++ platform/unix/audUnix.cpp	28 Apr 2008
20:07:39 -0000
> >>>  -73,7 +73,8 
> >>>  #include "hxprefs.h"
> >>>  #endif 
> >>>  
> >>> -
> >>> +#include "hxtlogutil.h"
> >>> +#include "ihxtlogsystem.h"
> >>>  
> >>>  //-1 is usually considered to be no file
descriptor.
> >>>  const int
CAudioOutUNIX::NO_FILE_DESCRIPTOR = -1;
> >>>  -102,6 +103,7 
> >>>      m_audioThread(NULL),
> >>>      m_bUserWantsThreads(TRUE),
> >>>      m_ulSleepTime(0),
> >>> +    m_pAvailableDataEvent(NULL),
> >>>  #endif
> >>>      m_pRollbackBuffer(NULL)
> >>>  {
> >>>  -114,7 +116,6 
> >>>      //Allco our write buffer list. Want
to throw from here? You will,
> >>> like
> >>>      //it or not.
> >>>      m_pWriteList = new CHXSimpleList();
> >>> -    
> >>>  }
> >>>  
> >>>  void CAudioOutUNIX::_initAfterContext()
> >>>  -142,6 +143,7 
> >>>  	CreateInstanceCCF(CLSID_IHXMutex,
> >>> (void**)&m_mtxWriteListPlayStateLock,
m_pContext);
> >>>  	CreateInstanceCCF(CLSID_IHXMutex,
(void**)&m_mtxDeviceStateLock,
> >>> m_pContext);
> >>>  	CreateInstanceCCF(CLSID_IHXThread,
(void**)&m_audioThread,
> >>> m_pContext);
> >>> +	CreateInstanceCCF(CLSID_IHXEvent,
(void**)&m_pAvailableDataEvent,
> >>> m_pContext);
> >>>      }
> >>>  #endif    
> >>>  
> >>>  -194,6 +196,7 
> >>>          HX_RELEASE(
m_mtxWriteListPlayStateLock );
> >>>          HX_RELEASE( m_mtxDeviceStateLock
);
> >>>          HX_RELEASE( m_audioThread );
> >>> +        HX_RELEASE( m_pAvailableDataEvent
);
> >>>      }
> >>>  #endif    
> >>>  
> >>>  -353,6 +356,8 
> >>>      //Wait for it to do so and clean up.
> >>>      if( m_bUserWantsThreads )
> >>>      {
> >>> +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Close signaling
> >>> event..."); 
> >>> +       
m_pAvailableDataEvent->SignalEvent();
> >>>          m_audioThread->Exit(0);
> >>>      }
> >>>      
> >>>  -778,8 +783,21 
> >>>         
that->m_mtxDeviceStateLock->Unlock();
> >>>         
that->m_mtxWriteListPlayStateLock->Unlock();
> >>>  
> >>> -        //OK, sleep the amount of time it
takes to play 1/4 of the
> >>> device's buffer.
> >>> -       
microsleep(that->m_ulSleepTime/4); 
> >>> +        if(bReadyToExit == FALSE) 
> >>> +	{
> >>> +	    if
(that->m_pWriteList->GetCount() == 0 ||
that->m_wState ==
> >>> RA_AOS_OPEN_PAUSED)
> >>> +	    {
> >>> +	        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::AudioThread() waiting for
> >>> audio data..."); 
> >>> +	       
that->m_pAvailableDataEvent->Wait(ALLFS);
> >>> +            } 
> >>> +            else
> >>> +	    {
> >>> +#if !defined(HELIX_FEATURE_ALSA)
> >>> +	        // OK, sleep the amount of time
it takes to play 1/4 of the
> >>> device's buffer.
> >>> +	       
microsleep(that->m_ulSleepTime/4); 
> >>> +#endif
> >>> +	    }
> >>> +	}
> >>>      }
> >>>  
> >>>      //Signal the parent thread that we
are done.
> >>>  -833,6 +851,7 
> >>>      }
> >>>  
> >>>      UNLOCK(m_mtxWriteListPlayStateLock);
> >>> +    HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_PushBits() writing %i bits",
> >>> (int)ulBufLen);
> >>>      _WriteBytes(pData, ulBufLen,
lCount);
> >>>      LOCK(m_mtxWriteListPlayStateLock);
> >>>  
> >>>  -995,6 +1014,8 
> >>>      //grab the data and write it to the
device.
> >>>      if( m_bUserWantsThreads )
> >>>      {
> >>> +        HXLOGL4 (HXLOG_ADEV,
"CAudioUnixOUT::_Imp_Write signaling
> >>> event..."); 
> >>> +       
m_pAvailableDataEvent->SignalEvent();
> >>>          return RA_AOE_NOERR;
> >>>      }
> >>>  #endif    
> >>> Index: pub/platform/unix/audUnix.h
> >>>
============================================================
=======
> >>> RCS file:
/cvsroot/audio/device/pub/platform/unix/audUnix.h,v
> >>> retrieving revision 1.8
> >>> diff -u -r1.8 audUnix.h
> >>> --- pub/platform/unix/audUnix.h	6 Jul 2007
20:21:19 -0000	1.8
> >>> +++ pub/platform/unix/audUnix.h	28 Apr
2008 20:07:39 -0000
> >>>  -289,6 +289,7 
> >>>      IHXThread*	m_audioThread;
> >>>      HXBOOL      m_bUserWantsThreads;
> >>>      ULONG32	m_ulSleepTime;
> >>> +    IHXEvent*	m_pAvailableDataEvent;
> >>>  #endif    
> >>>      
> >>>    private:
> >>>
> >>>
> >>>
> >>>
------------------------------------------------------------
------------
> >>>
> >>>
_______________________________________________
> >>> Audio-dev mailing list
> >>> Audio-devhelixcommunity.org
> >>> http://lists.helixcommunity.org/mailman/listinfo/audio
-dev
> > 
> 

_______________________________________________
Audio-dev mailing list
Audio-devhelixcommunity.org
http://lists.helixcommunity.org/mailman/listinfo/audio
-dev

[1-5]

about | contact  Other archives ( Real Estate discussion Medical topics )