summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/include/thread_private.h4
-rw-r--r--src/lib/libc/stdlib/malloc.c57
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
11void _malloc_init(int); 11void _malloc_init(int);
12#ifdef __LIBC__ 12#ifdef __LIBC__
13PROTO_NORMAL(_malloc_init); 13PROTO_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
181struct malloc_readonly { 183struct 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
273static __dead void 277static __dead void
@@ -316,6 +320,16 @@ static void
316omalloc_parseopt(char opt) 320omalloc_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);