]>
Commit | Line | Data |
---|---|---|
0b4e3aa0 A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | /* | |
23 | */ | |
24 | ||
25 | /* | |
26 | * File: vm/task_working_set.h | |
27 | * Author: Chris Youngworth | |
28 | * Date: 2001 | |
29 | * | |
30 | * Working set detection and maintainence module | |
31 | * | |
32 | */ | |
33 | ||
34 | #ifndef _VM_TASK_WORKING_SET_H_ | |
35 | #define _VM_TASK_WORKING_SET_H_ | |
36 | ||
37 | #include <kern/queue.h> | |
38 | #include <vm/vm_object.h> | |
39 | ||
40 | /* task working set */ | |
41 | ||
42 | #define tws_lock(tws) mutex_lock(&(tws)->lock) | |
43 | #define tws_lock_try(tws) mutex_try(&(tws)->lock) | |
44 | #define tws_unlock(tws) mutex_unlock(&(tws)->lock) | |
45 | ||
46 | ||
47 | #define TWS_ARRAY_SIZE 8 | |
48 | #define TWS_HASH_LINE_COUNT 32 | |
49 | /* start out size to allow monitoring of working set without excessive use */ | |
50 | /* of wired memory resource. */ | |
51 | #define TWS_SMALL_HASH_LINE_COUNT 4 | |
52 | ||
0b4e3aa0 A |
53 | /* |
54 | * do not think of changing this hash unless you understand the implications | |
55 | * for the hash element page_cache field | |
56 | */ | |
57 | #define do_tws_hash(object,offset, rows, lines) \ | |
9bccf70c A |
58 | ((((((natural_t)(object)) + \ |
59 | (((natural_t)(object)) >> 6) + \ | |
60 | (((natural_t)(object)) >> 12) + \ | |
61 | (((natural_t)(object)) >> 18) + \ | |
62 | (((natural_t)(object)) >> 24)) << 5) + \ | |
0b4e3aa0 | 63 | ((natural_t)(((vm_object_offset_t)(offset)) >> 17))) & \ |
9bccf70c | 64 | ((rows * lines) -1)) |
0b4e3aa0 A |
65 | |
66 | ||
67 | #define alt_tws_hash(addr, rows, lines) \ | |
9bccf70c A |
68 | ((((natural_t)(addr)) >> 17) & \ |
69 | ((rows * lines) -1)) | |
70 | ||
71 | ||
72 | /* Long term startup data structures for initial cache filling */ | |
73 | ||
74 | #define TWS_STARTUP_MAX_HASH_RETRY 3 | |
75 | ||
76 | /* 87 is the wrap skew, its based on RETRY times the RETRY offset of 29 */ | |
77 | /* | |
78 | #define do_startup_hash(addr, hash_size) \ | |
79 | ((((((natural_t)(addr)) >> 17) & \ | |
80 | ((2 * (hash_size)) -1)) + \ | |
81 | (87 * (((addr) & TWS_ADDR_OFF_MASK)/(2 * (hash_size))))) & \ | |
82 | ((2 * (hash_size)) -1)) | |
83 | */ | |
84 | #define do_startup_hash(addr, hash_size) \ | |
85 | (((((natural_t)(addr)) >> 17) * 3) & \ | |
86 | (hash_size -1)) | |
87 | ||
88 | ||
89 | ||
90 | struct tws_startup_ele { | |
91 | unsigned int page_cache; | |
92 | vm_offset_t page_addr; | |
93 | }; | |
94 | ||
95 | typedef struct tws_startup_ele *tws_startup_ele_t; | |
96 | ||
97 | ||
98 | struct tws_startup_ptr { | |
99 | tws_startup_ele_t element; | |
100 | struct tws_startup_ptr *next; | |
101 | }; | |
102 | ||
103 | typedef struct tws_startup_ptr *tws_startup_ptr_t; | |
104 | ||
105 | struct tws_startup { | |
106 | unsigned int tws_hash_size; /* total size of struct in bytes */ | |
107 | unsigned int ele_count; | |
108 | unsigned int array_size; /* lines * rows * expansion_count */ | |
109 | unsigned int hash_count; | |
110 | ||
111 | tws_startup_ptr_t *table; /* hash table */ | |
112 | struct tws_startup_ptr *ele; /* hash elements */ | |
113 | struct tws_startup_ele *array; | |
114 | }; | |
115 | ||
116 | typedef struct tws_startup *tws_startup_t; | |
117 | ||
118 | ||
119 | /* Dynamic cache data structures for working set */ | |
0b4e3aa0 A |
120 | |
121 | struct tws_hash_ele { | |
122 | vm_object_t object; | |
123 | vm_object_offset_t offset; | |
124 | unsigned int page_cache; | |
125 | vm_offset_t page_addr; | |
126 | int line; | |
127 | vm_map_t map; | |
128 | }; | |
129 | typedef struct tws_hash_ele *tws_hash_ele_t; | |
130 | ||
131 | #define TWS_HASH_OFF_MASK ((vm_object_offset_t)0xFFFFFFFFFFFE0000) | |
9bccf70c | 132 | #define TWS_ADDR_OFF_MASK ((vm_offset_t)0xFFFE0000) |
0b4e3aa0 A |
133 | #define TWS_INDEX_MASK ((vm_object_offset_t)0x000000000001F000) |
134 | ||
9bccf70c A |
135 | struct tws_hash_ptr { |
136 | tws_hash_ele_t element; | |
137 | struct tws_hash_ptr *next; | |
138 | }; | |
139 | typedef struct tws_hash_ptr *tws_hash_ptr_t; | |
140 | ||
0b4e3aa0 A |
141 | struct tws_hash_line { |
142 | int ele_count; | |
143 | struct tws_hash_ele list[TWS_ARRAY_SIZE]; | |
144 | }; | |
145 | typedef struct tws_hash_line *tws_hash_line_t; | |
146 | ||
147 | #define TWS_HASH_STYLE_DEFAULT 0x0 | |
148 | #define TWS_HASH_STYLE_BASIC 0x1 | |
149 | #define TWS_HASH_STYLE_SIGNAL 0x2 | |
150 | ||
151 | ||
9bccf70c | 152 | #define TWS_ADDR_HASH 1 |
0b4e3aa0 | 153 | #define TWS_HASH_EXPANSION_MAX 5 |
9bccf70c | 154 | #define TWS_MAX_REHASH 3 |
0b4e3aa0 A |
155 | |
156 | ||
157 | struct tws_hash { | |
158 | decl_mutex_data(,lock) /* tws_hash's lock */ | |
159 | int style; | |
160 | ||
161 | int current_line; | |
162 | unsigned int pageout_count; | |
163 | int line_count; | |
164 | ||
165 | int number_of_lines; | |
166 | int number_of_elements; | |
167 | int expansion_count; | |
168 | unsigned int time_of_creation; | |
169 | ||
170 | int lookup_count; | |
171 | int insert_count; | |
172 | ||
9bccf70c A |
173 | tws_startup_t startup_cache; |
174 | char *startup_name; | |
175 | int startup_name_length; | |
176 | unsigned int uid; | |
177 | int mod; | |
178 | int fid; | |
179 | ||
180 | unsigned int obj_free_count[TWS_HASH_EXPANSION_MAX]; | |
181 | unsigned int addr_free_count[TWS_HASH_EXPANSION_MAX]; | |
182 | tws_hash_ptr_t free_hash_ele[TWS_HASH_EXPANSION_MAX]; | |
183 | tws_hash_ptr_t *table[TWS_HASH_EXPANSION_MAX]; | |
184 | tws_hash_ptr_t table_ele[TWS_HASH_EXPANSION_MAX]; | |
185 | tws_hash_ptr_t alt_ele[TWS_HASH_EXPANSION_MAX]; | |
0b4e3aa0 A |
186 | struct tws_hash_line *cache[TWS_HASH_EXPANSION_MAX]; |
187 | }; | |
188 | ||
189 | typedef struct tws_hash *tws_hash_t; | |
190 | ||
191 | ||
192 | extern tws_hash_t tws_hash_create(); | |
193 | ||
194 | extern void tws_hash_line_clear( | |
195 | tws_hash_t tws, | |
196 | tws_hash_line_t hash_line, | |
197 | boolean_t live); | |
198 | ||
199 | extern kern_return_t tws_lookup( | |
200 | tws_hash_t tws, | |
201 | vm_object_offset_t offset, | |
202 | vm_object_t object, | |
203 | tws_hash_line_t *line); | |
204 | ||
205 | extern kern_return_t tws_insert( | |
206 | tws_hash_t tws, | |
207 | vm_object_offset_t offset, | |
208 | vm_object_t object, | |
209 | vm_offset_t page_addr, | |
210 | vm_map_t map); | |
211 | ||
212 | extern void tws_build_cluster( | |
213 | tws_hash_t tws, | |
214 | vm_object_t object, | |
215 | vm_object_offset_t *start, | |
216 | vm_object_offset_t *end, | |
217 | vm_size_t max_length); | |
218 | ||
219 | extern tws_line_signal( | |
220 | tws_hash_t tws, | |
221 | vm_map_t map, | |
222 | tws_hash_line_t hash_line, | |
223 | vm_offset_t target_page); | |
224 | ||
225 | extern void tws_hash_destroy( | |
226 | tws_hash_t tws); | |
227 | ||
228 | extern void tws_hash_clear( | |
229 | tws_hash_t tws); | |
230 | ||
231 | kern_return_t task_working_set_create( | |
232 | task_t task, | |
233 | unsigned int lines, | |
234 | unsigned int rows, | |
235 | unsigned int style); | |
236 | ||
237 | kern_return_t tws_expand_working_set( | |
238 | vm_offset_t old_tws, | |
9bccf70c A |
239 | int line_count, |
240 | boolean_t dump_data); | |
241 | ||
242 | kern_return_t tws_handle_startup_file( | |
243 | task_t task, | |
244 | unsigned int uid, | |
245 | char *app_name, | |
246 | vm_offset_t app_vp, | |
247 | boolean_t *new_info); | |
248 | ||
249 | kern_return_t tws_write_startup_file( | |
250 | task_t task, | |
251 | int fid, | |
252 | int mod, | |
253 | char *name, | |
254 | unsigned int string_length); | |
255 | ||
256 | kern_return_t tws_read_startup_file( | |
257 | task_t task, | |
258 | tws_startup_t startup, | |
259 | vm_offset_t cache_size); | |
260 | ||
0b4e3aa0 A |
261 | |
262 | ||
263 | #endif /* _VM_TASK_WORKING_SET_H_ */ |