8
8
#include <sys/mman.h>
9
9
#include <sys/types.h>
10
10
#include <sys/stat.h>
11
#include "trinity.h" // page_size
17
static unsigned int num_mappings = 0;
18
static struct map *maps_list;
25
void * alloc_shared(unsigned int size)
29
ret = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_SHARED, -1, 0);
30
if (ret == MAP_FAILED)
36
static struct map * alloc_map(void)
40
newmap = malloc(sizeof(struct map));
42
printf("Couldn't allocate maps list!\n");
45
memset(newmap, 0, sizeof(struct map));
49
static void dump_maps(void)
51
struct map *tmpmap = maps_list;
54
output(2, "There are %d entries in the map table\n", num_mappings);
56
for (j = 0; j < num_mappings; j++) {
57
output(2, " start: %p name: %s\n", tmpmap->ptr, tmpmap->name);
58
tmpmap = tmpmap->next;
62
static void * alloc_zero_map(struct map *map, int prot, const char *name)
64
struct map *tmpmap = map;
18
#include "trinity.h" // page_size
21
static unsigned int num_global_mappings = 0;
22
static struct map *global_mappings = NULL;
24
static void dump_global_mappings(void)
27
struct list_head *node;
29
output(2, "There are %d entries in the map table\n", num_global_mappings);
31
list_for_each(node, &global_mappings->list) {
32
m = (struct map *) node;
33
output(2, " start: %p name: %s\n", m->ptr, m->name);
37
static void alloc_zero_map(unsigned long size, int prot, const char *name)
40
struct list_head *list;
66
unsigned long size = 0;
71
43
fd = open("/dev/zero", O_RDWR);
73
printf("open /dev/zero failure. %s\n", strerror(errno));
77
/* Pick a random sized mmap. */
79
case 0: size = page_size;
81
case 1: size = 1024*1024;
83
case 2: size = 2 * (1024*1024);
85
case 3: size = 4 * (1024*1024);
45
outputerr("couldn't open /dev/zero\n");
49
newnode = zmalloc(sizeof(struct map));
50
newnode->name = strdup(name);
53
newnode->type = MAP_GLOBAL;
54
newnode->ptr = mmap(NULL, size, prot, MAP_ANONYMOUS | MAP_SHARED, fd, 0);
55
if (newnode->ptr == MAP_FAILED) {
56
outputerr("mmap failure\n");
60
newnode->name = malloc(80);
62
outputerr("malloc() failed in %s().", __func__);
66
sprintf(newnode->name, "anon(%s)", name);
68
num_global_mappings++;
70
list = &global_mappings->list;
71
list_add_tail(&newnode->list, list);
73
output(2, "mapping[%d]: (zeropage %s) %p (%lu bytes)\n",
74
num_global_mappings - 1, name, newnode->ptr, size);
79
void setup_global_mappings(void)
82
const unsigned long sizes[] = {
83
1 * MB, 2 * MB, 4 * MB, 10 * MB,
84
// 1 * GB, // disabled for now, due to OOM.
87
global_mappings = zmalloc(sizeof(struct map));
88
INIT_LIST_HEAD(&global_mappings->list);
91
90
/* page_size * 2, so we have a guard page afterwards.
92
91
* This is necessary for when we want to test page boundaries.
93
92
* see end of _get_address() for details.
97
tmpmap->ptr = mmap(NULL, size, prot, MAP_ANONYMOUS|MAP_SHARED, fd, 0);
99
if (tmpmap->ptr == MAP_FAILED) {
100
printf("mmap /dev/zero failure\n");
106
tmpmap->name = malloc(80);
108
fprintf(stderr, "malloc() failed in %s().", __func__);
112
sprintf(tmpmap->name, "/dev/zero(%s)", name);
115
output(2, "mapping[%d]: (zeropage %s) %p (%lu bytes)\n",
116
num_mappings - 1, name, tmpmap->ptr, size);
123
void setup_maps(void)
127
tmpmap = maps_list = alloc_map();
129
/* Add a bunch of /dev/zero mappings */
130
tmpmap->next = alloc_zero_map(tmpmap, PROT_READ | PROT_WRITE, "PROT_READ | PROT_WRITE");
131
tmpmap = tmpmap->next;
133
tmpmap->next = alloc_zero_map(NULL, PROT_READ, "PROT_READ");
134
tmpmap = tmpmap->next;
136
tmpmap->next = alloc_zero_map(NULL, PROT_WRITE, "PROT_WRITE");
138
output(2, "Added /dev/zero mappings.\n");
144
struct map *tmpmap = maps_list;
147
i = rand() % num_mappings;
148
for (j = 0; j < i; j++)
149
tmpmap = tmpmap->next;
154
void destroy_maps(void)
157
struct map *thismap = maps_list, *next;
159
for (i = 0; i < num_mappings; i++) {
160
next = thismap->next;
161
munmap(thismap->ptr, thismap->size);
169
void init_buffers(void)
173
output(2, "shm is at %p\n", shm);
175
page_zeros = memalign(page_size, page_size * 2);
178
memset(page_zeros, 0, page_size);
179
output(2, "page_zeros @ %p\n", page_zeros);
181
page_0xff = memalign(page_size, page_size * 2);
184
memset(page_0xff, 0xff, page_size);
185
output(2, "page_0xff @ %p\n", page_0xff);
187
page_rand = memalign(page_size, page_size * 2);
190
memset(page_rand, 0x55, page_size); /* overwritten below */
191
output(2, "page_rand @ %p\n", page_rand);
193
page_allocs = memalign(page_size, page_size * 2);
196
memset(page_allocs, 0xff, page_size);
197
output(2, "page_allocs @ %p\n", page_allocs);
199
for (i = 0; i < (page_size / sizeof(unsigned long *)); i++)
200
page_allocs[i] = (unsigned long) malloc(page_size);
204
// generate_random_page may end up using maps, so has to be last.
205
generate_random_page(page_rand);
94
alloc_zero_map(page_size * 2, PROT_READ | PROT_WRITE, "PROT_READ | PROT_WRITE");
95
alloc_zero_map(page_size * 2, PROT_READ, "PROT_READ");
96
alloc_zero_map(page_size * 2, PROT_WRITE, "PROT_WRITE");
99
* multi megabyte page mappings.
101
for (i = 0; i < ARRAY_SIZE(sizes); i++) {
102
alloc_zero_map(sizes[i], PROT_READ | PROT_WRITE, "PROT_READ | PROT_WRITE");
103
alloc_zero_map(sizes[i], PROT_READ, "PROT_READ");
104
alloc_zero_map(sizes[i], PROT_WRITE, "PROT_WRITE");
107
dump_global_mappings();
110
/* Walk the list, get the j'th element */
111
static struct map * __get_map(struct list_head *head, unsigned int max)
114
struct list_head *node;
116
unsigned int i, j = 0;
120
list_for_each(node, head) {
121
m = (struct map *) node;
130
struct map * get_map(void)
135
/* If we're not running in child context, just do global. */
137
return __get_map(&global_mappings->list, num_global_mappings);
139
/* Only toss the dice if we actually have local mappings. */
140
if (shm->num_mappings[this_child] > 0)
144
map = __get_map(&shm->mappings[this_child]->list, shm->num_mappings[this_child]);
146
map = __get_map(&global_mappings->list, num_global_mappings);
151
void destroy_global_mappings(void)
155
while (!list_empty(&global_mappings->list)) {
158
munmap(m->ptr, m->size);
161
global_mappings = (struct map *) m->list.next;
167
num_global_mappings = 0;
170
static void delete_local_mapping(int childno, struct map *map)
172
list_del(&map->list);
173
shm->num_mappings[childno]--;
176
void delete_mapping(int childno, struct map *map)
178
if (map->type == MAP_LOCAL)
179
delete_local_mapping(childno, map);
181
/* Right now, we don't want to delete MAP_GLOBAL mappings */
184
struct map * common_set_mmap_ptr_len(int childno)
188
map = (struct map *) shm->a1[childno];
189
shm->scratch[childno] = (unsigned long) map; /* Save this for ->post */
191
shm->a1[childno] = 0;
192
shm->a2[childno] = 0;
196
shm->a1[childno] = (unsigned long) map->ptr;
197
shm->a2[childno] = map->size; //TODO: Munge this.
202
void dirty_mapping(struct map *map)
207
/* Check mapping is writable. */
208
if (!(map->prot & PROT_WRITE))
212
/* Just fault in one page. */
213
p[rand() % page_size] = 1;
215
/* fault in the whole mapping */
216
for (i = 0; i < map->size; i += page_size)
219
//TODO: More access patterns.