2 * Copyright 2010, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
6 * Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
7 * Distributed under the terms of the NewOS License.
9 #ifndef VM_PAGE_QUEUE_H
10 #define VM_PAGE_QUEUE_H
13 #include <util/DoublyLinkedList.h>
17 #include <util/AutoLock.h>
18 #include <vm/vm_types.h>
23 typedef DoublyLinkedList
<vm_page
,
24 DoublyLinkedListMemberGetLink
<vm_page
, &vm_page::queue_link
> > PageList
;
25 typedef PageList::ConstIterator Iterator
;
28 void Init(const char* name
);
30 const char* Name() const { return fName
; }
32 inline void Append(vm_page
* page
);
33 inline void Prepend(vm_page
* page
);
34 inline void InsertAfter(vm_page
* insertAfter
,
36 inline void Remove(vm_page
* page
);
37 inline vm_page
* RemoveHead();
38 inline void Requeue(vm_page
* page
, bool tail
);
40 inline void AppendUnlocked(vm_page
* page
);
41 inline void AppendUnlocked(PageList
& pages
, uint32 count
);
42 inline void PrependUnlocked(vm_page
* page
);
43 inline void RemoveUnlocked(vm_page
* page
);
44 inline vm_page
* RemoveHeadUnlocked();
45 inline void RequeueUnlocked(vm_page
* page
, bool tail
);
47 inline vm_page
* Head() const;
48 inline vm_page
* Tail() const;
49 inline vm_page
* Previous(vm_page
* page
) const;
50 inline vm_page
* Next(vm_page
* page
) const;
52 inline phys_addr_t
Count() const { return fCount
; }
54 inline Iterator
GetIterator() const;
56 inline spinlock
& GetLock() { return fLock
; }
66 // #pragma mark - VMPageQueue
70 VMPageQueue::Append(vm_page
* page
)
73 if (page
->queue
!= NULL
) {
74 panic("%p->VMPageQueue::Append(page: %p): page thinks it is "
75 "already in queue %p", this, page
, page
->queue
);
77 #endif // DEBUG_PAGE_QUEUE
89 VMPageQueue::Prepend(vm_page
* page
)
92 if (page
->queue
!= NULL
) {
93 panic("%p->VMPageQueue::Prepend(page: %p): page thinks it is "
94 "already in queue %p", this, page
, page
->queue
);
96 #endif // DEBUG_PAGE_QUEUE
98 fPages
.Add(page
, false);
108 VMPageQueue::InsertAfter(vm_page
* insertAfter
, vm_page
* page
)
111 if (page
->queue
!= NULL
) {
112 panic("%p->VMPageQueue::InsertAfter(page: %p): page thinks it is "
113 "already in queue %p", this, page
, page
->queue
);
115 #endif // DEBUG_PAGE_QUEUE
117 fPages
.InsertAfter(insertAfter
, page
);
127 VMPageQueue::Remove(vm_page
* page
)
130 if (page
->queue
!= this) {
131 panic("%p->VMPageQueue::Remove(page: %p): page thinks it "
132 "is in queue %p", this, page
, page
->queue
);
134 #endif // DEBUG_PAGE_QUEUE
146 VMPageQueue::RemoveHead()
148 vm_page
* page
= fPages
.RemoveHead();
153 if (page
->queue
!= this) {
154 panic("%p->VMPageQueue::RemoveHead(): page %p thinks it is in "
155 "queue %p", this, page
, page
->queue
);
159 #endif // DEBUG_PAGE_QUEUE
167 VMPageQueue::Requeue(vm_page
* page
, bool tail
)
170 if (page
->queue
!= this) {
171 panic("%p->VMPageQueue::Requeue(): page %p thinks it is in "
172 "queue %p", this, page
, page
->queue
);
177 fPages
.Add(page
, tail
);
182 VMPageQueue::AppendUnlocked(vm_page
* page
)
184 InterruptsSpinLocker
locker(fLock
);
190 VMPageQueue::AppendUnlocked(PageList
& pages
, uint32 count
)
193 for (PageList::Iterator it
= pages
.GetIterator();
194 vm_page
* page
= it
.next();) {
195 if (page
->queue
!= NULL
) {
196 panic("%p->VMPageQueue::AppendUnlocked(): page %p thinks it is "
197 "already in queue %p", this, page
, page
->queue
);
203 #endif // DEBUG_PAGE_QUEUE
205 InterruptsSpinLocker
locker(fLock
);
207 fPages
.MoveFrom(&pages
);
213 VMPageQueue::PrependUnlocked(vm_page
* page
)
215 InterruptsSpinLocker
locker(fLock
);
221 VMPageQueue::RemoveUnlocked(vm_page
* page
)
223 InterruptsSpinLocker
locker(fLock
);
229 VMPageQueue::RemoveHeadUnlocked()
231 InterruptsSpinLocker
locker(fLock
);
237 VMPageQueue::RequeueUnlocked(vm_page
* page
, bool tail
)
239 InterruptsSpinLocker
locker(fLock
);
245 VMPageQueue::Head() const
247 return fPages
.Head();
252 VMPageQueue::Tail() const
254 return fPages
.Tail();
259 VMPageQueue::Previous(vm_page
* page
) const
261 return fPages
.GetPrevious(page
);
266 VMPageQueue::Next(vm_page
* page
) const
268 return fPages
.GetNext(page
);
272 VMPageQueue::Iterator
273 VMPageQueue::GetIterator() const
275 return fPages
.GetIterator();
279 #endif // VM_PAGE_QUEUE_H