- Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathring_buffer.c
More file actions
Latest commit
95 lines (77 loc) · 2.39 KB
/
Copy pathring_buffer.c
File metadata and controls
95 lines (77 loc) · 2.39 KB
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
#include"ring_buffer.h"
#include<string.h>
ring_buffer*init_ring_buffer(intuse_hugepages) {
ring_buffer*rb= (ring_buffer*)malloc(sizeof(ring_buffer));
if (!rb) {
printf("Unable to allocate memory for ringbuffer\n");
returnNULL;
}
// Setup flags depending on hugepages or not
intpage_size, mfd_flags, mmap_flags;
if (use_hugepages) {
mfd_flags=MFD_HUGETLB | MFD_HUGE_2MB;
mmap_flags=MAP_HUGETLB | MAP_HUGE_2MB;
page_size= (1 << 21); // 2MB
} else {
mfd_flags=0;
mmap_flags=0;
page_size=getpagesize();
}
rb->index=0;
// Create a filedescriptor that will be used to assign virtual memory
intfd=memfd_create("page", mfd_flags);
if (fd==-1) {
perror("memfd_create failed");
free(rb);
returnNULL;
}
// Modify size to fit exactly a page
if (ftruncate(fd, page_size) ==-1) {
perror("ftruncate failed");
free(rb);
close(fd);
returnNULL;
}
// Map twice the memory in a contigious way
rb->array=mmap(NULL, 2*page_size, PROT_READ | PROT_WRITE,
MAP_SHARED | mmap_flags, fd, 0);
if (rb->array==MAP_FAILED) {
perror("mmap failed for first region");
close(fd);
free(rb);
returnNULL;
}
// Map the same array to the second half as well
if (mmap((char*)rb->array+page_size, page_size, PROT_READ | PROT_WRITE,
MAP_SHARED | MAP_FIXED | mmap_flags, fd, 0) ==MAP_FAILED) {
perror("mmap failed for second region");
munmap(rb->array, page_size);
close(fd);
free(rb);
returnNULL;
}
rb->capacity=page_size;
close(fd);
returnrb;
}
voidfree_ring_buffer(ring_buffer*rb) {
munmap(rb->array, 2*rb->capacity);
free(rb);
}
voidroll_ring_buffer(ring_buffer*rb, constsize_tnum_bytes) {
rb->index= (rb->index+num_bytes) % rb->capacity;
}
void*get_ring_buffer(ring_buffer*rb, constsize_tnum_bytes_offset) {
return (char*)(rb->array) +rb->index+num_bytes_offset;
}
voidread_ring_buffer(ring_buffer*rb, void*out, constsize_tnum_bytes,
constsize_tnum_bytes_offset) {
memcpy(out, get_ring_buffer(rb, num_bytes_offset), num_bytes);
}
voidwrite_ring_buffer(ring_buffer*rb, void*in, constsize_tnum_bytes) {
memcpy(get_ring_buffer(rb, 0), in, num_bytes);
roll_ring_buffer(rb, num_bytes);
}
size_tlength_ring_buffer(ring_buffer*rb, constsize_tbytes) {
returnrb->capacity / bytes;
}