virtmem
virtual memory library for Arduino
base_alloc.h
Go to the documentation of this file.
1 #ifndef VIRTMEM_BASE_ALLOC_H
2 #define VIRTMEM_BASE_ALLOC_H
3 
9 #define NVALGRIND
10 
11 #ifndef NVALGRIND
12 # include <valgrind/memcheck.h>
13 #endif
14 
15 #include "config/config.h"
16 
17 #include <stdint.h>
18 
19 namespace virtmem {
20 
21 typedef uint32_t VPtrNum;
22 typedef uint32_t VPtrSize;
23 typedef uint16_t VirtPageSize;
24 
32 {
33 protected:
34  // \cond HIDDEN_SYMBOLS
35 #if defined(__x86_64__) || defined(_M_X64)
36  typedef __uint128_t TAlign;
37 #else
38  typedef double TAlign;
39 #endif
40 
41 private:
42  enum
43  {
44  PAGE_MAX_CLEAN_SKIPS = 5, // if page is dirty: max tries for finding another clean page when swapping
45  START_OFFSET = sizeof(TAlign), // don't start at zero so we can have NULL pointers
46  BASE_INDEX = 1, // Special pointer to baseFreeList, not actually stored in file
47  MIN_ALLOC_SIZE = 16
48  };
49 
50  union UMemHeader
51  {
52  struct
53  {
54  VPtrNum next;
55  VPtrSize size;
56  } s;
57 
58  TAlign alignDummy;
59  };
60 
61 protected:
62 #ifndef NVALGRIND
63  static const int valgrindPad = 12;
64 #endif
65 
66  // \cond HIDDEN_SYMBOLS
67  struct LockPage
68  {
69  VPtrNum start;
70  VirtPageSize size;
71  uint8_t *pool;
72  uint8_t locks, cleanSkips;
73  bool dirty;
74  int8_t next;
75 
76  LockPage(void) : start(0), size(0), pool(0), locks(0), cleanSkips(0), dirty(false), next(-1) { }
77  };
78  // \endcond
79 
80 private:
81  struct PageInfo
82  {
83  LockPage *pages;
84  VirtPageSize size;
85  uint8_t count;
86  int8_t freeIndex, lockedIndex;
87  };
88 
89  // Stuff configured from VAlloc
90  VPtrSize poolSize;
91  PageInfo smallPages, mediumPages, bigPages;
92 
93  UMemHeader baseFreeList;
94  VPtrNum freePointer;
95  VPtrNum poolFreePos;
96  int8_t nextPageToSwap;
97 
98 #ifdef VIRTMEM_TRACE_STATS
99  VPtrSize memUsed, maxMemUsed;
100  uint32_t bigPageReads, bigPageWrites, bytesRead, bytesWritten;
101 #endif
102 
103  void initPages(PageInfo *info, LockPage *pages, uint8_t *pool, uint8_t pcount, VirtPageSize psize);
104  VPtrNum getMem(VPtrSize size);
105  void syncBigPage(LockPage *page);
106  void copyRawData(void *dest, VPtrNum p, VPtrSize size);
107  void saveRawData(void *src, VPtrNum p, VPtrSize size);
108  void *pullRawData(VPtrNum p, VPtrSize size, bool readonly, bool forcestart);
109  void pushRawData(VPtrNum p, const void *d, VPtrSize size);
110  const UMemHeader *getHeaderConst(VPtrNum p);
111  void updateHeader(VPtrNum p, UMemHeader *h);
112  int8_t findFreePage(PageInfo *pinfo, VPtrNum p, VPtrSize size, bool atstart);
113  int8_t findUnusedLockedPage(PageInfo *pinfo);
114  void syncLockedPage(LockPage *page);
115  int8_t lockPage(PageInfo *pinfo, VPtrNum ptr, VirtPageSize size);
116  int8_t freeLockedPage(PageInfo *pinfo, int8_t index);
117  int8_t findLockedPage(PageInfo *pinfo, VPtrNum p);
118  LockPage *findLockedPage(VPtrNum p);
119  uint8_t getFreePages(const PageInfo *pinfo) const;
120  uint8_t getUnlockedPages(const PageInfo *pinfo) const;
121 
122 protected:
123  BaseVAlloc(void) : poolSize(0) { }
124 
125  // \cond HIDDEN_SYMBOLS
126  void initSmallPages(LockPage *pages, uint8_t *pool, uint8_t pcount, VirtPageSize psize) { initPages(&smallPages, pages, pool, pcount, psize); }
127  void initMediumPages(LockPage *pages, uint8_t *pool, uint8_t pcount, VirtPageSize psize) { initPages(&mediumPages, pages, pool, pcount, psize); }
128  void initBigPages(LockPage *pages, uint8_t *pool, uint8_t pcount, VirtPageSize psize) { initPages(&bigPages, pages, pool, pcount, psize); }
129  // \endcond
130 
131  void writeZeros(VPtrNum start, VPtrSize n); // NOTE: only call this in doStart()
132 
138  virtual void doStart(void) = 0;
139  virtual void doStop(void) = 0;
140  virtual void doRead(void *data, VPtrSize offset, VPtrSize size) = 0;
141  virtual void doWrite(const void *data, VPtrSize offset, VPtrSize size) = 0;
143 
144 public:
145  void start(void);
146  void stop(void);
147 
155  void setPoolSize(VPtrSize ps) { poolSize = ps; }
156 
157  VPtrNum allocRaw(VPtrSize size);
158  void freeRaw(VPtrNum ptr);
159 
160  void *read(VPtrNum p, VPtrSize size);
161  void write(VPtrNum p, const void *d, VPtrSize size);
162  void flush(void);
163  void clearPages(void);
164  uint8_t getFreeBigPages(void) const;
165  uint8_t getUnlockedSmallPages(void) const { return getUnlockedPages(&smallPages); }
166  uint8_t getUnlockedMediumPages(void) const { return getUnlockedPages(&mediumPages); }
167  uint8_t getUnlockedBigPages(void) const { return getUnlockedPages(&bigPages); }
168 
169  // \cond HIDDEN_SYMBOLS
170  void *makeDataLock(VPtrNum ptr, VirtPageSize size, bool ro=false);
171  void *makeFittingLock(VPtrNum ptr, VirtPageSize &size, bool ro=false);
172  void releaseLock(VPtrNum ptr);
173  // \endcond
174 
175  uint8_t getSmallPageCount(void) const { return smallPages.count; }
176  uint8_t getMediumPageCount(void) const { return mediumPages.count; }
177  uint8_t getBigPageCount(void) const { return bigPages.count; }
178  VirtPageSize getSmallPageSize(void) const { return smallPages.size; }
179  VirtPageSize getMediumPageSize(void) const { return mediumPages.size; }
180  VirtPageSize getBigPageSize(void) const { return bigPages.size; }
181 
187  VPtrSize getPoolSize(void) const { return poolSize; }
188 
189  // \cond HIDDEN_SYMBOLS
190  void printStats(void);
191  // \endcond
192 
193 #ifdef VIRTMEM_TRACE_STATS
194 
200  VPtrSize getMemUsed(void) const { return memUsed; }
201  VPtrSize getMaxMemUsed(void) const { return maxMemUsed; }
202  uint32_t getBigPageReads(void) const { return bigPageReads; }
203  uint32_t getBigPageWrites(void) const { return bigPageWrites; }
204  uint32_t getBytesRead(void) const { return bytesRead; }
205  uint32_t getBytesWritten(void) const { return bytesWritten; }
206  void resetStats(void) { memUsed = maxMemUsed = 0; bigPageReads = bigPageWrites = bytesRead = bytesWritten = 0; }
207 
208 #endif
209 };
210 
211 }
212 
213 #endif // VIRTMEM_BASE_ALLOC_H
contains all code from virtmem
Definition: base_alloc.cpp:22
uint8_t getSmallPageCount(void) const
Returns total amount of small pages.
Definition: base_alloc.h:175
void writeZeros(VPtrNum start, VPtrSize n)
Writes zeros to raw virtual memory. Can be used to initialize the memory pool.
Definition: base_alloc.cpp:489
VPtrSize getMemUsed(void) const
Returns total memory used.
Definition: base_alloc.h:200
uint32_t getBigPageReads(void) const
Returns the times big pages were read (swapped).
Definition: base_alloc.h:202
void write(VPtrNum p, const void *d, VPtrSize size)
Writes a piece of raw data to (virtual) memory.
Definition: base_alloc.cpp:770
uint8_t getUnlockedMediumPages(void) const
Returns amount of medium pages which are not locked.
Definition: base_alloc.h:166
uint8_t getBigPageCount(void) const
Returns total amount of big pages.
Definition: base_alloc.h:177
void setPoolSize(VPtrSize ps)
Sets the total size of the memory pool.
Definition: base_alloc.h:155
VirtPageSize getBigPageSize(void) const
Returns the size of a big page.
Definition: base_alloc.h:180
uint8_t getUnlockedBigPages(void) const
Returns amount of big pages which are not locked.
Definition: base_alloc.h:167
This header file contains several variables that can be used to customize virtmem.
uint8_t getUnlockedSmallPages(void) const
Returns amount of small pages which are not locked.
Definition: base_alloc.h:165
VirtPageSize getSmallPageSize(void) const
Returns the size of a small page.
Definition: base_alloc.h:178
uint16_t VirtPageSize
Numeric type used to store the size of a virtual memory page.
Definition: base_alloc.h:23
VPtrNum allocRaw(VPtrSize size)
Allocates a piece of raw (virtual) memory.
Definition: base_alloc.cpp:560
void freeRaw(VPtrNum ptr)
Frees a memory block for re-usage.
Definition: base_alloc.cpp:647
VirtPageSize getMediumPageSize(void) const
Returns the size of a medium page.
Definition: base_alloc.h:179
Base class for virtual memory allocators.
Definition: base_alloc.h:31
void start(void)
Starts the allocator.
Definition: base_alloc.cpp:507
uint32_t VPtrNum
Numeric type used to store raw virtual pointer addresses.
Definition: base_alloc.h:21
void clearPages(void)
Synchronizes and clears all big memory pages.
Definition: base_alloc.cpp:835
uint32_t VPtrSize
Numeric type used to store the size of a virtual memory block.
Definition: base_alloc.h:22
void resetStats(void)
Reset all statistics. Called by start()
Definition: base_alloc.h:206
uint8_t getMediumPageCount(void) const
Returns total amount of medium pages.
Definition: base_alloc.h:176
uint32_t getBytesWritten(void) const
Returns the amount of bytes written as a results of page swaps.
Definition: base_alloc.h:205
VPtrSize getMaxMemUsed(void) const
Returns the maximum memory used so far.
Definition: base_alloc.h:201
uint8_t getFreeBigPages(void) const
Definition: base_alloc.cpp:852
void * read(VPtrNum p, VPtrSize size)
Reads a raw block of (virtual) memory.
Definition: base_alloc.cpp:724
uint32_t getBytesRead(void) const
Returns the amount of bytes read as a result of page swaps.
Definition: base_alloc.h:204
VPtrSize getPoolSize(void) const
Returns the size the memory pool.
Definition: base_alloc.h:187
void flush(void)
Synchronizes all big memory pages.
Definition: base_alloc.cpp:820
void stop(void)
Deinitializes the allocator.
Definition: base_alloc.cpp:549
uint32_t getBigPageWrites(void) const
Returns the times big pages written (synchronized).
Definition: base_alloc.h:203