rambrain
managedFileSwap.h
Go to the documentation of this file.
1 /* rambrain - a dynamical physical memory extender
2  * Copyright (C) 2015 M. Imgrund, A. Arth
3  * mimgrund (at) mpifr-bonn.mpg.de
4  * arth (at) usm.uni-muenchen.de
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (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, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef MANAGEDFILESWAP_H
21 #define MANAGEDFILESWAP_H
22 
23 #include "managedSwap.h"
24 #include <stdio.h>
25 #include <unistd.h>
26 #include <map>
27 #include <queue>
28 #include <libaio.h>
29 #include <signal.h>
30 #include <unordered_map>
31 #include <sys/types.h>
32 #include <unistd.h>
33 
34 //Test classes
35 #ifdef BUILD_TESTS
36 class managedFileSwap_Unit_SwapAllocation_Test;
37 class managedFileSwap_Integration_RandomAccess_Test;
38 class managedFileSwap_Integration_RandomAccessVariousSize_Test;
39 class managedFileSwap_Unit_SwapPolicy_Test;
40 #endif
41 
42 namespace rambrain
43 {
46  PAGE_PART = 2 ,
47  PAGE_END = 4 ,
50  };
51 
52 typedef uint64_t global_offset;
53 
54 class pageFileLocation;
55 
57 struct swapFileDesc {
58  int fileno;
60 };
61 
63 struct aiotracker {
64  struct iocb aio;
65  int *tracker;
66 };
67 
73  chunk = NULL;
74  };
75 };
76 
77 
84 {
85 public:
87  file ( file ), offset ( offset ), size ( size ), status ( status ), aio_ptr ( NULL ) {}
88 
89  unsigned int file ;
94  struct aiotracker *aio_ptr = NULL ;
95  char aio_lock = 0 ;
96 };
97 
98 
99 
100 class managedFileSwap;
101 
108 {
109 public:
110 
111  managedFileSwap ( global_bytesize size, const char *filemask, global_bytesize oneFile = 0, bool enableDMA = false );
112  virtual ~managedFileSwap();
113 
114  virtual void swapDelete ( managedMemoryChunk *chunk );
115  virtual global_bytesize swapIn ( managedMemoryChunk **chunklist, unsigned int nchunks );
116  virtual global_bytesize swapIn ( managedMemoryChunk *chunk );
117  virtual global_bytesize swapOut ( managedMemoryChunk **chunklist, unsigned int nchunks );
118  virtual global_bytesize swapOut ( managedMemoryChunk *chunk );
119  virtual bool extendSwap ( global_bytesize size );
120  virtual bool extendSwapByPolicy ( global_bytesize min_size );
121 
122  void setDMA ( bool arg1 );
123 
124  virtual void close();
125 
126  const unsigned int pageSize;
127 
128 
129 private:
131  pageFileLocation determinePFLoc ( global_offset g_offset, global_bytesize length ) const;
133  inline global_offset determineGlobalOffset ( const pageFileLocation &ref ) const;
135  bool openSwapFiles();
137  bool openSwapFileRange ( unsigned int start, unsigned int stop );
139  void closeSwapFiles();
140 
141  const char *filemask;
142 
143  unsigned int pageFileNumber;
145 
146 
147  float swapFileResizeFrac = .1;
148 
149  struct swapFileDesc *swapFiles = NULL;
150 
152  void scheduleCopy ( rambrain::pageFileLocation &ref, void *ramBuf, int *tracker, bool reverse = false ) ;
158  void copyMem ( rambrain::pageFileLocation &ref, void *ramBuf, bool reverse = false ) ;
159 
161  inline void copyMem ( void *ramBuf, rambrain::pageFileLocation &ref ) {
162  copyMem ( ref, ramBuf, true );
163  }
165  inline void scheduleCopy ( void *ramBuf, pageFileLocation &ref, int *parttracker ) {
166  scheduleCopy ( ref, ramBuf, parttracker, true );
167  }
168 
170  inline size_t getMemoryAlignment() const {
171  return memoryAlignment;
172  }
173 
174 
175  //page file malloc:
178  void pffree ( pageFileLocation *pagePtr );
181 
182  std::map<global_offset, pageFileLocation *> free_space;
183  std::map<global_offset, pageFileLocation *> all_space;
184 
185 
186  bool enableDMA = false;
187 protected:
188  bool deleteFilesOnExit = true;
189 
190  //sigEvent Handler:
192  void asyncIoArrived ( rambrain::pageFileLocation *ref, struct io_event *aio );
194  void completeTransactionOn ( rambrain::pageFileLocation *ref, bool lock = true );
195 
200  virtual bool checkForAIO();
201 
202  struct iocb aio_template;
203  io_context_t aio_context = 0;
204  unsigned int aio_max_transactions = 10240;
205  struct io_event *aio_eventarr;
206  pthread_mutex_t aioWaiterLock = PTHREAD_MUTEX_INITIALIZER;
207 
208  std::unordered_map<struct iocb *, pageFileLocation *> pendingAios;
209 
212  static void sigStat ( int signum );
213 
214  //Thread pool for asynchronous io:
215  pthread_mutex_t io_submit_lock = PTHREAD_MUTEX_INITIALIZER;
216  pthread_cond_t io_submit_cond = PTHREAD_COND_INITIALIZER;
217  unsigned int io_submit_num_threads = 1;
218  pthread_t *io_submit_threads;
219  pthread_t io_waiter_thread;
220  pthread_t io_arrive_thread;
221 
222  std::queue<struct iocb *> io_submit_requests;
223 
224  void my_io_submit ( struct iocb *aio );
225  static void *io_submit_worker ( void *ptr );
226  static void *io_arrrive_worker ( void *ptr );
227 
228  bool io_arrive_work = true;
229 
231  bool cleanupCachedElements ( rambrain::global_bytesize minimum_size = 0 );
233  virtual void invalidateCacheFor ( managedMemoryChunk &chunk );
234 
237 
238  //Test classes
239 #ifdef BUILD_TESTS
240  friend class ::managedFileSwap_Unit_SwapAllocation_Test;
241  friend class ::managedFileSwap_Integration_RandomAccess_Test;
242  friend class ::managedFileSwap_Integration_RandomAccessVariousSize_Test;
243  friend class ::managedFileSwap_Unit_SwapPolicy_Test;
244 #endif
245 };
246 
247 }
248 
249 
250 #endif
251 
void scheduleCopy(rambrain::pageFileLocation &ref, void *ramBuf, int *tracker, bool reverse=false)
Schedules an elementary pageFileLocation chunk for copying (in or out)
void completeTransactionOn(rambrain::pageFileLocation *ref, bool lock=true)
called to finish a transaction when all pending aio on a managedMemoryChunk has completed ...
const unsigned int pageSize
virtual void invalidateCacheFor(managedMemoryChunk &chunk)
tells managedFileSwap that the chunk under consideration might have been changed by user and needs to...
bool cleanupCachedElements(rambrain::global_bytesize minimum_size=0)
throws out cached elements still in ram but also resident on disk. This makes space in situations of ...
std::unordered_map< struct iocb *, pageFileLocation * > pendingAios
Class that serves as a backend to managedMemory to actual write/read managedMemoryChunks to/from hard...
Definition: managedSwap.h:35
bool openSwapFileRange(unsigned int start, unsigned int stop)
opens certain range of swap files according to settings
managedMemoryChunk * chunk
pthread_mutex_t io_submit_lock
virtual bool extendSwap(global_bytesize size)
extend swap by size number of bytes
An implementation of managedSwap that is capable of kernel asynchronousIO.
uint64_t global_bytesize
Definition: common.h:65
pageFileLocation * allocInFree(pageFileLocation *freeChunk, global_bytesize size)
Helper function for pfmalloc.
virtual void close()
Close the swap if not already closed.
pageFileLocation determinePFLoc(global_offset g_offset, global_bytesize length) const
generate a pageFileLocation object given a global offset and a length of the data. This maps our "virtual" adress space to physical locations in a certain file
void asyncIoArrived(rambrain::pageFileLocation *ref, struct io_event *aio)
deals with a single asynchronous IO event completion
pthread_mutex_t aioWaiterLock
struct aiotracker * aio_ptr
void copyMem(rambrain::pageFileLocation &ref, void *ramBuf, bool reverse=false)
Schedules copying on level of whole managedMemoryChunks and calls scheduleCopy on the assigned parts...
void closeSwapFiles()
closes swap files
bool openSwapFiles()
opens swap files according to settings
pageChunkStatus
the status for pageFileLocations
pageFileLocation * pfmalloc(rambrain::global_bytesize size, rambrain::managedMemoryChunk *chunk)
Tries to find space in the swapFiles to write out an object of size size and returns first pageFileLo...
saves some storage in pageFileLocation
global_bytesize currentSize
std::queue< struct iocb * > io_submit_requests
pageFileLocation * glob_off_next
union glob_off_union glob_off_next
pageFileLocation(unsigned int file, global_bytesize offset, global_bytesize size, pageChunkStatus status=PAGE_FREE)
manages all managed Chunks of raw memory
tracks page file allocations while objects are preferably written continuous to page file...
global_offset determineGlobalOffset(const pageFileLocation &ref) const
maps from physical location to "virtual" adress
virtual global_bytesize swapOut(managedMemoryChunk **chunklist, unsigned int nchunks)
Trigger swap out of the chunks pointed to by chunklist.
struct swapFileDesc * swapFiles
struct io_event * aio_eventarr
void my_io_submit(struct iocb *aio)
size_t getMemoryAlignment() const
If we have any restrictions regarding memory alignment of RAM buffers(DMA), this function tells us ab...
static void sigStat(int signum)
returns some statistics. Typically, we will be sensitive to SIGUSR2 if compiled with -DSWAPSTATS=on ...
managedFileSwap(global_bytesize size, const char *filemask, global_bytesize oneFile=0, bool enableDMA=false)
virtual bool checkForAIO()
gives this class the chance to treat incoming aio events
global_bytesize getFreeDiskSpace()
returns free disk space at file system location specified by filemask
static managedFileSwap * instance
structure to handle swap files
void scheduleCopy(void *ramBuf, pageFileLocation &ref, int *parttracker)
Convenience function for reverse scheduling a copy.
std::map< global_offset, pageFileLocation * > free_space
virtual bool extendSwapByPolicy(global_bytesize min_size)
extend swap by policy
virtual void swapDelete(managedMemoryChunk *chunk)
Mark chunk as deleted.
void copyMem(void *ramBuf, rambrain::pageFileLocation &ref)
Convenience function for reverse copying.
static void * io_submit_worker(void *ptr)
unsigned int io_submit_num_threads
static void * io_arrrive_worker(void *ptr)
datastructure for handling asynchronous events
void pffree(pageFileLocation *pagePtr)
global_bytesize pageFileSize
std::map< global_offset, pageFileLocation * > all_space
uint64_t global_offset
virtual global_bytesize swapIn(managedMemoryChunk **chunklist, unsigned int nchunks)
Trigger swap in of the chunks pointed to by chunklist.