summaryrefslogtreecommitdiff
path: root/gfx/2d/JobScheduler_posix.h
blob: cc1bef84efecd8a67f3f94df567818e10ebb859f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* -*- 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/. */

#ifndef WIN32
#ifndef MOZILLA_GFX_TASKSCHEDULER_POSIX_H_
#define MOZILLA_GFX_TASKSCHEDULER_POSIX_H_

#include <string>
#include <vector>
#include <list>
#include <pthread.h>
#include <stdint.h>
#include <stdio.h>

#include "mozilla/RefPtr.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/gfx/CriticalSection.h"
#include "mozilla/RefCounted.h"

namespace mozilla {
namespace gfx {

class Job;
class PosixCondVar;
class WorkerThread;

// posix platforms only!
class PosixCondVar {
public:
  PosixCondVar() {
    DebugOnly<int> err = pthread_cond_init(&mCond, nullptr);
    MOZ_ASSERT(!err);
  }

  ~PosixCondVar() {
    DebugOnly<int> err = pthread_cond_destroy(&mCond);
    MOZ_ASSERT(!err);
  }

  void Wait(CriticalSection* aMutex) {
    DebugOnly<int> err = pthread_cond_wait(&mCond, &aMutex->mMutex);
    MOZ_ASSERT(!err);
  }

  void Broadcast() {
    DebugOnly<int> err = pthread_cond_broadcast(&mCond);
    MOZ_ASSERT(!err);
  }

protected:
  pthread_cond_t mCond;
};


/// A simple and naive multithreaded task queue
///
/// The public interface of this class must remain identical to its equivalent
/// in JobScheduler_win32.h
class MultiThreadedJobQueue {
public:
  enum AccessType {
    BLOCKING,
    NON_BLOCKING
  };

  // Producer thread
  MultiThreadedJobQueue();

  // Producer thread
  ~MultiThreadedJobQueue();

  // Worker threads
  bool WaitForJob(Job*& aOutJob);

  // Any thread
  bool PopJob(Job*& aOutJob, AccessType aAccess);

  // Any threads
  void SubmitJob(Job* aJob);

  // Producer thread
  void ShutDown();

  // Any thread
  size_t NumJobs();

  // Any thread
  bool IsEmpty();

  // Producer thread
  void RegisterThread();

  // Worker threads
  void UnregisterThread();

protected:

  std::list<Job*> mJobs;
  CriticalSection mMutex;
  PosixCondVar mAvailableCondvar;
  PosixCondVar mShutdownCondvar;
  int32_t mThreadsCount;
  bool mShuttingDown;

  friend class WorkerThread;
};

/// An object that a thread can synchronously wait on.
/// Usually set by a SetEventJob.
class EventObject : public external::AtomicRefCounted<EventObject>
{
public:
  MOZ_DECLARE_REFCOUNTED_TYPENAME(EventObject)

  EventObject();

  ~EventObject();

  /// Synchronously wait until the event is set.
  void Wait();

  /// Return true if the event is set, without blocking.
  bool Peak();

  /// Set the event.
  void Set();

protected:
  CriticalSection mMutex;
  PosixCondVar mCond;
  bool mIsSet;
};

} // namespace
} // namespace

#include "JobScheduler.h"

#endif
#endif