vm_radix.c (226930) | vm_radix.c (226952) |
---|---|
1/* 2 * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org> 3 * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 350 unchanged lines hidden (view full) --- 359 child = (uintptr_t)rnode->rn_child[slot]; 360 child &= ~VM_RADIX_FLAGS; 361 rnode->rn_child[slot] = (void *)(child | color); 362 363 return (void *)child; 364} 365 366/* | 1/* 2 * Copyright (c) 2011 Jeffrey Roberson <jeff@freebsd.org> 3 * Copyright (c) 2008 Mayur Shardul <mayur.shardul@gmail.com> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: --- 350 unchanged lines hidden (view full) --- 359 child = (uintptr_t)rnode->rn_child[slot]; 360 child &= ~VM_RADIX_FLAGS; 361 rnode->rn_child[slot] = (void *)(child | color); 362 363 return (void *)child; 364} 365 366/* |
367 * Looks up as many as cnt values between start and end, and stores 368 * them in the caller allocated array out. The next index can be used 369 * to restart the scan. This optimizes forward scans in the tree. | 367 * Find the first leaf with a valid node between *startp and end. Return 368 * the index of the first valid item in the leaf in *startp. |
370 */ | 369 */ |
371int 372vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start, 373 vm_pindex_t end, int color, void **out, int cnt, vm_pindex_t *next) | 370static struct vm_radix_node * 371vm_radix_leaf(struct vm_radix *rtree, vm_pindex_t *startp, vm_pindex_t end) |
374{ 375 struct vm_radix_node *rnode; | 372{ 373 struct vm_radix_node *rnode; |
374 vm_pindex_t start; |
|
376 vm_pindex_t inc; 377 int slot; 378 int level; | 375 vm_pindex_t inc; 376 int slot; 377 int level; |
379 void *val; 380 int outidx; | |
381 | 378 |
382 CTR3(KTR_VM, "lookupn: tree %p, start %p, end %p", 383 rtree, (void *)start, (void *)end); 384 outidx = 0; | 379 start = *startp; |
385restart: 386 level = vm_radix_height(rtree, &rnode); | 380restart: 381 level = vm_radix_height(rtree, &rnode); |
387 if (rnode == NULL || start > VM_RADIX_MAX(level)) | 382 if (start > VM_RADIX_MAX(level) || (end && start >= end)) { 383 rnode = NULL; |
388 goto out; | 384 goto out; |
389 if (end && start >= end) 390 goto out; | 385 } |
391 /* 392 * Search the tree from the top for any leaf node holding an index 393 * between start and end. 394 */ 395 for (level--; level; level--) { 396 slot = vm_radix_slot(start, level); 397 CTR5(KTR_VM, | 386 /* 387 * Search the tree from the top for any leaf node holding an index 388 * between start and end. 389 */ 390 for (level--; level; level--) { 391 slot = vm_radix_slot(start, level); 392 CTR5(KTR_VM, |
398 "lookupn: tree %p, index %p, level %d, slot %d, child %p", | 393 "leaf: tree %p, index %p, level %d, slot %d, child %p", |
399 rtree, (void *)start, level, slot, rnode->rn_child[slot]); 400 if (rnode->rn_child[slot] != NULL) { 401 rnode = rnode->rn_child[slot]; 402 continue; 403 } 404 /* 405 * Calculate how much to increment our index by 406 * based on the tree level. We must truncate the 407 * lower bits to start from the begnning of the 408 * next leaf. 409 */ 410 inc = 1LL << (level * VM_RADIX_WIDTH); 411 start &= ~VM_RADIX_MAX(level); 412 start += inc; 413 slot++; 414 CTR5(KTR_VM, | 394 rtree, (void *)start, level, slot, rnode->rn_child[slot]); 395 if (rnode->rn_child[slot] != NULL) { 396 rnode = rnode->rn_child[slot]; 397 continue; 398 } 399 /* 400 * Calculate how much to increment our index by 401 * based on the tree level. We must truncate the 402 * lower bits to start from the begnning of the 403 * next leaf. 404 */ 405 inc = 1LL << (level * VM_RADIX_WIDTH); 406 start &= ~VM_RADIX_MAX(level); 407 start += inc; 408 slot++; 409 CTR5(KTR_VM, |
415 "lookupn: start %p end %p inc %d mask 0x%lX slot %d", | 410 "leaf: start %p end %p inc %d mask 0x%lX slot %d", |
416 (void *)start, (void *)end, inc, 417 ~VM_RADIX_MAX(level), slot); 418 for (; slot < VM_RADIX_COUNT; slot++, start += inc) { | 411 (void *)start, (void *)end, inc, 412 ~VM_RADIX_MAX(level), slot); 413 for (; slot < VM_RADIX_COUNT; slot++, start += inc) { |
419 if (end != 0 && start >= end) | 414 if (end != 0 && start >= end) { 415 rnode = NULL; |
420 goto out; | 416 goto out; |
417 } |
|
421 if (rnode->rn_child[slot]) { 422 rnode = rnode->rn_child[slot]; 423 break; 424 } 425 } 426 if (slot == VM_RADIX_COUNT) 427 goto restart; 428 } | 418 if (rnode->rn_child[slot]) { 419 rnode = rnode->rn_child[slot]; 420 break; 421 } 422 } 423 if (slot == VM_RADIX_COUNT) 424 goto restart; 425 } |
429 slot = vm_radix_slot(start, 0); 430 for (; slot < VM_RADIX_COUNT; slot++, start++) { | 426 427out: 428 *startp = start; 429 return (rnode); 430} 431 432 433 434/* 435 * Looks up as many as cnt values between start and end, and stores 436 * them in the caller allocated array out. The next index can be used 437 * to restart the scan. This optimizes forward scans in the tree. 438 */ 439int 440vm_radix_lookupn(struct vm_radix *rtree, vm_pindex_t start, 441 vm_pindex_t end, int color, void **out, int cnt, vm_pindex_t *next) 442{ 443 struct vm_radix_node *rnode; 444 void *val; 445 int slot; 446 int outidx; 447 448 CTR3(KTR_VM, "lookupn: tree %p, start %p, end %p", 449 rtree, (void *)start, (void *)end); 450 if (rtree->rt_root == 0) 451 return (0); 452 outidx = 0; 453 while ((rnode = vm_radix_leaf(rtree, &start, end)) != NULL) { 454 slot = vm_radix_slot(start, 0); 455 for (; slot < VM_RADIX_COUNT; slot++, start++) { 456 if (end != 0 && start >= end) 457 goto out; 458 val = vm_radix_match(rnode->rn_child[slot], color); 459 if (val == NULL) 460 continue; 461 CTR4(KTR_VM, 462 "lookupn: tree %p index %p slot %d found child %p", 463 rtree, (void *)start, slot, val); 464 out[outidx] = val; 465 if (++outidx == cnt) 466 goto out; 467 } |
431 if (end != 0 && start >= end) | 468 if (end != 0 && start >= end) |
432 goto out; 433 val = vm_radix_match(rnode->rn_child[slot], color); 434 if (val == NULL) 435 continue; 436 CTR4(KTR_VM, 437 "lookupn: tree %p index %p slot %d found child %p", 438 rtree, (void *)start, slot, val); 439 out[outidx++] = val; 440 if (outidx == cnt) 441 goto out; | 469 break; |
442 } | 470 } |
443 /* 444 * Go fetch the next page to fill the requested number of pages 445 * otherwise the caller will simply call us again to fulfill the 446 * same request after the structures are pushed out of cache. 447 */ 448 if ((end == 0 || start < end)) 449 goto restart; | |
450out: 451 *next = start; | 471out: 472 *next = start; |
452 | |
453 return (outidx); 454} 455 | 473 return (outidx); 474} 475 |
476void 477vm_radix_foreach(struct vm_radix *rtree, vm_pindex_t start, vm_pindex_t end, 478 int color, void (*iter)(void *)) 479{ 480 struct vm_radix_node *rnode; 481 void *val; 482 int slot; 483 484 if (rtree->rt_root == 0) 485 return; 486 while ((rnode = vm_radix_leaf(rtree, &start, end)) != NULL) { 487 slot = vm_radix_slot(start, 0); 488 for (; slot < VM_RADIX_COUNT; slot++, start++) { 489 if (end != 0 && start >= end) 490 return; 491 val = vm_radix_match(rnode->rn_child[slot], color); 492 if (val) 493 iter(val); 494 } 495 if (end != 0 && start >= end) 496 return; 497 } 498} 499 500 |
|
456/* 457 * Look up any entry at a position less than or equal to index. 458 */ 459void * 460vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index, int color) 461{ 462 struct vm_radix_node *rnode; 463 struct vm_radix_node *child; --- 162 unchanged lines hidden --- | 501/* 502 * Look up any entry at a position less than or equal to index. 503 */ 504void * 505vm_radix_lookup_le(struct vm_radix *rtree, vm_pindex_t index, int color) 506{ 507 struct vm_radix_node *rnode; 508 struct vm_radix_node *child; --- 162 unchanged lines hidden --- |