Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[dvdplayer] rewrite syncronization message to be more efficient

This new sync message will now wakeup directly on object release
to check situation. It should reduce any scheduling delay that
previous implementation had.
  • Loading branch information...
commit 9303d3c092dd0e0ad9c4522605a8fd38e0dfa6e9 1 parent 095624e
@elupus authored
View
79 xbmc/cores/dvdplayer/DVDMessage.cpp
@@ -24,35 +24,86 @@
#include "DVDDemuxers/DVDDemuxUtils.h"
#include "DVDStreamInfo.h"
#include "utils/TimeUtils.h"
+#include "utils/log.h"
+#include "threads/CriticalSection.h"
+#include "threads/Condition.h"
+#include "threads/SystemClock.h"
+#include "utils/MathUtils.h"
+class CDVDMsgGeneralSynchronizePriv
+{
+public:
+ CDVDMsgGeneralSynchronizePriv(DWORD timeout, DWORD sources)
@elupus Owner
elupus added a note
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
+ : timeout(timeout)
+ , sources(sources ? sources : SYNCSOURCE_ALL)
+ , reached(0)
+ {}
+ unsigned int sources;
+ unsigned int reached;
+ CCriticalSection section;
+ XbmcThreads::ConditionVariable condition;
+ XbmcThreads::EndTime timeout;
+};
/**
* CDVDMsgGeneralSynchronize --- GENERAL_SYNCRONIZR
*/
CDVDMsgGeneralSynchronize::CDVDMsgGeneralSynchronize(DWORD timeout, DWORD sources) : CDVDMsg(GENERAL_SYNCHRONIZE)
+ , m_p(new CDVDMsgGeneralSynchronizePriv(timeout, sources))
{
- if( sources )
- m_sources = sources;
- else
- m_sources = SYNCSOURCE_ALL;
+}
- m_objects = 0;
- m_timeout = timeout;
+CDVDMsgGeneralSynchronize::~CDVDMsgGeneralSynchronize()
+{
+ delete m_p;
}
-void CDVDMsgGeneralSynchronize::Wait(volatile bool *abort, DWORD source)
+bool CDVDMsgGeneralSynchronize::Wait(unsigned long milliseconds, DWORD source)
{
+ if(source == 0)
+ source = SYNCSOURCE_OWNER;
+
/* if we are not requested to wait on this object just return, reference count will be decremented */
- if (source && !(m_sources & source)) return;
+ if (!(m_p->sources & source))
+ return true;
+
+ CSingleLock lock(m_p->section);
- AtomicIncrement(&m_objects);
+ XbmcThreads::EndTime timeout(milliseconds);
- XbmcThreads::EndTime timeout(m_timeout);
+ m_p->reached |= source & m_p->sources;
- if (abort)
- while( m_objects < GetNrOfReferences() && !timeout.IsTimePast() && !(*abort)) Sleep(1);
- else
- while( m_objects < GetNrOfReferences() && !timeout.IsTimePast() ) Sleep(1);
+ while( (long)MathUtils::bitcount(m_p->reached) < GetNrOfReferences() )
+ {
+ milliseconds = std::min(m_p->timeout.MillisLeft(), timeout.MillisLeft());
+ if(m_p->condition.wait(lock, milliseconds))
+ continue;
+ if(m_p->timeout.IsTimePast())
+ return true; /* global timeout, we are done */
+ if(timeout.IsTimePast())
+ return false; /* request timeout, should be retried */
+ }
+ return true;
+}
+
+void CDVDMsgGeneralSynchronize::Wait(volatile bool *abort, DWORD source)
+{
+ while(!Wait(100, source))
+ {
+ if(abort && *abort)
+ return;
+ }
+}
+
+long CDVDMsgGeneralSynchronize::Release()
+{
+ CSingleLock lock(m_p->section);
+ long count = --m_refs;
+ m_p->condition.notifyAll();
+ lock.Leave();
+ if (count == 0)
+ delete this;
+ return count;
}
/**
View
11 xbmc/cores/dvdplayer/DVDMessage.h
@@ -147,20 +147,23 @@ class CDVDMsgGeneralResync : public CDVDMsg
#define SYNCSOURCE_AUDIO 0x00000001
#define SYNCSOURCE_VIDEO 0x00000002
#define SYNCSOURCE_SUB 0x00000004
-#define SYNCSOURCE_ALL (SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO | SYNCSOURCE_SUB)
+#define SYNCSOURCE_OWNER 0x80000000 /* only allowed for the constructor of the object */
+#define SYNCSOURCE_ALL (SYNCSOURCE_AUDIO | SYNCSOURCE_VIDEO | SYNCSOURCE_SUB | SYNCSOURCE_OWNER)
+class CDVDMsgGeneralSynchronizePriv;
class CDVDMsgGeneralSynchronize : public CDVDMsg
{
public:
CDVDMsgGeneralSynchronize(DWORD timeout, DWORD sources);
+ ~CDVDMsgGeneralSynchronize();
+ virtual long Release();
// waits until all threads waiting, released the object
// if abort is set somehow
+ bool Wait(unsigned long ms , DWORD source);
void Wait(volatile bool *abort, DWORD source);
private:
- DWORD m_sources;
- long m_objects;
- unsigned int m_timeout;
+ class CDVDMsgGeneralSynchronizePriv* m_p;
};
template <typename T>
View
8 xbmc/utils/MathUtils.h
@@ -208,6 +208,14 @@ namespace MathUtils
return (a < 0) ? -a : a;
}
+ inline unsigned bitcount(unsigned v)
+ {
+ unsigned c = 0;
+ for (c = 0; v; c++)
+ v &= v - 1; // clear the least significant bit set
+ return c;
+ }
+
inline void hack()
{
// stupid hack to keep compiler from dropping these
Please sign in to comment.
Something went wrong with that request. Please try again.