]> git.saurik.com Git - apple/xnu.git/blobdiff - osfmk/vm/vm_map_store_rb.c
xnu-1699.22.73.tar.gz
[apple/xnu.git] / osfmk / vm / vm_map_store_rb.c
diff --git a/osfmk/vm/vm_map_store_rb.c b/osfmk/vm/vm_map_store_rb.c
new file mode 100644 (file)
index 0000000..2e103b0
--- /dev/null
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2009 Apple Inc. All rights reserved.
+ *
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
+ * 
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ * 
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
+ * 
+ * The Original Code and all software distributed under the License are
+ * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
+ * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
+ * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
+ * 
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
+ */
+
+#include <vm/vm_map_store_rb.h>
+
+RB_GENERATE(rb_head, vm_map_store, entry, rb_node_compare);
+
+#define VME_FOR_STORE( store)  \
+       (vm_map_entry_t)(((unsigned long)store) - ((unsigned long)sizeof(struct vm_map_links)))
+
+void
+vm_map_store_init_rb( struct vm_map_header* hdr )
+{
+       RB_INIT(&(hdr->rb_head_store));
+}
+
+int rb_node_compare(struct vm_map_store *node, struct vm_map_store *parent)
+{
+       vm_map_entry_t vme_c;
+       vm_map_entry_t vme_p;
+
+       vme_c = VME_FOR_STORE(node);
+       vme_p =  VME_FOR_STORE(parent);
+       if (vme_c->vme_start < vme_p->vme_start)
+               return -1;
+       if (vme_c->vme_start >= vme_p->vme_end)
+               return 1;
+       return 0;
+}
+
+void vm_map_store_walk_rb( vm_map_t map, vm_map_entry_t *wrong_vme, vm_map_entry_t *vm_entry)
+{
+       struct vm_map_header hdr = map->hdr;
+       struct vm_map_store *rb_entry = RB_ROOT(&(hdr.rb_head_store));
+       vm_map_entry_t cur = *vm_entry;
+
+       rb_entry = RB_FIND( rb_head, &(hdr.rb_head_store), &(cur->store));      
+       if(rb_entry == NULL)
+               panic("NO SUCH ENTRY %p. Gave back %p", *vm_entry, *wrong_vme);
+       else
+               panic("Cur: %p, L: %p, R: %p",  VME_FOR_STORE(rb_entry),  VME_FOR_STORE(RB_LEFT(rb_entry,entry)),  VME_FOR_STORE(RB_RIGHT(rb_entry,entry)));
+}
+
+
+boolean_t vm_map_store_lookup_entry_rb( vm_map_t map, vm_map_offset_t address, vm_map_entry_t *vm_entry)
+{
+       struct vm_map_header hdr = map->hdr;
+       struct vm_map_store *rb_entry = RB_ROOT(&(hdr.rb_head_store));
+       vm_map_entry_t cur = vm_map_to_entry(map);
+       vm_map_entry_t prev = VM_MAP_ENTRY_NULL;
+
+       while (rb_entry != (struct vm_map_store*)NULL) {
+                       cur =  VME_FOR_STORE(rb_entry);
+               if(cur == VM_MAP_ENTRY_NULL)
+                       panic("no entry");
+               if (address >= cur->vme_start) {
+                       if (address < cur->vme_end) {
+                               *vm_entry = cur;
+                               return TRUE;
+                       }
+                       rb_entry = RB_RIGHT(rb_entry, entry);
+                       prev = cur;
+               } else {
+                       rb_entry = RB_LEFT(rb_entry, entry);
+               }
+       }
+       if( prev == VM_MAP_ENTRY_NULL){
+               prev = vm_map_to_entry(map);
+       }
+       *vm_entry = prev;
+       return FALSE;
+}
+
+void   vm_map_store_entry_link_rb( struct vm_map_header *mapHdr, __unused vm_map_entry_t after_where, vm_map_entry_t entry)
+{
+       struct rb_head *rbh = &(mapHdr->rb_head_store);
+       struct vm_map_store *store = &(entry->store);
+       struct vm_map_store *tmp_store;
+       if((tmp_store = RB_INSERT( rb_head, rbh, store )) != NULL) {
+               panic("VMSEL: INSERT FAILED: 0x%lx, 0x%lx, 0x%lx, 0x%lx", (uintptr_t)entry->vme_start, (uintptr_t)entry->vme_end,
+                               (uintptr_t)(VME_FOR_STORE(tmp_store))->vme_start,  (uintptr_t)(VME_FOR_STORE(tmp_store))->vme_end);
+       }
+}
+
+void   vm_map_store_entry_unlink_rb( struct vm_map_header *mapHdr, vm_map_entry_t entry)
+{
+       struct rb_head *rbh = &(mapHdr->rb_head_store);
+       struct vm_map_store *rb_entry;
+       struct vm_map_store *store = &(entry->store);
+       
+       rb_entry = RB_FIND( rb_head, rbh, store);       
+       if(rb_entry == NULL)
+               panic("NO ENTRY TO DELETE");
+       RB_REMOVE( rb_head, rbh, store );
+}
+
+void   vm_map_store_copy_insert_rb( vm_map_t map, __unused vm_map_entry_t after_where, vm_map_copy_t copy)
+{
+       struct vm_map_header *mapHdr = &(map->hdr);
+       struct rb_head *rbh = &(mapHdr->rb_head_store);
+       struct vm_map_store *store;
+       vm_map_entry_t entry = vm_map_copy_first_entry(copy);
+       int inserted=0, nentries = copy->cpy_hdr.nentries;
+               
+       while (entry != vm_map_copy_to_entry(copy) && nentries > 0) {           
+               vm_map_entry_t prev = entry;
+               store = &(entry->store);
+               if( RB_INSERT( rb_head, rbh, store ) != NULL){
+                       panic("VMSCIR1: INSERT FAILED: %d: %p, %p, %p, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx",inserted, prev, entry, vm_map_copy_to_entry(copy), 
+                                       (uintptr_t)prev->vme_start,  (uintptr_t)prev->vme_end,  (uintptr_t)entry->vme_start,  (uintptr_t)entry->vme_end,  
+                                        (uintptr_t)(VME_FOR_STORE(rbh->rbh_root))->vme_start,  (uintptr_t)(VME_FOR_STORE(rbh->rbh_root))->vme_end);
+               } else {
+                       entry = entry->vme_next;
+                       inserted++;
+                       nentries--;
+               }
+       }
+}
+
+void
+vm_map_store_copy_reset_rb( vm_map_copy_t copy, vm_map_entry_t entry, int nentries )
+{
+       struct vm_map_header *mapHdr = &(copy->cpy_hdr);
+       struct rb_head *rbh = &(mapHdr->rb_head_store);
+       struct vm_map_store *store;
+       int deleted=0;
+               
+       while (entry != vm_map_copy_to_entry(copy) && nentries > 0) {           
+               store = &(entry->store);
+               RB_REMOVE( rb_head, rbh, store );
+               entry = entry->vme_next;
+               deleted++;
+               nentries--;
+       }
+}
+
+void   update_first_free_rb( __unused vm_map_t map, __unused vm_map_entry_t entry)
+{
+       return ;
+}
+