Deleted Added
sdiff udiff text old ( 289900 ) new ( 296221 )
full compact
1#define JEMALLOC_PROF_C_
2#include "jemalloc/internal/jemalloc_internal.h"
3/******************************************************************************/
4
5#ifdef JEMALLOC_PROF_LIBUNWIND
6#define UNW_LOCAL_ONLY
7#include <libunwind.h>
8#endif

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

104static char prof_dump_buf[
105 /* Minimize memory bloat for non-prof builds. */
106#ifdef JEMALLOC_PROF
107 PROF_DUMP_BUFSIZE
108#else
109 1
110#endif
111];
112static size_t prof_dump_buf_end;
113static int prof_dump_fd;
114
115/* Do not dump any profiles until bootstrapping is complete. */
116static bool prof_booted = false;
117
118/******************************************************************************/
119/*
120 * Function prototypes for static functions that are referenced prior to

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

546}
547
548static prof_gctx_t *
549prof_gctx_create(tsd_t *tsd, prof_bt_t *bt)
550{
551 /*
552 * Create a single allocation that has space for vec of length bt->len.
553 */
554 size_t size = offsetof(prof_gctx_t, vec) + (bt->len * sizeof(void *));
555 prof_gctx_t *gctx = (prof_gctx_t *)iallocztm(tsd, size,
556 size2index(size), false, tcache_get(tsd, true), true, NULL, true);
557 if (gctx == NULL)
558 return (NULL);
559 gctx->lock = prof_gctx_mutex_choose();
560 /*
561 * Set nlimbo to 1, in order to avoid a race condition with
562 * prof_tctx_destroy()/prof_gctx_try_destroy().
563 */
564 gctx->nlimbo = 1;

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

589 assert(gctx->nlimbo != 0);
590 if (tctx_tree_empty(&gctx->tctxs) && gctx->nlimbo == 1) {
591 /* Remove gctx from bt2gctx. */
592 if (ckh_remove(tsd, &bt2gctx, &gctx->bt, NULL, NULL))
593 not_reached();
594 prof_leave(tsd, tdata_self);
595 /* Destroy gctx. */
596 malloc_mutex_unlock(gctx->lock);
597 idalloctm(tsd, gctx, tcache_get(tsd, false), true, true);
598 } else {
599 /*
600 * Compensate for increment in prof_tctx_destroy() or
601 * prof_lookup().
602 */
603 gctx->nlimbo--;
604 malloc_mutex_unlock(gctx->lock);
605 prof_leave(tsd, tdata_self);

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

696 prof_gctx_try_destroy(tsd, prof_tdata_get(tsd, false), gctx,
697 tdata);
698 }
699
700 if (destroy_tdata)
701 prof_tdata_destroy(tsd, tdata, false);
702
703 if (destroy_tctx)
704 idalloctm(tsd, tctx, tcache_get(tsd, false), true, true);
705}
706
707static bool
708prof_lookup_global(tsd_t *tsd, prof_bt_t *bt, prof_tdata_t *tdata,
709 void **p_btkey, prof_gctx_t **p_gctx, bool *p_new_gctx)
710{
711 union {
712 prof_gctx_t *p;

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

725 if (gctx.v == NULL) {
726 prof_leave(tsd, tdata);
727 return (true);
728 }
729 btkey.p = &gctx.p->bt;
730 if (ckh_insert(tsd, &bt2gctx, btkey.v, gctx.v)) {
731 /* OOM. */
732 prof_leave(tsd, tdata);
733 idalloctm(tsd, gctx.v, tcache_get(tsd, false), true,
734 true);
735 return (true);
736 }
737 new_gctx = true;
738 } else {
739 /*
740 * Increment nlimbo, in order to avoid a race condition with
741 * prof_tctx_destroy()/prof_gctx_try_destroy().
742 */

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

785 * cache.
786 */
787 if (prof_lookup_global(tsd, bt, tdata, &btkey, &gctx,
788 &new_gctx))
789 return (NULL);
790
791 /* Link a prof_tctx_t into gctx for this thread. */
792 tcache = tcache_get(tsd, true);
793 ret.v = iallocztm(tsd, sizeof(prof_tctx_t),
794 size2index(sizeof(prof_tctx_t)), false, tcache, true, NULL,
795 true);
796 if (ret.p == NULL) {
797 if (new_gctx)
798 prof_gctx_try_destroy(tsd, tdata, gctx, tdata);
799 return (NULL);
800 }
801 ret.p->tdata = tdata;
802 ret.p->thr_uid = tdata->thr_uid;
803 ret.p->thr_discrim = tdata->thr_discrim;
804 memset(&ret.p->cnts, 0, sizeof(prof_cnt_t));
805 ret.p->gctx = gctx;
806 ret.p->tctx_uid = tdata->tctx_uid_next++;
807 ret.p->prepared = true;
808 ret.p->state = prof_tctx_state_initializing;
809 malloc_mutex_lock(tdata->lock);
810 error = ckh_insert(tsd, &tdata->bt2tctx, btkey, ret.v);
811 malloc_mutex_unlock(tdata->lock);
812 if (error) {
813 if (new_gctx)
814 prof_gctx_try_destroy(tsd, tdata, gctx, tdata);
815 idalloctm(tsd, ret.v, tcache, true, true);
816 return (NULL);
817 }
818 malloc_mutex_lock(gctx->lock);
819 ret.p->state = prof_tctx_state_nominal;
820 tctx_tree_insert(&gctx->tctxs, ret.p);
821 gctx->nlimbo--;
822 malloc_mutex_unlock(gctx->lock);
823 }

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

866 * For more information on the math, see:
867 *
868 * Non-Uniform Random Variate Generation
869 * Luc Devroye
870 * Springer-Verlag, New York, 1986
871 * pp 500
872 * (http://luc.devroye.org/rnbookindex.html)
873 */
874 r = prng_lg_range(&tdata->prng_state, 53);
875 u = (double)r * (1.0/9007199254740992.0L);
876 tdata->bytes_until_sample = (uint64_t)(log(u) /
877 log(1.0 - (1.0 / (double)((uint64_t)1U << lg_prof_sample))))
878 + (uint64_t)1U;
879#endif
880}
881
882#ifdef JEMALLOC_JET

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

984 prof_dump_fd = -1;
985
986 return (ret);
987}
988
989static bool
990prof_dump_write(bool propagate_err, const char *s)
991{
992 size_t i, slen, n;
993
994 cassert(config_prof);
995
996 i = 0;
997 slen = strlen(s);
998 while (i < slen) {
999 /* Flush the buffer if it is full. */
1000 if (prof_dump_buf_end == PROF_DUMP_BUFSIZE)

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

1207 tctx_tree_iter(&gctx->tctxs, next,
1208 prof_tctx_finish_iter, NULL);
1209 if (to_destroy != NULL) {
1210 next = tctx_tree_next(&gctx->tctxs,
1211 to_destroy);
1212 tctx_tree_remove(&gctx->tctxs,
1213 to_destroy);
1214 idalloctm(tsd, to_destroy,
1215 tcache_get(tsd, false), true, true);
1216 } else
1217 next = NULL;
1218 } while (next != NULL);
1219 }
1220 gctx->nlimbo--;
1221 if (prof_gctx_should_destroy(gctx)) {
1222 gctx->nlimbo++;
1223 malloc_mutex_unlock(gctx->lock);

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

1354 goto label_return;
1355 }
1356
1357 ret = false;
1358label_return:
1359 return (ret);
1360}
1361
1362#ifndef _WIN32
1363JEMALLOC_FORMAT_PRINTF(1, 2)
1364static int
1365prof_open_maps(const char *format, ...)
1366{
1367 int mfd;
1368 va_list ap;
1369 char filename[PATH_MAX + 1];
1370
1371 va_start(ap, format);
1372 malloc_vsnprintf(filename, sizeof(filename), format, ap);
1373 va_end(ap);
1374 mfd = open(filename, O_RDONLY);
1375
1376 return (mfd);
1377}
1378#endif
1379
1380static int
1381prof_getpid(void)
1382{
1383
1384#ifdef _WIN32
1385 return (GetCurrentProcessId());
1386#else
1387 return (getpid());
1388#endif
1389}
1390
1391static bool
1392prof_dump_maps(bool propagate_err)
1393{
1394 bool ret;
1395 int mfd;
1396
1397 cassert(config_prof);
1398#ifdef __FreeBSD__
1399 mfd = prof_open_maps("/proc/curproc/map");
1400#elif defined(_WIN32)
1401 mfd = -1; // Not implemented
1402#else
1403 {
1404 int pid = prof_getpid();
1405
1406 mfd = prof_open_maps("/proc/%d/task/%d/maps", pid, pid);
1407 if (mfd == -1)
1408 mfd = prof_open_maps("/proc/%d/maps", pid);
1409 }
1410#endif
1411 if (mfd != -1) {
1412 ssize_t nread;

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

1565{
1566
1567 cassert(config_prof);
1568
1569 if (vseq != VSEQ_INVALID) {
1570 /* "<prefix>.<pid>.<seq>.v<vseq>.heap" */
1571 malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
1572 "%s.%d.%"FMTu64".%c%"FMTu64".heap",
1573 opt_prof_prefix, prof_getpid(), prof_dump_seq, v, vseq);
1574 } else {
1575 /* "<prefix>.<pid>.<seq>.<v>.heap" */
1576 malloc_snprintf(filename, DUMP_FILENAME_BUFSIZE,
1577 "%s.%d.%"FMTu64".%c.heap",
1578 opt_prof_prefix, prof_getpid(), prof_dump_seq, v);
1579 }
1580 prof_dump_seq++;
1581}
1582
1583static void
1584prof_fdump(void)
1585{
1586 tsd_t *tsd;

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

1725{
1726 prof_tdata_t *tdata;
1727 tcache_t *tcache;
1728
1729 cassert(config_prof);
1730
1731 /* Initialize an empty cache for this thread. */
1732 tcache = tcache_get(tsd, true);
1733 tdata = (prof_tdata_t *)iallocztm(tsd, sizeof(prof_tdata_t),
1734 size2index(sizeof(prof_tdata_t)), false, tcache, true, NULL, true);
1735 if (tdata == NULL)
1736 return (NULL);
1737
1738 tdata->lock = prof_tdata_mutex_choose(thr_uid);
1739 tdata->thr_uid = thr_uid;
1740 tdata->thr_discrim = thr_discrim;
1741 tdata->thread_name = thread_name;
1742 tdata->attached = true;
1743 tdata->expired = false;
1744 tdata->tctx_uid_next = 0;
1745
1746 if (ckh_new(tsd, &tdata->bt2tctx, PROF_CKH_MINITEMS,
1747 prof_bt_hash, prof_bt_keycomp)) {
1748 idalloctm(tsd, tdata, tcache, true, true);
1749 return (NULL);
1750 }
1751
1752 tdata->prng_state = (uint64_t)(uintptr_t)tdata;
1753 prof_sample_threshold_update(tdata);
1754
1755 tdata->enq = false;
1756 tdata->enq_idump = false;

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

1795
1796 assert(prof_tdata_should_destroy(tdata, even_if_attached));
1797 assert(tsd_prof_tdata_get(tsd) != tdata);
1798
1799 tdata_tree_remove(&tdatas, tdata);
1800
1801 tcache = tcache_get(tsd, false);
1802 if (tdata->thread_name != NULL)
1803 idalloctm(tsd, tdata->thread_name, tcache, true, true);
1804 ckh_delete(tsd, &tdata->bt2tctx);
1805 idalloctm(tsd, tdata, tcache, true, true);
1806}
1807
1808static void
1809prof_tdata_destroy(tsd_t *tsd, prof_tdata_t *tdata, bool even_if_attached)
1810{
1811
1812 malloc_mutex_lock(&tdatas_mtx);
1813 prof_tdata_destroy_locked(tsd, tdata, even_if_attached);

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

1958
1959 if (thread_name == NULL)
1960 return (NULL);
1961
1962 size = strlen(thread_name) + 1;
1963 if (size == 1)
1964 return ("");
1965
1966 ret = iallocztm(tsd, size, size2index(size), false, tcache_get(tsd,
1967 true), true, NULL, true);
1968 if (ret == NULL)
1969 return (NULL);
1970 memcpy(ret, thread_name, size);
1971 return (ret);
1972}
1973
1974int
1975prof_thread_name_set(tsd_t *tsd, const char *thread_name)

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

1992 }
1993
1994 s = prof_thread_name_alloc(tsd, thread_name);
1995 if (s == NULL)
1996 return (EAGAIN);
1997
1998 if (tdata->thread_name != NULL) {
1999 idalloctm(tsd, tdata->thread_name, tcache_get(tsd, false),
2000 true, true);
2001 tdata->thread_name = NULL;
2002 }
2003 if (strlen(s) > 0)
2004 tdata->thread_name = s;
2005 return (0);
2006}
2007
2008bool

--- 246 unchanged lines hidden ---