Atlas Runtime
internal_api.h
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 INTERNAL_API
18 #define INTERNAL_API
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif
23  // TODO document these APIs.
24  void nvm_acquire(void *lock_address);
25  void nvm_rwlock_rdlock(void *lock_address);
26  void nvm_rwlock_wrlock(void *lock_address);
27  void nvm_release(void *lock_address);
28  void nvm_rwlock_unlock(void *lock_address);
29  void nvm_store(void *addr, size_t size);
30  void nvm_log_alloc(void *addr);
31  void nvm_log_free(void *addr);
32  void nvm_memset(void *addr, size_t sz);
33  void nvm_memcpy(void *dst, size_t sz);
34  void nvm_memmove(void *dst, size_t sz);
35  void nvm_strcpy(char *dst, size_t sz);
36  void nvm_strcat(char *dst, size_t sz);
37  size_t nvm_strlen(char *dst);//returns strlen + 1 - accounts for null char
38  // TODO nvm_barrier should really be inlined. For that to happen,
39  // the compiler must manually inline its instructions. Don't use this
40  // interface within the library, instead use NVM_FLUSH
41  void nvm_barrier(void*);
42 
43 #if defined(_USE_TABLE_FLUSH)
44  void AsyncDataFlush(void *p);
45  void AsyncMemOpDataFlush(void *dst, size_t sz);
46 #endif
47 
48 
49 #ifdef __cplusplus
50 }
51 #endif
52 
53 // Read timestamp (x86)
54 static inline uint64_t atlas_rdtsc() {
55  uint32_t lo, hi;
56  __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
57  return lo | ((uint64_t)hi << 32);
58 }
59 
60 #define NVM_LOG(var, size) { \
61  nvm_store((void*)&(var), (size)); \
62  } \
63 
64 #define NVM_LOCK(lock) { \
65  pthread_mutex_lock(&(lock)); \
66  nvm_acquire((void*)&(lock)); \
67  } \
68 
69 #define NVM_UNLOCK(lock) { \
70  nvm_release((void*)&(lock)); \
71  pthread_mutex_unlock(&(lock)); \
72  } \
73 
74 #define NVM_RWLOCK_RDLOCK(rwlock) { \
75  pthread_rwlock_rdlock(&(rwlock)); \
76  nvm_rwlock_rdlock((void *)&(rwlock)); \
77  } \
78 
79 #define NVM_RWLOCK_WRLOCK(rwlock) { \
80  pthread_rwlock_wrlock(&(rwlock)); \
81  nvm_rwlock_wrlock((void *)&(rwlock)); \
82  } \
83 
84 #define NVM_RWLOCK_UNLOCK(rwlock) { \
85  nvm_rwlock_unlock((void *)&(rwlock)); \
86  pthread_rwlock_unlock(&(rwlock)); \
87  } \
88 
89 #if defined(_FLUSH_LOCAL_COMMIT) || defined(_FLUSH_GLOBAL_COMMIT)
90 
91 #define NVM_STR(var,val,size) { \
92  nvm_store((void*)&(var),((size)*8)); \
93  var=val; \
94  } \
95 
96 #define NVM_STR2(var,val,size) { \
97  nvm_store((void*)&(var),(size)); \
98  var=val; \
99  } \
100 
101 #define NVM_MEMSET(s,c,n) { \
102  nvm_memset((void *)(s), (size_t)(n)); \
103  memset(s, c, n); \
104  } \
105 
106 #define NVM_MEMCPY(dst, src, n) { \
107  nvm_memcpy((void *)(dst), (size_t)(n)); \
108  memcpy(dst, src, n); \
109  } \
110 
111 #define NVM_MEMMOVE(dst, src, n) { \
112  nvm_memmove((void *)(dst), (size_t)(n)); \
113  memmove(dst, src, n); \
114  } \
115 
116 #define NVM_STRCPY(dst, src) { \
117  size_t sz=nvm_strlen(dst); \
118  nvm_strcpy((void *)(dst),(size_t)(sz)); \
119  strcpy(dst, src); \
120  } \
121 
122 #define NVM_STRNCPY(dst, src, n) { \
123  nvm_strcpy((void *)(dst),(size_t)(n)); \
124  strncpy(dst, src, n); \
125  } \
126 
127 #define NVM_STRCAT(dst, src) { \
128  size_t sz=nvm_strlen(dst); \
129  nvm_strcat((void *)(dst),(size_t)(sz)); \
130  strcat(dst, src); \
131  } \
132 
133 #define NVM_STRNCAT(dst, src, n) { \
134  size_t sz=nvm_strlen(dst); \
135  nvm_strcat((void *)(dst),(size_t)(sz)); \
136  strncat(dst, src, n); \
137  } \
138 
139 
140 #elif defined(_DISABLE_DATA_FLUSH)
141 
142 #define NVM_STR(var,val,size) { \
143  nvm_store((void*)&(var),((size)*8)); \
144  var=val; \
145  } \
146 
147 #define NVM_STR2(var,val,size) { \
148  nvm_store((void*)&(var),(size)); \
149  var=val; \
150  } \
151 
152 #define NVM_MEMSET(s,c,n) { \
153  nvm_memset((void *)(s), (size_t)(n)); \
154  memset(s, c, n); \
155  } \
156 
157 #define NVM_MEMCPY(dst, src, n) { \
158  nvm_memcpy((void *)(dst), (size_t)(n)); \
159  memcpy(dst, src, n); \
160  } \
161 
162 #define NVM_MEMMOVE(dst, src, n) { \
163  nvm_memmove((void *)(dst), (size_t)(n)); \
164  memmove(dst, src, n); \
165  } \
166 
167 #define NVM_STRCPY(dst, src) { \
168  size_t sz=nvm_strlen(dst); \
169  nvm_strcpy((void *)(dst),(size_t)(sz)); \
170  strcpy(dst, src); \
171  } \
172 
173 #define NVM_STRNCPY(dst, src, n) { \
174  nvm_strcpy((void *)(dst),(size_t)(n)); \
175  strncpy(dst, src, n); \
176  } \
177 
178 #define NVM_STRCAT(dst, src) { \
179  size_t sz=nvm_strlen(dst); \
180  nvm_strcat((void *)(dst),(size_t)(sz)); \
181  strcat(dst, src); \
182  } \
183 
184 #define NVM_STRNCAT(dst, src, n) { \
185  size_t sz=nvm_strlen(dst); \
186  nvm_strcat((void *)(dst),(size_t)(sz)); \
187  strncat(dst, src, n); \
188  } \
189 
190 #elif defined(_USE_TABLE_FLUSH)
191 
192 #define NVM_STR(var,val,size) { \
193  nvm_store((void*)&(var),((size)*8)); \
194  var=val; \
195  AsyncDataFlush((void*)&(var)); \
196  } \
197 
198 #define NVM_STR2(var,val,size) { \
199  nvm_store((void*)&(var),(size)); \
200  var=val; \
201  AsyncDataFlush((void*)&(var)); \
202  } \
203 
204 #define NVM_MEMSET(s,c,n) { \
205  nvm_memset((void *)(s), (size_t)(n)); \
206  memset(s, c, n); \
207  AsyncMemOpDataFlush((void*)(s), n); \
208  } \
209 
210 #define NVM_MEMCPY(dst, src, n) { \
211  nvm_memcpy((void *)(dst), (size_t)(n)); \
212  memcpy(dst, src, n); \
213  AsyncMemOpDataFlush((void*)(dst), n); \
214  } \
215 
216 #define NVM_MEMMOVE(dst, src, n) { \
217  nvm_memmove((void *)(dst), (size_t)(n)); \
218  memmove(dst, src, n); \
219  AsyncMemOpDataFlush((void*)(dst), n); \
220  } \
221 
222 #define NVM_STRCPY(dst, src) { \
223  size_t sz=nvm_strlen(dst); \
224  nvm_strcpy((dst),(size_t)(sz)); \
225  strcpy(dst, src); \
226  AsyncMemOpDataFlush((void*)(dst), sz); \
227  } \
228 
229 #define NVM_STRNCPY(dst, src, n) { \
230  nvm_strcpy((dst),(size_t)(n)); \
231  strncpy(dst, src, n); \
232  AsyncMemOpDataFlush((void*)(dst), n); \
233  } \
234 
235 #define NVM_STRCAT(dst, src) { \
236  size_t sz=nvm_strlen(dst); \
237  nvm_strcat((dst),(size_t)(sz)); \
238  strcat(dst, src); \
239  AsyncMemOpDataFlush((void*)(dst), sz); \
240  } \
241 
242 #define NVM_STRNCAT(dst, src, n) { \
243  size_t sz=nvm_strlen(dst); \
244  nvm_strcat((dst),(size_t)(sz)); \
245  strncat(dst, src, n); \
246  AsyncMemOpDataFlush((void*)(dst), sz); \
247  } \
248 
249 #else
250 
251 // TODO for transient locations, a filter avoids logging and flushing.
252 // Currently, this filter is being called twice. This should be optimized
253 // to call once only. Ensure that the fix is done in the compiled code-path
254 // as well, i.e. it should be there for nvm_barrier as well.
255 
256 #define NVM_STR(var,val,size) { \
257  nvm_store((void*)&(var),((size)*8)); \
258  var=val; \
259  NVM_FLUSH_ACQ_COND(&var); \
260  } \
261 
262 #define NVM_STR2(var,val,size) { \
263  nvm_store((void*)&(var),(size)); \
264  var=val; \
265  NVM_FLUSH_ACQ_COND(&var); \
266  } \
267 
268 #define NVM_MEMSET(s,c,n) { \
269  nvm_memset((void *)(s), (size_t)(n)); \
270  memset(s, c, n); \
271  NVM_PSYNC_ACQ_COND(s, n); \
272  } \
273 
274 #define NVM_MEMCPY(dst, src, n) { \
275  nvm_memcpy((void *)(dst), (size_t)(n)); \
276  memcpy(dst, src, n); \
277  NVM_PSYNC_ACQ_COND(dst, n); \
278  } \
279 
280 #define NVM_MEMMOVE(dst, src, n) { \
281  nvm_memmove((void *)(dst), (size_t)(n)); \
282  memmove(dst, src, n); \
283  NVM_PSYNC_ACQ_COND(dst, n); \
284  } \
285 
286 #define NVM_STRCPY(dst, src) { \
287  size_t sz=nvm_strlen(dst); \
288  nvm_strcpy((void *)(dst),(size_t)(sz)); \
289  strcpy(dst, src); \
290  NVM_PSYNC_ACQ_COND(dst, sz); \
291  } \
292 
293 #define NVM_STRNCPY(dst, src, n) { \
294  nvm_strcpy((void *)(dst),(size_t)(n)); \
295  strncpy(dst, src, n); \
296  NVM_PSYNC_ACQ_COND(dst, n); \
297  } \
298 
299 #define NVM_STRCAT(dst, src) { \
300  size_t sz=nvm_strlen(dst); \
301  nvm_strcat((void *)(dst),(size_t)(sz)); \
302  strcat(dst, src); \
303  NVM_PSYNC_ACQ_COND(dst, sz); \
304  } \
305 
306 #define NVM_STRNCAT(dst, src, n) { \
307  size_t sz=nvm_strlen(dst); \
308  nvm_strcat((void *)(dst),(size_t)(sz)); \
309  strncat(dst, src, n); \
310  NVM_PSYNC_ACQ_COND(dst, sz); \
311  } \
312 
313 #endif
314 
315 #endif
void nvm_rwlock_unlock(void *lock_address)
Definition: log_mgr_api.cpp:66
void nvm_rwlock_rdlock(void *lock_address)
Definition: log_mgr_api.cpp:54
void nvm_log_free(void *addr)
Definition: log_mgr_api.cpp:133
void nvm_rwlock_wrlock(void *lock_address)
Definition: log_mgr_api.cpp:60
void nvm_acquire(void *lock_address)
Definition: log_mgr_api.cpp:42
void nvm_log_alloc(void *addr)
Definition: log_mgr_api.cpp:127
size_t nvm_strlen(char *dst)
Definition: log_mgr_api.cpp:110
void nvm_memset(void *addr, size_t sz)
Definition: log_mgr_api.cpp:92
void nvm_memcpy(void *dst, size_t sz)
Definition: log_mgr_api.cpp:98
void nvm_memmove(void *dst, size_t sz)
Definition: log_mgr_api.cpp:104
void nvm_store(void *addr, size_t size)
Definition: log_mgr_api.cpp:86
void nvm_release(void *lock_address)
Definition: log_mgr_api.cpp:48
int size(COW_AL *cal)
Definition: cow_array_list.c:183
void nvm_strcat(char *dst, size_t sz)
Definition: log_mgr_api.cpp:121
void nvm_strcpy(char *dst, size_t sz)
Definition: log_mgr_api.cpp:115
void nvm_barrier(void *)
Definition: log_mgr_api.cpp:139