FreeBSD/sys/kern/kern_malloc.c
/*
 *	free:
 *
 *	Free a block of memory allocated by malloc.
 *
 *	This routine may not block.
 */
Free a block of memory allocated by malloc.

This routine may not block.
Free a block of memory allocated by malloc . This routine may not block .
void
free(void *addr, struct malloc_type *mtp)
{
	uma_slab_t slab;
	u_long size;
	KASSERT(mtp->ks_magic == M_MAGIC, ("free: bad malloc type magic"));
	KASSERT(curthread->td_critnest == 0 || SCHEDULER_STOPPED(),
	    ("free: called with spinlock or critical section held"));
	if (addr == NULL)
		return;
#ifdef DEBUG_MEMGUARD
	if (is_memguard_addr(addr)) {
		memguard_free(addr);
		return;
	}
#endif
#ifdef DEBUG_REDZONE
	redzone_check(addr);
	addr = redzone_addr_ntor(addr);
#endif
	slab = vtoslab((vm_offset_t)addr & (~UMA_SLAB_MASK));
	if (slab == NULL)
		panic("free: address %p(%p) has not been allocated.\n",
		    addr, (void *)((u_long)addr & (~UMA_SLAB_MASK)));
	if (!(slab->us_flags & UMA_SLAB_MALLOC)) {
#ifdef INVARIANTS
		struct malloc_type **mtpp = addr;
#endif
		size = slab->us_keg->uk_size;
#ifdef INVARIANTS
		mtpp = (struct malloc_type **)
		    ((unsigned long)mtpp & ~UMA_ALIGN_PTR);
		mtpp += (size - sizeof(struct malloc_type *)) /
		    sizeof(struct malloc_type *);
		*mtpp = mtp;
#endif
		uma_zfree_arg(LIST_FIRST(&slab->us_keg->uk_zones), addr, slab);
	} else {
		size = slab->us_size;
		uma_large_free(slab);
	}
	malloc_type_freed(mtp, size);
}
void free ( void * addr , struct malloc_type * mtp ) { uma_slab_t slab ; u_long size ; KASSERT ( mtp -> ks_magic == M_MAGIC , ( " " ) ) ; KASSERT ( curthread -> td_critnest == 0 || SCHEDULER_STOPPED ( ) , ( " " ) ) ; if ( addr == NULL ) return ; #ifdef DEBUG_MEMGUARD if ( is_memguard_addr ( addr ) ) { memguard_free ( addr ) ; return ; } #endif #ifdef DEBUG_REDZONE redzone_check ( addr ) ; addr = redzone_addr_ntor ( addr ) ; #endif slab = vtoslab ( ( vm_offset_t ) addr & ( ~ UMA_SLAB_MASK ) ) ; if ( slab == NULL ) panic ( " \n " , addr , ( void * ) ( ( u_long ) addr & ( ~ UMA_SLAB_MASK ) ) ) ; if ( ! ( slab -> us_flags & UMA_SLAB_MALLOC ) ) { #ifdef INVARIANTS struct malloc_type * * mtpp = addr ; #endif size = slab -> us_keg -> uk_size ; #ifdef INVARIANTS mtpp = ( struct malloc_type * * ) ( ( unsigned long ) mtpp & ~ UMA_ALIGN_PTR ) ; mtpp += ( size - sizeof ( struct malloc_type * ) ) / sizeof ( struct malloc_type * ) ; * mtpp = mtp ; #endif uma_zfree_arg ( LIST_FIRST ( & slab -> us_keg -> uk_zones ) , addr , slab ) ; } else { size = slab -> us_size ; uma_large_free ( slab ) ; } malloc_type_freed ( mtp , size ) ; }
free:
      Free a block of memory allocated by malloc.
free : Free a block of memory allocated by malloc .
/* free(NULL, ...) does nothing */ /*
		 * Cache a pointer to the malloc_type that most recently freed
		 * this memory here.  This way we know who is most likely to
		 * have stepped on it later.
		 *
		 * This code assumes that size is a multiple of 8 bytes for
		 * 64 bit machines
		 */