1 #include "page_queue_partitioned.h" 2 3 4 5 /* Discard all queued flexpages. */ 6 7 void PageQueuePartitioned::close(Memory *memory) 8 { 9 discard(_available, memory); 10 discard(_issued, memory); 11 } 12 13 /* Keep waiting for a potential queue non-empty condition. 14 Then, attempt to pop an entry from the queue. */ 15 16 void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage) 17 { 18 std::unique_lock<std::mutex> guard(_lock); 19 QueueEntry entry; 20 21 while (1) 22 { 23 if (_pop(&entry)) 24 { 25 *owner = entry.owner; 26 *flexpage = entry.flexpage; 27 return; 28 } 29 else 30 _counter.wait(guard); 31 } 32 } 33 34 /* Check the available pages queue for entries, returning false if no entries 35 are available, returning true and providing the details if an entry can be 36 removed from the front of the queue. */ 37 38 bool PageQueuePartitioned::_pop(QueueEntry *entry) 39 { 40 if (_available.empty()) 41 return false; 42 43 *entry = _available.front(); 44 _available.pop_front(); 45 46 return true; 47 } 48 49 /* Push an entry for the given owner and flexpage to the appropriate queue. */ 50 51 void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage) 52 { 53 std::lock_guard<std::mutex> guard(_lock); 54 55 /* Record the entry and a position reference for the flexpage. */ 56 57 Queue *queue; 58 Positions *positions = NULL; 59 60 if (owner == NULL) 61 queue = &_available; 62 else 63 { 64 queue = &_issued; 65 positions = &_positions; 66 } 67 68 queue->push_back((QueueEntry) {flexpage, owner}); 69 70 if (positions != NULL) 71 { 72 Queue::iterator last = queue->end(); 73 last--; 74 positions->insert(Position(flexpage, last)); 75 } 76 77 _counter.notify_one(); 78 } 79 80 /* Push an entry to the front of the appropriate queue. */ 81 82 void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage) 83 { 84 std::lock_guard<std::mutex> guard(_lock); 85 86 Queue *queue; 87 Positions *positions = NULL; 88 89 if (owner == NULL) 90 queue = &_available; 91 else 92 { 93 queue = &_issued; 94 positions = &_positions; 95 } 96 97 queue->push_back((QueueEntry) {flexpage, owner}); 98 99 if (positions != NULL) 100 positions->insert(Position(flexpage, queue->begin())); 101 102 _counter.notify_one(); 103 } 104 105 /* Remove an entry for the given owner and flexpage from the queue. */ 106 107 bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage) 108 { 109 return PageQueue::remove(_issued, _positions, owner, flexpage); 110 } 111 112 // vim: tabstop=4 expandtab shiftwidth=4