xref: /onnv-gate/usr/src/cmd/fm/modules/common/eversholt/alloc.c (revision 4436:35b72f77cdd9)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51717Swesolows  * Common Development and Distribution License (the "License").
61717Swesolows  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
211717Swesolows 
220Sstevel@tonic-gate /*
23*4436Sstephh  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  *
260Sstevel@tonic-gate  * alloc.c -- memory allocation wrapper functions, for eft.so FMD module
270Sstevel@tonic-gate  *
280Sstevel@tonic-gate  */
290Sstevel@tonic-gate 
300Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
310Sstevel@tonic-gate 
320Sstevel@tonic-gate #include <stdlib.h>
330Sstevel@tonic-gate #include <string.h>
340Sstevel@tonic-gate #include <strings.h>
350Sstevel@tonic-gate #include <fm/fmd_api.h>
360Sstevel@tonic-gate 
370Sstevel@tonic-gate #include "alloc.h"
380Sstevel@tonic-gate #include "out.h"
390Sstevel@tonic-gate #include "stats.h"
400Sstevel@tonic-gate 
410Sstevel@tonic-gate extern fmd_hdl_t *Hdl;		/* handle from eft.c */
420Sstevel@tonic-gate 
431717Swesolows /* room to store size, possibly more to maintain alignment for long longs */
441717Swesolows #define	HDRSIZ	sizeof (long long)
450Sstevel@tonic-gate 
460Sstevel@tonic-gate static struct stats *Malloctotal;
470Sstevel@tonic-gate static struct stats *Freetotal;
480Sstevel@tonic-gate static struct stats *Malloccount;
490Sstevel@tonic-gate static struct stats *Freecount;
500Sstevel@tonic-gate 
51*4436Sstephh static int totalcount;
52*4436Sstephh 
530Sstevel@tonic-gate void
alloc_init(void)540Sstevel@tonic-gate alloc_init(void)
550Sstevel@tonic-gate {
560Sstevel@tonic-gate 	Malloctotal = stats_new_counter("alloc.total", "bytes allocated", 1);
570Sstevel@tonic-gate 	Freetotal = stats_new_counter("free.total", "bytes freed", 1);
580Sstevel@tonic-gate 	Malloccount = stats_new_counter("alloc.calls", "alloc calls", 1);
590Sstevel@tonic-gate 	Freecount = stats_new_counter("free.calls", "free calls", 1);
600Sstevel@tonic-gate }
610Sstevel@tonic-gate 
620Sstevel@tonic-gate void
alloc_fini(void)630Sstevel@tonic-gate alloc_fini(void)
640Sstevel@tonic-gate {
650Sstevel@tonic-gate 	struct stats *mt, *ft, *mc, *fc;
660Sstevel@tonic-gate 
670Sstevel@tonic-gate 	mt = Malloctotal;
680Sstevel@tonic-gate 	ft = Freetotal;
690Sstevel@tonic-gate 	mc = Malloccount;
700Sstevel@tonic-gate 	fc = Freecount;
710Sstevel@tonic-gate 
720Sstevel@tonic-gate 	Malloctotal = NULL;
730Sstevel@tonic-gate 	Freetotal = NULL;
740Sstevel@tonic-gate 	Malloccount = NULL;
750Sstevel@tonic-gate 	Freecount = NULL;
760Sstevel@tonic-gate 
770Sstevel@tonic-gate 	stats_delete(mt);
780Sstevel@tonic-gate 	stats_delete(ft);
790Sstevel@tonic-gate 	stats_delete(mc);
800Sstevel@tonic-gate 	stats_delete(fc);
810Sstevel@tonic-gate }
820Sstevel@tonic-gate 
830Sstevel@tonic-gate /*
840Sstevel@tonic-gate  * alloc_malloc -- a malloc() with checks
850Sstevel@tonic-gate  *
860Sstevel@tonic-gate  * this routine is typically called via the MALLOC() macro in alloc.h
870Sstevel@tonic-gate  */
880Sstevel@tonic-gate /*ARGSUSED*/
890Sstevel@tonic-gate void *
alloc_malloc(size_t nbytes,const char * fname,int line)900Sstevel@tonic-gate alloc_malloc(size_t nbytes, const char *fname, int line)
910Sstevel@tonic-gate {
920Sstevel@tonic-gate 	char *retval;
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	ASSERT(nbytes > 0);
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	retval = fmd_hdl_alloc(Hdl, nbytes + HDRSIZ, FMD_SLEEP);
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	/* retval can't be NULL since fmd_hdl_alloc() sleeps for memory */
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	bcopy((void *)&nbytes, (void *)retval, sizeof (nbytes));
1010Sstevel@tonic-gate 	retval += HDRSIZ;
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate 	if (Malloctotal)
1040Sstevel@tonic-gate 		stats_counter_add(Malloctotal, nbytes);
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	if (Malloccount)
1070Sstevel@tonic-gate 		stats_counter_bump(Malloccount);
1080Sstevel@tonic-gate 
109*4436Sstephh 	totalcount += nbytes + HDRSIZ;
1100Sstevel@tonic-gate 	return ((void *)retval);
1110Sstevel@tonic-gate }
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate /*
1140Sstevel@tonic-gate  * alloc_realloc -- a realloc() with checks
1150Sstevel@tonic-gate  *
1160Sstevel@tonic-gate  * this routine is typically called via the REALLOC() macro in alloc.h
1170Sstevel@tonic-gate  */
1180Sstevel@tonic-gate void *
alloc_realloc(void * ptr,size_t nbytes,const char * fname,int line)1190Sstevel@tonic-gate alloc_realloc(void *ptr, size_t nbytes, const char *fname, int line)
1200Sstevel@tonic-gate {
1210Sstevel@tonic-gate 	void *retval = alloc_malloc(nbytes, fname, line);
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	if (ptr != NULL) {
1240Sstevel@tonic-gate 		size_t osize;
1250Sstevel@tonic-gate 
1260Sstevel@tonic-gate 		bcopy((void *)((char *)ptr - HDRSIZ), (void *)&osize,
1270Sstevel@tonic-gate 		    sizeof (osize));
1280Sstevel@tonic-gate 		/* now we have the new memory, copy in the old contents */
1290Sstevel@tonic-gate 		bcopy(ptr, retval, (osize < nbytes) ? osize : nbytes);
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 		/* don't need the old memory anymore */
1320Sstevel@tonic-gate 		alloc_free((char *)ptr, fname, line);
1330Sstevel@tonic-gate 	}
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate 	return (retval);
1360Sstevel@tonic-gate }
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate /*
1390Sstevel@tonic-gate  * alloc_strdup -- a strdup() with checks
1400Sstevel@tonic-gate  *
1410Sstevel@tonic-gate  * this routine is typically called via the STRDUP() macro in alloc.h
1420Sstevel@tonic-gate  */
1430Sstevel@tonic-gate char *
alloc_strdup(const char * ptr,const char * fname,int line)1440Sstevel@tonic-gate alloc_strdup(const char *ptr, const char *fname, int line)
1450Sstevel@tonic-gate {
1460Sstevel@tonic-gate 	char *retval = alloc_malloc(strlen(ptr) + 1, fname, line);
1470Sstevel@tonic-gate 
1480Sstevel@tonic-gate 	(void) strcpy(retval, ptr);
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate 	return (retval);
1510Sstevel@tonic-gate }
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate /*
1540Sstevel@tonic-gate  * alloc_free -- a free() with checks
1550Sstevel@tonic-gate  *
1560Sstevel@tonic-gate  * this routine is typically called via the FREE() macro in alloc.h
1570Sstevel@tonic-gate  */
1580Sstevel@tonic-gate /*ARGSUSED*/
1590Sstevel@tonic-gate void
alloc_free(void * ptr,const char * fname,int line)1600Sstevel@tonic-gate alloc_free(void *ptr, const char *fname, int line)
1610Sstevel@tonic-gate {
1620Sstevel@tonic-gate 	size_t osize;
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	ASSERT(ptr != NULL);
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 	bcopy((void *)((char *)ptr - HDRSIZ), (void *)&osize, sizeof (osize));
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 	/* nothing to check in this version */
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate 	fmd_hdl_free(Hdl, (char *)ptr - HDRSIZ, osize + HDRSIZ);
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	if (Freetotal)
1730Sstevel@tonic-gate 		stats_counter_add(Freetotal, osize);
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	if (Freecount)
1760Sstevel@tonic-gate 		stats_counter_bump(Freecount);
177*4436Sstephh 	totalcount -= osize + HDRSIZ;
1780Sstevel@tonic-gate }
179*4436Sstephh 
180*4436Sstephh int
alloc_total()181*4436Sstephh alloc_total()
182*4436Sstephh {
183*4436Sstephh 	return (totalcount);
184*4436Sstephh }
185*4436Sstephh 
186*4436Sstephh /*
187*4436Sstephh  * variants that don't maintain size in header - saves space
188*4436Sstephh  */
189*4436Sstephh void *
alloc_xmalloc(size_t nbytes)190*4436Sstephh alloc_xmalloc(size_t nbytes)
191*4436Sstephh {
192*4436Sstephh 	char *retval;
193*4436Sstephh 
194*4436Sstephh 	ASSERT(nbytes > 0);
195*4436Sstephh 	retval = fmd_hdl_alloc(Hdl, nbytes, FMD_SLEEP);
196*4436Sstephh 	if (Malloctotal)
197*4436Sstephh 		stats_counter_add(Malloctotal, nbytes);
198*4436Sstephh 	if (Malloccount)
199*4436Sstephh 		stats_counter_bump(Malloccount);
200*4436Sstephh 	totalcount += nbytes;
201*4436Sstephh 	return ((void *)retval);
202*4436Sstephh }
203*4436Sstephh 
204*4436Sstephh void
alloc_xfree(void * ptr,size_t size)205*4436Sstephh alloc_xfree(void *ptr, size_t size)
206*4436Sstephh {
207*4436Sstephh 	ASSERT(ptr != NULL);
208*4436Sstephh 
209*4436Sstephh 	fmd_hdl_free(Hdl, (char *)ptr, size);
210*4436Sstephh 	if (Freetotal)
211*4436Sstephh 		stats_counter_add(Freetotal, size);
212*4436Sstephh 	if (Freecount)
213*4436Sstephh 		stats_counter_bump(Freecount);
214*4436Sstephh 	totalcount -= size;
215*4436Sstephh }
216