1 /* 2 * Copyright (c) 2019 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24 /* 25 * Purgeable spelling rules 26 * It is believed that the correct spelling is 27 * { 'p', 'u', 'r', 'g', 'e', 'a', 'b', 'l', 'e' }. 28 * However, there is one published API that likes to spell it without the 29 * first 'e', vm_purgable_control(). Since we can't change that API, 30 * here are the rules. 31 * All qualifiers defined in vm_purgable.h are spelled without the e. 32 * All other qualifiers are spelled with the e. 33 * Right now, there are remains of the wrong spelling throughout the code, 34 * vm_object_t.purgable for example. We expect to change these on occasion. 35 */ 36 37 #ifndef __VM_PURGEABLE_INTERNAL__ 38 #define __VM_PURGEABLE_INTERNAL__ 39 40 #include <kern/queue.h> 41 42 enum purgeable_q_type { 43 PURGEABLE_Q_TYPE_OBSOLETE, 44 PURGEABLE_Q_TYPE_FIFO, 45 PURGEABLE_Q_TYPE_LIFO, 46 PURGEABLE_Q_TYPE_MAX 47 }; 48 49 typedef uint32_t token_idx_t; 50 typedef uint32_t token_cnt_t; 51 #define TOKEN_COUNT_MAX UINT32_MAX 52 53 #define NUM_VOLATILE_GROUPS 8 54 struct purgeable_q { 55 token_idx_t token_q_head; /* first token */ 56 token_idx_t token_q_tail; /* last token */ 57 token_idx_t token_q_unripe; /* first token which is not ripe */ 58 int32_t new_pages; 59 queue_head_t objq[NUM_VOLATILE_GROUPS]; 60 enum purgeable_q_type type; 61 #if MACH_ASSERT 62 int debug_count_tokens; 63 int debug_count_objects; 64 #endif 65 }; 66 67 typedef struct purgeable_q * purgeable_q_t; 68 69 extern struct purgeable_q purgeable_queues[PURGEABLE_Q_TYPE_MAX]; 70 extern queue_head_t purgeable_nonvolatile_queue; 71 extern int purgeable_nonvolatile_count; 72 extern int32_t token_new_pagecount; 73 #define TOKEN_NEW_PAGECOUNT_MAX INT32_MAX 74 extern int available_for_purge; 75 76 77 /* 78 * Locking: 79 * the token counters are protected by the vm_page_queue_lock, since they're 80 * mostly used in that context and we don't want to do a lot of extra locking 81 * the purgeable page queues are protected by a separate lock since they're 82 * mostly used on a user context and we don't want any contention with the 83 * pageout daemon. 84 */ 85 decl_lck_mtx_data(extern, vm_purgeable_queue_lock); 86 87 /* add a new token to queue. called by vm_object_purgeable_control */ 88 /* enter with page queue locked */ 89 kern_return_t vm_purgeable_token_add(purgeable_q_t queue); 90 91 /* enter with page queue locked */ 92 void vm_purgeable_token_delete_first(purgeable_q_t queue); 93 void vm_purgeable_token_delete_last(purgeable_q_t queue); 94 95 /* 96 * decrement token counters. 97 * enter with page queue locked 98 */ 99 void vm_purgeable_q_advance_all(void); 100 101 /* the object purger. purges the next eligible object from memory. */ 102 /* returns TRUE if an object was purged, otherwise FALSE. */ 103 boolean_t vm_purgeable_object_purge_one(int force_purge_below_group, int flags); 104 105 /* purge all volatile objects now */ 106 void vm_purgeable_object_purge_all(void); 107 108 /* insert purgeable object into queue */ 109 void vm_purgeable_object_add(vm_object_t object, purgeable_q_t queue, int group); 110 111 /* look for object. If found, remove from purgeable queue. */ 112 purgeable_q_t vm_purgeable_object_remove(vm_object_t object); 113 114 /* statistics for purgable objects in all queues */ 115 void vm_purgeable_stats(vm_purgeable_info_t info, task_t target_task); 116 117 #if DEVELOPMENT || DEBUG 118 /* statistics for purgeable object usage in all queues for a task */ 119 kern_return_t vm_purgeable_account(task_t task, pvm_account_info_t acnt_info); 120 #endif /* DEVELOPMENT || DEBUG */ 121 122 uint64_t vm_purgeable_purge_task_owned(task_t task); 123 void vm_purgeable_nonvolatile_enqueue(vm_object_t object, task_t task); 124 void vm_purgeable_nonvolatile_dequeue(vm_object_t object); 125 void vm_purgeable_accounting(vm_object_t object, 126 vm_purgable_t old_state); 127 void vm_object_owner_compressed_update(vm_object_t object, 128 int delta); 129 130 #define PURGEABLE_LOOP_MAX 64 131 132 #define TOKEN_ADD 0x40 /* 0x100 */ 133 #define TOKEN_DELETE 0x41 /* 0x104 */ 134 #define TOKEN_RIPEN 0x42 /* 0x108 */ 135 #define OBJECT_ADD 0x48 /* 0x120 */ 136 #define OBJECT_REMOVE 0x49 /* 0x124 */ 137 #define OBJECT_PURGE 0x4a /* 0x128 */ 138 #define OBJECT_PURGE_ALL 0x4b /* 0x12c */ 139 #define OBJECT_PURGE_ONE 0x4c /* 0x12d */ 140 #define OBJECT_PURGE_LOOP 0x4e /* 0x12e */ 141 142 #endif /* __VM_PURGEABLE_INTERNAL__ */ 143