The Pedigree Project  0.1
RequestQueue.h
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #ifndef REQUEST_QUEUE_H
21 #define REQUEST_QUEUE_H
22 
23 #include "pedigree/kernel/compiler.h"
24 #include "pedigree/kernel/process/ConditionVariable.h"
25 #include "pedigree/kernel/process/Mutex.h"
26 #include "pedigree/kernel/processor/state_forward.h"
27 #include "pedigree/kernel/processor/types.h"
28 #include "pedigree/kernel/utilities/String.h"
29 #ifdef THREADS
30 #include "pedigree/kernel/machine/TimerHandler.h"
31 #endif
32 
33 class Thread;
34 
35 #define REQUEST_QUEUE_NUM_PRIORITIES 4
36 
42 {
43  friend class Thread;
44 
45 #ifdef THREADS
47  {
48  friend class RequestQueue;
49 
50  RequestQueueOverrunChecker() : m_LastQueueSize(0), m_Tick(0), queue(0)
51  {
52  }
53 
54  private:
55  virtual void timer(uint64_t delta, InterruptState &state);
56 
57  size_t m_LastQueueSize;
58  uint64_t m_Tick;
59 
60  RequestQueue *queue;
61  };
62 #endif
63 
64  public:
66  RequestQueue(const String &name);
67  virtual ~RequestQueue();
68 
69  // Action to perform when a duplicate request is found in the queue.
70  enum ActionOnDuplicate
71  {
72  // Block waiting for it to complete, and return its return value.
73  Block,
74  // Ignore the duplicate and create a new request.
75  NewRequest,
76  // Return immediately, ignoring the result from the request.
77  ReturnImmediately
78  };
79 
81  virtual void initialise();
82 
84  virtual void destroy();
85 
89  MUST_USE_RESULT uint64_t addRequest(
90  size_t priority, uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0,
91  uint64_t p4 = 0, uint64_t p5 = 0, uint64_t p6 = 0, uint64_t p7 = 0,
92  uint64_t p8 = 0);
93 
96  MUST_USE_RESULT uint64_t addRequest(
97  size_t priority, ActionOnDuplicate action, uint64_t p1 = 0,
98  uint64_t p2 = 0, uint64_t p3 = 0, uint64_t p4 = 0, uint64_t p5 = 0,
99  uint64_t p6 = 0, uint64_t p7 = 0, uint64_t p8 = 0);
100 
102  uint64_t addAsyncRequest(
103  size_t priority, uint64_t p1 = 0, uint64_t p2 = 0, uint64_t p3 = 0,
104  uint64_t p4 = 0, uint64_t p5 = 0, uint64_t p6 = 0, uint64_t p7 = 0,
105  uint64_t p8 = 0);
106 
110  void halt();
111 
115  void resume();
116 
117  protected:
121  virtual uint64_t executeRequest(
122  uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5,
123  uint64_t p6, uint64_t p7, uint64_t p8) = 0;
124 
125  RequestQueue(const RequestQueue &);
126  void operator=(const RequestQueue &);
127 
129  class Request
130  {
131  public:
132  Request()
133  : p1(0), p2(0), p3(0), p4(0), p5(0), p6(0), p7(0), p8(0), ret(0),
134 #ifdef THREADS
135  mutex(true), pThread(0),
136 #endif
137  bReject(false), bCompleted(false), next(0), refcnt(0), owner(0),
138  priority(0)
139  {
140  }
141  ~Request()
142  {
143  }
144  uint64_t p1, p2, p3, p4, p5, p6, p7, p8;
145  uint64_t ret;
146 #ifdef THREADS
147  Mutex mutex;
148  Thread *pThread;
149 #endif
150  bool bReject;
151  bool bCompleted;
152  Request *next;
153  size_t refcnt;
154  RequestQueue *owner;
155  size_t priority;
156 
157  private:
158  Request(const Request &);
159  void operator=(const Request &);
160  };
161 
166  virtual bool compareRequests(const Request &a, const Request &b)
167  {
168  return false;
169  }
170 
175  bool isRequestValid(const Request *r);
176 
178  static int trampoline(void *p);
179 
181  static int doAsync(void *p);
182 
184  int work();
185 
187  Request *getNextRequest();
188 
190  Request *m_pRequestQueue[REQUEST_QUEUE_NUM_PRIORITIES];
191 
193  volatile bool m_Stop;
194 
195 #ifdef THREADS
196 
198 
201 
204 
205  Thread *m_pThread;
206 
207  bool m_Halted;
208  Mutex m_HaltAcknowledged;
209 
210  RequestQueueOverrunChecker m_OverrunChecker;
211 #endif
212 
213  size_t m_nMaxAsyncRequests;
214  size_t m_nAsyncRequests;
215 
216  size_t m_nTotalRequests;
217 
218  String m_Name;
219 };
220 
221 #endif
volatile bool m_Stop
Definition: RequestQueue.h:193
virtual bool compareRequests(const Request &a, const Request &b)
Definition: RequestQueue.h:166
uint64_t addAsyncRequest(size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0)
Definition: Mutex.h:58
Definition: String.h:49
virtual void destroy()
Definition: RequestQueue.cc:85
Mutex m_RequestQueueMutex
Definition: RequestQueue.h:197
virtual uint64_t executeRequest(uint64_t p1, uint64_t p2, uint64_t p3, uint64_t p4, uint64_t p5, uint64_t p6, uint64_t p7, uint64_t p8)=0
ConditionVariable m_RequestQueueCondition
Definition: RequestQueue.h:200
Definition: Thread.h:54
ConditionVariable m_AsyncRequestQueueCondition
Definition: RequestQueue.h:203
virtual void initialise()
Definition: RequestQueue.cc:55
MUST_USE_RESULT uint64_t addRequest(size_t priority, uint64_t p1=0, uint64_t p2=0, uint64_t p3=0, uint64_t p4=0, uint64_t p5=0, uint64_t p6=0, uint64_t p7=0, uint64_t p8=0)
RequestQueue(const String &name)
Definition: RequestQueue.cc:35