Index: sys/vm/vm_page.c =================================================================== --- sys/vm/vm_page.c (revision 232652) +++ sys/vm/vm_page.c (working copy) @@ -766,6 +766,63 @@ } /* + * vm_page_splay: + * + * Implements Sleator and Tarjan's top-down splay algorithm. Returns + * the vm_page containing the given pindex. If, however, that + * pindex is not found in the vm_object, returns a vm_page that is + * adjacent to the pindex, coming before or after it. + */ +vm_page_t +vm_page_splay(vm_pindex_t pindex, vm_page_t root) +{ + struct vm_page dummy; + vm_page_t lefttreemax, righttreemin, y; + + if (root == NULL) + return (root); + lefttreemax = righttreemin = &dummy; + for (;; root = y) { + if (pindex < root->pindex) { + if ((y = root->left) == NULL) + break; + if (pindex < y->pindex) { + /* Rotate right. */ + root->left = y->right; + y->right = root; + root = y; + if ((y = root->left) == NULL) + break; + } + /* Link into the new root's right tree. */ + righttreemin->left = root; + righttreemin = root; + } else if (pindex > root->pindex) { + if ((y = root->right) == NULL) + break; + if (pindex > y->pindex) { + /* Rotate left. */ + root->right = y->left; + y->left = root; + root = y; + if ((y = root->right) == NULL) + break; + } + /* Link into the new root's left tree. */ + lefttreemax->right = root; + lefttreemax = root; + } else + break; + } + /* Assemble the new root. */ + lefttreemax->right = root->left; + righttreemin->left = root->right; + root->left = dummy.right; + root->right = dummy.left; + return (root); +} + +/* * vm_page_insert: [ internal use only ] * * Inserts the given mem entry into the object and object list. Index: sys/vm/vm_page.h =================================================================== --- sys/vm/vm_page.h (revision 232652) +++ sys/vm/vm_page.h (working copy) @@ -130,6 +130,8 @@ struct vm_page { TAILQ_ENTRY(vm_page) pageq; /* queue info for FIFO queue or free list (Q) */ TAILQ_ENTRY(vm_page) listq; /* pages in same object (O) */ + struct vm_page *left; /* splay tree link (O) */ + struct vm_page *right; /* splay tree link (O) */ vm_object_t object; /* which object am I in (O,P)*/ vm_pindex_t pindex; /* offset into object (O,P) */ @@ -398,6 +400,7 @@ void vm_page_requeue(vm_page_t m); void vm_page_set_valid_range(vm_page_t m, int base, int size); void vm_page_sleep(vm_page_t m, const char *msg); +vm_page_t vm_page_splay(vm_pindex_t, vm_page_t); vm_offset_t vm_page_startup(vm_offset_t vaddr); void vm_page_unhold_pages(vm_page_t *ma, int count); void vm_page_unwire (vm_page_t, int);