1 #include "memory_incremental.h" 2 #include "memory_preallocated.h" 3 #include "page_queue_partitioned.h" 4 #include "pipe_paging.h" 5 6 7 8 PipePaging::PipePaging(Memory *memory, offset_t size) 9 : _memory(NULL), _size(size) 10 { 11 /* Reserve space for two pipe regions. */ 12 13 _memory = new MemoryPreallocated(memory, size * 2); 14 _queue = new PageQueuePartitioned(); 15 _pages = new Pages(_memory, _queue); 16 17 for (unsigned int i = 0; i < 2; i++) 18 _regions[i] = NULL; 19 } 20 21 /* Detach one endpoint. */ 22 23 void PipePaging::detach() 24 { 25 if (!_endpoints) 26 return; 27 else 28 _endpoints--; 29 30 /* Return if the other endpoint is attached. */ 31 32 if (_endpoints) 33 return; 34 35 /* Discard all regions from the pipe. */ 36 37 for (unsigned int i = 0; i < 2; i++) 38 { 39 PageMapper *mapper = _regions[i]; 40 41 if (mapper != NULL) 42 { 43 mapper->detach(); 44 _regions[i] = NULL; 45 delete mapper; 46 } 47 } 48 49 /* Delete the page collection and related objects. */ 50 51 delete _pages; 52 delete _queue; 53 delete _memory; 54 } 55 56 /* Add a region to the sequence. */ 57 58 PageMapper *PipePaging::add_region() 59 { 60 /* If the writer already accesses a different region to the reader, no new 61 region is added. */ 62 63 if (_writing != _reading) 64 return NULL; 65 66 /* Select the other region of the pair being maintained. */ 67 68 _writing = 1 - _writing; 69 70 /* Make a new mapper for the region. */ 71 72 PageMapper *mapper = new PageMapper(&_accessors[_writing], _pages); 73 74 /* Initialise and record the mapper. */ 75 76 mapper->attach(); 77 mapper->set_data_size(0); 78 79 _regions[_writing] = mapper; 80 return mapper; 81 } 82 83 /* Return the current region for reading. */ 84 85 PageMapper *PipePaging::current_region() 86 { 87 return _regions[_reading]; 88 } 89 90 /* Return the next region for the reader if the writer is using a different one. 91 Otherwise, return NULL. */ 92 93 PageMapper *PipePaging::next_region() 94 { 95 /* If the reader already accesses the same region to the writer, no next 96 region can be obtained. */ 97 98 if (_reading == _writing) 99 return NULL; 100 101 /* Detach and discard the current page mapper. */ 102 103 PageMapper *mapper = _regions[_reading]; 104 105 if (mapper != NULL) 106 { 107 mapper->detach(); 108 _regions[_reading] = NULL; 109 delete mapper; 110 } 111 112 /* Return the next region. */ 113 114 _reading = 1 - _reading; 115 return _regions[_reading]; 116 } 117 118 // vim: tabstop=4 expandtab shiftwidth=4