Deleted Added
full compact
memstat_malloc.c (148354) memstat_malloc.c (148357)
1/*-
2 * Copyright (c) 2005 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
1/*-
2 * Copyright (c) 2005 Robert N. M. Watson
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 9 unchanged lines hidden (view full) ---

18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 * $FreeBSD: head/lib/libmemstat/memstat_malloc.c 148354 2005-07-23 21:17:15Z rwatson $
26 * $FreeBSD: head/lib/libmemstat/memstat_malloc.c 148357 2005-07-24 01:28:54Z rwatson $
27 */
28
29#include <sys/param.h>
30#include <sys/malloc.h>
31#include <sys/sysctl.h>
32
33#include <err.h>
34#include <errno.h>

--- 18 unchanged lines hidden (view full) ---

53 */
54int
55memstat_sysctl_malloc(struct memory_type_list *list, int flags)
56{
57 struct malloc_type_stream_header *mtshp;
58 struct malloc_type_header *mthp;
59 struct malloc_type_stats *mtsp;
60 struct memory_type *mtp;
27 */
28
29#include <sys/param.h>
30#include <sys/malloc.h>
31#include <sys/sysctl.h>
32
33#include <err.h>
34#include <errno.h>

--- 18 unchanged lines hidden (view full) ---

53 */
54int
55memstat_sysctl_malloc(struct memory_type_list *list, int flags)
56{
57 struct malloc_type_stream_header *mtshp;
58 struct malloc_type_header *mthp;
59 struct malloc_type_stats *mtsp;
60 struct memory_type *mtp;
61 int count, error, hint_dontsearch, i, j, maxcpus;
61 int count, hint_dontsearch, i, j, maxcpus;
62 char *buffer, *p;
63 size_t size;
64
62 char *buffer, *p;
63 size_t size;
64
65 hint_dontsearch = LIST_EMPTY(list);
65 hint_dontsearch = LIST_EMPTY(&list->mtl_list);
66
67 /*
68 * Query the number of CPUs, number of malloc types so that we can
69 * guess an initial buffer size. We loop until we succeed or really
70 * fail. Note that the value of maxcpus we query using sysctl is not
71 * the version we use when processing the real data -- that is read
72 * from the header.
73 */
74retry:
75 size = sizeof(maxcpus);
76 if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
66
67 /*
68 * Query the number of CPUs, number of malloc types so that we can
69 * guess an initial buffer size. We loop until we succeed or really
70 * fail. Note that the value of maxcpus we query using sysctl is not
71 * the version we use when processing the real data -- that is read
72 * from the header.
73 */
74retry:
75 size = sizeof(maxcpus);
76 if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
77 error = errno;
78 perror("kern.smp.maxcpus");
79 errno = error;
77 if (errno == EACCES || errno == EPERM)
78 list->mtl_error = MEMSTAT_ERROR_PERMISSION;
79 else
80 list->mtl_error = MEMSTAT_ERROR_DATAERROR;
80 return (-1);
81 }
82 if (size != sizeof(maxcpus)) {
81 return (-1);
82 }
83 if (size != sizeof(maxcpus)) {
83 fprintf(stderr, "kern.smp.maxcpus: wrong size");
84 errno = EINVAL;
84 list->mtl_error = MEMSTAT_ERROR_DATAERROR;
85 return (-1);
86 }
87
88 if (maxcpus > MEMSTAT_MAXCPU) {
85 return (-1);
86 }
87
88 if (maxcpus > MEMSTAT_MAXCPU) {
89 fprintf(stderr, "kern.smp.maxcpus: too many CPUs\n");
90 errno = EINVAL;
89 list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
91 return (-1);
92 }
93
94 size = sizeof(count);
95 if (sysctlbyname("kern.malloc_count", &count, &size, NULL, 0) < 0) {
90 return (-1);
91 }
92
93 size = sizeof(count);
94 if (sysctlbyname("kern.malloc_count", &count, &size, NULL, 0) < 0) {
96 error = errno;
97 perror("kern.malloc_count");
98 errno = error;
95 if (errno == EACCES || errno == EPERM)
96 list->mtl_error = MEMSTAT_ERROR_PERMISSION;
97 else
98 list->mtl_error = MEMSTAT_ERROR_VERSION;
99 return (-1);
100 }
101 if (size != sizeof(count)) {
99 return (-1);
100 }
101 if (size != sizeof(count)) {
102 fprintf(stderr, "kern.malloc_count: wrong size");
103 errno = EINVAL;
102 list->mtl_error = MEMSTAT_ERROR_DATAERROR;
104 return (-1);
105 }
106
107 size = sizeof(*mthp) + count * (sizeof(*mthp) + sizeof(*mtsp) *
108 maxcpus);
109
110 buffer = malloc(size);
111 if (buffer == NULL) {
103 return (-1);
104 }
105
106 size = sizeof(*mthp) + count * (sizeof(*mthp) + sizeof(*mtsp) *
107 maxcpus);
108
109 buffer = malloc(size);
110 if (buffer == NULL) {
112 error = errno;
113 perror("malloc");
114 errno = error;
111 list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
115 return (-1);
116 }
117
118 if (sysctlbyname("kern.malloc_stats", buffer, &size, NULL, 0) < 0) {
119 /*
120 * XXXRW: ENOMEM is an ambiguous return, we should bound the
121 * number of loops, perhaps.
122 */
123 if (errno == ENOMEM) {
124 free(buffer);
125 goto retry;
126 }
112 return (-1);
113 }
114
115 if (sysctlbyname("kern.malloc_stats", buffer, &size, NULL, 0) < 0) {
116 /*
117 * XXXRW: ENOMEM is an ambiguous return, we should bound the
118 * number of loops, perhaps.
119 */
120 if (errno == ENOMEM) {
121 free(buffer);
122 goto retry;
123 }
127 error = errno;
124 if (errno == EACCES || errno == EPERM)
125 list->mtl_error = MEMSTAT_ERROR_PERMISSION;
126 else
127 list->mtl_error = MEMSTAT_ERROR_VERSION;
128 free(buffer);
128 free(buffer);
129 perror("kern.malloc_stats");
130 errno = error;
131 return (-1);
132 }
133
134 if (size == 0) {
135 free(buffer);
136 return (0);
137 }
138
139 if (size < sizeof(*mtshp)) {
129 return (-1);
130 }
131
132 if (size == 0) {
133 free(buffer);
134 return (0);
135 }
136
137 if (size < sizeof(*mtshp)) {
140 fprintf(stderr, "sysctl_malloc: invalid malloc header");
138 list->mtl_error = MEMSTAT_ERROR_VERSION;
141 free(buffer);
139 free(buffer);
142 errno = EINVAL;
143 return (-1);
144 }
145 p = buffer;
146 mtshp = (struct malloc_type_stream_header *)p;
147 p += sizeof(*mtshp);
148
149 if (mtshp->mtsh_version != MALLOC_TYPE_STREAM_VERSION) {
140 return (-1);
141 }
142 p = buffer;
143 mtshp = (struct malloc_type_stream_header *)p;
144 p += sizeof(*mtshp);
145
146 if (mtshp->mtsh_version != MALLOC_TYPE_STREAM_VERSION) {
150 fprintf(stderr, "sysctl_malloc: unknown malloc version");
147 list->mtl_error = MEMSTAT_ERROR_VERSION;
151 free(buffer);
148 free(buffer);
152 errno = EINVAL;
153 return (-1);
154 }
155
156 if (mtshp->mtsh_maxcpus > MEMSTAT_MAXCPU) {
149 return (-1);
150 }
151
152 if (mtshp->mtsh_maxcpus > MEMSTAT_MAXCPU) {
157 fprintf(stderr, "sysctl_malloc: too many CPUs");
153 list->mtl_error = MEMSTAT_ERROR_TOOMANYCPUS;
158 free(buffer);
154 free(buffer);
159 errno = EINVAL;
160 return (-1);
161 }
162
163 /*
164 * For the remainder of this function, we are quite trusting about
165 * the layout of structures and sizes, since we've determined we have
166 * a matching version and acceptable CPU count.
167 */

--- 9 unchanged lines hidden (view full) ---

177 } else
178 mtp = NULL;
179 if (mtp == NULL)
180 mtp = _memstat_mt_allocate(list, ALLOCATOR_MALLOC,
181 mthp->mth_name);
182 if (mtp == NULL) {
183 memstat_mtl_free(list);
184 free(buffer);
155 return (-1);
156 }
157
158 /*
159 * For the remainder of this function, we are quite trusting about
160 * the layout of structures and sizes, since we've determined we have
161 * a matching version and acceptable CPU count.
162 */

--- 9 unchanged lines hidden (view full) ---

172 } else
173 mtp = NULL;
174 if (mtp == NULL)
175 mtp = _memstat_mt_allocate(list, ALLOCATOR_MALLOC,
176 mthp->mth_name);
177 if (mtp == NULL) {
178 memstat_mtl_free(list);
179 free(buffer);
185 errno = ENOMEM;
186 perror("malloc");
187 errno = ENOMEM;
180 list->mtl_error = MEMSTAT_ERROR_NOMEMORY;
188 return (-1);
189 }
190
191 /*
192 * Reset the statistics on a current node.
193 */
194 _memstat_mt_reset_stats(mtp);
195

--- 40 unchanged lines hidden ---
181 return (-1);
182 }
183
184 /*
185 * Reset the statistics on a current node.
186 */
187 _memstat_mt_reset_stats(mtp);
188

--- 40 unchanged lines hidden ---