vm_object.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * Mach Operating System
  3. * Copyright (c) 1993-1987 Carnegie Mellon University
  4. * All Rights Reserved.
  5. *
  6. * Permission to use, copy, modify and distribute this software and its
  7. * documentation is hereby granted, provided that both the copyright
  8. * notice and this permission notice appear in all copies of the
  9. * software, derivative works or modified versions, and any portions
  10. * thereof, and that both notices appear in supporting documentation.
  11. *
  12. * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
  13. * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
  14. * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
  15. *
  16. * Carnegie Mellon requests users of this software to return to
  17. *
  18. * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
  19. * School of Computer Science
  20. * Carnegie Mellon University
  21. * Pittsburgh PA 15213-3890
  22. *
  23. * any improvements or extensions that they make and grant Carnegie Mellon
  24. * the rights to redistribute these changes.
  25. */
  26. /*
  27. * File: vm_object.h
  28. * Author: Avadis Tevanian, Jr., Michael Wayne Young
  29. * Date: 1985
  30. *
  31. * Virtual memory object module definitions.
  32. */
  33. #ifndef _VM_VM_OBJECT_H_
  34. #define _VM_VM_OBJECT_H_
  35. #include <sys/types.h>
  36. #include <mach/kern_return.h>
  37. #include <mach/boolean.h>
  38. #include <mach/memory_object.h>
  39. #include <mach/port.h>
  40. #include <mach/vm_prot.h>
  41. #include <mach/machine/vm_types.h>
  42. #include <kern/queue.h>
  43. #include <kern/lock.h>
  44. #include <kern/assert.h>
  45. #include <kern/debug.h>
  46. #include <kern/macros.h>
  47. #include <vm/pmap.h>
  48. #include <ipc/ipc_types.h>
  49. #if MACH_PAGEMAP
  50. #include <vm/vm_external.h>
  51. #endif /* MACH_PAGEMAP */
  52. typedef struct ipc_port * pager_request_t;
  53. #define PAGER_REQUEST_NULL ((pager_request_t) 0)
  54. /*
  55. * We use "struct ipc_port *" instead of "ipc_port_t"
  56. * to avoid include file circularities.
  57. */
  58. struct vm_object {
  59. queue_head_t memq; /* Resident memory */
  60. decl_simple_lock_data(, Lock) /* Synchronization */
  61. #if VM_OBJECT_DEBUG
  62. thread_t LockHolder; /* Thread holding Lock */
  63. #endif /* VM_OBJECT_DEBUG */
  64. vm_size_t size; /* Object size (only valid
  65. * if internal)
  66. */
  67. int ref_count; /* Number of references */
  68. unsigned long resident_page_count;
  69. /* number of resident pages */
  70. struct vm_object *copy; /* Object that should receive
  71. * a copy of my changed pages
  72. */
  73. struct vm_object *shadow; /* My shadow */
  74. vm_offset_t shadow_offset; /* Offset into shadow */
  75. struct ipc_port *pager; /* Where to get data */
  76. vm_offset_t paging_offset; /* Offset into memory object */
  77. pager_request_t pager_request; /* Where data comes back */
  78. struct ipc_port *pager_name; /* How to identify region */
  79. memory_object_copy_strategy_t
  80. copy_strategy; /* How to handle data copy */
  81. unsigned int
  82. absent_count; /* The number of pages that
  83. * have been requested but
  84. * not filled. That is, the
  85. * number of pages for which
  86. * the "absent" attribute is
  87. * asserted.
  88. */
  89. unsigned int /* boolean_t array */
  90. all_wanted; /* Bit array of "want to be
  91. * awakened" notations. See
  92. * VM_OBJECT_EVENT_* items
  93. * below
  94. */
  95. unsigned int
  96. paging_in_progress:16,
  97. /* The memory object ports are
  98. * being used (e.g., for pagein
  99. * or pageout) -- don't change any
  100. * of these fields (i.e., don't
  101. * collapse, destroy or terminate)
  102. */
  103. /* boolean_t */ used_for_pageout:1,/* The object carries data sent to
  104. * a memory manager, which signals
  105. * it's done by releasing memory.
  106. * This flag prevents coalescing so
  107. * that unmapping memory immediately
  108. * results in object termination.
  109. */
  110. /* boolean_t */ pager_created:1,/* Has pager ever been created? */
  111. /* boolean_t */ pager_initialized:1,/* Are fields ready to use? */
  112. /* boolean_t */ pager_ready:1, /* Will manager take requests? */
  113. /* boolean_t */ can_persist:1, /* The kernel may keep the data
  114. * for this object (and rights to
  115. * the memory object) after all
  116. * address map references are
  117. * deallocated?
  118. */
  119. /* boolean_t */ internal:1, /* Created by the kernel (and
  120. * therefore, managed by the
  121. * default memory manger)
  122. */
  123. /* boolean_t */ temporary:1, /* Permanent objects may be changed
  124. * externally by the memory manager,
  125. * and changes made in memory must
  126. * be reflected back to the memory
  127. * manager. Temporary objects lack
  128. * both of these characteristics.
  129. */
  130. /* boolean_t */ alive:1, /* Not yet terminated (debug) */
  131. /* boolean_t */ lock_in_progress : 1,
  132. /* Is a multi-page lock
  133. * request in progress?
  134. */
  135. /* boolean_t */ lock_restart : 1,
  136. /* Should lock request in
  137. * progress restart search?
  138. */
  139. /* boolean_t */ use_shared_copy : 1,/* Use shared (i.e.,
  140. * delayed) copy on write */
  141. /* boolean_t */ shadowed: 1, /* Shadow may exist */
  142. /* boolean_t */ cached: 1; /* Object is cached */
  143. queue_chain_t cached_list; /* Attachment point for the list
  144. * of objects cached as a result
  145. * of their can_persist value
  146. */
  147. vm_offset_t last_alloc; /* last allocation offset */
  148. #if MACH_PAGEMAP
  149. vm_external_t existence_info;
  150. #endif /* MACH_PAGEMAP */
  151. };
  152. extern
  153. vm_object_t kernel_object; /* the single kernel object */
  154. /*
  155. * Declare procedures that operate on VM objects.
  156. */
  157. extern void vm_object_bootstrap(void);
  158. extern void vm_object_init(void);
  159. extern void vm_object_collect(vm_object_t);
  160. extern void vm_object_terminate(vm_object_t);
  161. extern vm_object_t vm_object_allocate(vm_size_t);
  162. extern void vm_object_reference(vm_object_t);
  163. extern void vm_object_deallocate(vm_object_t);
  164. extern void vm_object_pmap_protect(
  165. vm_object_t object,
  166. vm_offset_t offset,
  167. vm_size_t size,
  168. pmap_t pmap,
  169. vm_offset_t pmap_start,
  170. vm_prot_t prot);
  171. extern void vm_object_pmap_remove(
  172. vm_object_t object,
  173. vm_offset_t start,
  174. vm_offset_t end);
  175. extern void vm_object_page_remove(
  176. vm_object_t object,
  177. vm_offset_t start,
  178. vm_offset_t end);
  179. extern void vm_object_shadow(
  180. vm_object_t *object, /* in/out */
  181. vm_offset_t *offset, /* in/out */
  182. vm_size_t length);
  183. extern void vm_object_collapse(vm_object_t);
  184. extern vm_object_t vm_object_lookup(struct ipc_port *);
  185. extern vm_object_t vm_object_lookup_name(struct ipc_port *);
  186. extern struct ipc_port *vm_object_name(vm_object_t);
  187. extern void vm_object_remove(vm_object_t);
  188. extern boolean_t vm_object_copy_temporary(
  189. vm_object_t *_object, /* in/out */
  190. vm_offset_t *_offset, /* in/out */
  191. boolean_t *_src_needs_copy, /* out */
  192. boolean_t *_dst_needs_copy); /* out */
  193. extern kern_return_t vm_object_copy_strategically(
  194. vm_object_t src_object,
  195. vm_offset_t src_offset,
  196. vm_size_t size,
  197. vm_object_t *dst_object, /* out */
  198. vm_offset_t *dst_offset, /* out */
  199. boolean_t *dst_needs_copy); /* out */
  200. extern kern_return_t vm_object_copy_slowly(
  201. vm_object_t src_object,
  202. vm_offset_t src_offset,
  203. vm_size_t size,
  204. boolean_t interruptible,
  205. vm_object_t *_result_object); /* out */
  206. extern vm_object_t vm_object_enter(
  207. struct ipc_port *pager,
  208. vm_size_t size,
  209. boolean_t internal);
  210. extern void vm_object_pager_create(
  211. vm_object_t object);
  212. extern void vm_object_destroy(
  213. struct ipc_port *pager);
  214. extern void vm_object_page_map(
  215. vm_object_t,
  216. vm_offset_t,
  217. vm_size_t,
  218. vm_offset_t (*)(void *, vm_offset_t),
  219. void *);
  220. extern vm_object_t vm_object_request_object(struct ipc_port *);
  221. extern boolean_t vm_object_coalesce(
  222. vm_object_t prev_object,
  223. vm_object_t next_object,
  224. vm_offset_t prev_offset,
  225. vm_offset_t next_offset,
  226. vm_size_t prev_size,
  227. vm_size_t next_size);
  228. extern void vm_object_pager_wakeup(ipc_port_t pager);
  229. void memory_object_release(
  230. ipc_port_t pager,
  231. pager_request_t pager_request,
  232. ipc_port_t pager_name);
  233. void vm_object_deactivate_pages(vm_object_t);
  234. vm_object_t vm_object_copy_delayed(
  235. vm_object_t src_object);
  236. /*
  237. * Event waiting handling
  238. */
  239. #define VM_OBJECT_EVENT_INITIALIZED 0
  240. #define VM_OBJECT_EVENT_PAGER_READY 1
  241. #define VM_OBJECT_EVENT_PAGING_IN_PROGRESS 2
  242. #define VM_OBJECT_EVENT_ABSENT_COUNT 3
  243. #define VM_OBJECT_EVENT_LOCK_IN_PROGRESS 4
  244. #define vm_object_wait(object, event, interruptible) \
  245. MACRO_BEGIN \
  246. (object)->all_wanted |= 1 << (event); \
  247. vm_object_sleep(((vm_offset_t) object) + (event), \
  248. (object), \
  249. (interruptible)); \
  250. MACRO_END
  251. #define vm_object_assert_wait(object, event, interruptible) \
  252. MACRO_BEGIN \
  253. (object)->all_wanted |= 1 << (event); \
  254. assert_wait((event_t)(((vm_offset_t) object) + (event)), (interruptible)); \
  255. MACRO_END
  256. #define vm_object_wakeup(object, event) \
  257. MACRO_BEGIN \
  258. if ((object)->all_wanted & (1 << (event))) \
  259. thread_wakeup((event_t)(((vm_offset_t) object) + (event))); \
  260. (object)->all_wanted &= ~(1 << (event)); \
  261. MACRO_END
  262. /*
  263. * Routines implemented as macros
  264. */
  265. #define vm_object_collectable(object) \
  266. (((object)->ref_count == 0) \
  267. && ((object)->resident_page_count == 0))
  268. #define vm_object_paging_begin(object) \
  269. ((object)->paging_in_progress++)
  270. #define vm_object_paging_end(object) \
  271. MACRO_BEGIN \
  272. assert((object)->paging_in_progress != 0); \
  273. if (--(object)->paging_in_progress == 0) { \
  274. vm_object_wakeup(object, \
  275. VM_OBJECT_EVENT_PAGING_IN_PROGRESS); \
  276. } \
  277. MACRO_END
  278. #define vm_object_paging_wait(object, interruptible) \
  279. MACRO_BEGIN \
  280. while ((object)->paging_in_progress != 0) { \
  281. vm_object_wait( (object), \
  282. VM_OBJECT_EVENT_PAGING_IN_PROGRESS, \
  283. (interruptible)); \
  284. vm_object_lock(object); \
  285. \
  286. /*XXX if ((interruptible) && */ \
  287. /*XXX (current_thread()->wait_result != THREAD_AWAKENED))*/ \
  288. /*XXX break; */ \
  289. } \
  290. MACRO_END
  291. #define vm_object_absent_assert_wait(object, interruptible) \
  292. MACRO_BEGIN \
  293. vm_object_assert_wait( (object), \
  294. VM_OBJECT_EVENT_ABSENT_COUNT, \
  295. (interruptible)); \
  296. MACRO_END
  297. #define vm_object_absent_release(object) \
  298. MACRO_BEGIN \
  299. (object)->absent_count--; \
  300. vm_object_wakeup((object), \
  301. VM_OBJECT_EVENT_ABSENT_COUNT); \
  302. MACRO_END
  303. /*
  304. * Object locking macros (with and without debugging)
  305. */
  306. #if VM_OBJECT_DEBUG
  307. #define vm_object_lock_init(object) \
  308. MACRO_BEGIN \
  309. simple_lock_init(&(object)->Lock); \
  310. (object)->LockHolder = 0; \
  311. MACRO_END
  312. #define vm_object_lock(object) \
  313. MACRO_BEGIN \
  314. simple_lock(&(object)->Lock); \
  315. (object)->LockHolder = current_thread(); \
  316. MACRO_END
  317. #define vm_object_unlock(object) \
  318. MACRO_BEGIN \
  319. if ((object)->LockHolder != current_thread()) \
  320. panic("vm_object_unlock 0x%x", (object)); \
  321. (object)->LockHolder = 0; \
  322. simple_unlock(&(object)->Lock); \
  323. MACRO_END
  324. #define vm_object_lock_try(object) \
  325. (simple_lock_try(&(object)->Lock) \
  326. ? ( ((object)->LockHolder = current_thread()) , TRUE) \
  327. : FALSE)
  328. #define vm_object_sleep(event, object, interruptible) \
  329. MACRO_BEGIN \
  330. if ((object)->LockHolder != current_thread()) \
  331. panic("vm_object_sleep %#x", (object)); \
  332. (object)->LockHolder = 0; \
  333. thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
  334. (interruptible)); \
  335. MACRO_END
  336. #define vm_object_lock_taken(object) \
  337. ((object)->LockHolder == current_thread())
  338. #else /* VM_OBJECT_DEBUG */
  339. #define vm_object_lock_init(object) simple_lock_init(&(object)->Lock)
  340. #define vm_object_lock(object) simple_lock(&(object)->Lock)
  341. #define vm_object_unlock(object) simple_unlock(&(object)->Lock)
  342. #define vm_object_lock_try(object) simple_lock_try(&(object)->Lock)
  343. #define vm_object_sleep(event, object, interruptible) \
  344. thread_sleep((event_t)(event), simple_lock_addr((object)->Lock), \
  345. (interruptible))
  346. #define vm_object_lock_taken(object) simple_lock_taken(&(object)->Lock)
  347. #endif /* VM_OBJECT_DEBUG */
  348. /*
  349. * Page cache accounting.
  350. *
  351. * The page queues must be locked when changing these counters.
  352. */
  353. extern int vm_object_external_count;
  354. extern int vm_object_external_pages;
  355. /* Add a reference to a locked VM object. */
  356. static inline int
  357. vm_object_reference_locked (vm_object_t obj)
  358. {
  359. return (++obj->ref_count);
  360. }
  361. /* Remove a reference from a locked VM object. */
  362. static inline int
  363. vm_object_unreference_locked (vm_object_t obj)
  364. {
  365. return (--obj->ref_count);
  366. }
  367. #endif /* _VM_VM_OBJECT_H_ */