xref: /onnv-gate/usr/src/cmd/fm/modules/common/eversholt/alloc.c (revision 1717:ef845d4a1074)
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
5*1717Swesolows  * Common Development and Distribution License (the "License").
6*1717Swesolows  * 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  */
21*1717Swesolows 
220Sstevel@tonic-gate /*
23*1717Swesolows  * Copyright 2006 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 
43*1717Swesolows /* room to store size, possibly more to maintain alignment for long longs */
44*1717Swesolows #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 
510Sstevel@tonic-gate void
520Sstevel@tonic-gate alloc_init(void)
530Sstevel@tonic-gate {
540Sstevel@tonic-gate 	Malloctotal = stats_new_counter("alloc.total", "bytes allocated", 1);
550Sstevel@tonic-gate 	Freetotal = stats_new_counter("free.total", "bytes freed", 1);
560Sstevel@tonic-gate 	Malloccount = stats_new_counter("alloc.calls", "alloc calls", 1);
570Sstevel@tonic-gate 	Freecount = stats_new_counter("free.calls", "free calls", 1);
580Sstevel@tonic-gate }
590Sstevel@tonic-gate 
600Sstevel@tonic-gate void
610Sstevel@tonic-gate alloc_fini(void)
620Sstevel@tonic-gate {
630Sstevel@tonic-gate 	struct stats *mt, *ft, *mc, *fc;
640Sstevel@tonic-gate 
650Sstevel@tonic-gate 	mt = Malloctotal;
660Sstevel@tonic-gate 	ft = Freetotal;
670Sstevel@tonic-gate 	mc = Malloccount;
680Sstevel@tonic-gate 	fc = Freecount;
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 	Malloctotal = NULL;
710Sstevel@tonic-gate 	Freetotal = NULL;
720Sstevel@tonic-gate 	Malloccount = NULL;
730Sstevel@tonic-gate 	Freecount = NULL;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate 	stats_delete(mt);
760Sstevel@tonic-gate 	stats_delete(ft);
770Sstevel@tonic-gate 	stats_delete(mc);
780Sstevel@tonic-gate 	stats_delete(fc);
790Sstevel@tonic-gate }
800Sstevel@tonic-gate 
810Sstevel@tonic-gate /*
820Sstevel@tonic-gate  * alloc_malloc -- a malloc() with checks
830Sstevel@tonic-gate  *
840Sstevel@tonic-gate  * this routine is typically called via the MALLOC() macro in alloc.h
850Sstevel@tonic-gate  */
860Sstevel@tonic-gate /*ARGSUSED*/
870Sstevel@tonic-gate void *
880Sstevel@tonic-gate alloc_malloc(size_t nbytes, const char *fname, int line)
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	char *retval;
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	ASSERT(nbytes > 0);
930Sstevel@tonic-gate 
940Sstevel@tonic-gate 	retval = fmd_hdl_alloc(Hdl, nbytes + HDRSIZ, FMD_SLEEP);
950Sstevel@tonic-gate 
960Sstevel@tonic-gate 	/* retval can't be NULL since fmd_hdl_alloc() sleeps for memory */
970Sstevel@tonic-gate 
980Sstevel@tonic-gate 	bcopy((void *)&nbytes, (void *)retval, sizeof (nbytes));
990Sstevel@tonic-gate 	retval += HDRSIZ;
1000Sstevel@tonic-gate 
1010Sstevel@tonic-gate 	if (Malloctotal)
1020Sstevel@tonic-gate 		stats_counter_add(Malloctotal, nbytes);
1030Sstevel@tonic-gate 
1040Sstevel@tonic-gate 	if (Malloccount)
1050Sstevel@tonic-gate 		stats_counter_bump(Malloccount);
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate 	return ((void *)retval);
1080Sstevel@tonic-gate }
1090Sstevel@tonic-gate 
1100Sstevel@tonic-gate /*
1110Sstevel@tonic-gate  * alloc_realloc -- a realloc() with checks
1120Sstevel@tonic-gate  *
1130Sstevel@tonic-gate  * this routine is typically called via the REALLOC() macro in alloc.h
1140Sstevel@tonic-gate  */
1150Sstevel@tonic-gate void *
1160Sstevel@tonic-gate alloc_realloc(void *ptr, size_t nbytes, const char *fname, int line)
1170Sstevel@tonic-gate {
1180Sstevel@tonic-gate 	void *retval = alloc_malloc(nbytes, fname, line);
1190Sstevel@tonic-gate 
1200Sstevel@tonic-gate 	if (ptr != NULL) {
1210Sstevel@tonic-gate 		size_t osize;
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 		bcopy((void *)((char *)ptr - HDRSIZ), (void *)&osize,
1240Sstevel@tonic-gate 		    sizeof (osize));
1250Sstevel@tonic-gate 		/* now we have the new memory, copy in the old contents */
1260Sstevel@tonic-gate 		bcopy(ptr, retval, (osize < nbytes) ? osize : nbytes);
1270Sstevel@tonic-gate 
1280Sstevel@tonic-gate 		/* don't need the old memory anymore */
1290Sstevel@tonic-gate 		alloc_free((char *)ptr, fname, line);
1300Sstevel@tonic-gate 	}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 	return (retval);
1330Sstevel@tonic-gate }
1340Sstevel@tonic-gate 
1350Sstevel@tonic-gate /*
1360Sstevel@tonic-gate  * alloc_strdup -- a strdup() with checks
1370Sstevel@tonic-gate  *
1380Sstevel@tonic-gate  * this routine is typically called via the STRDUP() macro in alloc.h
1390Sstevel@tonic-gate  */
1400Sstevel@tonic-gate char *
1410Sstevel@tonic-gate alloc_strdup(const char *ptr, const char *fname, int line)
1420Sstevel@tonic-gate {
1430Sstevel@tonic-gate 	char *retval = alloc_malloc(strlen(ptr) + 1, fname, line);
1440Sstevel@tonic-gate 
1450Sstevel@tonic-gate 	(void) strcpy(retval, ptr);
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	return (retval);
1480Sstevel@tonic-gate }
1490Sstevel@tonic-gate 
1500Sstevel@tonic-gate /*
1510Sstevel@tonic-gate  * alloc_free -- a free() with checks
1520Sstevel@tonic-gate  *
1530Sstevel@tonic-gate  * this routine is typically called via the FREE() macro in alloc.h
1540Sstevel@tonic-gate  */
1550Sstevel@tonic-gate /*ARGSUSED*/
1560Sstevel@tonic-gate void
1570Sstevel@tonic-gate alloc_free(void *ptr, const char *fname, int line)
1580Sstevel@tonic-gate {
1590Sstevel@tonic-gate 	size_t osize;
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate 	ASSERT(ptr != NULL);
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 	bcopy((void *)((char *)ptr - HDRSIZ), (void *)&osize, sizeof (osize));
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate 	/* nothing to check in this version */
1660Sstevel@tonic-gate 
1670Sstevel@tonic-gate 	fmd_hdl_free(Hdl, (char *)ptr - HDRSIZ, osize + HDRSIZ);
1680Sstevel@tonic-gate 
1690Sstevel@tonic-gate 	if (Freetotal)
1700Sstevel@tonic-gate 		stats_counter_add(Freetotal, osize);
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate 	if (Freecount)
1730Sstevel@tonic-gate 		stats_counter_bump(Freecount);
1740Sstevel@tonic-gate }
175