L4Re/departure

libfsserver/lib/pages/page_queue_partitioned.cc

618:7123a7307a82
8 months ago Paul Boddie Introduced some debugging output control.
     1 /*     2  * A page queue retaining two internal collections of memory pages.     3  *     4  * Copyright (C) 2021 Paul Boddie <paul@boddie.org.uk>     5  *     6  * This program is free software; you can redistribute it and/or     7  * modify it under the terms of the GNU General Public License as     8  * published by the Free Software Foundation; either version 2 of     9  * the License, or (at your option) any later version.    10  *    11  * This program is distributed in the hope that it will be useful,    12  * but WITHOUT ANY WARRANTY; without even the implied warranty of    13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    14  * GNU General Public License for more details.    15  *    16  * You should have received a copy of the GNU General Public License    17  * along with this program; if not, write to the Free Software    18  * Foundation, Inc., 51 Franklin Street, Fifth Floor,    19  * Boston, MA  02110-1301, USA    20  */    21     22 #include "page_queue_partitioned.h"    23     24     25     26 /* Discard all queued flexpages. */    27     28 void PageQueuePartitioned::close(Memory *memory)    29 {    30     discard(_available, memory);    31     discard(_issued, memory);    32 }    33     34 /* Keep waiting for a potential queue non-empty condition.    35    Then, attempt to pop an entry from the queue. */    36     37 void PageQueuePartitioned::pop(PageOwner **owner, Flexpage **flexpage)    38 {    39     std::unique_lock<std::mutex> guard(_lock);    40     QueueEntry entry;    41     42     while (1)    43     {    44         if (_pop(&entry))    45         {    46             *owner = entry.owner;    47             *flexpage = entry.flexpage;    48             return;    49         }    50         else    51             _counter.wait(guard);    52     }    53 }    54     55 /* Check the available pages queue for entries, returning false if no entries    56    are available, returning true and providing the details if an entry can be    57    removed from the front of the queue. */    58     59 bool PageQueuePartitioned::_pop(QueueEntry *entry)    60 {    61     if (_available.empty())    62         return false;    63     64     *entry = _available.front();    65     _available.pop_front();    66     67     return true;    68 }    69     70 /* Push an entry for the given owner and flexpage to the appropriate queue. */    71     72 void PageQueuePartitioned::push(PageOwner *owner, Flexpage *flexpage)    73 {    74     std::lock_guard<std::mutex> guard(_lock);    75     76     /* Record the entry and a position reference for the flexpage. */    77     78     Queue *queue;    79     Positions *positions = NULL;    80     81     if (owner == NULL)    82         queue = &_available;    83     else    84     {    85         queue = &_issued;    86         positions = &_positions;    87     }    88     89     queue->push_back((QueueEntry) {flexpage, owner});    90     91     if (positions != NULL)    92     {    93         Queue::iterator last = queue->end();    94         last--;    95         positions->insert(Position(flexpage, last));    96     }    97     98     _counter.notify_one();    99 }   100    101 /* Push an entry to the front of the appropriate queue. */   102    103 void PageQueuePartitioned::push_front(PageOwner *owner, Flexpage *flexpage)   104 {   105     std::lock_guard<std::mutex> guard(_lock);   106    107     Queue *queue;   108     Positions *positions = NULL;   109    110     if (owner == NULL)   111         queue = &_available;   112     else   113     {   114         queue = &_issued;   115         positions = &_positions;   116     }   117    118     queue->push_back((QueueEntry) {flexpage, owner});   119    120     if (positions != NULL)   121         positions->insert(Position(flexpage, queue->begin()));   122    123     _counter.notify_one();   124 }   125    126 /* Remove an entry for the given owner and flexpage from the queue. */   127    128 bool PageQueuePartitioned::remove(PageOwner *owner, Flexpage *flexpage)   129 {   130     return PageQueue::remove(_issued, _positions, owner, flexpage);   131 }   132    133 // vim: tabstop=4 expandtab shiftwidth=4