void * __MALLOC( size_t size, int type, int flags, vm_allocation_site_t *site) { struct _mhead *hdr = NULL; size_t memsize = sizeof (*hdr) + size; if (type >= M_LAST) panic("_malloc TYPE"); if (size == 0) return (NULL); if (flags & M_NOWAIT) { if (size > memsize) /* overflow detected */ return (NULL); else hdr = (void *)kalloc_canblock(memsize, FALSE, site); } else { if (size > memsize) { /* * We get here when the caller told us to block, waiting for memory but an overflow * has been detected. The caller isn't expecting a NULL return code so we panic * with a descriptive message. */ panic("_MALLOC: overflow detected, size %llu ", (uint64_t) size); } else hdr = (void *)kalloc_canblock(memsize, TRUE, site); if (hdr == NULL) { /* * We get here when the caller told us to block waiting for memory, but * kalloc said there's no memory left to get. Generally, this means there's a * leak or the caller asked for an impossibly large amount of memory. Since there's * nothing left to wait for and the caller isn't expecting a NULL return code, we * just panic. This is less than ideal, but returning NULL doesn't help since the * majority of callers don't check the return value and will just dereference the pointer and * trap anyway. We may as well get a more descriptive message out while we can. */ panic("_MALLOC: kalloc returned NULL (potential leak), size %llu", (uint64_t) size); } } if (!hdr) return (0); hdr->mlen = memsize; if (flags & M_ZERO) bzero(hdr->dat, size); return (hdr->dat); }
void * __MALLOC_ZONE( size_t size, int type, int flags, vm_allocation_site_t *site) { struct kmzones *kmz; void *elem; if (type >= M_LAST) panic("_malloc_zone TYPE"); kmz = &kmzones[type]; if (kmz->kz_zalloczone == KMZ_MALLOC) panic("_malloc_zone ZONE: type = %d", type); /* XXX */ if (kmz->kz_elemsize == (size_t)(-1)) panic("_malloc_zone XXX"); /* XXX */ if (size == kmz->kz_elemsize) if (flags & M_NOWAIT) { elem = (void *)zalloc_noblock(kmz->kz_zalloczone); } else { elem = (void *)zalloc(kmz->kz_zalloczone); } else if (flags & M_NOWAIT) { elem = (void *)kalloc_canblock(size, FALSE, site); } else { elem = (void *)kalloc_canblock(size, TRUE, site); } return (elem); }
vm_offset_t kalloc_noblock( vm_size_t size) { return( kalloc_canblock(size, FALSE) ); }
vm_offset_t kalloc( vm_size_t size) { return( kalloc_canblock(size, TRUE) ); }
void * kalloc_noblock( vm_size_t size) { return( kalloc_canblock(size, FALSE) ); }
void * kalloc( vm_size_t size) { return( kalloc_canblock(size, TRUE) ); }