usr/src/lib/libc/port/gen/malloc.c
author Jon Tibble <meths@btinternet.com>
Thu, 09 Dec 2010 22:32:39 +0100
changeset 13255 4afa820d78b9
parent 6812 febeba71273d
permissions -rw-r--r--
298 SPARC build fails in smt_pause.o 478 Build needs fixing for pkgdepend flag day Reviewed by: [email protected] Reviewed by: [email protected] Reviewed by: [email protected] Approved by: [email protected]
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     1
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     2
 * CDDL HEADER START
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     3
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
2186
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
     5
 * Common Development and Distribution License (the "License").
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
     6
 * You may not use this file except in compliance with the License.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     7
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    11
 * and limitations under the License.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    12
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    18
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    19
 * CDDL HEADER END
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    20
 */
2186
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    21
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    22
/*
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
    23
 * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    24
 * Use is subject to license terms.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    25
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    26
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    27
/*	Copyright (c) 1988 AT&T	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    28
/*	  All Rights Reserved  	*/
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    29
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    30
#pragma ident	"%Z%%M%	%I%	%E% SMI"
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    31
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    32
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    33
 *	Memory management: malloc(), realloc(), free().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    34
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    35
 *	The following #-parameters may be redefined:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    36
 *	SEGMENTED: if defined, memory requests are assumed to be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    37
 *		non-contiguous across calls of GETCORE's.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    38
 *	GETCORE: a function to get more core memory. If not SEGMENTED,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    39
 *		GETCORE(0) is assumed to return the next available
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    40
 *		address. Default is 'sbrk'.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    41
 *	ERRCORE: the error code as returned by GETCORE.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    42
 *		Default is (char *)(-1).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    43
 *	CORESIZE: a desired unit (measured in bytes) to be used
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    44
 *		with GETCORE. Default is (1024*ALIGN).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    45
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    46
 *	This algorithm is based on a  best fit strategy with lists of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    47
 *	free elts maintained in a self-adjusting binary tree. Each list
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    48
 *	contains all elts of the same size. The tree is ordered by size.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    49
 *	For results on self-adjusting trees, see the paper:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    50
 *		Self-Adjusting Binary Trees,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    51
 *		DD Sleator & RE Tarjan, JACM 1985.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    52
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    53
 *	The header of a block contains the size of the data part in bytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    54
 *	Since the size of a block is 0%4, the low two bits of the header
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    55
 *	are free and used as follows:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    56
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    57
 *		BIT0:	1 for busy (block is in use), 0 for free.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    58
 *		BIT1:	if the block is busy, this bit is 1 if the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    59
 *			preceding block in contiguous memory is free.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    60
 *			Otherwise, it is always 0.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    61
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    62
6812
febeba71273d PSARC 2008/309 expunge synonyms.h
raf
parents: 6515
diff changeset
    63
#include "lint.h"
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    64
#include "mallint.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    65
#include "mtlib.h"
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    66
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    67
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    68
 * Some abusers of the system (notably java1.2) acquire __malloc_lock
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    69
 * in order to prevent threads from holding it while they are being
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    70
 * suspended via thr_suspend() or thr_suspend_allmutators().
2186
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    71
 * This never worked when alternate malloc() libraries were used
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    72
 * because they don't use __malloc_lock for their locking strategy.
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    73
 * We leave __malloc_lock as an external variable to satisfy these
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    74
 * old programs, but we define a new lock, private to libc, to do the
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    75
 * real locking: libc_malloc_lock.  This puts libc's malloc() package
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
    76
 * on the same footing as all other malloc packages.
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    77
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    78
mutex_t __malloc_lock = DEFAULTMUTEX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    79
mutex_t libc_malloc_lock = DEFAULTMUTEX;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    80
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    81
static TREE	*Root,		/* root of the free tree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    82
		*Bottom,	/* the last free chunk in the arena */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    83
		*_morecore(size_t);	/* function to get more core */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    84
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    85
static char	*Baddr;		/* current high address of the arena */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    86
static char	*Lfree;		/* last freed block with data intact */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    87
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    88
static void	t_delete(TREE *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    89
static void	t_splay(TREE *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    90
static void	realfree(void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    91
static void	cleanfree(void *);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    92
static void	*_malloc_unlocked(size_t);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    93
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    94
#define	FREESIZE (1<<5) /* size for preserving free blocks until next malloc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    95
#define	FREEMASK FREESIZE-1
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    96
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    97
static void *flist[FREESIZE];	/* list of blocks to be freed on next malloc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    98
static int freeidx;		/* index of free blocks in flist % FREESIZE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
    99
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   100
/*
2186
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   101
 * Interfaces used only by atfork_init() functions.
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   102
 */
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   103
void
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   104
malloc_locks(void)
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   105
{
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   106
	(void) mutex_lock(&libc_malloc_lock);
2186
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   107
}
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   108
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   109
void
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   110
malloc_unlocks(void)
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   111
{
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   112
	(void) mutex_unlock(&libc_malloc_lock);
2186
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   113
}
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   114
7b18ba5d9cfe 6418491 solaris 10 runtime prevents sigbus signal to correctly get passed to the handler
raf
parents: 0
diff changeset
   115
/*
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   116
 *	Allocation of small blocks
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   117
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   118
static TREE	*List[MINSIZE/WORDSIZE-1]; /* lists of small blocks */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   119
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   120
static void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   121
_smalloc(size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   122
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   123
	TREE	*tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   124
	size_t	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   125
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   126
	ASSERT(size % WORDSIZE == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   127
	/* want to return a unique pointer on malloc(0) */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   128
	if (size == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   129
		size = WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   130
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   131
	/* list to use */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   132
	i = size / WORDSIZE - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   133
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   134
	if (List[i] == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   135
		TREE *np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   136
		int n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   137
		/* number of blocks to get at one time */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   138
#define	NPS (WORDSIZE*8)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   139
		ASSERT((size + WORDSIZE) * NPS >= MINSIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   140
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   141
		/* get NPS of these block types */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   142
		if ((List[i] = _malloc_unlocked((size + WORDSIZE) * NPS)) == 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   143
			return (0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   144
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   145
		/* make them into a link list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   146
		for (n = 0, np = List[i]; n < NPS; ++n) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   147
			tp = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   148
			SIZE(tp) = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   149
			np = NEXT(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   150
			AFTER(tp) = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   151
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   152
		AFTER(tp) = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   153
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   154
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   155
	/* allocate from the head of the queue */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   156
	tp = List[i];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   157
	List[i] = AFTER(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   158
	SETBIT0(SIZE(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   159
	return (DATA(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   160
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   161
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   162
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   163
malloc(size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   164
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   165
	void *ret;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   166
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   167
	if (!primary_link_map) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   168
		errno = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   169
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   170
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   171
	assert_no_libc_locks_held();
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   172
	(void) mutex_lock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   173
	ret = _malloc_unlocked(size);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   174
	(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   175
	return (ret);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   176
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   177
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   178
static void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   179
_malloc_unlocked(size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   180
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   181
	size_t	n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   182
	TREE	*tp, *sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   183
	size_t	o_bit1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   184
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   185
	COUNT(nmalloc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   186
	ASSERT(WORDSIZE == ALIGN);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   187
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   188
	/* check for size that could overflow calculations */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   189
	if (size > MAX_MALLOC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   190
		errno = ENOMEM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   191
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   192
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   193
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   194
	/* make sure that size is 0 mod ALIGN */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   195
	ROUND(size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   196
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   197
	/* see if the last free block can be used */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   198
	if (Lfree) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   199
		sp = BLOCK(Lfree);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   200
		n = SIZE(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   201
		CLRBITS01(n);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   202
		if (n == size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   203
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   204
			 * exact match, use it as is
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   205
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   206
			freeidx = (freeidx + FREESIZE - 1) &
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   207
			    FREEMASK; /* 1 back */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   208
			flist[freeidx] = Lfree = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   209
			return (DATA(sp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   210
		} else if (size >= MINSIZE && n > size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   211
			/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   212
			 * got a big enough piece
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   213
			 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   214
			freeidx = (freeidx + FREESIZE - 1) &
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   215
			    FREEMASK; /* 1 back */
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   216
			flist[freeidx] = Lfree = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   217
			o_bit1 = SIZE(sp) & BIT1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   218
			SIZE(sp) = n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   219
			goto leftover;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   220
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   221
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   222
	o_bit1 = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   223
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   224
	/* perform free's of space since last malloc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   225
	cleanfree(NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   226
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   227
	/* small blocks */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   228
	if (size < MINSIZE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   229
		return (_smalloc(size));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   230
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   231
	/* search for an elt of the right size */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   232
	sp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   233
	n  = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   234
	if (Root) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   235
		tp = Root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   236
		for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   237
			/* branch left */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   238
			if (SIZE(tp) >= size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   239
				if (n == 0 || n >= SIZE(tp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   240
					sp = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   241
					n = SIZE(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   242
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   243
				if (LEFT(tp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   244
					tp = LEFT(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   245
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   246
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   247
			} else { /* branch right */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   248
				if (RIGHT(tp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   249
					tp = RIGHT(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   250
				else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   251
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   252
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   253
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   254
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   255
		if (sp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   256
			t_delete(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   257
		} else if (tp != Root) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   258
			/* make the searched-to element the root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   259
			t_splay(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   260
			Root = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   261
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   262
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   263
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   264
	/* if found none fitted in the tree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   265
	if (!sp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   266
		if (Bottom && size <= SIZE(Bottom)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   267
			sp = Bottom;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   268
			CLRBITS01(SIZE(sp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   269
		} else if ((sp = _morecore(size)) == NULL) /* no more memory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   270
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   271
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   272
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   273
	/* tell the forward neighbor that we're busy */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   274
	CLRBIT1(SIZE(NEXT(sp)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   275
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   276
	ASSERT(ISBIT0(SIZE(NEXT(sp))));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   277
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   278
leftover:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   279
	/* if the leftover is enough for a new free piece */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   280
	if ((n = (SIZE(sp) - size)) >= MINSIZE + WORDSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   281
		n -= WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   282
		SIZE(sp) = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   283
		tp = NEXT(sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   284
		SIZE(tp) = n|BIT0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   285
		realfree(DATA(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   286
	} else if (BOTTOM(sp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   287
		Bottom = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   288
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   289
	/* return the allocated space */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   290
	SIZE(sp) |= BIT0 | o_bit1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   291
	return (DATA(sp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   292
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   293
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   294
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   295
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   296
 * realloc().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   297
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   298
 * If the block size is increasing, we try forward merging first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   299
 * This is not best-fit but it avoids some data recopying.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   300
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   301
void *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   302
realloc(void *old, size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   303
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   304
	TREE	*tp, *np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   305
	size_t	ts;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   306
	char	*new;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   307
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   308
	if (!primary_link_map) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   309
		errno = ENOTSUP;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   310
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   311
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   312
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   313
	assert_no_libc_locks_held();
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   314
	COUNT(nrealloc);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   315
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   316
	/* check for size that could overflow calculations */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   317
	if (size > MAX_MALLOC) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   318
		errno = ENOMEM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   319
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   320
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   321
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   322
	/* pointer to the block */
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   323
	(void) mutex_lock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   324
	if (old == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   325
		new = _malloc_unlocked(size);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   326
		(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   327
		return (new);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   328
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   329
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   330
	/* perform free's of space since last malloc */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   331
	cleanfree(old);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   332
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   333
	/* make sure that size is 0 mod ALIGN */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   334
	ROUND(size);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   335
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   336
	tp = BLOCK(old);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   337
	ts = SIZE(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   338
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   339
	/* if the block was freed, data has been destroyed. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   340
	if (!ISBIT0(ts)) {
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   341
		(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   342
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   343
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   344
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   345
	/* nothing to do */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   346
	CLRBITS01(SIZE(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   347
	if (size == SIZE(tp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   348
		SIZE(tp) = ts;
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   349
		(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   350
		return (old);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   351
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   352
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   353
	/* special cases involving small blocks */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   354
	if (size < MINSIZE || SIZE(tp) < MINSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   355
		/* free is size is zero */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   356
		if (size == 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   357
			SETOLD01(SIZE(tp), ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   358
			_free_unlocked(old);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   359
			(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   360
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   361
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   362
			goto call_malloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   363
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   364
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   365
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   366
	/* block is increasing in size, try merging the next block */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   367
	if (size > SIZE(tp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   368
		np = NEXT(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   369
		if (!ISBIT0(SIZE(np))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   370
			ASSERT(SIZE(np) >= MINSIZE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   371
			ASSERT(!ISBIT1(SIZE(np)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   372
			SIZE(tp) += SIZE(np) + WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   373
			if (np != Bottom)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   374
				t_delete(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   375
			else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   376
				Bottom = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   377
			CLRBIT1(SIZE(NEXT(np)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   378
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   379
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   380
#ifndef SEGMENTED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   381
		/* not enough & at TRUE end of memory, try extending core */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   382
		if (size > SIZE(tp) && BOTTOM(tp) && GETCORE(0) == Baddr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   383
			Bottom = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   384
			if ((tp = _morecore(size)) == NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   385
				tp = Bottom;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   386
				Bottom = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   387
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   388
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   389
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   390
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   391
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   392
	/* got enough space to use */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   393
	if (size <= SIZE(tp)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   394
		size_t n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   395
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   396
chop_big:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   397
		if ((n = (SIZE(tp) - size)) >= MINSIZE + WORDSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   398
			n -= WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   399
			SIZE(tp) = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   400
			np = NEXT(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   401
			SIZE(np) = n|BIT0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   402
			realfree(DATA(np));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   403
		} else if (BOTTOM(tp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   404
			Bottom = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   405
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   406
		/* the previous block may be free */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   407
		SETOLD01(SIZE(tp), ts);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   408
		(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   409
		return (old);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   410
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   411
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   412
	/* call malloc to get a new block */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   413
call_malloc:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   414
	SETOLD01(SIZE(tp), ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   415
	if ((new = _malloc_unlocked(size)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   416
		CLRBITS01(ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   417
		if (ts > size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   418
			ts = size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   419
		MEMCOPY(new, old, ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   420
		_free_unlocked(old);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   421
		(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   422
		return (new);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   423
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   424
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   425
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   426
	 * Attempt special case recovery allocations since malloc() failed:
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   427
	 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   428
	 * 1. size <= SIZE(tp) < MINSIZE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   429
	 *	Simply return the existing block
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   430
	 * 2. SIZE(tp) < size < MINSIZE
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   431
	 *	malloc() may have failed to allocate the chunk of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   432
	 *	small blocks. Try asking for MINSIZE bytes.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   433
	 * 3. size < MINSIZE <= SIZE(tp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   434
	 *	malloc() may have failed as with 2.  Change to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   435
	 *	MINSIZE allocation which is taken from the beginning
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   436
	 *	of the current block.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   437
	 * 4. MINSIZE <= SIZE(tp) < size
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   438
	 *	If the previous block is free and the combination of
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   439
	 *	these two blocks has at least size bytes, then merge
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   440
	 *	the two blocks copying the existing contents backwards.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   441
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   442
	CLRBITS01(SIZE(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   443
	if (SIZE(tp) < MINSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   444
		if (size < SIZE(tp)) {			/* case 1. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   445
			SETOLD01(SIZE(tp), ts);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   446
			(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   447
			return (old);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   448
		} else if (size < MINSIZE) {		/* case 2. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   449
			size = MINSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   450
			goto call_malloc;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   451
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   452
	} else if (size < MINSIZE) {			/* case 3. */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   453
		size = MINSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   454
		goto chop_big;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   455
	} else if (ISBIT1(ts) &&
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   456
	    (SIZE(np = LAST(tp)) + SIZE(tp) + WORDSIZE) >= size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   457
		ASSERT(!ISBIT0(SIZE(np)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   458
		t_delete(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   459
		SIZE(np) += SIZE(tp) + WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   460
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   461
		 * Since the copy may overlap, use memmove() if available.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   462
		 * Otherwise, copy by hand.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   463
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   464
		(void) memmove(DATA(np), old, SIZE(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   465
		old = DATA(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   466
		tp = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   467
		CLRBIT1(ts);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   468
		goto chop_big;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   469
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   470
	SETOLD01(SIZE(tp), ts);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   471
	(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   472
	return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   473
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   474
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   475
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   476
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   477
 * realfree().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   478
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   479
 * Coalescing of adjacent free blocks is done first.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   480
 * Then, the new free block is leaf-inserted into the free tree
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   481
 * without splaying. This strategy does not guarantee the amortized
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   482
 * O(nlogn) behaviour for the insert/delete/find set of operations
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   483
 * on the tree. In practice, however, free is much more infrequent
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   484
 * than malloc/realloc and the tree searches performed by these
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   485
 * functions adequately keep the tree in balance.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   486
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   487
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   488
realfree(void *old)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   489
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   490
	TREE	*tp, *sp, *np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   491
	size_t	ts, size;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   492
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   493
	COUNT(nfree);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   494
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   495
	/* pointer to the block */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   496
	tp = BLOCK(old);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   497
	ts = SIZE(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   498
	if (!ISBIT0(ts))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   499
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   500
	CLRBITS01(SIZE(tp));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   501
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   502
	/* small block, put it in the right linked list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   503
	if (SIZE(tp) < MINSIZE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   504
		ASSERT(SIZE(tp) / WORDSIZE >= 1);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   505
		ts = SIZE(tp) / WORDSIZE - 1;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   506
		AFTER(tp) = List[ts];
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   507
		List[ts] = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   508
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   509
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   510
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   511
	/* see if coalescing with next block is warranted */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   512
	np = NEXT(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   513
	if (!ISBIT0(SIZE(np))) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   514
		if (np != Bottom)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   515
			t_delete(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   516
		SIZE(tp) += SIZE(np) + WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   517
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   518
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   519
	/* the same with the preceding block */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   520
	if (ISBIT1(ts)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   521
		np = LAST(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   522
		ASSERT(!ISBIT0(SIZE(np)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   523
		ASSERT(np != Bottom);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   524
		t_delete(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   525
		SIZE(np) += SIZE(tp) + WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   526
		tp = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   527
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   528
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   529
	/* initialize tree info */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   530
	PARENT(tp) = LEFT(tp) = RIGHT(tp) = LINKFOR(tp) = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   531
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   532
	/* the last word of the block contains self's address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   533
	*(SELFP(tp)) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   534
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   535
	/* set bottom block, or insert in the free tree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   536
	if (BOTTOM(tp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   537
		Bottom = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   538
	else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   539
		/* search for the place to insert */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   540
		if (Root) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   541
			size = SIZE(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   542
			np = Root;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   543
			for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   544
				if (SIZE(np) > size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   545
					if (LEFT(np))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   546
						np = LEFT(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   547
					else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   548
						LEFT(np) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   549
						PARENT(tp) = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   550
						break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   551
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   552
				} else if (SIZE(np) < size) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   553
					if (RIGHT(np))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   554
						np = RIGHT(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   555
					else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   556
						RIGHT(np) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   557
						PARENT(tp) = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   558
						break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   559
					}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   560
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   561
					if ((sp = PARENT(np)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   562
						if (np == LEFT(sp))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   563
							LEFT(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   564
						else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   565
							RIGHT(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   566
						PARENT(tp) = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   567
					} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   568
						Root = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   569
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   570
					/* insert to head of list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   571
					if ((sp = LEFT(np)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   572
						PARENT(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   573
					LEFT(tp) = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   574
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   575
					if ((sp = RIGHT(np)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   576
						PARENT(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   577
					RIGHT(tp) = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   578
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   579
					/* doubly link list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   580
					LINKFOR(tp) = np;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   581
					LINKBAK(np) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   582
					SETNOTREE(np);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   583
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   584
					break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   585
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   586
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   587
		} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   588
			Root = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   589
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   590
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   591
	/* tell next block that this one is free */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   592
	SETBIT1(SIZE(NEXT(tp)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   593
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   594
	ASSERT(ISBIT0(SIZE(NEXT(tp))));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   595
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   596
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   597
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   598
 * Get more core. Gaps in memory are noted as busy blocks.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   599
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   600
static TREE *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   601
_morecore(size_t size)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   602
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   603
	TREE	*tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   604
	ssize_t	n, offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   605
	char	*addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   606
	ssize_t	nsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   607
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   608
	/* compute new amount of memory to get */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   609
	tp = Bottom;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   610
	n = (ssize_t)size + 2 * WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   611
	addr = GETCORE(0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   612
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   613
	if (addr == ERRCORE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   614
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   615
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   616
	/* need to pad size out so that addr is aligned */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   617
	if ((((uintptr_t)addr) % ALIGN) != 0)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   618
		offset = ALIGN - (uintptr_t)addr % ALIGN;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   619
	else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   620
		offset = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   621
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   622
#ifndef SEGMENTED
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   623
	/* if not segmented memory, what we need may be smaller */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   624
	if (addr == Baddr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   625
		n -= WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   626
		if (tp != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   627
			n -= SIZE(tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   628
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   629
#endif
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   630
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   631
	/* get a multiple of CORESIZE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   632
	n = ((n - 1) / CORESIZE + 1) * CORESIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   633
	nsize = n + offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   634
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   635
	/* check if nsize request could overflow in GETCORE */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   636
	if ((size_t)nsize > MAX_MALLOC - (uintptr_t)addr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   637
		errno = ENOMEM;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   638
		return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   639
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   640
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   641
	if ((size_t)nsize <= MAX_GETCORE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   642
		if (GETCORE(nsize) == ERRCORE)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   643
			return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   644
	} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   645
		intptr_t	delta;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   646
		/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   647
		 * the value required is too big for GETCORE() to deal with
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   648
		 * in one go, so use GETCORE() at most 2 times instead.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   649
		 * Argument to GETCORE() must be multiple of ALIGN.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   650
		 * If not, GETCORE(-MAX_GETCORE) will not return brk point
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   651
		 * to previous value, but will be ALIGN more.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   652
		 * This would leave a small hole.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   653
		 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   654
		delta = MAX_GETCORE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   655
		while (delta > 0) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   656
			if (GETCORE(delta) == ERRCORE) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   657
				if (addr != GETCORE(0))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   658
					(void) GETCORE(-MAX_GETCORE);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   659
				return (NULL);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   660
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   661
			nsize -= MAX_GETCORE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   662
			delta = nsize;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   663
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   664
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   665
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   666
	/* contiguous memory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   667
	if (addr == Baddr) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   668
		ASSERT(offset == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   669
		if (tp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   670
			addr = (char *)tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   671
			n += SIZE(tp) + 2 * WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   672
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   673
			addr = Baddr - WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   674
			n += WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   675
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   676
	} else
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   677
		addr += offset;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   678
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   679
	/* new bottom address */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   680
	Baddr = addr + n;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   681
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   682
	/* new bottom block */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   683
	tp = (TREE *)(uintptr_t)addr;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   684
	SIZE(tp) = n - 2 * WORDSIZE;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   685
	ASSERT((SIZE(tp) % ALIGN) == 0);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   686
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   687
	/* reserved the last word to head any noncontiguous memory */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   688
	SETBIT0(SIZE(NEXT(tp)));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   689
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   690
	/* non-contiguous memory, free old bottom block */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   691
	if (Bottom && Bottom != tp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   692
		SETBIT0(SIZE(Bottom));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   693
		realfree(DATA(Bottom));
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   694
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   695
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   696
	return (tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   697
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   698
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   699
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   700
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   701
 * Tree rotation functions (BU: bottom-up, TD: top-down)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   702
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   703
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   704
#define	LEFT1(x, y)		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   705
			if ((RIGHT(x) = LEFT(y)) != NULL) PARENT(RIGHT(x)) = x;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   706
			if ((PARENT(y) = PARENT(x)) != NULL)\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   707
				if (LEFT(PARENT(x)) == x) LEFT(PARENT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   708
				else RIGHT(PARENT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   709
			LEFT(y) = x; PARENT(x) = y
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   710
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   711
#define	RIGHT1(x, y)		\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   712
			if ((LEFT(x) = RIGHT(y)) != NULL) PARENT(LEFT(x)) = x;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   713
			if ((PARENT(y) = PARENT(x)) != NULL)\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   714
				if (LEFT(PARENT(x)) == x) LEFT(PARENT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   715
				else RIGHT(PARENT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   716
			RIGHT(y) = x; PARENT(x) = y
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   717
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   718
#define	BULEFT2(x, y, z)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   719
			if ((RIGHT(x) = LEFT(y)) != NULL) PARENT(RIGHT(x)) = x;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   720
			if ((RIGHT(y) = LEFT(z)) != NULL) PARENT(RIGHT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   721
			if ((PARENT(z) = PARENT(x)) != NULL)\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   722
				if (LEFT(PARENT(x)) == x) LEFT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   723
				else RIGHT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   724
			LEFT(z) = y; PARENT(y) = z; LEFT(y) = x; PARENT(x) = y
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   725
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   726
#define	BURIGHT2(x, y, z)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   727
			if ((LEFT(x) = RIGHT(y)) != NULL) PARENT(LEFT(x)) = x;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   728
			if ((LEFT(y) = RIGHT(z)) != NULL) PARENT(LEFT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   729
			if ((PARENT(z) = PARENT(x)) != NULL)\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   730
				if (LEFT(PARENT(x)) == x) LEFT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   731
				else RIGHT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   732
			RIGHT(z) = y; PARENT(y) = z; RIGHT(y) = x; PARENT(x) = y
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   733
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   734
#define	TDLEFT2(x, y, z)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   735
			if ((RIGHT(y) = LEFT(z)) != NULL) PARENT(RIGHT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   736
			if ((PARENT(z) = PARENT(x)) != NULL)\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   737
				if (LEFT(PARENT(x)) == x) LEFT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   738
				else RIGHT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   739
			PARENT(x) = z; LEFT(z) = x;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   740
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   741
#define	TDRIGHT2(x, y, z)	\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   742
			if ((LEFT(y) = RIGHT(z)) != NULL) PARENT(LEFT(y)) = y;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   743
			if ((PARENT(z) = PARENT(x)) != NULL)\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   744
				if (LEFT(PARENT(x)) == x) LEFT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   745
				else RIGHT(PARENT(z)) = z;\
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   746
			PARENT(x) = z; RIGHT(z) = x;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   747
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   748
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   749
 * Delete a tree element
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   750
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   751
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   752
t_delete(TREE *op)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   753
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   754
	TREE	*tp, *sp, *gp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   755
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   756
	/* if this is a non-tree node */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   757
	if (ISNOTREE(op)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   758
		tp = LINKBAK(op);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   759
		if ((sp = LINKFOR(op)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   760
			LINKBAK(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   761
		LINKFOR(tp) = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   762
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   763
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   764
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   765
	/* make op the root of the tree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   766
	if (PARENT(op))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   767
		t_splay(op);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   768
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   769
	/* if this is the start of a list */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   770
	if ((tp = LINKFOR(op)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   771
		PARENT(tp) = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   772
		if ((sp = LEFT(op)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   773
			PARENT(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   774
		LEFT(tp) = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   775
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   776
		if ((sp = RIGHT(op)) != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   777
			PARENT(sp) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   778
		RIGHT(tp) = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   779
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   780
		Root = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   781
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   782
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   783
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   784
	/* if op has a non-null left subtree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   785
	if ((tp = LEFT(op)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   786
		PARENT(tp) = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   787
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   788
		if (RIGHT(op)) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   789
			/* make the right-end of the left subtree its root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   790
			while ((sp = RIGHT(tp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   791
				if ((gp = RIGHT(sp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   792
					TDLEFT2(tp, sp, gp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   793
					tp = gp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   794
				} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   795
					LEFT1(tp, sp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   796
					tp = sp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   797
				}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   798
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   799
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   800
			/* hook the right subtree of op to the above elt */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   801
			RIGHT(tp) = RIGHT(op);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   802
			PARENT(RIGHT(tp)) = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   803
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   804
	} else if ((tp = RIGHT(op)) != NULL)	/* no left subtree */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   805
		PARENT(tp) = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   806
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   807
	Root = tp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   808
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   809
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   810
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   811
 * Bottom up splaying (simple version).
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   812
 * The basic idea is to roughly cut in half the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   813
 * path from Root to tp and make tp the new root.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   814
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   815
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   816
t_splay(TREE *tp)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   817
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   818
	TREE	*pp, *gp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   819
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   820
	/* iterate until tp is the root */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   821
	while ((pp = PARENT(tp)) != NULL) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   822
		/* grandparent of tp */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   823
		gp = PARENT(pp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   824
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   825
		/* x is a left child */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   826
		if (LEFT(pp) == tp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   827
			if (gp && LEFT(gp) == pp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   828
				BURIGHT2(gp, pp, tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   829
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   830
				RIGHT1(pp, tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   831
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   832
		} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   833
			ASSERT(RIGHT(pp) == tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   834
			if (gp && RIGHT(gp) == pp) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   835
				BULEFT2(gp, pp, tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   836
			} else {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   837
				LEFT1(pp, tp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   838
			}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   839
		}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   840
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   841
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   842
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   843
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   844
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   845
 *	free().
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   846
 *	Performs a delayed free of the block pointed to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   847
 *	by old. The pointer to old is saved on a list, flist,
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   848
 *	until the next malloc or realloc. At that time, all the
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   849
 *	blocks pointed to in flist are actually freed via
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   850
 *	realfree(). This allows the contents of free blocks to
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   851
 *	remain undisturbed until the next malloc or realloc.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   852
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   853
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   854
free(void *old)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   855
{
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   856
	if (!primary_link_map) {
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   857
		errno = ENOTSUP;
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   858
		return;
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   859
	}
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   860
	assert_no_libc_locks_held();
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   861
	(void) mutex_lock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   862
	_free_unlocked(old);
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   863
	(void) mutex_unlock(&libc_malloc_lock);
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   864
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   865
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   866
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   867
void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   868
_free_unlocked(void *old)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   869
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   870
	int	i;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   871
6515
10dab2b883e0 6678310 using LD_AUDIT, ld.so.1 calls shared library's .init before library is fully relocated
raf
parents: 2186
diff changeset
   872
	if (old == NULL)
0
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   873
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   874
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   875
	/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   876
	 * Make sure the same data block is not freed twice.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   877
	 * 3 cases are checked.  It returns immediately if either
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   878
	 * one of the conditions is true.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   879
	 *	1. Last freed.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   880
	 *	2. Not in use or freed already.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   881
	 *	3. In the free list.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   882
	 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   883
	if (old == Lfree)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   884
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   885
	if (!ISBIT0(SIZE(BLOCK(old))))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   886
		return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   887
	for (i = 0; i < freeidx; i++)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   888
		if (old == flist[i])
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   889
			return;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   890
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   891
	if (flist[freeidx] != NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   892
		realfree(flist[freeidx]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   893
	flist[freeidx] = Lfree = old;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   894
	freeidx = (freeidx + 1) & FREEMASK; /* one forward */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   895
}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   896
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   897
/*
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   898
 * cleanfree() frees all the blocks pointed to be flist.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   899
 *
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   900
 * realloc() should work if it is called with a pointer
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   901
 * to a block that was freed since the last call to malloc() or
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   902
 * realloc(). If cleanfree() is called from realloc(), ptr
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   903
 * is set to the old block and that block should not be
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   904
 * freed since it is actually being reallocated.
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   905
 */
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   906
static void
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   907
cleanfree(void *ptr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   908
{
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   909
	char	**flp;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   910
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   911
	flp = (char **)&(flist[freeidx]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   912
	for (;;) {
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   913
		if (flp == (char **)&(flist[0]))
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   914
			flp = (char **)&(flist[FREESIZE]);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   915
		if (*--flp == NULL)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   916
			break;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   917
		if (*flp != ptr)
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   918
			realfree(*flp);
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   919
		*flp = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   920
	}
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   921
	freeidx = 0;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   922
	Lfree = NULL;
68f95e015346 OpenSolaris Launch
stevel@tonic-gate
parents:
diff changeset
   923
}