A platform for high-performance distributed tool and library development written in C++. It can be deployed in two different cluster modes: standalone or distributed. API for v0.5.0, released on June 13, 2018.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
SharedMem.cc
Go to the documentation of this file.
1 /*****************************************************************************
2  * *
3  * Copyright 2018 Rice University *
4  * *
5  * Licensed under the Apache License, Version 2.0 (the "License"); *
6  * you may not use this file except in compliance with the License. *
7  * You may obtain a copy of the License at *
8  * *
9  * http://www.apache.org/licenses/LICENSE-2.0 *
10  * *
11  * Unless required by applicable law or agreed to in writing, software *
12  * distributed under the License is distributed on an "AS IS" BASIS, *
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
14  * See the License for the specific language governing permissions and *
15  * limitations under the License. *
16  * *
17  *****************************************************************************/
18 #include "SharedMem.h"
19 #include "Configuration.h"
20 #include <sys/mman.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <sys/types.h>
24 #include <err.h>
25 #include <errno.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <pthread.h>
30 #include <stdio.h>
31 #include <string>
32 #include <iostream>
33 
34 #ifndef USE_MEMCACHED_SLAB_ALLOCATOR
35 #include "tlsf.h"
36 #endif
37 
38 SharedMem::SharedMem(size_t memSize, pdb::PDBLoggerPtr logger) {
39  this->shmMemSize = memSize;
40  this->memPool = nullptr;
41  if (this->getMem() < 0) {
42  std::cout << "Fatal error: initialize shared memory failed with size=" << memSize
43  << std::endl;
44  logger->error(std::string("Fatal error: initialize shared memory failed with size=") +
45  std::to_string(memSize));
46  exit(-1);
47  }
48 #ifdef USE_MEMCACHED_SLAB_ALLOCATOR
49  this->allocator =
50  make_shared<SlabAllocator>(this->memPool, this->shmMemSize, DEFAULT_PAGE_SIZE, 512);
51 #else
52  this->my_tlsf = this->allocator.tlsf_create_with_pool(this->memPool, this->shmMemSize);
53 #endif
54  this->initMutex();
55  this->logger = logger;
56 }
57 
59  this->destroy();
60 }
61 
63  pthread_mutex_lock(this->memLock);
64 }
65 
67  pthread_mutex_unlock(this->memLock);
68 }
69 
71  return this->shmMemSize;
72 }
73 
74 
75 void* SharedMem::malloc(size_t size) {
76  void* ptr;
77  this->lock();
78 #ifdef USE_MEMCACHED_SLAB_ALLOCATOR
79  ptr = this->allocator->slabs_alloc_unsafe(size);
80 #else
81  ptr = this->allocator.tlsf_malloc(this->my_tlsf, size);
82 #endif
83  this->unlock();
84  return ptr;
85 }
86 
87 
88 void* SharedMem::mallocAlign(size_t size, size_t alignment, int& offset) {
89  void* ptr = this->malloc(size + alignment);
90  void* retPtr = ptr;
91  offset = 0;
92  if (ptr != nullptr) {
93  retPtr = (void*)this->addressRoundUp((char*)ptr, alignment);
94  offset = (char*)retPtr - (char*)ptr;
95  }
96  return retPtr;
97 }
98 
99 
100 void SharedMem::free(void* ptr, size_t size) {
101  this->lock();
102 #ifdef USE_MEMCACHED_SLAB_ALLOCATOR
103  this->allocator->slabs_free_unsafe(ptr, size);
104 #else
105  this->allocator.tlsf_free(this->my_tlsf, ptr);
106 #endif
107  this->unlock();
108 }
109 
110 
111 char* SharedMem::addressRoundUp(char* address, size_t roundTo) {
112  size_t roundToMask = (~((size_t)roundTo - 1));
113  return (char*)((size_t)((address) + (roundTo - 1)) & roundToMask);
114 }
115 
116 size_t SharedMem::roundUp(size_t address, size_t roundTo) {
117  size_t roundToMask = (~((size_t)roundTo - 1));
118  return (((address) + (roundTo - 1)) & roundToMask);
119 }
120 
121 size_t SharedMem::roundDown(size_t address, size_t roundTo) {
122  size_t roundToMask = (~((size_t)roundTo - 1));
123  return ((address)&roundToMask);
124 }
125 
126 
128  return 0;
129 }
130 
132  if (this->memLock) {
133  pthread_mutex_destroy(this->memLock);
134  }
135  if (this->memPool && (this->memPool != (void*)-1)) {
136  munmap(this->memPool, this->shmMemSize);
137  this->memPool = (void*)-1;
138  }
139 }
140 
142  if (this->memPool && (this->memPool != (void*)-1)) {
143  return -1;
144  }
145  this->memPool = mmap(0, this->shmMemSize, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
146  if (this->memPool == (void*)-1) {
147  return -1;
148  }
149  return 0;
150 }
151 
152 long long SharedMem::computeOffset(void* shmAddress) {
153  return (long long)((char*)shmAddress - (char*)this->memPool);
154 }
155 
156 void* SharedMem::getPointer(size_t offset) {
157  return (void*)((size_t)this->memPool + (size_t)offset);
158 }
159 
161  this->memLock = (pthread_mutex_t*)this->_malloc_unsafe(sizeof(pthread_mutex_t));
162  if (this->memLock == 0) {
163  std::cout << "FATAL ERROR: can't allocate for memLock from buffer pool" << std::endl;
164  return -1;
165  }
166  if (pthread_mutex_init(this->memLock, nullptr) != 0) {
167  return -1;
168  }
169  return 0;
170 }
171 
172 void* SharedMem::_malloc_unsafe(size_t size) {
173 #ifdef USE_MEMCACHED_SLAB_ALLOCATOR
174  return this->allocator->slabs_alloc_unsafe(size);
175 #else
176  return this->allocator.tlsf_malloc(this->my_tlsf, size);
177 #endif
178 }
179 
180 void SharedMem::_free_unsafe(void* ptr, size_t size) {
181 #ifdef USE_MEMCACHED_SLAB_ALLOCATOR
182  return this->allocator->slabs_free_unsafe(ptr, size);
183 #else
184  return this->allocator.tlsf_free(this->my_tlsf, ptr);
185 #endif
186 }
int initialize()
Definition: SharedMem.cc:127
void free(void *ptr, size_t size)
Definition: SharedMem.cc:100
void _free_unsafe(void *ptr, size_t size)
Definition: SharedMem.cc:180
pdb::PDBLoggerPtr logger
Definition: SharedMem.h:66
void unlock()
Definition: SharedMem.cc:66
void * getPointer(size_t offset)
Definition: SharedMem.cc:156
static char * addressRoundUp(char *address, size_t roundTo)
Definition: SharedMem.cc:111
void destroy()
Definition: SharedMem.cc:131
void tlsf_free(tlsf_t tlsf, void *ptr)
Definition: tlsf.cc:980
static size_t roundDown(size_t size, size_t roundTo)
Definition: SharedMem.cc:121
void * _malloc_unsafe(size_t size)
Definition: SharedMem.cc:172
static size_t roundUp(size_t size, size_t roundTo)
Definition: SharedMem.cc:116
void * malloc(size_t size)
Definition: SharedMem.cc:75
tlsf_t tlsf_create_with_pool(void *mem, size_t bytes)
Definition: tlsf.cc:948
size_t shmMemSize
Definition: SharedMem.h:74
~SharedMem()
Definition: SharedMem.cc:58
size_t getShmSize()
Definition: SharedMem.cc:70
void lock()
Definition: SharedMem.cc:62
SharedMem(size_t shmMemSize, pdb::PDBLoggerPtr logger)
Definition: SharedMem.cc:38
void * my_tlsf
Definition: SharedMem.h:71
std::shared_ptr< PDBLogger > PDBLoggerPtr
Definition: PDBLogger.h:40
void * mallocAlign(size_t size, size_t alignment, int &offset)
Definition: SharedMem.cc:88
int getMem()
Definition: SharedMem.cc:141
long long computeOffset(void *shmAddress)
Definition: SharedMem.cc:152
#define DEFAULT_PAGE_SIZE
Definition: Configuration.h:36
void * tlsf_malloc(tlsf_t tlsf, size_t bytes)
Definition: tlsf.cc:963
pthread_mutex_t * memLock
Definition: SharedMem.h:65
void * memPool
Definition: SharedMem.h:73
tlsfAllocator allocator
Definition: SharedMem.h:70
int initMutex()
Definition: SharedMem.cc:160