FreeBSD/sys/kern/subr_pcpu.c
/*
 * Free dynamic per-cpu space at module unload time. 
 */
Free dynamic per-cpu space at module unload time.
Free dynamic per - cpu space at module unload time .
void
dpcpu_free(void *s, int size)
{
	struct dpcpu_free *df;
	struct dpcpu_free *dn;
	uintptr_t start;
	uintptr_t end;
	size = roundup2(size, sizeof(void *));
	start = (uintptr_t)s;
	end = start + size;
	sx_xlock(&dpcpu_lock);
	TAILQ_FOREACH(df, &dpcpu_head, df_link) {
		if (df->df_start > end)
			break;
		if (df->df_start + df->df_len == start) {
			df->df_len += size;
			dn = TAILQ_NEXT(df, df_link);
			if (df->df_start + df->df_len == dn->df_start) {
				df->df_len += dn->df_len;
				TAILQ_REMOVE(&dpcpu_head, dn, df_link);
				free(dn, M_PCPU);
			}
			sx_xunlock(&dpcpu_lock);
			return;
		}
		if (df->df_start == end) {
			df->df_start = start;
			df->df_len += size;
			sx_xunlock(&dpcpu_lock);
			return;
		}
	}
	dn = malloc(sizeof(*df), M_PCPU, M_WAITOK | M_ZERO);
	dn->df_start = start;
	dn->df_len = size;
	if (df)
		TAILQ_INSERT_BEFORE(df, dn, df_link);
	else
		TAILQ_INSERT_TAIL(&dpcpu_head, dn, df_link);
	sx_xunlock(&dpcpu_lock);
}
void dpcpu_free ( void * s , int size ) { struct dpcpu_free * df ; struct dpcpu_free * dn ; uintptr_t start ; uintptr_t end ; size = roundup2 ( size , sizeof ( void * ) ) ; start = ( uintptr_t ) s ; end = start + size ; sx_xlock ( & dpcpu_lock ) ; TAILQ_FOREACH ( df , & dpcpu_head , df_link ) { if ( df -> df_start > end ) break ; if ( df -> df_start + df -> df_len == start ) { df -> df_len += size ; dn = TAILQ_NEXT ( df , df_link ) ; if ( df -> df_start + df -> df_len == dn -> df_start ) { df -> df_len += dn -> df_len ; TAILQ_REMOVE ( & dpcpu_head , dn , df_link ) ; free ( dn , M_PCPU ) ; } sx_xunlock ( & dpcpu_lock ) ; return ; } if ( df -> df_start == end ) { df -> df_start = start ; df -> df_len += size ; sx_xunlock ( & dpcpu_lock ) ; return ; } } dn = malloc ( sizeof ( * df ) , M_PCPU , M_WAITOK | M_ZERO ) ; dn -> df_start = start ; dn -> df_len = size ; if ( df ) TAILQ_INSERT_BEFORE ( df , dn , df_link ) ; else TAILQ_INSERT_TAIL ( & dpcpu_head , dn , df_link ) ; sx_xunlock ( & dpcpu_lock ) ; }
Free dynamic per-cpu space at module unload time.
Free dynamic per - cpu space at module unload time .
/*
	 * Free a region of space and merge it with as many neighbors as
	 * possible.  Keeping the list sorted simplifies this operation.
	 */ /*
		 * If we expand at the end of an entry we may have to
		 * merge it with the one following it as well.
		 */