20 |
|
|
21 |
#include <stdbool.h> |
#include <stdbool.h> |
22 |
#include <rtmk/vm-types.h> |
#include <rtmk/vm-types.h> |
23 |
|
#include <rtmk/memory-object.h> |
24 |
#include "queue.h" |
#include "queue.h" |
25 |
#include "thread-lock.h" |
#include "thread-lock.h" |
26 |
#include "vm-pager.h" |
#include "vm-pager.h" |
32 |
|
|
33 |
The page list is ordered according to location within the object. |
The page list is ordered according to location within the object. |
34 |
A page can only be assigned to one object once. A object can |
A page can only be assigned to one object once. A object can |
35 |
"shadow" another object and use its pages, though. */ |
"shadow" another object and use its pages, though. |
36 |
|
|
37 |
|
PAGER_OBJECT is the backing storage pager, which is either |
38 |
|
the default internal pager, the host pager or the external pager. |
39 |
|
PAGER_COOKIE is a cookie for PAGER_OBJECT. |
40 |
|
|
41 |
|
PAGER_NAME is a kernel port that represents the object. */ |
42 |
struct vm_object |
struct vm_object |
43 |
{ |
{ |
|
vm_size_t size; /* Size of object. */ |
|
44 |
int refcnt; /* Reference counter. */ |
int refcnt; /* Reference counter. */ |
45 |
|
|
46 |
struct thread_lock lock; /* Lock for structure. */ |
/* Lock for object. Use vm_object_lock/unlock macros. */ |
47 |
|
struct thread_lock lock; |
48 |
struct queue_entry pageq; /* List of pages */ |
|
49 |
int resident_page_cnt; /* Number of pages in list. */ |
/* Size of the object, must be page aligned. */ |
50 |
|
vm_size_t size; |
51 |
struct vm_object *shadow_object; /* Object that we shadow. */ |
|
52 |
vm_offset_t shadow_offset; /* Offset into shadow_object. */ |
/* List of resident pages for this object. List is ordered |
53 |
|
according to location within the object. */ |
54 |
|
struct queue_entry pageq; |
55 |
|
int resident_page_cnt; |
56 |
|
|
57 |
|
/* Pointer to object that this object is shadowing. SHADOW_OFFSET |
58 |
|
is offset into that object. We hold reference to object. */ |
59 |
|
struct vm_object *shadow_object; |
60 |
|
vm_offset_t shadow_offset; |
61 |
|
|
62 |
struct vm_object *copy_object; /* Object that have shadowed us. */ |
struct vm_object *copy_object; /* Object that have shadowed us. */ |
63 |
|
struct vm_object *copy; |
64 |
|
|
65 |
struct vm_pager *pager_object; /* Pager of this object. */ |
/* Backing storage pager for this object. PAGER_COOKIE |
66 |
void *pager_cookie; /* Cookie to pager. */ |
is a cookie for the pager, may be set to whatever. */ |
67 |
|
struct vm_pager *pager; |
68 |
|
void *pager_cookie; |
69 |
|
|
70 |
|
/* Offset into the pager object. */ |
71 |
|
vm_offset_t pager_offset; |
72 |
|
|
73 |
|
/* The memory object ports are being used (e.g., for pagein or pageout) |
74 |
|
-- don't change any of these fields (i.e., don't collapse, destroy |
75 |
|
or terminate) */ |
76 |
|
unsigned int paging_in_progress; |
77 |
|
|
78 |
struct ipc_port *object_port; /* External object port. */ |
struct ipc_port *object_port; /* External object port. */ |
79 |
|
|
80 |
bool shadowed_p; /* If we're a shadow, or not. */ |
/* Kernel object port that represents this object. */ |
81 |
|
struct ipc_port *pager_request; |
82 |
|
|
83 |
|
unsigned int all_wanted; |
84 |
|
unsigned int copy_strategy; |
85 |
|
|
86 |
|
bool shadowed_p: 1; |
87 |
|
bool temporary_p: 1; |
88 |
|
bool pager_created_p: 1; |
89 |
|
bool pager_initialized_p: 1; |
90 |
|
bool internal_p: 1; |
91 |
|
bool pager_ready_p: 1; |
92 |
|
bool can_persist_p: 1; |
93 |
}; |
}; |
94 |
|
|
95 |
|
/* Convenience macros for locking/unlocking OBJECT. */ |
96 |
|
#define vm_object_lock(OBJECT) thread_lock_write (& (OBJECT)->lock) |
97 |
|
#define vm_object_unlock(OBJECT) thread_lock_unlock (& (OBJECT)->lock) |
98 |
|
|
99 |
/* Bootstrap VM objects. */ |
/* Bootstrap VM objects. */ |
|
|
|
100 |
extern void vm_object_bootstrap (void); |
extern void vm_object_bootstrap (void); |
101 |
|
|
102 |
/* Initialize VM objects. */ |
/* Initialize VM objects. */ |
|
|
|
103 |
extern void vm_object_init (void); |
extern void vm_object_init (void); |
104 |
|
|
105 |
/* Allocate a new memory object. SIZE is the size of the object, |
/* Allocate a new memory object. SIZE is the size of the object, |
106 |
should be page aligned. */ |
should be page aligned. */ |
|
|
|
107 |
extern struct vm_object *vm_object_allocate (unsigned int size); |
extern struct vm_object *vm_object_allocate (unsigned int size); |
108 |
|
|
109 |
/* Get a reference to OBJECT. */ |
/* Get a reference to OBJECT. */ |
|
|
|
110 |
extern void vm_object_reference (struct vm_object *object); |
extern void vm_object_reference (struct vm_object *object); |
111 |
|
|
112 |
/* Shadow object OBJECT at offset OFFSET. */ |
/* Release a reference to the specified object, gained either |
113 |
|
through a vm_object_allocate or a vm_object_reference call. |
114 |
|
|
115 |
|
When all references are gone, storage associated with this |
116 |
|
object may be relinquished. No object may be locked. */ |
117 |
|
extern void vm_object_deallocate (struct vm_object *object); |
118 |
|
|
119 |
|
/* Free all resources associated with OBJECT. Upon entry, the object |
120 |
|
must be locked and have no references. The shadow object reference |
121 |
|
is left alone. */ |
122 |
|
extern void vm_object_terminate (struct vm_object *object); |
123 |
|
|
124 |
|
/* Shadow object OBJECT at offset OFFSET. */ |
125 |
extern struct vm_object *vm_object_shadow (struct vm_object *object, |
extern struct vm_object *vm_object_shadow (struct vm_object *object, |
126 |
vm_offset_t offset); |
vm_offset_t offset); |
127 |
|
|
128 |
/* Prepare for delayed copy (copy-on-write share) of OBJECT. */ |
/* Prepare for delayed copy (copy-on-write share) of OBJECT. */ |
|
|
|
129 |
extern void vm_object_prepare_delayed_copy (struct vm_object *object); |
extern void vm_object_prepare_delayed_copy (struct vm_object *object); |
130 |
|
|
131 |
/* Destroy OBJECT. If all references to it is lost, we deallocate |
/* We want to map memory object STORE. PAGER is the pager facility |
132 |
it as well. */ |
that communicates with STORE. SIZE is the size of the object. |
133 |
|
|
134 |
extern void vm_object_destroy (struct vm_object *object); |
If INTERNAL_P is true we create a new object in the default |
135 |
|
pager. */ |
136 |
|
extern struct vm_object *vm_object_enter (struct vm_pager *pager, |
137 |
|
struct ipc_port *store, |
138 |
|
vm_size_t size, int internal_p); |
139 |
|
|
140 |
/* Memory object for kernel memory. */ |
/* Memory object for kernel memory. */ |
|
|
|
141 |
extern struct vm_object *object_kernel; |
extern struct vm_object *object_kernel; |
142 |
#define VM_OBJECT_KERNEL() (object_kernel) |
#define VM_OBJECT_KERNEL() (object_kernel) |
143 |
|
|
144 |
|
/* Event waiting handling. */ |
145 |
|
#define VM_OBJECT_EVENT_INITIALIZED 0 |
146 |
|
#define VM_OBJECT_EVENT_PAGER_READY 1 |
147 |
|
#define VM_OBJECT_EVENT_PAGING_IN_PROGRESS 2 |
148 |
|
#define VM_OBJECT_EVENT_ABSENT_COUNT 3 |
149 |
|
#define VM_OBJECT_EVENT_LOCK_IN_PROGRESS 4 |
150 |
|
#define VM_OBJECT_EVENT_PAGER_REQUEST 5 |
151 |
|
|
152 |
|
#define vm_object_sleep(EVENT, OBJECT) \ |
153 |
|
thread_wait ((int) (EVENT), &(OBJECT)->lock, 0) |
154 |
|
|
155 |
|
#define vm_object_assert_wait(OBJECT, EVENT) \ |
156 |
|
do \ |
157 |
|
{ \ |
158 |
|
(OBJECT)->all_wanted |= 1 << (EVENT); \ |
159 |
|
assert_wait ((int) ((int) OBJECT) + (EVENT)); \ |
160 |
|
} \ |
161 |
|
while (0) |
162 |
|
|
163 |
|
#define vm_object_wait(OBJECT, EVENT) \ |
164 |
|
do \ |
165 |
|
{ \ |
166 |
|
(OBJECT)->all_wanted |= 1 << (EVENT); \ |
167 |
|
vm_object_unlock (OBJECT); \ |
168 |
|
assert_wait ((int) ((int) OBJECT) + (EVENT)); \ |
169 |
|
thread_block (0); \ |
170 |
|
} \ |
171 |
|
while (0) |
172 |
|
|
173 |
|
#define vm_object_wakeup(OBJECT, EVENT) \ |
174 |
|
do \ |
175 |
|
{ \ |
176 |
|
if ((OBJECT)->all_wanted & (1 << (EVENT))) \ |
177 |
|
thread_wakeup ((int) ((int) OBJECT) + (EVENT)); \ |
178 |
|
(OBJECT)->all_wanted &= ~(1 << (EVENT)); \ |
179 |
|
} \ |
180 |
|
while (0) |
181 |
|
|
182 |
|
#define vm_object_paging_begin(OBJECT) \ |
183 |
|
((OBJECT)->paging_in_progress++) |
184 |
|
|
185 |
|
#define vm_object_paging_end(OBJECT) \ |
186 |
|
do \ |
187 |
|
{ \ |
188 |
|
assert((OBJECT)->paging_in_progress != 0); \ |
189 |
|
if (--(OBJECT)->paging_in_progress == 0) \ |
190 |
|
vm_object_wakeup ((OBJECT), \ |
191 |
|
VM_OBJECT_EVENT_PAGING_IN_PROGRESS); \ |
192 |
|
} \ |
193 |
|
while (0) |
194 |
|
|
195 |
|
#define vm_object_paging_wait(OBJECT) \ |
196 |
|
do \ |
197 |
|
{ \ |
198 |
|
while ((OBJECT)->paging_in_progress != 0) \ |
199 |
|
{ \ |
200 |
|
vm_object_wait ((OBJECT), \ |
201 |
|
VM_OBJECT_EVENT_PAGING_IN_PROGRESS); \ |
202 |
|
} \ |
203 |
|
} \ |
204 |
|
while (0) |
205 |
|
|
206 |
#endif /* vm-object.h */ |
#endif /* vm-object.h */ |