merge send* syscall variants
[trinity.git] / maps-fault.c
blob1fbae5bb59301ba20502ef984fe3168d8020726f
1 /*
2 * Routines to dirty/fault-in mapped pages.
3 */
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/mman.h>
8 #include <sys/types.h>
9 #include <sys/stat.h>
10 #include "arch.h"
11 #include "maps.h"
12 #include "random.h"
13 #include "utils.h"
15 struct faultfn {
16 void (*func)(struct map *map);
19 /*****************************************************************************/
20 /* dirty page routines */
22 static void dirty_one_page(struct map *map)
24 char *p = map->ptr;
26 p[rand() % map->size] = rand();
29 static void dirty_whole_mapping(struct map *map)
31 char *p = map->ptr;
32 unsigned int i;
34 for (i = 0; i < map->size; i += page_size)
35 p[i] = rand();
38 static void dirty_every_other_page(struct map *map)
40 char *p = map->ptr;
41 unsigned int i;
43 for (i = 0; i < map->size; i += (page_size * 2))
44 p[i] = rand();
47 static void dirty_mapping_reverse(struct map *map)
49 char *p = map->ptr;
50 unsigned int i;
52 for (i = (map->size - page_size); i > 0; i -= page_size)
53 p[i] = rand();
56 /* dirty a random set of map->size pages. (some may be faulted >once) */
57 static void dirty_random_pages(struct map *map)
59 char *p = map->ptr;
60 unsigned int i;
61 unsigned int num_pages = map->size / page_size;
63 for (i = 0; i < num_pages; i++)
64 p[(rand() % (num_pages + 1)) * page_size] = rand();
67 /* Dirty the last page in a mapping
68 * Fill it with ascii, in the hope we do something like
69 * a strlen and go off the end. */
70 static void dirty_last_page(struct map *map)
72 char *p = map->ptr;
74 memset((void *) p + (map->size - page_size), 'A', page_size);
77 static const struct faultfn write_faultfns[] = {
78 { .func = dirty_one_page },
79 { .func = dirty_whole_mapping },
80 { .func = dirty_every_other_page },
81 { .func = dirty_mapping_reverse },
82 { .func = dirty_random_pages },
83 { .func = dirty_last_page },
86 /*****************************************************************************/
87 /* routines to fault in pages */
89 static void read_one_page(struct map *map)
91 char *p = map->ptr;
92 unsigned long offset = (rand() % map->size) & PAGE_MASK;
93 char buf[page_size];
95 p += offset;
96 memcpy(buf, p, page_size);
100 static void read_whole_mapping(struct map *map)
102 char *p = map->ptr;
103 unsigned int i;
104 char buf[page_size];
106 for (i = 0; i < map->size; i += page_size)
107 memcpy(buf, p + i, page_size);
110 static void read_every_other_page(struct map *map)
112 char *p = map->ptr;
113 unsigned int i;
114 char buf[page_size];
116 for (i = 0; i < map->size; i += (page_size * 2))
117 memcpy(buf, p + i, page_size);
120 static void read_mapping_reverse(struct map *map)
122 char *p = map->ptr;
123 unsigned int i;
124 char buf[page_size];
126 for (i = (map->size - page_size); i > 0; i -= page_size)
127 memcpy(buf, p + i, page_size);
130 /* fault in a random set of map->size pages. (some may be faulted >once) */
131 static void read_random_pages(struct map *map)
133 char *p = map->ptr;
134 unsigned int i;
135 unsigned int num_pages = map->size / page_size;
136 char buf[page_size];
138 for (i = 0; i < num_pages; i++)
139 memcpy(buf, p + ((rand() % (num_pages + 1)) * page_size), page_size);
142 /* Fault in the last page in a mapping */
143 static void read_last_page(struct map *map)
145 char *p = map->ptr;
146 char buf[page_size];
148 memcpy(buf, p + (map->size - page_size), page_size);
151 static const struct faultfn read_faultfns[] = {
152 { .func = read_one_page },
153 { .func = read_whole_mapping },
154 { .func = read_every_other_page },
155 { .func = read_mapping_reverse },
156 { .func = read_random_pages },
157 { .func = read_last_page },
160 /*****************************************************************************/
163 * Routine to perform various kinds of write operations to a mapping
164 * that we created.
166 void dirty_mapping(struct map *map)
168 bool rw = rand_bool();
170 if (rw == TRUE) {
171 /* Check mapping is writable, or we'll segv.
172 * TODO: Perhaps we should do that, and trap it, mark it writable,
173 * then reprotect after we dirtied it ? */
174 if (!(map->prot & PROT_WRITE))
175 return;
177 write_faultfns[rand() % ARRAY_SIZE(write_faultfns)].func(map);
178 return;
179 } else {
180 if (!(map->prot & PROT_READ))
181 return;
183 read_faultfns[rand() % ARRAY_SIZE(read_faultfns)].func(map);