Changeset 5158549 in mainline
- Timestamp:
- 2006-02-05T01:19:16Z (19 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- e22f561
- Parents:
- e72b0a3
- Location:
- generic
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
generic/include/mm/slab.h
re72b0a3 r5158549 82 82 atomic_t allocated_objs; 83 83 atomic_t cached_objs; 84 atomic_t magazine_counter; /*<< How many magazines in magazines list */ 84 85 85 86 /* Slabs */ -
generic/src/mm/slab.c
re72b0a3 r5158549 308 308 309 309 /** 310 * Finds a full magazine in cache, takes it from list 311 * and returns it 312 * 313 * @param first If true, return first, else last mag 314 */ 315 static slab_magazine_t * get_mag_from_cache(slab_cache_t *cache, 316 int first) 317 { 318 slab_magazine_t *mag = NULL; 319 link_t *cur; 320 321 spinlock_lock(&cache->maglock); 322 if (!list_empty(&cache->magazines)) { 323 if (first) 324 cur = cache->magazines.next; 325 else 326 cur = cache->magazines.prev; 327 mag = list_get_instance(cur, slab_magazine_t, link); 328 list_remove(&mag->link); 329 atomic_dec(&cache->magazine_counter); 330 } 331 spinlock_unlock(&cache->maglock); 332 return mag; 333 } 334 335 /** Prepend magazine to magazine list in cache */ 336 static void put_mag_to_cache(slab_cache_t *cache, slab_magazine_t *mag) 337 { 338 spinlock_lock(&cache->maglock); 339 340 list_prepend(&mag->link, &cache->magazines); 341 atomic_inc(&cache->magazine_counter); 342 343 spinlock_unlock(&cache->maglock); 344 } 345 346 /** 310 347 * Free all objects in magazine and free memory associated with magazine 311 348 * … … 350 387 } 351 388 /* Local magazines are empty, import one from magazine list */ 352 spinlock_lock(&cache->maglock); 353 if (list_empty(&cache->magazines)) { 354 spinlock_unlock(&cache->maglock); 389 newmag = get_mag_from_cache(cache, 1); 390 if (!newmag) 355 391 return NULL; 356 }357 newmag = list_get_instance(cache->magazines.next,358 slab_magazine_t,359 link);360 list_remove(&newmag->link);361 spinlock_unlock(&cache->maglock);362 392 363 393 if (lastmag) 364 slab_free(&mag_cache, lastmag); 394 magazine_destroy(cache, lastmag); 395 365 396 cache->mag_cache[CPU->id].last = cmag; 366 397 cache->mag_cache[CPU->id].current = newmag; … … 435 466 436 467 /* Flush last to magazine list */ 437 if (lastmag) { 438 spinlock_lock(&cache->maglock); 439 list_prepend(&lastmag->link, &cache->magazines); 440 spinlock_unlock(&cache->maglock); 441 } 468 if (lastmag) 469 put_mag_to_cache(cache, lastmag); 470 442 471 /* Move current as last, save new as current */ 443 472 cache->mag_cache[CPU->id].last = cmag; … … 589 618 int i; 590 619 slab_magazine_t *mag; 591 link_t *cur;592 620 count_t frames = 0; 621 int magcount; 593 622 594 623 if (cache->flags & SLAB_CACHE_NOMAGAZINE) 595 624 return 0; /* Nothing to do */ 596 597 /* First lock all cpu caches, then the complete cache lock */ 625 626 /* We count up to original magazine count to avoid 627 * endless loop 628 */ 629 magcount = atomic_get(&cache->magazine_counter); 630 while (magcount-- && (mag=get_mag_from_cache(cache,0))) { 631 frames += magazine_destroy(cache,mag); 632 if (!(flags & SLAB_RECLAIM_ALL) && frames) 633 break; 634 } 635 598 636 if (flags & SLAB_RECLAIM_ALL) { 599 for (i=0; i < config.cpu_count; i++) 600 spinlock_lock(&cache->mag_cache[i].lock); 601 } 602 spinlock_lock(&cache->maglock); 603 604 if (flags & SLAB_RECLAIM_ALL) { 605 /* Aggressive memfree */ 637 /* Free cpu-bound magazines */ 606 638 /* Destroy CPU magazines */ 607 639 for (i=0; i<config.cpu_count; i++) { 640 spinlock_lock(&cache->mag_cache[i].lock); 641 608 642 mag = cache->mag_cache[i].current; 609 643 if (mag) … … 615 649 frames += magazine_destroy(cache, mag); 616 650 cache->mag_cache[i].last = NULL; 651 652 spinlock_unlock(&cache->mag_cache[i].lock); 617 653 } 618 654 } 619 /* We can release the cache locks now */ 620 if (flags & SLAB_RECLAIM_ALL) { 621 for (i=0; i < config.cpu_count; i++) 622 spinlock_unlock(&cache->mag_cache[i].lock); 623 } 624 /* Destroy full magazines */ 625 cur=cache->magazines.prev; 626 627 while (cur != &cache->magazines) { 628 mag = list_get_instance(cur, slab_magazine_t, link); 629 630 cur = cur->prev; 631 list_remove(&mag->link); 632 frames += magazine_destroy(cache,mag); 633 /* If we do not do full reclaim, break 634 * as soon as something is freed */ 635 if (!(flags & SLAB_RECLAIM_ALL) && frames) 636 break; 637 } 638 639 spinlock_unlock(&cache->maglock); 640 655 641 656 return frames; 642 657 } … … 645 660 void slab_cache_destroy(slab_cache_t *cache) 646 661 { 662 ipl_t ipl; 663 664 /* First remove cache from link, so that we don't need 665 * to disable interrupts later 666 */ 667 668 ipl = interrupts_disable(); 669 spinlock_lock(&slab_cache_lock); 670 671 list_remove(&cache->link); 672 673 spinlock_unlock(&slab_cache_lock); 674 interrupts_restore(ipl); 675 647 676 /* Do not lock anything, we assume the software is correct and 648 677 * does not touch the cache when it decides to destroy it */ … … 656 685 panic("Destroying cache that is not empty."); 657 686 658 spinlock_lock(&slab_cache_lock);659 list_remove(&cache->link);660 spinlock_unlock(&slab_cache_lock);661 662 687 slab_free(&slab_cache_cache, cache); 663 688 } … … 675 700 if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) 676 701 result = magazine_obj_get(cache); 677 678 702 if (!result) 679 703 result = slab_obj_create(cache, flags); … … 721 745 /* TODO: Add assert, that interrupts are disabled, otherwise 722 746 * memory allocation from interrupts can deadlock. 747 * - cache_destroy can call this with interrupts enabled :-/ 723 748 */ 724 749 … … 815 840 void kfree(void *obj) 816 841 { 817 slab_t *slab = obj2slab(obj); 818 842 slab_t *slab; 843 844 if (!obj) return; 845 846 slab = obj2slab(obj); 819 847 _slab_free(slab->cache, obj, slab); 820 848 }
Note:
See TracChangeset
for help on using the changeset viewer.