Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/gfx/2d/JobScheduler_posix.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
3
/* This Source Code Form is subject to the terms of the Mozilla Public
4
 * License, v. 2.0. If a copy of the MPL was not distributed with this
5
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6
7
#include "JobScheduler.h"
8
#include "mozilla/gfx/Logging.h"
9
10
using namespace std;
11
12
namespace mozilla {
13
namespace gfx {
14
15
void* ThreadCallback(void* threadData);
16
17
class WorkerThreadPosix : public WorkerThread {
18
public:
19
  explicit WorkerThreadPosix(MultiThreadedJobQueue* aJobQueue)
20
  : WorkerThread(aJobQueue)
21
0
  {
22
0
    pthread_create(&mThread, nullptr, ThreadCallback, static_cast<WorkerThread*>(this));
23
0
  }
24
25
  ~WorkerThreadPosix() override
26
0
  {
27
0
    pthread_join(mThread, nullptr);
28
0
  }
29
30
  void SetName(const char*) override
31
0
  {
32
0
// XXX - temporarily disabled, see bug 1209039
33
0
//
34
0
//    // Call this from the thread itself because of Mac.
35
0
//#ifdef XP_MACOSX
36
0
//    pthread_setname_np(aName);
37
0
//#elif defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__)
38
0
//    pthread_set_name_np(mThread, aName);
39
0
//#elif defined(__NetBSD__)
40
0
//    pthread_setname_np(mThread, "%s", (void*)aName);
41
0
//#else
42
0
//    pthread_setname_np(mThread, aName);
43
0
//#endif
44
0
  }
45
46
protected:
47
  pthread_t mThread;
48
};
49
50
void* ThreadCallback(void* threadData)
51
0
{
52
0
  WorkerThread* thread = static_cast<WorkerThread*>(threadData);
53
0
  thread->Run();
54
0
  return nullptr;
55
0
}
56
57
WorkerThread*
58
WorkerThread::Create(MultiThreadedJobQueue* aJobQueue)
59
0
{
60
0
  return new WorkerThreadPosix(aJobQueue);
61
0
}
62
63
MultiThreadedJobQueue::MultiThreadedJobQueue()
64
: mThreadsCount(0)
65
, mShuttingDown(false)
66
0
{}
67
68
MultiThreadedJobQueue::~MultiThreadedJobQueue()
69
0
{
70
0
  MOZ_ASSERT(mJobs.empty());
71
0
}
72
73
bool
74
MultiThreadedJobQueue::WaitForJob(Job*& aOutJob)
75
0
{
76
0
  return PopJob(aOutJob, BLOCKING);
77
0
}
78
79
bool
80
MultiThreadedJobQueue::PopJob(Job*& aOutJobs, AccessType aAccess)
81
0
{
82
0
  for (;;) {
83
0
    CriticalSectionAutoEnter lock(&mMutex);
84
0
85
0
    while (aAccess == BLOCKING && !mShuttingDown && mJobs.empty()) {
86
0
      mAvailableCondvar.Wait(&mMutex);
87
0
    }
88
0
89
0
    if (mShuttingDown) {
90
0
      return false;
91
0
    }
92
0
93
0
    if (mJobs.empty()) {
94
0
      if (aAccess == NON_BLOCKING) {
95
0
        return false;
96
0
      }
97
0
      continue;
98
0
    }
99
0
100
0
    Job* task = mJobs.front();
101
0
    MOZ_ASSERT(task);
102
0
103
0
    mJobs.pop_front();
104
0
105
0
    aOutJobs = task;
106
0
    return true;
107
0
  }
108
0
}
109
110
void
111
MultiThreadedJobQueue::SubmitJob(Job* aJobs)
112
0
{
113
0
  MOZ_ASSERT(aJobs);
114
0
  CriticalSectionAutoEnter lock(&mMutex);
115
0
  mJobs.push_back(aJobs);
116
0
  mAvailableCondvar.Broadcast();
117
0
}
118
119
size_t
120
MultiThreadedJobQueue::NumJobs()
121
0
{
122
0
  CriticalSectionAutoEnter lock(&mMutex);
123
0
  return mJobs.size();
124
0
}
125
126
bool
127
MultiThreadedJobQueue::IsEmpty()
128
0
{
129
0
  CriticalSectionAutoEnter lock(&mMutex);
130
0
  return mJobs.empty();
131
0
}
132
133
void
134
MultiThreadedJobQueue::ShutDown()
135
0
{
136
0
  CriticalSectionAutoEnter lock(&mMutex);
137
0
  mShuttingDown = true;
138
0
  while (mThreadsCount) {
139
0
    mAvailableCondvar.Broadcast();
140
0
    mShutdownCondvar.Wait(&mMutex);
141
0
  }
142
0
}
143
144
void
145
MultiThreadedJobQueue::RegisterThread()
146
0
{
147
0
  mThreadsCount += 1;
148
0
}
149
150
void
151
MultiThreadedJobQueue::UnregisterThread()
152
0
{
153
0
  CriticalSectionAutoEnter lock(&mMutex);
154
0
  mThreadsCount -= 1;
155
0
  if (mThreadsCount == 0) {
156
0
    mShutdownCondvar.Broadcast();
157
0
  }
158
0
}
159
160
EventObject::EventObject()
161
: mIsSet(false)
162
0
{}
163
164
0
EventObject::~EventObject() = default;
165
166
bool
167
EventObject::Peak()
168
0
{
169
0
  CriticalSectionAutoEnter lock(&mMutex);
170
0
  return mIsSet;
171
0
}
172
173
void
174
EventObject::Set()
175
0
{
176
0
  CriticalSectionAutoEnter lock(&mMutex);
177
0
  if (!mIsSet) {
178
0
    mIsSet = true;
179
0
    mCond.Broadcast();
180
0
  }
181
0
}
182
183
void
184
EventObject::Wait()
185
0
{
186
0
  CriticalSectionAutoEnter lock(&mMutex);
187
0
  if (mIsSet) {
188
0
    return;
189
0
  }
190
0
  mCond.Wait(&mMutex);
191
0
}
192
193
} // namespce
194
} // namespce