-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhugepages.c
133 lines (108 loc) · 3.43 KB
/
hugepages.c
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
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <numa.h>
#include <numaif.h>
#include <ncurses.h>
#define GIGABYTE (1UL << 30)
unsigned long long get_physical_address(void *virtual_addr) {
unsigned long long paddr;
unsigned long long vaddr = (unsigned long long)virtual_addr;
int fd = open("/proc/self/pagemap", O_RDONLY);
if (fd < 0) {
perror("open");
exit(1);
}
unsigned long long offset = (vaddr / sysconf(_SC_PAGESIZE)) * sizeof(unsigned long long);
if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
perror("lseek");
exit(1);
}
if (read(fd, &paddr, sizeof(unsigned long long)) != sizeof(unsigned long long)) {
perror("read");
exit(1);
}
close(fd);
// Check if page is present
if (!(paddr & (1ULL << 63))) {
fprintf(stderr, "Page not present\n");
exit(1);
}
// Extract the physical page number
paddr = (paddr & ((1ULL << 55) - 1)) * sysconf(_SC_PAGESIZE);
// Add the page offset
paddr |= (vaddr & (sysconf(_SC_PAGESIZE) - 1));
return paddr;
}
int main() {
void *addr1, *addr2;
int status;
char ch;
// Ensure NUMA is available and nodes exist
if (numa_available() == -1) {
fprintf(stderr, "NUMA is not available\n");
exit(1);
}
if (numa_num_configured_nodes() < 2) {
fprintf(stderr, "At least two NUMA nodes are required\n");
exit(1);
}
// Allocate 1GB page on node 0
addr1 = mmap(NULL, GIGABYTE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
if (addr1 == MAP_FAILED) {
perror("mmap addr1");
exit(1);
}
status = mbind(addr1, GIGABYTE, MPOL_BIND, (unsigned long[]){1}, sizeof(unsigned long) * 8, 0);
if (status != 0) {
perror("mbind addr1");
munmap(addr1, GIGABYTE);
exit(1);
}
// Access memory to ensure pages are allocated
memset(addr1, 0, GIGABYTE);
// Allocate 1GB page on node 1
addr2 = mmap(NULL, GIGABYTE, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB, -1, 0);
if (addr2 == MAP_FAILED) {
perror("mmap addr2");
munmap(addr1, GIGABYTE);
exit(1);
}
status = mbind(addr2, GIGABYTE, MPOL_BIND, (unsigned long[]){2}, sizeof(unsigned long) * 8, 0);
if (status != 0) {
perror("mbind addr2");
munmap(addr1, GIGABYTE);
munmap(addr2, GIGABYTE);
exit(1);
}
// Access memory to ensure pages are allocated
memset(addr2, 0, GIGABYTE);
printf("Virtual address of addr1: %p\n", addr1);
printf("Virtual address of addr2: %p\n", addr2);
unsigned long long paddr1 = get_physical_address(addr1);
unsigned long long paddr2 = get_physical_address(addr2);
printf("Physical address of addr1: 0x%llx\n", paddr1);
printf("Physical address of addr2: 0x%llx\n", paddr2);
while (1) {
printf("Enter a character (' ' to exit): ");
ch = getchar(); // 获取键盘输入
if (ch == ' ') {
break; // 如果按下空格键,退出循环
} else {
printf("Key pressed: %c\n", ch);
// 在这里执行其他操作
}
}
// Clean up
printf("munmap\n");
munmap(addr1, GIGABYTE);
munmap(addr2, GIGABYTE);
return 0;
}