libroot/posix/stdio: Remove unused portions.
[haiku.git] / src / system / kernel / scheduler / RunQueue.h
blobaae6482195ba6bab762ade8beed01ed5483bac5a
1 /*
2 * Copyright 2013 Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Paweł Dziepak, pdziepak@quarnos.org
7 */
8 #ifndef RUN_QUEUE_H
9 #define RUN_QUEUE_H
12 #include <util/Heap.h>
14 #include "scheduler_profiler.h"
17 template<typename Element>
18 struct RunQueueLink {
19 RunQueueLink();
21 unsigned int fPriority;
22 Element* fPrevious;
23 Element* fNext;
26 template<typename Element>
27 class RunQueueLinkImpl {
28 public:
29 inline RunQueueLink<Element>* GetRunQueueLink();
31 private:
32 RunQueueLink<Element> fRunQueueLink;
35 template<typename Element>
36 class RunQueueStandardGetLink {
37 private:
38 typedef RunQueueLink<Element> Link;
40 public:
41 inline Link* operator()(Element* element) const;
44 template<typename Element, RunQueueLink<Element> Element::*LinkMember>
45 class RunQueueMemberGetLink {
46 private:
47 typedef RunQueueLink<Element> Link;
49 public:
50 inline Link* operator()(Element* element) const;
53 #define RUN_QUEUE_TEMPLATE_LIST \
54 template<typename Element, unsigned int MaxPriority, typename GetLink>
55 #define RUN_QUEUE_CLASS_NAME RunQueue<Element, MaxPriority, GetLink>
57 template<typename Element, unsigned int MaxPriority,
58 typename GetLink = RunQueueStandardGetLink<Element> >
59 class RunQueue {
60 public:
61 class ConstIterator {
62 public:
63 ConstIterator();
64 ConstIterator(const RunQueue<Element,
65 MaxPriority, GetLink>* list);
67 inline ConstIterator& operator=(const ConstIterator& other);
69 bool HasNext() const;
70 Element* Next();
72 void Rewind();
74 private:
75 inline void _FindNextPriority();
77 const RUN_QUEUE_CLASS_NAME* fList;
78 unsigned int fPriority;
79 Element* fNext;
81 static GetLink sGetLink;
84 RunQueue();
86 inline status_t GetInitStatus();
88 inline Element* PeekMaximum() const;
90 inline void PushFront(Element* element, unsigned int priority);
91 inline void PushBack(Element* elementt, unsigned int priority);
93 inline void Remove(Element* element);
95 inline Element* GetHead(unsigned int priority) const;
97 inline ConstIterator GetConstIterator() const;
99 private:
100 struct PriorityEntry : public HeapLinkImpl<PriorityEntry, unsigned int>
104 typedef Heap<PriorityEntry, unsigned int, HeapGreaterCompare<unsigned int> >
105 PriorityHeap;
107 status_t fInitStatus;
109 PriorityEntry fPriorityEntries[MaxPriority + 1];
110 PriorityHeap fPriorityHeap;
112 Element* fHeads[MaxPriority + 1];
113 Element* fTails[MaxPriority + 1];
115 static GetLink sGetLink;
119 template<typename Element>
120 RunQueueLink<Element>::RunQueueLink()
122 fPrevious(NULL),
123 fNext(NULL)
128 template<typename Element>
129 RunQueueLink<Element>*
130 RunQueueLinkImpl<Element>::GetRunQueueLink()
132 return &fRunQueueLink;
136 template<typename Element>
137 RunQueueLink<Element>*
138 RunQueueStandardGetLink<Element>::operator()(Element* element) const
140 return element->GetRunQueueLink();
144 template<typename Element, RunQueueLink<Element> Element::*LinkMember>
145 RunQueueLink<Element>*
146 RunQueueMemberGetLink<Element, LinkMember>::operator()(Element* element) const
148 return &(element->*LinkMember);
152 RUN_QUEUE_TEMPLATE_LIST
153 RUN_QUEUE_CLASS_NAME::ConstIterator::ConstIterator()
155 fList(NULL)
160 RUN_QUEUE_TEMPLATE_LIST
161 RUN_QUEUE_CLASS_NAME::ConstIterator::ConstIterator(const RunQueue<Element,
162 MaxPriority, GetLink>* list)
164 fList(list)
166 Rewind();
170 RUN_QUEUE_TEMPLATE_LIST
171 typename RUN_QUEUE_CLASS_NAME::ConstIterator&
172 RUN_QUEUE_CLASS_NAME::ConstIterator::operator=(const ConstIterator& other)
174 fList = other.fList;
175 fPriority = other.fPriority;
176 fNext = other.fNext;
178 return *this;
182 RUN_QUEUE_TEMPLATE_LIST
183 bool
184 RUN_QUEUE_CLASS_NAME::ConstIterator::HasNext() const
186 return fNext != NULL;
190 RUN_QUEUE_TEMPLATE_LIST
191 Element*
192 RUN_QUEUE_CLASS_NAME::ConstIterator::Next()
194 ASSERT(HasNext());
196 Element* current = fNext;
197 RunQueueLink<Element>* link = sGetLink(fNext);
199 fNext = link->fNext;
200 if (fNext == NULL)
201 _FindNextPriority();
203 return current;
207 RUN_QUEUE_TEMPLATE_LIST
208 void
209 RUN_QUEUE_CLASS_NAME::ConstIterator::Rewind()
211 ASSERT(fList != NULL);
213 fPriority = MaxPriority;
214 fNext = fList->GetHead(fPriority);
215 if (fNext == NULL)
216 _FindNextPriority();
220 RUN_QUEUE_TEMPLATE_LIST
221 void
222 RUN_QUEUE_CLASS_NAME::ConstIterator::_FindNextPriority()
224 ASSERT(fList != NULL);
226 while (fPriority-- > 0) {
227 fNext = fList->GetHead(fPriority);
228 if (fNext != NULL)
229 break;
234 RUN_QUEUE_TEMPLATE_LIST
235 RUN_QUEUE_CLASS_NAME::RunQueue()
237 fInitStatus(B_OK),
238 fPriorityHeap(MaxPriority + 1)
240 memset(fHeads, 0, sizeof(fHeads));
241 memset(fTails, 0, sizeof(fTails));
245 RUN_QUEUE_TEMPLATE_LIST
246 status_t
247 RUN_QUEUE_CLASS_NAME::GetInitStatus()
249 return fInitStatus;
253 RUN_QUEUE_TEMPLATE_LIST
254 Element*
255 RUN_QUEUE_CLASS_NAME::PeekMaximum() const
257 SCHEDULER_ENTER_FUNCTION();
259 PriorityEntry* maxPriority = fPriorityHeap.PeekRoot();
260 if (maxPriority == NULL)
261 return NULL;
262 unsigned int priority = PriorityHeap::GetKey(maxPriority);
264 ASSERT(priority <= MaxPriority);
265 ASSERT(fHeads[priority] != NULL);
267 Element* element = fHeads[priority];
269 ASSERT(sGetLink(element)->fPriority == priority);
270 ASSERT(fTails[priority] != NULL);
271 ASSERT(sGetLink(element)->fPrevious == NULL);
273 return element;
277 RUN_QUEUE_TEMPLATE_LIST
278 void
279 RUN_QUEUE_CLASS_NAME::PushFront(Element* element,
280 unsigned int priority)
282 SCHEDULER_ENTER_FUNCTION();
284 ASSERT(priority <= MaxPriority);
286 RunQueueLink<Element>* elementLink = sGetLink(element);
288 ASSERT(elementLink->fPrevious == NULL);
289 ASSERT(elementLink->fNext == NULL);
291 ASSERT((fHeads[priority] == NULL && fTails[priority] == NULL)
292 || (fHeads[priority] != NULL && fTails[priority] != NULL));
294 elementLink->fPriority = priority;
295 elementLink->fNext = fHeads[priority];
296 if (fHeads[priority] != NULL)
297 sGetLink(fHeads[priority])->fPrevious = element;
298 else {
299 fTails[priority] = element;
300 fPriorityHeap.Insert(&fPriorityEntries[priority], priority);
302 fHeads[priority] = element;
306 RUN_QUEUE_TEMPLATE_LIST
307 void
308 RUN_QUEUE_CLASS_NAME::PushBack(Element* element,
309 unsigned int priority)
311 SCHEDULER_ENTER_FUNCTION();
313 ASSERT(priority <= MaxPriority);
315 RunQueueLink<Element>* elementLink = sGetLink(element);
317 ASSERT(elementLink->fPrevious == NULL);
318 ASSERT(elementLink->fNext == NULL);
320 ASSERT((fHeads[priority] == NULL && fTails[priority] == NULL)
321 || (fHeads[priority] != NULL && fTails[priority] != NULL));
323 elementLink->fPriority = priority;
324 elementLink->fPrevious = fTails[priority];
325 if (fTails[priority] != NULL)
326 sGetLink(fTails[priority])->fNext = element;
327 else {
328 fHeads[priority] = element;
329 fPriorityHeap.Insert(&fPriorityEntries[priority], priority);
331 fTails[priority] = element;
335 RUN_QUEUE_TEMPLATE_LIST
336 void
337 RUN_QUEUE_CLASS_NAME::Remove(Element* element)
339 SCHEDULER_ENTER_FUNCTION();
341 RunQueueLink<Element>* elementLink = sGetLink(element);
342 unsigned int priority = elementLink->fPriority;
344 ASSERT(elementLink->fPrevious != NULL || fHeads[priority] == element);
345 ASSERT(elementLink->fNext != NULL || fTails[priority] == element);
347 if (elementLink->fPrevious != NULL)
348 sGetLink(elementLink->fPrevious)->fNext = elementLink->fNext;
349 else
350 fHeads[priority] = elementLink->fNext;
351 if (elementLink->fNext != NULL)
352 sGetLink(elementLink->fNext)->fPrevious = elementLink->fPrevious;
353 else
354 fTails[priority] = elementLink->fPrevious;
356 ASSERT((fHeads[priority] == NULL && fTails[priority] == NULL)
357 || (fHeads[priority] != NULL && fTails[priority] != NULL));
359 if (fHeads[priority] == NULL) {
360 fPriorityHeap.ModifyKey(&fPriorityEntries[priority], MaxPriority + 1);
361 ASSERT(fPriorityHeap.PeekRoot() == &fPriorityEntries[priority]);
362 fPriorityHeap.RemoveRoot();
365 elementLink->fPrevious = NULL;
366 elementLink->fNext = NULL;
370 RUN_QUEUE_TEMPLATE_LIST
371 Element*
372 RUN_QUEUE_CLASS_NAME::GetHead(unsigned int priority) const
374 SCHEDULER_ENTER_FUNCTION();
376 ASSERT(priority <= MaxPriority);
377 return fHeads[priority];
381 RUN_QUEUE_TEMPLATE_LIST
382 typename RUN_QUEUE_CLASS_NAME::ConstIterator
383 RUN_QUEUE_CLASS_NAME::GetConstIterator() const
385 return ConstIterator(this);
389 RUN_QUEUE_TEMPLATE_LIST
390 GetLink RUN_QUEUE_CLASS_NAME::sGetLink;
392 RUN_QUEUE_TEMPLATE_LIST
393 GetLink RUN_QUEUE_CLASS_NAME::ConstIterator::sGetLink;
396 #endif // RUN_QUEUE_H