diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib/libc/include/thread_private.h | 4 | ||||
-rw-r--r-- | src/lib/libc/stdlib/malloc.c | 57 |
2 files changed, 39 insertions, 22 deletions
diff --git a/src/lib/libc/include/thread_private.h b/src/lib/libc/include/thread_private.h index ae8d554a8a..774e0cba1f 100644 --- a/src/lib/libc/include/thread_private.h +++ b/src/lib/libc/include/thread_private.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: thread_private.h,v 1.33 2017/12/05 13:45:31 kettenis Exp $ */ | 1 | /* $OpenBSD: thread_private.h,v 1.34 2019/01/10 18:45:33 otto Exp $ */ |
2 | 2 | ||
3 | /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ | 3 | /* PUBLIC DOMAIN: No Rights Reserved. Marco S Hyman <marc@snafu.org> */ |
4 | 4 | ||
@@ -7,7 +7,7 @@ | |||
7 | 7 | ||
8 | #include <stdio.h> /* for FILE and __isthreaded */ | 8 | #include <stdio.h> /* for FILE and __isthreaded */ |
9 | 9 | ||
10 | #define _MALLOC_MUTEXES 4 | 10 | #define _MALLOC_MUTEXES 32 |
11 | void _malloc_init(int); | 11 | void _malloc_init(int); |
12 | #ifdef __LIBC__ | 12 | #ifdef __LIBC__ |
13 | PROTO_NORMAL(_malloc_init); | 13 | PROTO_NORMAL(_malloc_init); |
diff --git a/src/lib/libc/stdlib/malloc.c b/src/lib/libc/stdlib/malloc.c index de504cdd8b..2a1bcfc8b6 100644 --- a/src/lib/libc/stdlib/malloc.c +++ b/src/lib/libc/stdlib/malloc.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: malloc.c,v 1.257 2018/12/10 07:57:49 otto Exp $ */ | 1 | /* $OpenBSD: malloc.c,v 1.258 2019/01/10 18:45:33 otto Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> | 3 | * Copyright (c) 2008, 2010, 2011, 2016 Otto Moerbeek <otto@drijf.net> |
4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> | 4 | * Copyright (c) 2012 Matthew Dempsky <matthew@openbsd.org> |
@@ -143,6 +143,8 @@ struct dir_info { | |||
143 | size_t cheap_reallocs; | 143 | size_t cheap_reallocs; |
144 | size_t malloc_used; /* bytes allocated */ | 144 | size_t malloc_used; /* bytes allocated */ |
145 | size_t malloc_guarded; /* bytes used for guards */ | 145 | size_t malloc_guarded; /* bytes used for guards */ |
146 | size_t pool_searches; /* searches for pool */ | ||
147 | size_t other_pool; /* searches in other pool */ | ||
146 | #define STATS_ADD(x,y) ((x) += (y)) | 148 | #define STATS_ADD(x,y) ((x) += (y)) |
147 | #define STATS_SUB(x,y) ((x) -= (y)) | 149 | #define STATS_SUB(x,y) ((x) -= (y)) |
148 | #define STATS_INC(x) ((x)++) | 150 | #define STATS_INC(x) ((x)++) |
@@ -179,7 +181,9 @@ struct chunk_info { | |||
179 | }; | 181 | }; |
180 | 182 | ||
181 | struct malloc_readonly { | 183 | struct malloc_readonly { |
182 | struct dir_info *malloc_pool[_MALLOC_MUTEXES]; /* Main bookkeeping information */ | 184 | /* Main bookkeeping information */ |
185 | struct dir_info *malloc_pool[_MALLOC_MUTEXES]; | ||
186 | u_int malloc_mutexes; /* how much in actual use? */ | ||
183 | int malloc_mt; /* multi-threaded mode? */ | 187 | int malloc_mt; /* multi-threaded mode? */ |
184 | int malloc_freecheck; /* Extensive double free check */ | 188 | int malloc_freecheck; /* Extensive double free check */ |
185 | int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ | 189 | int malloc_freeunmap; /* mprotect free pages PROT_NONE? */ |
@@ -267,7 +271,7 @@ getpool(void) | |||
267 | return mopts.malloc_pool[0]; | 271 | return mopts.malloc_pool[0]; |
268 | else | 272 | else |
269 | return mopts.malloc_pool[TIB_GET()->tib_tid & | 273 | return mopts.malloc_pool[TIB_GET()->tib_tid & |
270 | (_MALLOC_MUTEXES - 1)]; | 274 | (mopts.malloc_mutexes - 1)]; |
271 | } | 275 | } |
272 | 276 | ||
273 | static __dead void | 277 | static __dead void |
@@ -316,6 +320,16 @@ static void | |||
316 | omalloc_parseopt(char opt) | 320 | omalloc_parseopt(char opt) |
317 | { | 321 | { |
318 | switch (opt) { | 322 | switch (opt) { |
323 | case '+': | ||
324 | mopts.malloc_mutexes <<= 1; | ||
325 | if (mopts.malloc_mutexes > _MALLOC_MUTEXES) | ||
326 | mopts.malloc_mutexes = _MALLOC_MUTEXES; | ||
327 | break; | ||
328 | case '-': | ||
329 | mopts.malloc_mutexes >>= 1; | ||
330 | if (mopts.malloc_mutexes < 1) | ||
331 | mopts.malloc_mutexes = 1; | ||
332 | break; | ||
319 | case '>': | 333 | case '>': |
320 | mopts.malloc_cache <<= 1; | 334 | mopts.malloc_cache <<= 1; |
321 | if (mopts.malloc_cache > MALLOC_MAXCACHE) | 335 | if (mopts.malloc_cache > MALLOC_MAXCACHE) |
@@ -395,6 +409,7 @@ omalloc_init(void) | |||
395 | /* | 409 | /* |
396 | * Default options | 410 | * Default options |
397 | */ | 411 | */ |
412 | mopts.malloc_mutexes = 4; | ||
398 | mopts.malloc_junk = 1; | 413 | mopts.malloc_junk = 1; |
399 | mopts.malloc_cache = MALLOC_DEFAULT_CACHE; | 414 | mopts.malloc_cache = MALLOC_DEFAULT_CACHE; |
400 | 415 | ||
@@ -485,7 +500,7 @@ omalloc_poolinit(struct dir_info **dp) | |||
485 | for (j = 0; j < MALLOC_CHUNK_LISTS; j++) | 500 | for (j = 0; j < MALLOC_CHUNK_LISTS; j++) |
486 | LIST_INIT(&d->chunk_dir[i][j]); | 501 | LIST_INIT(&d->chunk_dir[i][j]); |
487 | } | 502 | } |
488 | STATS_ADD(d->malloc_used, regioninfo_size); | 503 | STATS_ADD(d->malloc_used, regioninfo_size + 3 * MALLOC_PAGESIZE); |
489 | d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d; | 504 | d->canary1 = mopts.malloc_canary ^ (u_int32_t)(uintptr_t)d; |
490 | d->canary2 = ~d->canary1; | 505 | d->canary2 = ~d->canary1; |
491 | 506 | ||
@@ -1196,7 +1211,7 @@ _malloc_init(int from_rthreads) | |||
1196 | if (!mopts.malloc_canary) | 1211 | if (!mopts.malloc_canary) |
1197 | omalloc_init(); | 1212 | omalloc_init(); |
1198 | 1213 | ||
1199 | max = from_rthreads ? _MALLOC_MUTEXES : 1; | 1214 | max = from_rthreads ? mopts.malloc_mutexes : 1; |
1200 | if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) | 1215 | if (((uintptr_t)&malloc_readonly & MALLOC_PAGEMASK) == 0) |
1201 | mprotect(&malloc_readonly, sizeof(malloc_readonly), | 1216 | mprotect(&malloc_readonly, sizeof(malloc_readonly), |
1202 | PROT_READ | PROT_WRITE); | 1217 | PROT_READ | PROT_WRITE); |
@@ -1281,16 +1296,19 @@ findpool(void *p, struct dir_info *argpool, struct dir_info **foundpool, | |||
1281 | struct dir_info *pool = argpool; | 1296 | struct dir_info *pool = argpool; |
1282 | struct region_info *r = find(pool, p); | 1297 | struct region_info *r = find(pool, p); |
1283 | 1298 | ||
1299 | STATS_INC(pool->pool_searches); | ||
1284 | if (r == NULL) { | 1300 | if (r == NULL) { |
1285 | if (mopts.malloc_mt) { | 1301 | if (mopts.malloc_mt) { |
1286 | int i; | 1302 | int i; |
1287 | 1303 | ||
1288 | for (i = 0; i < _MALLOC_MUTEXES; i++) { | 1304 | STATS_INC(pool->other_pool); |
1289 | if (i == argpool->mutex) | 1305 | for (i = 1; i < mopts.malloc_mutexes; i++) { |
1290 | continue; | 1306 | int j = (argpool->mutex + i) & |
1307 | (mopts.malloc_mutexes - 1); | ||
1308 | |||
1291 | pool->active--; | 1309 | pool->active--; |
1292 | _MALLOC_UNLOCK(pool->mutex); | 1310 | _MALLOC_UNLOCK(pool->mutex); |
1293 | pool = mopts.malloc_pool[i]; | 1311 | pool = mopts.malloc_pool[j]; |
1294 | _MALLOC_LOCK(pool->mutex); | 1312 | _MALLOC_LOCK(pool->mutex); |
1295 | pool->active++; | 1313 | pool->active++; |
1296 | r = find(pool, p); | 1314 | r = find(pool, p); |
@@ -2220,14 +2238,13 @@ malloc_dump1(int fd, int poolno, struct dir_info *d) | |||
2220 | return; | 2238 | return; |
2221 | dprintf(fd, "Region slots free %zu/%zu\n", | 2239 | dprintf(fd, "Region slots free %zu/%zu\n", |
2222 | d->regions_free, d->regions_total); | 2240 | d->regions_free, d->regions_total); |
2223 | dprintf(fd, "Finds %zu/%zu\n", d->finds, | 2241 | dprintf(fd, "Finds %zu/%zu\n", d->finds, d->find_collisions); |
2224 | d->find_collisions); | 2242 | dprintf(fd, "Inserts %zu/%zu\n", d->inserts, d->insert_collisions); |
2225 | dprintf(fd, "Inserts %zu/%zu\n", d->inserts, | 2243 | dprintf(fd, "Deletes %zu/%zu\n", d->deletes, d->delete_moves); |
2226 | d->insert_collisions); | ||
2227 | dprintf(fd, "Deletes %zu/%zu\n", d->deletes, | ||
2228 | d->delete_moves); | ||
2229 | dprintf(fd, "Cheap reallocs %zu/%zu\n", | 2244 | dprintf(fd, "Cheap reallocs %zu/%zu\n", |
2230 | d->cheap_reallocs, d->cheap_realloc_tries); | 2245 | d->cheap_reallocs, d->cheap_realloc_tries); |
2246 | dprintf(fd, "Other pool searches %zu/%zu\n", | ||
2247 | d->other_pool, d->pool_searches); | ||
2231 | dprintf(fd, "In use %zu\n", d->malloc_used); | 2248 | dprintf(fd, "In use %zu\n", d->malloc_used); |
2232 | dprintf(fd, "Guarded %zu\n", d->malloc_guarded); | 2249 | dprintf(fd, "Guarded %zu\n", d->malloc_guarded); |
2233 | dump_free_chunk_info(fd, d); | 2250 | dump_free_chunk_info(fd, d); |
@@ -2289,7 +2306,7 @@ malloc_gdump(int fd) | |||
2289 | int i; | 2306 | int i; |
2290 | int saved_errno = errno; | 2307 | int saved_errno = errno; |
2291 | 2308 | ||
2292 | for (i = 0; i < _MALLOC_MUTEXES; i++) | 2309 | for (i = 0; i < mopts.malloc_mutexes; i++) |
2293 | malloc_dump(fd, i, mopts.malloc_pool[i]); | 2310 | malloc_dump(fd, i, mopts.malloc_pool[i]); |
2294 | 2311 | ||
2295 | errno = saved_errno; | 2312 | errno = saved_errno; |
@@ -2305,15 +2322,15 @@ malloc_exit(void) | |||
2305 | if (fd != -1) { | 2322 | if (fd != -1) { |
2306 | dprintf(fd, "******** Start dump %s *******\n", __progname); | 2323 | dprintf(fd, "******** Start dump %s *******\n", __progname); |
2307 | dprintf(fd, | 2324 | dprintf(fd, |
2308 | "MT=%d I=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", | 2325 | "MT=%d M=%u I=%d F=%d U=%d J=%d R=%d X=%d C=%d cache=%u G=%zu\n", |
2309 | mopts.malloc_mt, mopts.internal_funcs, | 2326 | mopts.malloc_mt, mopts.mallloc_mutexes, |
2310 | mopts.malloc_freecheck, | 2327 | mopts.internal_funcs, mopts.malloc_freecheck, |
2311 | mopts.malloc_freeunmap, mopts.malloc_junk, | 2328 | mopts.malloc_freeunmap, mopts.malloc_junk, |
2312 | mopts.malloc_realloc, mopts.malloc_xmalloc, | 2329 | mopts.malloc_realloc, mopts.malloc_xmalloc, |
2313 | mopts.chunk_canaries, mopts.malloc_cache, | 2330 | mopts.chunk_canaries, mopts.malloc_cache, |
2314 | mopts.malloc_guard); | 2331 | mopts.malloc_guard); |
2315 | 2332 | ||
2316 | for (i = 0; i < _MALLOC_MUTEXES; i++) | 2333 | for (i = 0; i < mopts.malloc_mutexes; i++) |
2317 | malloc_dump(fd, i, mopts.malloc_pool[i]); | 2334 | malloc_dump(fd, i, mopts.malloc_pool[i]); |
2318 | dprintf(fd, "******** End dump %s *******\n", __progname); | 2335 | dprintf(fd, "******** End dump %s *******\n", __progname); |
2319 | close(fd); | 2336 | close(fd); |