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
;
43 fd
= open("/dev/zero", O_RDWR
);
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
);
90 /* page_size * 2, so we have a guard page afterwards.
91 * This is necessary for when we want to test page boundaries.
92 * see end of _get_address() for details.
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.