summaryrefslogtreecommitdiffstats
path: root/gfx/2d/JobScheduler_posix.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/2d/JobScheduler_posix.cpp')
-rw-r--r--gfx/2d/JobScheduler_posix.cpp194
1 files changed, 194 insertions, 0 deletions
diff --git a/gfx/2d/JobScheduler_posix.cpp b/gfx/2d/JobScheduler_posix.cpp
new file mode 100644
index 000000000..e41388f21
--- /dev/null
+++ b/gfx/2d/JobScheduler_posix.cpp
@@ -0,0 +1,194 @@
+/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "JobScheduler.h"
+#include "mozilla/gfx/Logging.h"
+
+using namespace std;
+
+namespace mozilla {
+namespace gfx {
+
+void* ThreadCallback(void* threadData);
+
+class WorkerThreadPosix : public WorkerThread {
+public:
+ explicit WorkerThreadPosix(MultiThreadedJobQueue* aJobQueue)
+ : WorkerThread(aJobQueue)
+ {
+ pthread_create(&mThread, nullptr, ThreadCallback, static_cast<WorkerThread*>(this));
+ }
+
+ ~WorkerThreadPosix()
+ {
+ pthread_join(mThread, nullptr);
+ }
+
+ virtual void SetName(const char*) override
+ {
+// XXX - temporarily disabled, see bug 1209039
+//
+// // Call this from the thread itself because of Mac.
+//#ifdef XP_MACOSX
+// pthread_setname_np(aName);
+//#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
+// pthread_set_name_np(mThread, aName);
+//#elif defined(__NetBSD__)
+// pthread_setname_np(mThread, "%s", (void*)aName);
+//#else
+// pthread_setname_np(mThread, aName);
+//#endif
+ }
+
+protected:
+ pthread_t mThread;
+};
+
+void* ThreadCallback(void* threadData)
+{
+ WorkerThread* thread = static_cast<WorkerThread*>(threadData);
+ thread->Run();
+ return nullptr;
+}
+
+WorkerThread*
+WorkerThread::Create(MultiThreadedJobQueue* aJobQueue)
+{
+ return new WorkerThreadPosix(aJobQueue);
+}
+
+MultiThreadedJobQueue::MultiThreadedJobQueue()
+: mThreadsCount(0)
+, mShuttingDown(false)
+{}
+
+MultiThreadedJobQueue::~MultiThreadedJobQueue()
+{
+ MOZ_ASSERT(mJobs.empty());
+}
+
+bool
+MultiThreadedJobQueue::WaitForJob(Job*& aOutJob)
+{
+ return PopJob(aOutJob, BLOCKING);
+}
+
+bool
+MultiThreadedJobQueue::PopJob(Job*& aOutJobs, AccessType aAccess)
+{
+ for (;;) {
+ CriticalSectionAutoEnter lock(&mMutex);
+
+ while (aAccess == BLOCKING && !mShuttingDown && mJobs.empty()) {
+ mAvailableCondvar.Wait(&mMutex);
+ }
+
+ if (mShuttingDown) {
+ return false;
+ }
+
+ if (mJobs.empty()) {
+ if (aAccess == NON_BLOCKING) {
+ return false;
+ }
+ continue;
+ }
+
+ Job* task = mJobs.front();
+ MOZ_ASSERT(task);
+
+ mJobs.pop_front();
+
+ aOutJobs = task;
+ return true;
+ }
+}
+
+void
+MultiThreadedJobQueue::SubmitJob(Job* aJobs)
+{
+ MOZ_ASSERT(aJobs);
+ CriticalSectionAutoEnter lock(&mMutex);
+ mJobs.push_back(aJobs);
+ mAvailableCondvar.Broadcast();
+}
+
+size_t
+MultiThreadedJobQueue::NumJobs()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ return mJobs.size();
+}
+
+bool
+MultiThreadedJobQueue::IsEmpty()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ return mJobs.empty();
+}
+
+void
+MultiThreadedJobQueue::ShutDown()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ mShuttingDown = true;
+ while (mThreadsCount) {
+ mAvailableCondvar.Broadcast();
+ mShutdownCondvar.Wait(&mMutex);
+ }
+}
+
+void
+MultiThreadedJobQueue::RegisterThread()
+{
+ mThreadsCount += 1;
+}
+
+void
+MultiThreadedJobQueue::UnregisterThread()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ mThreadsCount -= 1;
+ if (mThreadsCount == 0) {
+ mShutdownCondvar.Broadcast();
+ }
+}
+
+EventObject::EventObject()
+: mIsSet(false)
+{}
+
+EventObject::~EventObject()
+{}
+
+bool
+EventObject::Peak()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ return mIsSet;
+}
+
+void
+EventObject::Set()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ if (!mIsSet) {
+ mIsSet = true;
+ mCond.Broadcast();
+ }
+}
+
+void
+EventObject::Wait()
+{
+ CriticalSectionAutoEnter lock(&mMutex);
+ if (mIsSet) {
+ return;
+ }
+ mCond.Wait(&mMutex);
+}
+
+} // namespce
+} // namespce