2 .\" Copyright (c) 2004 Mark W. Krentel <krentel@dreamscape.com>
3 .\" All rights reserved.
5 .\" Redistribution and use in source and binary forms, with or without
6 .\" modification, are permitted provided that the following conditions
8 .\" 1. Redistributions of source code must retain the above copyright
9 .\" notice, this list of conditions and the following disclaimer.
10 .\" 2. Redistributions in binary form must reproduce the above copyright
11 .\" notice, this list of conditions and the following disclaimer in the
12 .\" documentation and/or other materials provided with the distribution.
14 .\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 .\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 .Dt VM_MAP_ENTRY_RESIZE_FREE 9
32 .Nm vm_map_entry_resize_free
33 .Nd "vm map free space algorithm"
39 .Fn vm_map_entry_resize_free "vm_map_t map" "vm_map_entry_t entry"
41 This manual page describes the
43 fields used in the VM map free space algorithm, how to maintain
44 consistency of these variables, and the
45 .Fn vm_map_entry_resize_free
48 VM map entries are organized as both a doubly-linked list
52 pointers) and as a binary search tree
57 The search tree is organized as a Sleator and Tarjan splay tree,
59 .Dq "self-adjusting tree" .
60 .Bd -literal -offset indent
62 struct vm_map_entry *prev;
63 struct vm_map_entry *next;
64 struct vm_map_entry *left;
65 struct vm_map_entry *right;
68 vm_offset_t avail_ssize;
75 The free space algorithm adds two fields to
76 .Vt "struct vm_map_entry" :
83 is the amount of free address space adjacent to and immediately
84 following (higher address) the map entry.
85 This field is unused in the map header.
88 depends on the linked list, not the splay tree and that
91 .Bd -literal -offset indent
92 entry->adj_free = (entry->next == &map->header ?
93 map->max_offset : entry->next->start) - entry->end;
99 is the maximum amount of contiguous free space in the entry's subtree.
102 depends on the splay tree, not the linked list and that
104 is computed by taking the maximum of its own
108 of its left and right subtrees.
111 is unused in the map header.
113 These fields allow for an
116 .Fn vm_map_findspace .
119 we can immediately test for a sufficiently large free region
120 in an entire subtree.
121 This makes it possible to find a first-fit free region of a given size
122 in one pass down the tree, so
124 amortized using splay trees.
126 When a free region changes size, we must update
130 in the preceding map entry and propagate
134 .Fn vm_map_entry_link
136 .Fn vm_map_entry_unlink
137 for the cases of inserting and deleting an entry.
139 .Fn vm_map_entry_link
140 updates both the new entry and the previous entry, and that
141 .Fn vm_map_entry_unlink
142 updates the previous entry.
145 is not actually propagated up the tree.
146 Instead, that entry is first splayed to the root and
147 then the change is made there.
148 This is a common technique in splay trees and is also
149 how map entries are linked and unlinked into the tree.
152 .Fn vm_map_entry_resize_free
153 function updates the free space variables in the given
155 and propagates those values up the tree.
156 This function should be called whenever a map entry is resized
157 in-place, that is, by modifying its
162 Note that if you change
164 then you should resize that entry, but if you change
166 then you should resize the previous entry.
167 The map must be locked before calling this function,
168 and again, propagating
170 is performed by splaying that entry to the root.
172 Consider adding a map entry with
174 .Bd -literal -offset indent
175 ret = vm_map_insert(map, object, offset, start, end, prot,
179 In this case, no further action is required to maintain
180 consistency of the free space variables.
184 .Fn vm_map_entry_link
185 which updates both the new entry and the previous entry.
186 The same would be true for
189 .Fn vm_map_entry_link
191 .Fn vm_map_entry_unlink
194 Now consider resizing an entry in-place without a call to
195 .Fn vm_map_entry_link
197 .Fn vm_map_entry_unlink .
198 .Bd -literal -offset indent
199 entry->start = new_start;
200 if (entry->prev != &map->header)
201 vm_map_entry_resize_free(map, entry->prev);
204 In this case, resetting
206 changes the amount of free space following the previous entry,
208 .Fn vm_map_entry_resize_free
209 to update the previous entry.
211 Finally, suppose we change an entry's
214 .Bd -literal -offset indent
215 entry->end = new_end;
216 vm_map_entry_resize_free(map, entry);
220 .Fn vm_map_entry_resize_free
224 .Xr vm_map_findspace 9
226 .%A Daniel D. Sleator
228 .%T Self-Adjusting Binary Search Trees
235 Splay trees were added to the VM map in
239 tree-based free space algorithm was added in
242 The tree-based free space algorithm and this manual page were written by
244 .Aq krentel@dreamscape.com .