-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpfences.h
111 lines (92 loc) · 3.55 KB
/
pfences.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
* Created on Tue Feb 25 2020
* Author: 2020 xxx
* University of Neuchatel (IIUN),
* University of Neuchatel (IIUN)
* Copyright Romulus by
* University of Neuchatel (IIUN) and
* University of Neuchatel (IIUN)
*/
#ifndef PFENCES_H
#define PFENCES_H
//#include <fcntl.h> header for file control
//#include <pthread.h> thread managment
//#include "stdatomic.h"
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
//#define PWB_IS_CLFLUSHOPT
#define PWB_IS_CLFLUSH
#define CL_SIZE 64 // Size of one CPU cache line
#define FLUSH_ALIGN ((uintptr_t)64)
#define ENTRY_SIZE 4096 // One complete page at maximum
//#define PMEM_PATH "/dev/shm."
//------------------------------
#if defined(PWB_IS_CLFLUSH)
#define PWB(addr) \
__asm__ volatile("clflush (%0)" ::"r"(addr) \
: "memory") // Broadwell only works with this.
#define PFENCE() \
{ \
} // No ordering fences needed for CLFLUSH (section 7.4.6 of Intel manual)
#define PSYNC() \
{ \
} // For durability it's not obvious, but CLFLUSH seems to be enough, and \
// PMDK uses the same approach
#elif defined(PWB_IS_CLWB)
/* Use this for CPUs that support clwb, such as the SkyLake SP series (c5
* compute intensive instances in AWS are an example of it) */
#define PWB(addr) \
__asm__ volatile( \
".byte 0x66; xsaveopt %0" \
: "+m"(*(volatile char *)(addr))) // clwb() only for Ice Lake onwards
#define PFENCE() __asm__ volatile("sfence" \
: \
: \
: "memory")
#define PSYNC() __asm__ volatile("sfence" \
: \
: \
: "memory")
#elif defined(PWB_IS_NOP)
/* pwbs are not needed for shared memory persistency (i.e. persistency across
* process failure) */
#define PWB(addr) \
{ \
}
#define PFENCE() __asm__ volatile("sfence" \
: \
: \
: "memory")
#define PSYNC() __asm__ volatile("sfence" \
: \
: \
: "memory")
#elif defined(PWB_IS_CLFLUSHOPT)
/* Use this for CPUs that support clflushopt, which is most recent x86 */
#define PWB(addr) \
__asm__ volatile(".byte 0x66; clflush %0" \
: "+m"(*(volatile char *)(addr))) // clflushopt (Kaby Lake)
#define PFENCE() __asm__ volatile("sfence" \
: \
: \
: "memory")
#define PSYNC() __asm__ volatile("sfence" \
: \
: \
: "memory")
#else
#error \
"You must define what PWB is. Choose PWB_IS_CLFLUSHOPT if you don't know what your CPU is capable of"
#endif
// Flush each cache line in a range
// TODO: fix cache alignment
inline static void flushFromTo(void* from, void* to) noexcept {
const int cache_line_size = 64;
uint8_t* ptr = (uint8_t*)from;
for (; ptr < (uint8_t*)to; ptr += cache_line_size) PWB(ptr);
}
//-----------------------------
#endif /* PFENCES_H */