Atlas Runtime
pmalloc.hpp
Go to the documentation of this file.
1 /*
2  * (c) Copyright 2016 Hewlett Packard Enterprise Development LP
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as
6  * published by the Free Software Foundation, either version 3 of the
7  * License, or (at your option) any later version. This program is
8  * distributed in the hope that it will be useful, but WITHOUT ANY
9  * WARRANTY; without even the implied warranty of MERCHANTABILITY or
10  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
11  * for more details. You should have received a copy of the GNU Lesser
12  * General Public License along with this program. If not, see
13  * <http://www.gnu.org/licenses/>.
14  */
15 
16 
17 #ifndef PMALLOC_HPP
18 #define PMALLOC_HPP
19 
20 #include <iostream>
21 #include <cstdlib>
22 #include <cassert>
23 #include <map>
24 
25 #include <pthread.h>
26 
27 #include "pregion_configs.hpp"
28 
29 #include "atlas_api.h"
30 
31 namespace Atlas {
32 
33 typedef std::map<void* /* chunk address */, bool /* dummy */> MemMap;
34 typedef std::map<uint32_t /* bin number */, MemMap> FreeList;
35 
36 // Physically persistent arena, contains logically transient data as well
37 class PArena {
38 public:
39  explicit PArena() : CurrAllocAddr_{nullptr}, StartAddr_{nullptr},
40  EndAddr_{nullptr}, ActualAlloced_{0}, FreeList_{new FreeList}
41  { pthread_mutex_init(&Lock_, NULL); flushDirtyCacheLines(); }
42 
44  { if (FreeList_) { delete FreeList_; FreeList_ = nullptr; } }
45 
46  PArena(const PArena&) = delete;
47  PArena(PArena&&) = delete;
48  PArena& operator=(const PArena&) = delete;
49  PArena& operator=(PArena&&) = delete;
50 
51  void initAllocAddresses(void *start_addr);
52  void initTransients();
53 
54  void *get_curr_alloc_addr() const { return CurrAllocAddr_; }
55  void *get_start_addr() const { return StartAddr_; }
56  void *get_end_addr() const { return EndAddr_; }
57  uint64_t get_actual_alloced() const { return ActualAlloced_; }
58 
59  bool doesRangeCheck(void *start, size_t sz) const
60  { return start >= StartAddr_ &&
61  (static_cast<char*>(start) + sz) <
62  static_cast<char*>(EndAddr_); }
63 
64  void *allocMem(
65  size_t sz, bool does_need_cache_line_alignment,
66  bool does_need_logging);
67  void *allocFromFreeList(
68  size_t sz, bool does_need_cache_line_alignment,
69  bool does_need_logging);
71  size_t sz, bool does_need_cache_line_alignment,
72  bool does_need_logging);
73  void *allocRawMem(size_t);
74 
75  void freeMem(void *ptr, bool should_log);
76 
77  void Lock() { pthread_mutex_lock(&Lock_); }
78  int tryLock() { return pthread_mutex_trylock(&Lock_); }
79  void Unlock() { pthread_mutex_unlock(&Lock_); }
80 
81 private:
82  // The 3 addresses below are persistent. Their updates are flushed
83  // but not logged.
84  void *CurrAllocAddr_; // bump pointer
85  void *StartAddr_;
86  void *EndAddr_;
87 
88  // The following is persistent as well. Its update is flushed
89  // but not logged. For accuracy purposes, start with a fresh
90  // region when the stats are turned on --- otherwise, allocation
91  // from a prior run may not be captured.
92  // This field is unconditionally included here to avoid
93  // layout incompatibility but updated only under the stats flag.
94  uint64_t ActualAlloced_;
95 
96  // The following are considered logically transient and hence not
97  // flushed. They must be reset at init time.
98  pthread_mutex_t Lock_;
99  FreeList *FreeList_;
100 
101  void flushDirtyCacheLines()
102  { NVM_FLUSH(&CurrAllocAddr_); NVM_FLUSH(&ActualAlloced_); }
103 
104  void *carveExtraMem(char *mem, size_t actual_sz, size_t actual_free_sz);
105 
106  void insertToFreeList(uint32_t bin_no, void *mem);
107  void deleteFromFreeList(uint32_t bin_no, void *mem);
108 
109  void incrementActualAllocedStats(size_t sz);
110  void decrementActualAllocedStats(size_t sz);
111 };
112 
113 inline void PArena::initAllocAddresses(void *start_addr)
114 {
115  StartAddr_ = CurrAllocAddr_ = start_addr;
116  EndAddr_ = static_cast<void*>(
117  static_cast<char*>(start_addr) + kArenaSize_);
118  flushDirtyCacheLines();
119 }
120 
122 {
123  pthread_mutex_init(&Lock_, NULL);
124  FreeList_ = new FreeList;
125 }
126 
127 inline void PArena::incrementActualAllocedStats(size_t sz)
128 {
129 #if defined(ATLAS_ALLOC_STATS)
130  ActualAlloced_ += sz;
131  NVM_FLUSH(&ActualAlloced_);
132 #endif
133 }
134 
135 inline void PArena::decrementActualAllocedStats(size_t sz)
136 {
137 #if defined(ATLAS_ALLOC_STATS)
138  ActualAlloced_ -= sz;
139  NVM_FLUSH(&ActualAlloced_);
140 #endif
141 }
142 
143 } // namespace Atlas
144 
145 #endif
Definition: pmalloc.hpp:37
void * get_end_addr() const
Definition: pmalloc.hpp:56
std::map< void *, bool > MemMap
Definition: pmalloc.hpp:33
PArena & operator=(const PArena &)=delete
const uint32_t kArenaSize_
Definition: pregion_configs.hpp:31
~PArena()
Definition: pmalloc.hpp:43
void * get_curr_alloc_addr() const
Definition: pmalloc.hpp:54
void * allocFromFreeList(size_t sz, bool does_need_cache_line_alignment, bool does_need_logging)
Definition: pmalloc.cpp:175
void * get_start_addr() const
Definition: pmalloc.hpp:55
PArena()
Definition: pmalloc.hpp:39
#define NVM_FLUSH(p)
Definition: atlas_api.h:106
bool doesRangeCheck(void *start, size_t sz) const
Definition: pmalloc.hpp:59
void * allocRawMem(size_t)
Definition: pmalloc.cpp:339
void initAllocAddresses(void *start_addr)
Definition: pmalloc.hpp:113
void initTransients()
Definition: pmalloc.hpp:121
void * allocMem(size_t sz, bool does_need_cache_line_alignment, bool does_need_logging)
Definition: pmalloc.cpp:79
void Lock()
Definition: pmalloc.hpp:77
uint64_t get_actual_alloced() const
Definition: pmalloc.hpp:57
int tryLock()
Definition: pmalloc.hpp:78
std::map< uint32_t, MemMap > FreeList
Definition: pmalloc.hpp:34
void Unlock()
Definition: pmalloc.hpp:79
void freeMem(void *ptr, bool should_log)
Definition: pmalloc.cpp:37
Definition: atlas_alloc_cpp.hpp:21
void * allocFromUpdatedFreeList(size_t sz, bool does_need_cache_line_alignment, bool does_need_logging)
Definition: pmalloc.cpp:264