kern_malloc.c (71859) | kern_malloc.c (72200) |
---|---|
1/* 2 * Copyright (c) 1987, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94 | 1/* 2 * Copyright (c) 1987, 1991, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31 * SUCH DAMAGE. 32 * 33 * @(#)kern_malloc.c 8.3 (Berkeley) 1/4/94 |
34 * $FreeBSD: head/sys/kern/kern_malloc.c 71859 2001-01-31 04:50:20Z bp $ | 34 * $FreeBSD: head/sys/kern/kern_malloc.c 72200 2001-02-09 06:11:45Z bmilekic $ |
35 */ 36 37#include "opt_vm.h" 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/kernel.h> 42#include <sys/malloc.h> --- 106 unchanged lines hidden (view full) --- 149#if defined(INVARIANTS) 150 if (flags == M_WAITOK) 151 KASSERT(curproc->p_intr_nesting_level == 0, 152 ("malloc(M_WAITOK) in interrupt context")); 153#endif 154 indx = BUCKETINDX(size); 155 kbp = &bucket[indx]; 156 s = splmem(); | 35 */ 36 37#include "opt_vm.h" 38 39#include <sys/param.h> 40#include <sys/systm.h> 41#include <sys/kernel.h> 42#include <sys/malloc.h> --- 106 unchanged lines hidden (view full) --- 149#if defined(INVARIANTS) 150 if (flags == M_WAITOK) 151 KASSERT(curproc->p_intr_nesting_level == 0, 152 ("malloc(M_WAITOK) in interrupt context")); 153#endif 154 indx = BUCKETINDX(size); 155 kbp = &bucket[indx]; 156 s = splmem(); |
157 mtx_enter(&malloc_mtx, MTX_DEF); | 157 mtx_lock(&malloc_mtx); |
158 while (ksp->ks_memuse >= ksp->ks_limit) { 159 if (flags & M_ASLEEP) { 160 if (ksp->ks_limblocks < 65535) 161 ksp->ks_limblocks++; 162 asleep((caddr_t)ksp, PSWP+2, type->ks_shortdesc, 0); 163 } 164 if (flags & M_NOWAIT) { 165 splx(s); | 158 while (ksp->ks_memuse >= ksp->ks_limit) { 159 if (flags & M_ASLEEP) { 160 if (ksp->ks_limblocks < 65535) 161 ksp->ks_limblocks++; 162 asleep((caddr_t)ksp, PSWP+2, type->ks_shortdesc, 0); 163 } 164 if (flags & M_NOWAIT) { 165 splx(s); |
166 mtx_exit(&malloc_mtx, MTX_DEF); | 166 mtx_unlock(&malloc_mtx); |
167 return ((void *) NULL); 168 } 169 if (ksp->ks_limblocks < 65535) 170 ksp->ks_limblocks++; 171 msleep((caddr_t)ksp, &malloc_mtx, PSWP+2, type->ks_shortdesc, 172 0); 173 } 174 ksp->ks_size |= 1 << indx; 175#ifdef INVARIANTS 176 copysize = 1 << indx < MAX_COPY ? 1 << indx : MAX_COPY; 177#endif 178 if (kbp->kb_next == NULL) { 179 kbp->kb_last = NULL; 180 if (size > MAXALLOCSAVE) 181 allocsize = roundup(size, PAGE_SIZE); 182 else 183 allocsize = 1 << indx; 184 npg = btoc(allocsize); 185 | 167 return ((void *) NULL); 168 } 169 if (ksp->ks_limblocks < 65535) 170 ksp->ks_limblocks++; 171 msleep((caddr_t)ksp, &malloc_mtx, PSWP+2, type->ks_shortdesc, 172 0); 173 } 174 ksp->ks_size |= 1 << indx; 175#ifdef INVARIANTS 176 copysize = 1 << indx < MAX_COPY ? 1 << indx : MAX_COPY; 177#endif 178 if (kbp->kb_next == NULL) { 179 kbp->kb_last = NULL; 180 if (size > MAXALLOCSAVE) 181 allocsize = roundup(size, PAGE_SIZE); 182 else 183 allocsize = 1 << indx; 184 npg = btoc(allocsize); 185 |
186 mtx_exit(&malloc_mtx, MTX_DEF); | 186 mtx_unlock(&malloc_mtx); |
187 va = (caddr_t) kmem_malloc(kmem_map, (vm_size_t)ctob(npg), flags); 188 189 if (va == NULL) { 190 splx(s); 191 return ((void *) NULL); 192 } 193 /* 194 * Enter malloc_mtx after the error check to avoid having to 195 * immediately exit it again if there is an error. 196 */ | 187 va = (caddr_t) kmem_malloc(kmem_map, (vm_size_t)ctob(npg), flags); 188 189 if (va == NULL) { 190 splx(s); 191 return ((void *) NULL); 192 } 193 /* 194 * Enter malloc_mtx after the error check to avoid having to 195 * immediately exit it again if there is an error. 196 */ |
197 mtx_enter(&malloc_mtx, MTX_DEF); | 197 mtx_lock(&malloc_mtx); |
198 199 kbp->kb_total += kbp->kb_elmpercl; 200 kup = btokup(va); 201 kup->ku_indx = indx; 202 if (allocsize > MAXALLOCSAVE) { 203 if (npg > 65535) 204 panic("malloc: allocation too large"); 205 kup->ku_pagecnt = npg; --- 67 unchanged lines hidden (view full) --- 273 ksp->ks_memuse += 1 << indx; 274out: 275 kbp->kb_calls++; 276 ksp->ks_inuse++; 277 ksp->ks_calls++; 278 if (ksp->ks_memuse > ksp->ks_maxused) 279 ksp->ks_maxused = ksp->ks_memuse; 280 splx(s); | 198 199 kbp->kb_total += kbp->kb_elmpercl; 200 kup = btokup(va); 201 kup->ku_indx = indx; 202 if (allocsize > MAXALLOCSAVE) { 203 if (npg > 65535) 204 panic("malloc: allocation too large"); 205 kup->ku_pagecnt = npg; --- 67 unchanged lines hidden (view full) --- 273 ksp->ks_memuse += 1 << indx; 274out: 275 kbp->kb_calls++; 276 ksp->ks_inuse++; 277 ksp->ks_calls++; 278 if (ksp->ks_memuse > ksp->ks_maxused) 279 ksp->ks_maxused = ksp->ks_memuse; 280 splx(s); |
281 mtx_exit(&malloc_mtx, MTX_DEF); | 281 mtx_unlock(&malloc_mtx); |
282 /* XXX: Do idle pre-zeroing. */ 283 if (va != NULL && (flags & M_ZERO)) 284 bzero(va, size); 285 return ((void *) va); 286} 287 288/* 289 * free: --- 19 unchanged lines hidden (view full) --- 309 register struct malloc_type *ksp = type; 310 311 KASSERT(kmembase <= (char *)addr && (char *)addr < kmemlimit, 312 ("free: address %p out of range", (void *)addr)); 313 kup = btokup(addr); 314 size = 1 << kup->ku_indx; 315 kbp = &bucket[kup->ku_indx]; 316 s = splmem(); | 282 /* XXX: Do idle pre-zeroing. */ 283 if (va != NULL && (flags & M_ZERO)) 284 bzero(va, size); 285 return ((void *) va); 286} 287 288/* 289 * free: --- 19 unchanged lines hidden (view full) --- 309 register struct malloc_type *ksp = type; 310 311 KASSERT(kmembase <= (char *)addr && (char *)addr < kmemlimit, 312 ("free: address %p out of range", (void *)addr)); 313 kup = btokup(addr); 314 size = 1 << kup->ku_indx; 315 kbp = &bucket[kup->ku_indx]; 316 s = splmem(); |
317 mtx_enter(&malloc_mtx, MTX_DEF); | 317 mtx_lock(&malloc_mtx); |
318#ifdef INVARIANTS 319 /* 320 * Check for returns of data that do not point to the 321 * beginning of the allocation. 322 */ 323 if (size > PAGE_SIZE) 324 alloc = addrmask[BUCKETINDX(PAGE_SIZE)]; 325 else 326 alloc = addrmask[kup->ku_indx]; 327 if (((uintptr_t)(void *)addr & alloc) != 0) 328 panic("free: unaligned addr %p, size %ld, type %s, mask %ld", 329 (void *)addr, size, type->ks_shortdesc, alloc); 330#endif /* INVARIANTS */ 331 if (size > MAXALLOCSAVE) { | 318#ifdef INVARIANTS 319 /* 320 * Check for returns of data that do not point to the 321 * beginning of the allocation. 322 */ 323 if (size > PAGE_SIZE) 324 alloc = addrmask[BUCKETINDX(PAGE_SIZE)]; 325 else 326 alloc = addrmask[kup->ku_indx]; 327 if (((uintptr_t)(void *)addr & alloc) != 0) 328 panic("free: unaligned addr %p, size %ld, type %s, mask %ld", 329 (void *)addr, size, type->ks_shortdesc, alloc); 330#endif /* INVARIANTS */ 331 if (size > MAXALLOCSAVE) { |
332 mtx_exit(&malloc_mtx, MTX_DEF); | 332 mtx_unlock(&malloc_mtx); |
333 kmem_free(kmem_map, (vm_offset_t)addr, ctob(kup->ku_pagecnt)); | 333 kmem_free(kmem_map, (vm_offset_t)addr, ctob(kup->ku_pagecnt)); |
334 mtx_enter(&malloc_mtx, MTX_DEF); | 334 mtx_lock(&malloc_mtx); |
335 336 size = kup->ku_pagecnt << PAGE_SHIFT; 337 ksp->ks_memuse -= size; 338 kup->ku_indx = 0; 339 kup->ku_pagecnt = 0; 340 if (ksp->ks_memuse + size >= ksp->ks_limit && 341 ksp->ks_memuse < ksp->ks_limit) 342 wakeup((caddr_t)ksp); 343 ksp->ks_inuse--; 344 kbp->kb_total -= 1; 345 splx(s); | 335 336 size = kup->ku_pagecnt << PAGE_SHIFT; 337 ksp->ks_memuse -= size; 338 kup->ku_indx = 0; 339 kup->ku_pagecnt = 0; 340 if (ksp->ks_memuse + size >= ksp->ks_limit && 341 ksp->ks_memuse < ksp->ks_limit) 342 wakeup((caddr_t)ksp); 343 ksp->ks_inuse--; 344 kbp->kb_total -= 1; 345 splx(s); |
346 mtx_exit(&malloc_mtx, MTX_DEF); | 346 mtx_unlock(&malloc_mtx); |
347 return; 348 } 349 freep = (struct freelist *)addr; 350#ifdef INVARIANTS 351 /* 352 * Check for multiple frees. Use a quick check to see if 353 * it looks free before laboriously searching the freelist. 354 */ --- 50 unchanged lines hidden (view full) --- 405 kbp->kb_last = addr; 406 freep->next = NULL; 407 } else { 408 freep->next = kbp->kb_next; 409 kbp->kb_next = addr; 410 } 411#endif 412 splx(s); | 347 return; 348 } 349 freep = (struct freelist *)addr; 350#ifdef INVARIANTS 351 /* 352 * Check for multiple frees. Use a quick check to see if 353 * it looks free before laboriously searching the freelist. 354 */ --- 50 unchanged lines hidden (view full) --- 405 kbp->kb_last = addr; 406 freep->next = NULL; 407 } else { 408 freep->next = kbp->kb_next; 409 kbp->kb_next = addr; 410 } 411#endif 412 splx(s); |
413 mtx_exit(&malloc_mtx, MTX_DEF); | 413 mtx_unlock(&malloc_mtx); |
414} 415 416/* 417 * Initialize the kernel memory allocator 418 */ 419/* ARGSUSED*/ 420static void 421kmeminit(dummy) --- 113 unchanged lines hidden (view full) --- 535 if (cnt.v_page_count == 0) 536 panic("malloc_uninit not allowed before vm init"); 537 538 if (type->ks_limit == 0) 539 panic("malloc_uninit on uninitialized type"); 540 541#ifdef INVARIANTS 542 s = splmem(); | 414} 415 416/* 417 * Initialize the kernel memory allocator 418 */ 419/* ARGSUSED*/ 420static void 421kmeminit(dummy) --- 113 unchanged lines hidden (view full) --- 535 if (cnt.v_page_count == 0) 536 panic("malloc_uninit not allowed before vm init"); 537 538 if (type->ks_limit == 0) 539 panic("malloc_uninit on uninitialized type"); 540 541#ifdef INVARIANTS 542 s = splmem(); |
543 mtx_enter(&malloc_mtx, MTX_DEF); | 543 mtx_lock(&malloc_mtx); |
544 for (indx = 0; indx < MINBUCKET + 16; indx++) { 545 kbp = bucket + indx; 546 freep = (struct freelist*)kbp->kb_next; 547 while (freep) { 548 if (freep->type == type) 549 freep->type = M_FREE; 550 freep = (struct freelist*)freep->next; 551 } 552 } 553 splx(s); | 544 for (indx = 0; indx < MINBUCKET + 16; indx++) { 545 kbp = bucket + indx; 546 freep = (struct freelist*)kbp->kb_next; 547 while (freep) { 548 if (freep->type == type) 549 freep->type = M_FREE; 550 freep = (struct freelist*)freep->next; 551 } 552 } 553 splx(s); |
554 mtx_exit(&malloc_mtx, MTX_DEF); | 554 mtx_unlock(&malloc_mtx); |
555 556 if (type->ks_memuse != 0) 557 printf("malloc_uninit: %ld bytes of '%s' still allocated\n", 558 type->ks_memuse, type->ks_shortdesc); 559#endif 560 561 if (type == kmemstatistics) 562 kmemstatistics = type->ks_next; 563 else { 564 for (t = kmemstatistics; t->ks_next != NULL; t = t->ks_next) { 565 if (t->ks_next == type) { 566 t->ks_next = type->ks_next; 567 break; 568 } 569 } 570 } 571 type->ks_next = NULL; 572 type->ks_limit = 0; 573} | 555 556 if (type->ks_memuse != 0) 557 printf("malloc_uninit: %ld bytes of '%s' still allocated\n", 558 type->ks_memuse, type->ks_shortdesc); 559#endif 560 561 if (type == kmemstatistics) 562 kmemstatistics = type->ks_next; 563 else { 564 for (t = kmemstatistics; t->ks_next != NULL; t = t->ks_next) { 565 if (t->ks_next == type) { 566 t->ks_next = type->ks_next; 567 break; 568 } 569 } 570 } 571 type->ks_next = NULL; 572 type->ks_limit = 0; 573} |